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_fbx/export_fbx_bin.py')
-rw-r--r--io_scene_fbx/export_fbx_bin.py64
1 files changed, 40 insertions, 24 deletions
diff --git a/io_scene_fbx/export_fbx_bin.py b/io_scene_fbx/export_fbx_bin.py
index d3aeee76..7247caea 100644
--- a/io_scene_fbx/export_fbx_bin.py
+++ b/io_scene_fbx/export_fbx_bin.py
@@ -719,7 +719,8 @@ def fbx_data_bindpose_element(root, me_obj, me, scene_data, arm_obj=None, mat_wo
elem_data_single_string(fbx_pose, b"Type", b"BindPose")
elem_data_single_int32(fbx_pose, b"Version", FBX_POSE_BIND_VERSION)
- elem_data_single_int32(fbx_pose, b"NbPoseNodes", 1 + (1 if (arm_obj != me_obj) else 0) + len(bones))
+ elem_data_single_int32(fbx_pose, b"NbPoseNodes",
+ 1 + (1 if (arm_obj != me_obj and mat_world_arm) else 0) + len(bones))
# First node is mesh/object.
mat_world_obj = me_obj.fbx_object_matrix(scene_data, global_space=True)
@@ -727,7 +728,7 @@ def fbx_data_bindpose_element(root, me_obj, me, scene_data, arm_obj=None, mat_wo
elem_data_single_int64(fbx_posenode, b"Node", me_obj.fbx_uuid)
elem_data_single_float64_array(fbx_posenode, b"Matrix", matrix4_to_array(mat_world_obj))
# Second node is armature object itself.
- if arm_obj != me_obj:
+ if arm_obj != me_obj and mat_world_arm:
fbx_posenode = elem_empty(fbx_pose, b"PoseNode")
elem_data_single_int64(fbx_posenode, b"Node", arm_obj.fbx_uuid)
elem_data_single_float64_array(fbx_posenode, b"Matrix", matrix4_to_array(mat_world_arm))
@@ -1405,10 +1406,10 @@ def fbx_data_armature_elements(root, arm_obj, scene_data):
* Deformers (i.e. Skin), bind between an armature and a mesh.
** SubDeformers (i.e. Cluster), one per bone/vgroup pair.
* BindPose.
- Note armature itself has no data, it is a mere "Null" Model...
+ Note armature itself has no data, it is a mere "Null" Model (when exported)...
"""
- mat_world_arm = arm_obj.fbx_object_matrix(scene_data, global_space=True)
- bones = tuple(bo_obj for bo_obj in arm_obj.bones if bo_obj in scene_data.objects)
+ mat_world_arm = arm_obj.fbx_object_matrix(scene_data, global_space=True) if not arm_obj.skip_export else None
+ bones = tuple(bo_obj for bo_obj in arm_obj.bones if bo_obj in scene_data.objects and not bo_obj.skip_export)
bone_radius_scale = 33.0
@@ -1494,7 +1495,8 @@ def fbx_data_armature_elements(root, arm_obj, scene_data):
elem_data_single_float64_array(fbx_clstr, b"Transform",
matrix4_to_array(mat_world_bones[bo_obj].inverted_safe() * mat_world_obj))
elem_data_single_float64_array(fbx_clstr, b"TransformLink", matrix4_to_array(mat_world_bones[bo_obj]))
- elem_data_single_float64_array(fbx_clstr, b"TransformAssociateModel", matrix4_to_array(mat_world_arm))
+ if mat_world_arm:
+ elem_data_single_float64_array(fbx_clstr, b"TransformAssociateModel", matrix4_to_array(mat_world_arm))
def fbx_data_leaf_bone_elements(root, scene_data):
@@ -1758,8 +1760,11 @@ def fbx_skeleton_from_armature(scene, settings, arm_obj, objects, data_meshes,
Also supports "parent to bone" (simple parent to Model/LimbNode).
arm_parents is a set of tuples (armature, object) for all successful armature bindings.
"""
- # We need some data for our armature 'object' too!!!
- data_empties[arm_obj] = get_blender_empty_key(arm_obj.bdata)
+ if (settings.use_armature_as_root):
+ # We need some data for our armature 'object' too!!!
+ data_empties[arm_obj] = get_blender_empty_key(arm_obj.bdata)
+ else:
+ arm_obj.skip_export = True
arm_data = arm_obj.bdata.data
bones = OrderedDict()
@@ -1817,11 +1822,14 @@ def fbx_skeleton_from_armature(scene, settings, arm_obj, objects, data_meshes,
def fbx_generate_leaf_bones(settings, data_bones):
- # find which bons have no children
+ # find which bones have no children.
child_count = {bo: 0 for bo, _bo_key in data_bones.items()}
for bo, _bo_key in data_bones.items():
- if bo.parent and bo.parent.is_bone:
- child_count[bo.parent] += 1
+ if bo.skip_export:
+ continue
+ bo_par = bo.fbx_parent
+ if bo_par and bo_par.is_bone:
+ child_count[bo_par] += 1
bone_radius_scale = settings.global_scale * 33.0
@@ -2345,7 +2353,8 @@ def fbx_data_from_scene(scene, settings):
templates[b"Camera"] = fbx_template_def_camera(scene, settings, nbr_users=len(data_cameras))
if data_bones:
- templates[b"Bone"] = fbx_template_def_bone(scene, settings, nbr_users=len(data_bones))
+ nbr_users = sum(1 for db in data_bones if not db.skip_export)
+ templates[b"Bone"] = fbx_template_def_bone(scene, settings, nbr_users=nbr_users)
if data_meshes:
nbr = len({me_key for me_key, _me, _free in data_meshes.values()})
@@ -2354,7 +2363,8 @@ def fbx_data_from_scene(scene, settings):
templates[b"Geometry"] = fbx_template_def_geometry(scene, settings, nbr_users=nbr)
if objects:
- templates[b"Model"] = fbx_template_def_model(scene, settings, nbr_users=len(objects))
+ nbr_users = sum(1 for ob in objects if not ob.skip_export)
+ templates[b"Model"] = fbx_template_def_model(scene, settings, nbr_users=nbr_users)
if arm_parents:
# Number of Pose|BindPose elements should be the same as number of meshes-parented-to-armatures
@@ -2417,22 +2427,25 @@ def fbx_data_from_scene(scene, settings):
for ob_obj in objects:
# Bones are handled later.
if not ob_obj.is_bone:
- par_obj = ob_obj.parent
+ par_obj = ob_obj.fbx_parent
# Meshes parented to armature are handled separately, yet we want the 'no parent' connection (0).
- if par_obj and ob_obj.has_valid_parent(objects) and (par_obj, ob_obj) not in arm_parents:
+ if par_obj and ob_obj.has_valid_fbx_parent(objects) and (par_obj, ob_obj) not in arm_parents:
connections.append((b"OO", ob_obj.fbx_uuid, par_obj.fbx_uuid, None))
else:
connections.append((b"OO", ob_obj.fbx_uuid, 0, None))
# Armature & Bone chains.
for bo_obj in data_bones.keys():
- par_obj = bo_obj.parent
- if par_obj not in objects:
- continue
- connections.append((b"OO", bo_obj.fbx_uuid, par_obj.fbx_uuid, None))
+ par_obj = bo_obj.fbx_parent
+ if par_obj is None:
+ connections.append((b"OO", bo_obj.fbx_uuid, 0, None))
+ elif par_obj in objects:
+ connections.append((b"OO", bo_obj.fbx_uuid, par_obj.fbx_uuid, None))
# Object data.
for ob_obj in objects:
+ if ob_obj.skip_export:
+ continue
if ob_obj.is_bone:
bo_data_key = data_bones[ob_obj]
connections.append((b"OO", get_fbx_uuid_from_key(bo_data_key), ob_obj.fbx_uuid, None))
@@ -2767,7 +2780,7 @@ def fbx_objects_elements(root, scene_data):
perfmon.step("FBX export fetch objects (%d)..." % len(scene_data.objects))
for ob_obj in scene_data.objects:
- if ob_obj.is_dupli:
+ if ob_obj.is_dupli or ob_obj.skip_export:
continue
fbx_data_object_elements(objects, ob_obj, scene_data)
ob_obj.dupli_list_create(scene_data.scene, 'RENDER')
@@ -2840,6 +2853,7 @@ def fbx_takes_elements(root, scene_data):
# ##### "Main" functions. #####
# This func can be called with just the filepath
+# Warning! Arg order is not guaranteed, only use keyargs!
def save_single(operator, scene, filepath="",
global_matrix=Matrix(),
apply_unit_scale=False,
@@ -2849,7 +2863,11 @@ def save_single(operator, scene, filepath="",
object_types=None,
use_mesh_modifiers=True,
mesh_smooth_type='FACE',
+ use_armature_as_root=True,
use_armature_deform_only=False,
+ add_leaf_bones=False,
+ primary_bone_axis='Y',
+ secondary_bone_axis='X',
bake_anim=True,
bake_anim_use_all_bones=True,
bake_anim_use_nla_strips=True,
@@ -2857,9 +2875,6 @@ def save_single(operator, scene, filepath="",
bake_anim_step=1.0,
bake_anim_simplify_factor=1.0,
bake_anim_force_startend_keying=True,
- add_leaf_bones=False,
- primary_bone_axis='Y',
- secondary_bone_axis='X',
use_metadata=True,
path_mode='AUTO',
use_mesh_edges=True,
@@ -2919,7 +2934,8 @@ def save_single(operator, scene, filepath="",
bake_space_transform, global_matrix_inv, global_matrix_inv_transposed,
context_objects, object_types, use_mesh_modifiers,
mesh_smooth_type, use_mesh_edges, use_tspace,
- use_armature_deform_only, add_leaf_bones, bone_correction_matrix, bone_correction_matrix_inv,
+ use_armature_as_root, use_armature_deform_only, add_leaf_bones,
+ bone_correction_matrix, bone_correction_matrix_inv,
bake_anim, bake_anim_use_all_bones, bake_anim_use_nla_strips, bake_anim_use_all_actions,
bake_anim_step, bake_anim_simplify_factor, bake_anim_force_startend_keying,
False, media_settings, use_custom_props,