Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'io_scene_gltf2')
-rwxr-xr-xio_scene_gltf2/__init__.py49
-rw-r--r--io_scene_gltf2/blender/com/gltf2_blender_extras.py91
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather.py12
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channel_target.py9
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py10
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py4
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_cameras.py4
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py12
-rw-r--r--io_scene_gltf2/blender/exp/gltf2_blender_gather_lights.py3
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py4
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_mesh.py4
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py11
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_skins.py71
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_camera.py2
-rw-r--r--io_scene_gltf2/blender/imp/gltf2_blender_light.py4
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_material.py4
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_mesh.py3
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_node.py5
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_skin.py7
19 files changed, 273 insertions, 36 deletions
diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py
index 36fda5ce..06012f5e 100755
--- a/io_scene_gltf2/__init__.py
+++ b/io_scene_gltf2/__init__.py
@@ -15,7 +15,7 @@
bl_info = {
'name': 'glTF 2.0 format',
'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
- "version": (1, 0, 4),
+ "version": (1, 0, 9),
'blender': (2, 81, 6),
'location': 'File > Import-Export',
'description': 'Import-Export as glTF 2.0',
@@ -57,7 +57,8 @@ import bpy
from bpy.props import (StringProperty,
BoolProperty,
EnumProperty,
- IntProperty)
+ IntProperty,
+ CollectionProperty)
from bpy.types import Operator
from bpy_extras.io_utils import ImportHelper, ExportHelper
@@ -256,6 +257,12 @@ class ExportGLTF2_Base:
default=True
)
+ export_def_bones: BoolProperty(
+ name='Export Deformation bones only',
+ description='Export Deformation bones only (and needed bones for hierarchy)',
+ default=False
+ )
+
export_current_frame: BoolProperty(
name='Use Current Frame',
description='Export the scene in the current animation frame',
@@ -389,11 +396,16 @@ class ExportGLTF2_Base:
if self.export_animations:
export_settings['gltf_frame_range'] = self.export_frame_range
export_settings['gltf_force_sampling'] = self.export_force_sampling
+ if self.export_force_sampling:
+ export_settings['gltf_def_bones'] = self.export_def_bones
+ else:
+ export_settings['gltf_def_bones'] = False
export_settings['gltf_nla_strips'] = self.export_nla_strips
else:
export_settings['gltf_frame_range'] = False
export_settings['gltf_move_keyframes'] = False
export_settings['gltf_force_sampling'] = False
+ export_settings['gltf_def_bones'] = False
export_settings['gltf_skins'] = self.export_skins
if self.export_skins:
export_settings['gltf_all_vertex_influences'] = self.export_all_influences
@@ -642,6 +654,10 @@ class GLTF_PT_export_animation_export(bpy.types.Panel):
layout.prop(operator, 'export_force_sampling')
layout.prop(operator, 'export_nla_strips')
+ row = layout.row()
+ row.active = operator.export_force_sampling
+ row.prop(operator, 'export_def_bones')
+
class GLTF_PT_export_animation_shapekeys(bpy.types.Panel):
bl_space_type = 'FILE_BROWSER'
@@ -730,6 +746,11 @@ class ImportGLTF2(Operator, ImportHelper):
filter_glob: StringProperty(default="*.glb;*.gltf", options={'HIDDEN'})
+ files: CollectionProperty(
+ name="File Path",
+ type=bpy.types.OperatorFileListElement,
+ )
+
loglevel: IntProperty(
name='Log Level',
description="Log Level")
@@ -758,14 +779,30 @@ class ImportGLTF2(Operator, ImportHelper):
return self.import_gltf2(context)
def import_gltf2(self, context):
- import time
- from .io.imp.gltf2_io_gltf import glTFImporter
- from .blender.imp.gltf2_blender_gltf import BlenderGlTF
+ import os
self.set_debug_log()
import_settings = self.as_keywords()
- self.gltf_importer = glTFImporter(self.filepath, import_settings)
+ if self.files:
+ # Multiple file import
+ ret = {'CANCELLED'}
+ dirname = os.path.dirname(self.filepath)
+ for file in self.files:
+ path = os.path.join(dirname, file.name)
+ if self.unit_import(path, import_settings) == {'FINISHED'}:
+ ret = {'FINISHED'}
+ return ret
+ else:
+ # Single file import
+ return self.unit_import(self.filepath, import_settings)
+
+ def unit_import(self, filename, import_settings):
+ import time
+ from .io.imp.gltf2_io_gltf import glTFImporter
+ from .blender.imp.gltf2_blender_gltf import BlenderGlTF
+
+ self.gltf_importer = glTFImporter(filename, import_settings)
success, txt = self.gltf_importer.read()
if not success:
self.report({'ERROR'}, txt)
diff --git a/io_scene_gltf2/blender/com/gltf2_blender_extras.py b/io_scene_gltf2/blender/com/gltf2_blender_extras.py
new file mode 100644
index 00000000..0be942a0
--- /dev/null
+++ b/io_scene_gltf2/blender/com/gltf2_blender_extras.py
@@ -0,0 +1,91 @@
+# Copyright 2018-2019 The glTF-Blender-IO authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import bpy
+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):
+ """Filter and create a custom property, which is stored in the glTF extra field."""
+ if not blender_element:
+ return None
+
+ extras = {}
+
+ for custom_property in blender_element.keys():
+ if custom_property in BLACK_LIST:
+ continue
+
+ value = __to_json_compatible(blender_element[custom_property])
+
+ if value is not None:
+ extras[custom_property] = value
+
+ if not extras:
+ return None
+
+ return extras
+
+
+def __to_json_compatible(value):
+ """Make a value (usually a custom property) compatible with json"""
+
+ if isinstance(value, bpy.types.ID):
+ return value
+
+ elif isinstance(value, str):
+ return value
+
+ elif isinstance(value, (int, float)):
+ return value
+
+ # for list classes
+ elif isinstance(value, list):
+ value = list(value)
+ # make sure contents are json-compatible too
+ for index in range(len(value)):
+ value[index] = __to_json_compatible(value[index])
+ return value
+
+ # for IDPropertyArray classes
+ elif hasattr(value, "to_list"):
+ value = value.to_list()
+ return value
+
+ elif hasattr(value, "to_dict"):
+ value = value.to_dict()
+ 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/io_scene_gltf2/blender/exp/gltf2_blender_gather.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather.py
index 2e4bfe31..f4fd70dd 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather.py
@@ -19,7 +19,7 @@ from io_scene_gltf2.io.com.gltf2_io_debug import print_console
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
@@ -97,6 +97,14 @@ def __gather_animations(blender_scene, export_settings):
to_delete_idx.append(anim_idx)
+ # Merging extras
+ # Warning, some values can be overwritten if present in multiple merged animations
+ if animations[anim_idx].extras is not None:
+ for k in animations[anim_idx].extras.keys():
+ if animations[base_animation_idx].extras is None:
+ animations[base_animation_idx].extras = {}
+ animations[base_animation_idx].extras[k] = animations[anim_idx].extras[k]
+
offset_sampler = len(animations[base_animation_idx].samplers)
for sampler in animations[anim_idx].samplers:
animations[base_animation_idx].samplers.append(sampler)
@@ -124,6 +132,6 @@ 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/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channel_target.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channel_target.py
index 04028d20..fa0f9976 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channel_target.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channel_target.py
@@ -19,7 +19,7 @@ from io_scene_gltf2.io.com import gltf2_io
from io_scene_gltf2.blender.exp.gltf2_blender_gather_cache import cached
from io_scene_gltf2.blender.exp import gltf2_blender_gather_nodes
from io_scene_gltf2.blender.exp import gltf2_blender_gather_joints
-
+from io_scene_gltf2.blender.exp import gltf2_blender_gather_skins
@cached
def gather_animation_channel_target(channels: typing.Tuple[bpy.types.FCurve],
@@ -66,7 +66,12 @@ def __gather_node(channels: typing.Tuple[bpy.types.FCurve],
blender_bone = blender_object.path_resolve(channels[0].data_path.rsplit('.', 1)[0])
if isinstance(blender_bone, bpy.types.PoseBone):
- return gltf2_blender_gather_joints.gather_joint(blender_bone, export_settings)
+ if export_settings["gltf_def_bones"] is False:
+ return gltf2_blender_gather_joints.gather_joint(blender_bone, export_settings)
+ else:
+ bones, _, _ = gltf2_blender_gather_skins.get_bone_tree(None, blender_object)
+ if blender_bone.name in [b.name for b in bones]:
+ return gltf2_blender_gather_joints.gather_joint(blender_bone, export_settings)
return gltf2_blender_gather_nodes.gather_node(blender_object, None, export_settings)
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py
index edee0971..611cd74a 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py
@@ -22,6 +22,7 @@ from io_scene_gltf2.blender.exp.gltf2_blender_gather_cache import cached
from io_scene_gltf2.blender.exp import gltf2_blender_gather_animation_samplers
from io_scene_gltf2.blender.exp import gltf2_blender_gather_animation_channel_target
from io_scene_gltf2.blender.exp import gltf2_blender_get
+from io_scene_gltf2.blender.exp import gltf2_blender_gather_skins
@cached
@@ -58,7 +59,14 @@ def gather_animation_channels(blender_action: bpy.types.Action,
return []
# Then bake all bones
- for bone in blender_object.data.bones:
+ bones_to_be_animated = []
+ if export_settings["gltf_def_bones"] is False:
+ bones_to_be_animated = blender_object.data.bones
+ else:
+ bones_to_be_animated, _, _ = gltf2_blender_gather_skins.get_bone_tree(None, blender_object)
+ bones_to_be_animated = [blender_object.pose.bones[b.name] for b in bones_to_be_animated]
+
+ for bone in bones_to_be_animated:
for p in ["location", "rotation_quaternion", "scale"]:
channel = __gather_animation_channel(
(),
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py
index de205913..d55c20b1 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py
@@ -18,6 +18,7 @@ import typing
from io_scene_gltf2.io.com import gltf2_io
from io_scene_gltf2.blender.exp import gltf2_blender_gather_animation_channels
from io_scene_gltf2.io.com.gltf2_io_debug import print_console
+from ..com.gltf2_blender_extras import generate_extras
def gather_animations(blender_object: bpy.types.Object,
@@ -139,6 +140,9 @@ def __gather_extras(blender_action: bpy.types.Action,
blender_object: bpy.types.Object,
export_settings
) -> typing.Any:
+
+ if export_settings['gltf_extras']:
+ return generate_extras(blender_action)
return None
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_cameras.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_cameras.py
index e6d82121..3cde0fcb 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_cameras.py
+++ b/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/io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py
index 2059ea88..dce70c31 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py
@@ -20,6 +20,7 @@ from io_scene_gltf2.io.com import gltf2_io
from io_scene_gltf2.io.com import gltf2_io_debug
from io_scene_gltf2.blender.exp import gltf2_blender_extract
from io_scene_gltf2.blender.com import gltf2_blender_math
+from io_scene_gltf2.blender.exp import gltf2_blender_gather_skins
@cached
@@ -55,8 +56,15 @@ def gather_joint(blender_bone, export_settings):
# traverse into children
children = []
- for bone in blender_bone.children:
- children.append(gather_joint(bone, export_settings))
+
+ if export_settings["gltf_def_bones"] is False:
+ for bone in blender_bone.children:
+ children.append(gather_joint(bone, export_settings))
+ else:
+ _, children_, _ = gltf2_blender_gather_skins.get_bone_tree(None, blender_bone.id_data)
+ if blender_bone.name in children_.keys():
+ for bone in children_[blender_bone.name]:
+ children.append(gather_joint(blender_bone.id_data.pose.bones[bone], export_settings))
# finally add to the joints array containing all the joints in the hierarchy
return gltf2_io.Node(
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_lights.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_lights.py
index c87318d0..dbb59e21 100644
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_lights.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_lights.py
@@ -17,6 +17,7 @@ import math
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/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py
index 3f4466f5..9b9a9abe 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py
@@ -23,7 +23,7 @@ from io_scene_gltf2.blender.exp import gltf2_blender_gather_material_occlusion_t
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
@@ -136,7 +136,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/io_scene_gltf2/blender/exp/gltf2_blender_gather_mesh.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_mesh.py
index ca79ef33..3af26ced 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_mesh.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_mesh.py
@@ -18,7 +18,7 @@ from .gltf2_blender_export_keys import MORPH
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/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
index 32745027..6ab77945 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
@@ -25,7 +25,7 @@ from io_scene_gltf2.blender.exp import gltf2_blender_gather_mesh
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
@@ -135,7 +135,12 @@ def __gather_children(blender_object, blender_scene, export_settings):
# blender bones
if blender_object.type == "ARMATURE":
root_joints = []
- for blender_bone in blender_object.pose.bones:
+ if export_settings["gltf_def_bones"] is False:
+ bones = blender_object.pose.bones
+ else:
+ bones, _, _ = gltf2_blender_gather_skins.get_bone_tree(None, blender_object)
+ bones = [blender_object.pose.bones[b.name] for b in bones]
+ for blender_bone in bones:
if not blender_bone.parent:
joint = gltf2_blender_gather_joints.gather_joint(blender_bone, export_settings)
children.append(joint)
@@ -214,7 +219,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/io_scene_gltf2/blender/exp/gltf2_blender_gather_skins.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_skins.py
index 59af7d72..18503fdd 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_skins.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_skins.py
@@ -67,11 +67,14 @@ def __gather_inverse_bind_matrices(blender_object, export_settings):
axis_basis_change = mathutils.Matrix(
((1.0, 0.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0), (0.0, -1.0, 0.0, 0.0), (0.0, 0.0, 0.0, 1.0)))
- # build the hierarchy of nodes out of the bones
- root_bones = []
- for blender_bone in blender_object.pose.bones:
- if not blender_bone.parent:
- root_bones.append(blender_bone)
+ if export_settings['gltf_def_bones'] is False:
+ # build the hierarchy of nodes out of the bones
+ root_bones = []
+ for blender_bone in blender_object.pose.bones:
+ if not blender_bone.parent:
+ root_bones.append(blender_bone)
+ else:
+ _, children_, root_bones = get_bone_tree(None, blender_object)
matrices = []
@@ -86,8 +89,13 @@ def __gather_inverse_bind_matrices(blender_object, export_settings):
).inverted()
matrices.append(inverse_bind_matrix)
- for child in bone.children:
- __collect_matrices(child)
+ if export_settings['gltf_def_bones'] is False:
+ for child in bone.children:
+ __collect_matrices(child)
+ else:
+ if bone.name in children_.keys():
+ for child in children_[bone.name]:
+ __collect_matrices(blender_object.pose.bones[child])
# start with the "root" bones and recurse into children, in the same ordering as the how joints are gathered
for root_bone in root_bones:
@@ -114,18 +122,28 @@ def __gather_inverse_bind_matrices(blender_object, export_settings):
def __gather_joints(blender_object, export_settings):
root_joints = []
- # build the hierarchy of nodes out of the bones
- for blender_bone in blender_object.pose.bones:
- if not blender_bone.parent:
- root_joints.append(gltf2_blender_gather_joints.gather_joint(blender_bone, export_settings))
+ if export_settings['gltf_def_bones'] is False:
+ # build the hierarchy of nodes out of the bones
+ for blender_bone in blender_object.pose.bones:
+ if not blender_bone.parent:
+ root_joints.append(gltf2_blender_gather_joints.gather_joint(blender_bone, export_settings))
+ else:
+ _, children_, root_joints = get_bone_tree(None, blender_object)
+ root_joints = [gltf2_blender_gather_joints.gather_joint(i, export_settings) for i in root_joints]
# joints is a flat list containing all nodes belonging to the skin
joints = []
def __collect_joints(node):
joints.append(node)
- for child in node.children:
- __collect_joints(child)
+ if export_settings['gltf_def_bones'] is False:
+ for child in node.children:
+ __collect_joints(child)
+ else:
+ if node.name in children_.keys():
+ for child in children_[node.name]:
+ __collect_joints(gltf2_blender_gather_joints.gather_joint(blender_object.pose.bones[child], export_settings))
+
for joint in root_joints:
__collect_joints(joint)
@@ -140,3 +158,30 @@ def __gather_skeleton(blender_object, export_settings):
# In the future support the result of https://github.com/KhronosGroup/glTF/pull/1195
return None # gltf2_blender_gather_nodes.gather_node(blender_object, blender_scene, export_settings)
+@cached
+def get_bone_tree(blender_dummy, blender_object):
+
+ bones = []
+ children = {}
+ root_bones = []
+
+ def get_parent(bone):
+ bones.append(bone.name)
+ if bone.parent is not None:
+ if bone.parent.name not in children.keys():
+ children[bone.parent.name] = []
+ children[bone.parent.name].append(bone.name)
+ get_parent(bone.parent)
+ else:
+ root_bones.append(bone.name)
+
+ for bone in [b for b in blender_object.data.bones if b.use_deform is True]:
+ get_parent(bone)
+
+ # remove duplicates
+ for k, v in children.items():
+ children[k] = list(set(v))
+ list_ = list(set(bones))
+ root_ = list(set(root_bones))
+ return [blender_object.data.bones[b] for b in list_], children, [blender_object.pose.bones[b] for b in root_]
+
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_camera.py b/io_scene_gltf2/blender/imp/gltf2_blender_camera.py
index d746c1b1..ec5f0ee4 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_camera.py
+++ b/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 @@ class BlenderCamera():
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/io_scene_gltf2/blender/imp/gltf2_blender_light.py b/io_scene_gltf2/blender/imp/gltf2_blender_light.py
index 492c552e..6213091e 100644
--- a/io_scene_gltf2/blender/imp/gltf2_blender_light.py
+++ b/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."""
@@ -45,6 +47,8 @@ class BlenderLight():
else:
bpy.data.scenes[gltf.blender_scene].collection.objects.link(obj)
+ set_extras(obj.data, pylight.get('extras'))
+
return obj
@staticmethod
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_material.py b/io_scene_gltf2/blender/imp/gltf2_blender_material.py
index 55be1626..c5e3b51c 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_material.py
+++ b/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 @@ class BlenderMaterial():
mat = bpy.data.materials.new(name)
pymaterial.blender_material[vertex_color] = mat.name
+ set_extras(mat, pymaterial.extras)
+
mat.use_backface_culling = (pymaterial.double_sided != True)
ignore_map = False
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py b/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
index 1f7f7b66..eb92d9a3 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
@@ -16,6 +16,7 @@ import bpy
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 @@ class BlenderMesh():
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/io_scene_gltf2/blender/imp/gltf2_blender_node.py b/io_scene_gltf2/blender/imp/gltf2_blender_node.py
index 6a40aecc..a02514de 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_node.py
+++ b/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 @@ class BlenderNode():
name = "Object_" + str(node_idx)
obj = bpy.data.objects.new(name, mesh)
+ set_extras(obj, pynode.extras)
obj.rotation_mode = 'QUATERNION'
if gltf.blender_active_collection is not None:
bpy.data.collections[gltf.blender_active_collection].objects.link(obj)
@@ -104,6 +106,7 @@ class BlenderNode():
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)
@@ -134,6 +137,7 @@ class BlenderNode():
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
@@ -154,6 +158,7 @@ class BlenderNode():
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 gltf.blender_active_collection is not None:
bpy.data.collections[gltf.blender_active_collection].objects.link(obj)
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_skin.py b/io_scene_gltf2/blender/imp/gltf2_blender_skin.py
index 2758b348..00996371 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_skin.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_skin.py
@@ -17,7 +17,7 @@ import bpy
from mathutils import Vector, Matrix
from ..com.gltf2_blender_conversion import matrix_gltf_to_blender, scale_to_matrix
from ...io.imp.gltf2_io_binary import BinaryData
-
+from ..com.gltf2_blender_extras import set_extras
class BlenderSkin():
"""Blender Skinning / Armature."""
@@ -130,10 +130,15 @@ class BlenderSkin():
pynode.blender_bone_name = bone.name
pynode.blender_armature_name = pyskin.blender_armature_name
bone.tail = Vector((0.0, 1.0, 0.0)) # Needed to keep bone alive
+ # Custom prop on edit bone
+ set_extras(bone, pynode.extras)
# set bind and pose transforms
BlenderSkin.set_bone_transforms(gltf, skin_id, bone, node_id, parent)
bpy.ops.object.mode_set(mode="OBJECT")
+ # Custom prop on pose bone
+ if bone.name in obj.pose.bones:
+ set_extras(obj.pose.bones[bone.name], pynode.extras)
@staticmethod
def create_vertex_groups(gltf, skin_id):