diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_generate_extras.py b/addons/io_scene_gltf2/blender/com/gltf2_blender_extras.py similarity index 72% rename from addons/io_scene_gltf2/blender/exp/gltf2_blender_generate_extras.py rename to addons/io_scene_gltf2/blender/com/gltf2_blender_extras.py index 4137f257c..91da9045a 100644 --- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_generate_extras.py +++ b/addons/io_scene_gltf2/blender/com/gltf2_blender_extras.py @@ -14,7 +14,11 @@ import bpy -from io_scene_gltf2.blender.com import gltf2_blender_json +from .gltf2_blender_json import is_json_convertible + + +# Custom properties, which are in most cases present and should not be imported/exported. +BLACK_LIST = ['cycles', 'cycles_visibility', 'cycles_curves', '_RNA_UI'] def generate_extras(blender_element): @@ -24,21 +28,16 @@ def generate_extras(blender_element): extras = {} - # Custom properties, which are in most cases present and should not be exported. - black_list = ['cycles', 'cycles_visibility', 'cycles_curves', '_RNA_UI'] - - count = 0 for custom_property in blender_element.keys(): - if custom_property in black_list: + if custom_property in BLACK_LIST: continue value = __to_json_compatible(blender_element[custom_property]) if value is not None: extras[custom_property] = value - count += 1 - if count == 0: + if not extras: return None return extras @@ -71,7 +70,21 @@ def __to_json_compatible(value): elif hasattr(value, "to_dict"): value = value.to_dict() - if gltf2_blender_json.is_json_convertible(value): + if is_json_convertible(value): return value return None + + +def set_extras(blender_element, extras, exclude=[]): + """Copy extras onto a Blender object.""" + if not extras or not isinstance(extras, dict): + return + + for custom_property, value in extras.items(): + if custom_property in BLACK_LIST: + continue + if custom_property in exclude: + continue + + blender_element[custom_property] = value diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather.py index 1c835239f..721239237 100644 --- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather.py +++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather.py @@ -19,7 +19,7 @@ from io_scene_gltf2.blender.exp import gltf2_blender_gather_nodes from io_scene_gltf2.blender.exp import gltf2_blender_gather_animations from io_scene_gltf2.blender.exp.gltf2_blender_gather_cache import cached -from io_scene_gltf2.blender.exp import gltf2_blender_generate_extras +from ..com.gltf2_blender_extras import generate_extras from io_scene_gltf2.blender.exp import gltf2_blender_export_keys @@ -124,5 +124,5 @@ def __gather_animations(blender_scene, export_settings): def __gather_extras(blender_object, export_settings): if export_settings[gltf2_blender_export_keys.EXTRAS]: - return gltf2_blender_generate_extras.generate_extras(blender_object) + return generate_extras(blender_object) return None diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_cameras.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_cameras.py index f7c5a1dae..e0bb18894 100644 --- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_cameras.py +++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_cameras.py @@ -14,7 +14,7 @@ from . import gltf2_blender_export_keys from io_scene_gltf2.blender.exp.gltf2_blender_gather_cache import cached -from io_scene_gltf2.blender.exp import gltf2_blender_generate_extras +from ..com.gltf2_blender_extras import generate_extras from io_scene_gltf2.io.com import gltf2_io import bpy @@ -46,7 +46,7 @@ def __gather_extensions(blender_camera, export_settings): def __gather_extras(blender_camera, export_settings): if export_settings['gltf_extras']: - return gltf2_blender_generate_extras.generate_extras(blender_camera) + return generate_extras(blender_camera) return None diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_lights.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_lights.py index c17b54f45..5d76674b3 100644 --- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_lights.py +++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_lights.py @@ -17,6 +17,7 @@ from typing import Optional, List, Dict, Any from io_scene_gltf2.blender.exp.gltf2_blender_gather_cache import cached +from ..com.gltf2_blender_extras import generate_extras from io_scene_gltf2.io.com import gltf2_io_lights_punctual from io_scene_gltf2.io.com import gltf2_io_debug @@ -112,6 +113,8 @@ def __gather_extensions(blender_lamp, export_settings) -> Optional[dict]: def __gather_extras(blender_lamp, export_settings) -> Optional[Any]: + if export_settings['gltf_extras']: + return generate_extras(blender_lamp) return None diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py index 8c18c6b13..347693f48 100644 --- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py +++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py @@ -23,7 +23,7 @@ from io_scene_gltf2.blender.exp import gltf2_blender_search_node_tree from io_scene_gltf2.blender.exp import gltf2_blender_gather_materials_pbr_metallic_roughness -from io_scene_gltf2.blender.exp import gltf2_blender_generate_extras +from ..com.gltf2_blender_extras import generate_extras from io_scene_gltf2.blender.exp import gltf2_blender_get @@ -146,7 +146,7 @@ def __gather_extensions(blender_material, export_settings): def __gather_extras(blender_material, export_settings): if export_settings['gltf_extras']: - return gltf2_blender_generate_extras.generate_extras(blender_material) + return generate_extras(blender_material) return None diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_mesh.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_mesh.py index 7fe3a6019..a4d02cf9e 100644 --- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_mesh.py +++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_mesh.py @@ -18,7 +18,7 @@ from io_scene_gltf2.blender.exp.gltf2_blender_gather_cache import cached from io_scene_gltf2.io.com import gltf2_io from io_scene_gltf2.blender.exp import gltf2_blender_gather_primitives -from io_scene_gltf2.blender.exp import gltf2_blender_generate_extras +from ..com.gltf2_blender_extras import generate_extras from io_scene_gltf2.io.com.gltf2_io_debug import print_console @@ -76,7 +76,7 @@ def __gather_extras(blender_mesh: bpy.types.Mesh, extras = {} if export_settings['gltf_extras']: - extras = gltf2_blender_generate_extras.generate_extras(blender_mesh) or {} + extras = generate_extras(blender_mesh) or {} if export_settings[MORPH] and blender_mesh.shape_keys: morph_max = len(blender_mesh.shape_keys.key_blocks) - 1 diff --git a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py index 77b0a7be0..351eba21d 100644 --- a/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py +++ b/addons/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py @@ -25,7 +25,7 @@ from io_scene_gltf2.blender.exp import gltf2_blender_gather_joints from io_scene_gltf2.blender.exp import gltf2_blender_extract from io_scene_gltf2.blender.exp import gltf2_blender_gather_lights -from io_scene_gltf2.blender.exp import gltf2_blender_generate_extras +from ..com.gltf2_blender_extras import generate_extras from io_scene_gltf2.io.com import gltf2_io from io_scene_gltf2.io.com import gltf2_io_extensions @@ -228,7 +228,7 @@ def __gather_extensions(blender_object, export_settings): def __gather_extras(blender_object, export_settings): if export_settings['gltf_extras']: - return gltf2_blender_generate_extras.generate_extras(blender_object) + return generate_extras(blender_object) return None diff --git a/addons/io_scene_gltf2/blender/imp/gltf2_blender_camera.py b/addons/io_scene_gltf2/blender/imp/gltf2_blender_camera.py index 315c26548..7684f2f1a 100644 --- a/addons/io_scene_gltf2/blender/imp/gltf2_blender_camera.py +++ b/addons/io_scene_gltf2/blender/imp/gltf2_blender_camera.py @@ -13,6 +13,7 @@ # limitations under the License. import bpy +from ..com.gltf2_blender_extras import set_extras class BlenderCamera(): @@ -29,6 +30,7 @@ def create(gltf, camera_id): pycamera.name = "Camera" cam = bpy.data.cameras.new(pycamera.name) + set_extras(cam, pycamera.extras) # Blender create a perspective camera by default if pycamera.type == "orthographic": diff --git a/addons/io_scene_gltf2/blender/imp/gltf2_blender_light.py b/addons/io_scene_gltf2/blender/imp/gltf2_blender_light.py index 577402daa..901b82f5f 100644 --- a/addons/io_scene_gltf2/blender/imp/gltf2_blender_light.py +++ b/addons/io_scene_gltf2/blender/imp/gltf2_blender_light.py @@ -15,6 +15,8 @@ import bpy from math import pi +from ..com.gltf2_blender_extras import set_extras + class BlenderLight(): """Blender Light.""" @@ -48,6 +50,8 @@ def create(gltf, light_id): else: bpy.data.scenes[gltf.blender_scene].collection.objects.link(obj) + set_extras(obj.data, pylight.get('extras')) + return obj @staticmethod diff --git a/addons/io_scene_gltf2/blender/imp/gltf2_blender_material.py b/addons/io_scene_gltf2/blender/imp/gltf2_blender_material.py index 75f514943..ef226c479 100644 --- a/addons/io_scene_gltf2/blender/imp/gltf2_blender_material.py +++ b/addons/io_scene_gltf2/blender/imp/gltf2_blender_material.py @@ -13,6 +13,8 @@ # limitations under the License. import bpy + +from ..com.gltf2_blender_extras import set_extras from .gltf2_blender_pbrMetallicRoughness import BlenderPbr from .gltf2_blender_KHR_materials_pbrSpecularGlossiness import BlenderKHR_materials_pbrSpecularGlossiness from .gltf2_blender_KHR_materials_unlit import BlenderKHR_materials_unlit @@ -49,6 +51,8 @@ def create(gltf, material_idx, vertex_color): mat = bpy.data.materials.new(name) pymaterial.blender_material[vertex_color] = mat.name + set_extras(mat, pymaterial.extras) + if bpy.app.version < (2, 80, 0): pass # Blender 2.79 did not have a per-material double-sided flag. else: diff --git a/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py b/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py index b2eb06587..9628293cd 100644 --- a/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py +++ b/addons/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py @@ -16,6 +16,7 @@ import bmesh from mathutils import Vector +from ..com.gltf2_blender_extras import set_extras from .gltf2_blender_material import BlenderMaterial from .gltf2_blender_primitive import BlenderPrimitive from ...io.imp.gltf2_io_binary import BinaryData @@ -75,6 +76,8 @@ def create(gltf, mesh_idx, node_idx, parent): mesh.materials.append(bpy.data.materials[name_material]) mesh.update() + set_extras(mesh, pymesh.extras, exclude=['targetNames']) + pymesh.blender_name = mesh.name # Clear accessor cache after all primitives are done diff --git a/addons/io_scene_gltf2/blender/imp/gltf2_blender_node.py b/addons/io_scene_gltf2/blender/imp/gltf2_blender_node.py index 356968eb6..3f86e054f 100644 --- a/addons/io_scene_gltf2/blender/imp/gltf2_blender_node.py +++ b/addons/io_scene_gltf2/blender/imp/gltf2_blender_node.py @@ -13,6 +13,7 @@ # limitations under the License. import bpy +from ..com.gltf2_blender_extras import set_extras from .gltf2_blender_mesh import BlenderMesh from .gltf2_blender_camera import BlenderCamera from .gltf2_blender_skin import BlenderSkin @@ -76,6 +77,7 @@ def create(gltf, node_idx, parent): name = "Object_" + str(node_idx) obj = bpy.data.objects.new(name, mesh) + set_extras(obj, pynode.extras) obj.rotation_mode = 'QUATERNION' if bpy.app.version < (2, 80, 0): bpy.data.scenes[gltf.blender_scene].objects.link(obj) @@ -107,6 +109,7 @@ def create(gltf, node_idx, parent): else: gltf.log.info("Blender create Camera node") obj = BlenderCamera.create(gltf, pynode.camera) + set_extras(obj, pynode.extras) BlenderNode.set_transforms(gltf, node_idx, pynode, obj, parent) # TODO default rotation of cameras ? pynode.blender_object = obj.name BlenderNode.set_parent(gltf, obj, parent) @@ -137,6 +140,7 @@ def create(gltf, node_idx, parent): if pynode.extensions is not None: if 'KHR_lights_punctual' in pynode.extensions.keys(): obj = BlenderLight.create(gltf, pynode.extensions['KHR_lights_punctual']['light']) + set_extras(obj, pynode.extras) obj.rotation_mode = 'QUATERNION' BlenderNode.set_transforms(gltf, node_idx, pynode, obj, parent, correction=True) pynode.blender_object = obj.name @@ -157,6 +161,7 @@ def create(gltf, node_idx, parent): else: gltf.log.info("Blender create Empty node") obj = bpy.data.objects.new("Node", None) + set_extras(obj, pynode.extras) obj.rotation_mode = 'QUATERNION' if bpy.app.version < (2, 80, 0): bpy.data.scenes[gltf.blender_scene].objects.link(obj)