From 8fe942987f7f20713be9839fc12e09c6e75c27a0 Mon Sep 17 00:00:00 2001 From: Philipp Henzler Date: Tue, 12 Mar 2024 10:14:35 -0700 Subject: [PATCH] Fix bug when loading glbs with multiple meshes. (#311) The previous code was deleting all objects that were not of type "MESH" and then join all 'MESH' types. Doing it that way seemed to cause objects to 'split up' as they seem to have different transforms and their different parts are distributed all over the scene. The new code selects all objects of type "MESH" without removal of any objects. This seems to fix the issue. PiperOrigin-RevId: 611289628 Co-authored-by: kubric-team --- kubric/renderer/blender.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/kubric/renderer/blender.py b/kubric/renderer/blender.py index e17e0d53..3e5e2fa6 100644 --- a/kubric/renderer/blender.py +++ b/kubric/renderer/blender.py @@ -420,20 +420,28 @@ def _add_asset(self, obj: core.FileBasedObject): **obj.render_import_kwargs) # gltf files often contain "Empty" objects as placeholders for camera / lights etc. # here we are interested only in the meshes, we filter these out and join all meshes into one. - bpy.ops.object.select_all(action='DESELECT') - mesh = [m for m in bpy.context.scene.objects if m.type == 'MESH'] + mesh = [m for m in bpy.context.selected_objects if m.type == "MESH"] + assert mesh for ob in mesh: ob.select_set(state=True) bpy.context.view_layer.objects.active = ob # make sure one of the objects is active, otherwise join() fails. # see https://blender.stackexchange.com/questions/132266/joining-all-meshes-in-any-context-gets-error - bpy.context.view_layer.objects.active = ( - bpy.context.selected_objects[0] - ) + bpy.context.view_layer.objects.active = mesh[0] bpy.ops.object.join() - # By default gltf objects are loaded with a different rotation than obj files - # here we compensate for that to ensure alignment between pybullet and blender + + # Make sure to delete all remaining non-mesh objects. Note that for + # some reason deleting the non-mesh objets before joining removes + # parts of the meshes in some cases. + non_mesh_objects = [ + obj + for obj in bpy.context.selected_objects + if obj.type != "MESH" + ] + with bpy.context.temp_override(selected_objects=non_mesh_objects): + bpy.ops.object.delete() + assert len(bpy.context.selected_objects) == 1 blender_obj = bpy.context.selected_objects[0] blender_obj.rotation_quaternion = (0.707107, -0.707107, 0, 0)