From 849e7196eb4ee7bc5ca8a5644da49ffbd3ff3c97 Mon Sep 17 00:00:00 2001 From: Julien Duroure Date: Fri, 1 Jul 2022 06:30:32 +0200 Subject: glTF exporter: Fix T99306 : Fix camera & light export when Yup is off --- io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py') diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py index ba63e049..0377a6b7 100644 --- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py +++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py @@ -163,10 +163,16 @@ class VExportTree: # So real world matrix is collection world_matrix @ "world_matrix" of object node.matrix_world = parent_coll_matrix_world @ blender_object.matrix_world.copy() if node.blender_type == VExportNode.CAMERA and self.export_settings[gltf2_blender_export_keys.CAMERAS]: - correction = Quaternion((2**0.5/2, -2**0.5/2, 0.0, 0.0)) + if self.export_settings[gltf2_blender_export_keys.YUP]: + correction = Quaternion((2**0.5/2, -2**0.5/2, 0.0, 0.0)) + else: + correction = Matrix.Identity(4).to_quaternion() node.matrix_world @= correction.to_matrix().to_4x4() elif node.blender_type == VExportNode.LIGHT and self.export_settings[gltf2_blender_export_keys.LIGHTS]: - correction = Quaternion((2**0.5/2, -2**0.5/2, 0.0, 0.0)) + if self.export_settings[gltf2_blender_export_keys.YUP]: + correction = Quaternion((2**0.5/2, -2**0.5/2, 0.0, 0.0)) + else: + correction = Matrix.Identity(4).to_quaternion() node.matrix_world @= correction.to_matrix().to_4x4() elif node.blender_type == VExportNode.BONE: if self.export_settings['gltf_current_frame'] is True: -- cgit v1.2.3 From 042fbefac686666190915d206600a5dab8e03066 Mon Sep 17 00:00:00 2001 From: Julien Duroure Date: Thu, 7 Jul 2022 08:03:39 +0200 Subject: glTF importer/exporter: Manage some official Khronos Extensions about Materials KHR_materials_ior KHR_materials_sheen KHR_materials_specular KHR_materials_transmission KHR_materials_variants KHR_materials_emissive_strength KHR_materials_volume Documentation update is still in progress --- io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py') diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py index 0377a6b7..36772667 100644 --- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py +++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py @@ -468,3 +468,20 @@ class VExportTree: skin = gather_skin(n.uuid, self.export_settings) skins.append(skin) return skins + + def variants_reset_to_original(self): + # Only if Variants are displayed and exported + if bpy.context.preferences.addons['io_scene_gltf2'].preferences.KHR_materials_variants_ui is False: + return + objects = [self.nodes[o].blender_object for o in self.get_all_node_of_type(VExportNode.OBJECT) if self.nodes[o].blender_object.type == "MESH" \ + and self.nodes[o].blender_object.data.get('gltf2_variant_default_materials') is not None] + for obj in objects: + # loop on material slots ( primitives ) + for mat_slot_idx, s in enumerate(obj.material_slots): + # Check if there is a default material for this slot + for i in obj.data.gltf2_variant_default_materials: + if i.material_slot_index == mat_slot_idx: + s.material = i.default_material + break + + # If not found, keep current material as default -- cgit v1.2.3 From 5b2953ad0883223bf8f58cf2bd650891f759bb65 Mon Sep 17 00:00:00 2001 From: Julien Duroure Date: Sat, 6 Aug 2022 11:52:04 +0200 Subject: glTF exporter: performance: cache parent/children data to avoid bad .children performance when used a lot Thanks rotoglup! --- .../blender/exp/gltf2_blender_gather_tree.py | 28 ++++++++++++++-------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py') diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py index 36772667..c654b445 100644 --- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py +++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py @@ -95,10 +95,18 @@ class VExportTree: bpy.context.window.scene = blender_scene depsgraph = bpy.context.evaluated_depsgraph_get() + # Gather parent/children information once, as calling bobj.children is + # very expensive operation : takes O(len(bpy.data.objects)) time. + blender_children = dict() + for bobj in bpy.data.objects: + bparent = bobj.parent + blender_children.setdefault(bobj, []) + blender_children.setdefault(bparent, []).append(bobj) + for blender_object in [obj.original for obj in depsgraph.scene_eval.objects if obj.parent is None]: - self.recursive_node_traverse(blender_object, None, None, Matrix.Identity(4)) + self.recursive_node_traverse(blender_object, None, None, Matrix.Identity(4), blender_children) - def recursive_node_traverse(self, blender_object, blender_bone, parent_uuid, parent_coll_matrix_world, armature_uuid=None, dupli_world_matrix=None): + def recursive_node_traverse(self, blender_object, blender_bone, parent_uuid, parent_coll_matrix_world, blender_children, armature_uuid=None, dupli_world_matrix=None): node = VExportNode() node.uuid = str(uuid.uuid4()) node.parent_uuid = parent_uuid @@ -199,42 +207,42 @@ class VExportTree: # standard children if blender_bone is None and blender_object.is_instancer is False: - for child_object in blender_object.children: + for child_object in blender_children[blender_object]: if child_object.parent_bone: # Object parented to bones # Will be manage later continue else: # Classic parenting - self.recursive_node_traverse(child_object, None, node.uuid, parent_coll_matrix_world) + self.recursive_node_traverse(child_object, None, node.uuid, parent_coll_matrix_world, blender_children) # Collections if blender_object.instance_type == 'COLLECTION' and blender_object.instance_collection: for dupli_object in blender_object.instance_collection.all_objects: if dupli_object.parent is not None: continue - self.recursive_node_traverse(dupli_object, None, node.uuid, node.matrix_world) + self.recursive_node_traverse(dupli_object, None, node.uuid, node.matrix_world, blender_children) # Armature : children are bones with no parent if blender_object.type == "ARMATURE" and blender_bone is None: for b in [b for b in blender_object.pose.bones if b.parent is None]: - self.recursive_node_traverse(blender_object, b, node.uuid, parent_coll_matrix_world, node.uuid) + self.recursive_node_traverse(blender_object, b, node.uuid, parent_coll_matrix_world, blender_children, node.uuid) # Bones if blender_object.type == "ARMATURE" and blender_bone is not None: for b in blender_bone.children: - self.recursive_node_traverse(blender_object, b, node.uuid, parent_coll_matrix_world, armature_uuid) + self.recursive_node_traverse(blender_object, b, node.uuid, parent_coll_matrix_world, blender_children, armature_uuid) # Object parented to bone if blender_bone is not None: - for child_object in [c for c in blender_object.children if c.parent_bone is not None and c.parent_bone == blender_bone.name]: - self.recursive_node_traverse(child_object, None, node.uuid, parent_coll_matrix_world) + for child_object in [c for c in blender_children[blender_object] if c.parent_bone is not None and c.parent_bone == blender_bone.name]: + self.recursive_node_traverse(child_object, None, node.uuid, parent_coll_matrix_world, blender_children) # Duplis if blender_object.is_instancer is True and blender_object.instance_type != 'COLLECTION': depsgraph = bpy.context.evaluated_depsgraph_get() for (dupl, mat) in [(dup.object.original, dup.matrix_world.copy()) for dup in depsgraph.object_instances if dup.parent and id(dup.parent.original) == id(blender_object)]: - self.recursive_node_traverse(dupl, None, node.uuid, parent_coll_matrix_world, dupli_world_matrix=mat) + self.recursive_node_traverse(dupl, None, node.uuid, parent_coll_matrix_world, blender_children, dupli_world_matrix=mat) def get_all_objects(self): return [n.uuid for n in self.nodes.values() if n.blender_type != VExportNode.BONE] -- cgit v1.2.3