[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