@@ -99,6 +99,7 @@ def __init__(
9999 ):
100100 self ._blend_file = blend_file
101101 self ._bpy_settings_file = bpy_settings_file
102+ self ._client_objects = None
102103
103104 def reset_scene (self ):
104105 """
@@ -138,15 +139,32 @@ def render_image(self, *, params: RenderParams, output_path: Path):
138139 code = compile (f .read (), self ._bpy_settings_file , "exec" )
139140 exec (code , {"bpy" : bpy }, dict ())
140141
142+ self ._client_objects = bpy .data .collections .new ("ClientObjects" )
143+ old_count = len (bpy .data .objects )
141144 # Import a glTF file. Note that the Blender glTF importer imposes a
142145 # +90 degree rotation around the X-axis when loading meshes. Thus, we
143146 # counterbalance the rotation right after the glTF-loading.
144- # TODO(#39) This is very suspicious. Get to the bottom of it.
145147 bpy .ops .import_scene .gltf (filepath = str (params .scene ))
148+ new_count = len (bpy .data .objects )
149+ # Reality check that all of the imported objects are selected by
150+ # default.
151+ assert new_count - old_count == len (bpy .context .selected_objects )
152+
153+ # TODO(#39) This rotation is very suspicious. Get to the bottom of it.
154+ # We explicitly specify the pivot point for the rotation to allow for
155+ # glTF files with root nodes with arbitrary positioning. We simply want
156+ # to rotate around the world origin.
146157 bpy .ops .transform .rotate (
147- value = math .pi / 2 , orient_axis = "X" , orient_type = "GLOBAL"
158+ value = math .pi / 2 ,
159+ orient_axis = "X" ,
160+ orient_type = "GLOBAL" ,
161+ center_override = (0 , 0 , 0 ),
148162 )
149163
164+ # All imported objects get put in our "client objects" collection.
165+ for obj in bpy .context .selected_objects :
166+ self ._client_objects .objects .link (obj )
167+
150168 # Set rendering parameters.
151169 scene = bpy .context .scene
152170 scene .render .image_settings .file_format = "PNG"
@@ -247,6 +265,13 @@ def label_render_settings(self):
247265 world_nodes = bpy .data .worlds ["World" ].node_tree .nodes
248266 world_nodes ["Background" ].inputs [0 ].default_value = background_color
249267
268+ # Every object imported from the glTF file has been placed in a
269+ # special collection; simply test for its presence.
270+ assert self ._client_objects is not None
271+
272+ def is_from_gltf (object ):
273+ return object .name in self ._client_objects .objects
274+
250275 # Iterate over all meshes and set their label values.
251276 for bpy_object in bpy .data .objects :
252277 assert bpy_object is not None
@@ -257,11 +282,10 @@ def label_render_settings(self):
257282 if bpy_object .type != "MESH" :
258283 continue
259284
260- # If a mesh is imported from a glTF, its parent node will be
261- # `Renderer Node`, and we will set its label value to its diffuse
262- # color. If a mesh is loaded from a blend file, its label value
263- # will be set to white (same as the background).
264- if bpy_object .parent .name == "Renderer Node" :
285+ # If a mesh is imported from a glTF, we will set its label value to
286+ # its diffuse color. If a mesh is loaded from a blend file, its
287+ # label value will be set to white (same as the background).
288+ if is_from_gltf (bpy_object ):
265289 mesh_color = bpy_object .data .materials [0 ].diffuse_color
266290 else :
267291 mesh_color = background_color
0 commit comments