[Bf-extensions-cvs] [a691677] master: FBX Importer: Allow changes to bone orientation during import, allow ignoring "end" bones added by some modellers.

Bastien Montagne noreply at git.blender.org
Mon Sep 8 15:02:04 CEST 2014


Commit: a6916776e7952a6fba010427fb97b4582e961775
Author: Bastien Montagne
Date:   Mon Sep 8 14:32:41 2014 +0200
Branches: master
https://developer.blender.org/rBAa6916776e7952a6fba010427fb97b4582e961775

FBX Importer: Allow changes to bone orientation during import, allow ignoring "end" bones added by some modellers.

Revision: D732

Patch by jrestemeier (Jens Restemeier).

===================================================================

M	io_scene_fbx_experimental/__init__.py
M	io_scene_fbx_experimental/fbx_utils.py
M	io_scene_fbx_experimental/import_fbx.py

===================================================================

diff --git a/io_scene_fbx_experimental/__init__.py b/io_scene_fbx_experimental/__init__.py
index efa88e3..aa10ca8 100644
--- a/io_scene_fbx_experimental/__init__.py
+++ b/io_scene_fbx_experimental/__init__.py
@@ -135,6 +135,42 @@ class ImportFBX_experimental(bpy.types.Operator, ImportHelper):
             options={'HIDDEN'},
             )
 
+    ignore_leaf_bones = BoolProperty(
+            name="Ignore leaf bones",
+            description="Ignore the last bone at the end of a chain that is used to mark the length of the previous bone",
+            default=False,
+            options={'HIDDEN'},
+            )
+
+    automatic_bone_orientation = BoolProperty(
+            name="Automatic Bone Orientation",
+            description="Try to align the major bone axis with the bone children",
+            default=False,
+            options={'HIDDEN'},
+            )
+    primary_bone_axis = EnumProperty(
+            name="Primary Bone Axis",
+            items=(('X', "X Axis", ""),
+                   ('Y', "Y Axis", ""),
+                   ('Z', "Z Axis", ""),
+                   ('-X', "-X Axis", ""),
+                   ('-Y', "-Y Axis", ""),
+                   ('-Z', "-Z Axis", ""),
+                   ),
+            default='Y',
+            )
+    secondary_bone_axis = EnumProperty(
+            name="Secondary Bone Axis",
+            items=(('X', "X Axis", ""),
+                   ('Y', "Y Axis", ""),
+                   ('Z', "Z Axis", ""),
+                   ('-X', "-X Axis", ""),
+                   ('-Y', "-Y Axis", ""),
+                   ('-Z', "-Z Axis", ""),
+                   ),
+            default='X',
+            )
+
     def draw(self, context):
         layout = self.layout
 
@@ -154,6 +190,14 @@ class ImportFBX_experimental(bpy.types.Operator, ImportHelper):
         sub.enabled = self.use_custom_props
         sub.prop(self, "use_custom_props_enum_as_string")
 
+        layout.prop(self, "ignore_leaf_bones")
+
+        layout.prop(self, "automatic_bone_orientation"),
+        sub = layout.column()
+        sub.enabled = not self.automatic_bone_orientation
+        sub.prop(self, "primary_bone_axis")
+        sub.prop(self, "secondary_bone_axis")
+
     def execute(self, context):
         print("Using EXPERIMENTAL FBX export!")
         keywords = self.as_keywords(ignore=("filter_glob", "directory"))
diff --git a/io_scene_fbx_experimental/fbx_utils.py b/io_scene_fbx_experimental/fbx_utils.py
index d661cea..5ffdb8e 100644
--- a/io_scene_fbx_experimental/fbx_utils.py
+++ b/io_scene_fbx_experimental/fbx_utils.py
@@ -1100,5 +1100,7 @@ FBXImportSettings = namedtuple("FBXImportSettings", (
     "use_cycles", "use_image_search",
     "use_alpha_decals", "decal_offset",
     "use_custom_props", "use_custom_props_enum_as_string",
-    "object_tdata_cache", "cycles_material_wrap_map", "image_cache",
+    "cycles_material_wrap_map", "image_cache",
+    "ignore_leaf_bones",
+    "automatic_bone_orientation", "bone_correction_matrix"
 ))
diff --git a/io_scene_fbx_experimental/import_fbx.py b/io_scene_fbx_experimental/import_fbx.py
index d809fd6..4bb6443 100644
--- a/io_scene_fbx_experimental/import_fbx.py
+++ b/io_scene_fbx_experimental/import_fbx.py
@@ -420,232 +420,6 @@ def blen_read_object_transform_preprocess(fbx_props, fbx_obj, rot_alt_mat):
                             sca, sca_ofs, sca_piv)
 
 
-def blen_read_object(fbx_tmpl, fbx_obj, object_data, settings):
-    elem_name_utf8 = elem_name_ensure_class(fbx_obj)
-
-    # Object data must be created already
-    obj = bpy.data.objects.new(name=elem_name_utf8, object_data=object_data)
-    object_tdata_cache = settings.object_tdata_cache
-
-    fbx_props = (elem_find_first(fbx_obj, b'Properties70'),
-                 elem_find_first(fbx_tmpl, b'Properties70', fbx_elem_nil))
-    assert(fbx_props[0] is not None)
-
-    # ----
-    # Misc Attributes
-
-    obj.color[0:3] = elem_props_get_color_rgb(fbx_props, b'Color', (0.8, 0.8, 0.8))
-    obj.hide = not bool(elem_props_get_visibility(fbx_props, b'Visibility', 1.0))
-
-    # ----
-    # Transformation
-
-    from mathutils import Matrix
-    from math import pi
-
-    # rotation corrections
-    if obj.type == 'CAMERA':
-        rot_alt_mat = MAT_CONVERT_CAMERA
-    elif obj.type == 'LAMP':
-        rot_alt_mat = MAT_CONVERT_LAMP
-    else:
-        rot_alt_mat = Matrix()
-
-    transform_data = object_tdata_cache.get(obj)
-    if transform_data is None:
-        transform_data = blen_read_object_transform_preprocess(fbx_props, fbx_obj, rot_alt_mat)
-        object_tdata_cache[obj] = transform_data
-    obj.matrix_basis = blen_read_object_transform_do(transform_data)
-
-    if settings.use_custom_props:
-        blen_read_custom_properties(fbx_obj, obj, settings)
-
-    return obj
-
-
-# --------
-# Armature
-
-def blen_read_armatures_add_bone(bl_obj, bl_arm, bones, b_uuid, matrices, fbx_tmpl_model):
-    from mathutils import Matrix, Vector
-
-    b_item, bsize, p_uuid, clusters = bones[b_uuid]
-    fbx_bdata, bl_bname = b_item
-    if bl_bname is not None:
-        return bl_arm.edit_bones[bl_bname]  # Have already been created...
-
-    p_ebo = None
-    if p_uuid is not None:
-        # Recurse over parents!
-        p_ebo = blen_read_armatures_add_bone(bl_obj, bl_arm, bones, p_uuid, matrices, fbx_tmpl_model)
-
-    if clusters:
-        # Note in some cases, one bone can have several clusters (kind of LoD?), in Blender we'll always
-        # use only the first, for now.
-        fbx_cdata, meshes, objects = clusters[0]
-        objects = {blen_o for fbx_o, blen_o in objects}
-
-        # We assume matrices in cluster are rest pose of bones (they are in Global space!).
-        # TransformLink is matrix of bone, in global space.
-        # TransformAssociateModel is matrix of armature, in global space (at bind time).
-        elm = elem_find_first(fbx_cdata, b'Transform', default=None)
-        mmat_bone = array_to_matrix4(elm.props[0]) if elm is not None else None
-        elm = elem_find_first(fbx_cdata, b'TransformLink', default=None)
-        bmat_glob = array_to_matrix4(elm.props[0]) if elm is not None else Matrix()
-        elm = elem_find_first(fbx_cdata, b'TransformAssociateModel', default=None)
-        amat_glob = array_to_matrix4(elm.props[0]) if elm is not None else Matrix()
-
-        mmat_glob = bmat_glob * mmat_bone
-
-        # We seek for matrix of bone in armature space...
-        bmat_arm = amat_glob.inverted_safe() * bmat_glob
-
-        # Bone correction, works here...
-        bmat_loc = (p_ebo.matrix.inverted_safe() * bmat_arm) if p_ebo else bmat_arm
-        bmat_loc = bmat_loc * MAT_CONVERT_BONE
-        bmat_arm = (p_ebo.matrix * bmat_loc) if p_ebo else bmat_loc
-    else:
-        # Armature bound to no mesh...
-        fbx_cdata, meshes, objects = (None, (), ())
-        mmat_bone = None
-        amat_glob = bl_obj.matrix_world
-
-        fbx_props = (elem_find_first(fbx_bdata, b'Properties70'),
-                     elem_find_first(fbx_tmpl_model, b'Properties70', fbx_elem_nil))
-        assert(fbx_props[0] is not None)
-
-        # Bone correction, works here...
-        transform_data = blen_read_object_transform_preprocess(fbx_props, fbx_bdata, MAT_CONVERT_BONE)
-        bmat_loc = blen_read_object_transform_do(transform_data)
-        # Bring back matrix in armature space.
-        bmat_arm = (p_ebo.matrix * bmat_loc) if p_ebo else bmat_loc
-
-    # ----
-    # Now, create the (edit)bone.
-    bone_name = elem_name_ensure_class(fbx_bdata, b'Model')
-
-    ebo = bl_arm.edit_bones.new(name=bone_name)
-    bone_name = ebo.name  # Might differ from FBX bone name!
-    b_item[1] = bone_name  # since ebo is only valid in Edit mode... :/
-
-    # So that our bone gets its final length, but still Y-aligned in armature space.
-    # XXX We now know bsize is not len of bone... but still forbid zero len!
-    ebo.tail = Vector((0.0, 1.0, 0.0)) * max(bsize, 1e-3)
-    # And rotate/move it to its final "rest pose".
-    ebo.matrix = bmat_arm.normalized()
-
-    # Connection to parent.
-    if p_ebo is not None:
-        ebo.parent = p_ebo
-        if similar_values_iter(p_ebo.tail, ebo.head):
-            ebo.use_connect = True
-
-    if fbx_cdata is not None:
-        # ----
-        # Add a new vgroup to the meshes (their objects, actually!).
-        # Quite obviously, only one mesh is expected...
-        indices = elem_prop_first(elem_find_first(fbx_cdata, b'Indexes', default=None), default=())
-        weights = elem_prop_first(elem_find_first(fbx_cdata, b'Weights', default=None), default=())
-        add_vgroup_to_objects(indices, weights, bone_name, objects)
-
-    # ----
-    # If we get a valid mesh matrix (in bone space), store armature and mesh global matrices, we need to set temporarily
-    # both objects to those matrices when actually binding them via the modifier.
-    # Note we assume all bones were bound with the same mesh/armature (global) matrix, we do not support otherwise
-    # in Blender anyway!
-    if mmat_bone is not None:
-        for obj in objects:
-            if obj in matrices:
-                continue
-            matrices[obj] = (amat_glob, mmat_glob)
-
-    return ebo
-
-
-def blen_read_armatures(fbx_tmpl, armatures, fbx_bones_to_fake_object, scene, arm_parents, settings):
-    from mathutils import Matrix
-
-    global_matrix = settings.global_matrix
-    assert(global_matrix is not None)
-    object_tdata_cache = settings.object_tdata_cache
-
-    for a_item, bones in armatures:
-        fbx_adata, bl_adata = a_item
-        matrices = {}
-
-        # ----
-        # Armature data.
-        elem_name_utf8 = elem_name_ensure_class(fbx_adata, b'Model')
-        bl_arm = bpy.data.armatures.new(name=elem_name_utf8)
-
-        # Need to create the object right now, since we can only add bones in Edit mode... :/
-        assert(a_item[1] is None)
-
-        if fbx_adata.props[2] in {b'LimbNode', b'Root'}:
-            # rootbone-as-armature case...
-            bl_adata = blen_read_object(fbx_tmpl, fbx_adata, bl_arm, settings)
-            fbx_bones_to_fake_object[fbx_adata.props[0]] = bl_adata
-            # reset transform.
-            bl_adata.matrix_basis = M

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list