[Bf-extensions-cvs] [b756779] master: FBX export: add option to not key first/last frames of an exported action.

Bastien Montagne noreply at git.blender.org
Wed Jul 15 22:28:52 CEST 2015


Commit: b7567791a19f85b6886ab3bc933f9c2e1ed7333f
Author: Bastien Montagne
Date:   Wed Jul 15 21:37:41 2015 +0200
Branches: master
https://developer.blender.org/rBAb7567791a19f85b6886ab3bc933f9c2e1ed7333f

FBX export: add option to not key first/last frames of an exported action.

User request (see T45438).

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

M	io_scene_fbx/__init__.py
M	io_scene_fbx/export_fbx_bin.py
M	io_scene_fbx/fbx_utils.py

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

diff --git a/io_scene_fbx/__init__.py b/io_scene_fbx/__init__.py
index da4a423..7c75245 100644
--- a/io_scene_fbx/__init__.py
+++ b/io_scene_fbx/__init__.py
@@ -21,7 +21,7 @@
 bl_info = {
     "name": "FBX format",
     "author": "Campbell Barton, Bastien Montagne, Jens Restemeier",
-    "version": (3, 4, 7),
+    "version": (3, 4, 8),
     "blender": (2, 74, 0),
     "location": "File > Import-Export",
     "description": "FBX IO meshes, UV's, vertex colors, materials, textures, cameras, lamps and actions",
@@ -373,6 +373,11 @@ class ExportFBX(bpy.types.Operator, ExportHelper, IOFBXOrientationHelper):
                         "others will get no animation at all)",
             default=True,
             )
+    bake_anim_force_startend_keying = BoolProperty(
+            name="Force Start/End Keying",
+            description="Always add a keyframe at start and end of actions for animated channels",
+            default=True,
+            )
     bake_anim_step = FloatProperty(
             name="Sampling Rate",
             description="How often to evaluate animated values (in frames)",
@@ -475,6 +480,7 @@ class ExportFBX(bpy.types.Operator, ExportHelper, IOFBXOrientationHelper):
             col.prop(self, "bake_anim_use_all_bones")
             col.prop(self, "bake_anim_use_nla_strips")
             col.prop(self, "bake_anim_use_all_actions")
+            col.prop(self, "bake_anim_force_startend_keying")
             col.prop(self, "bake_anim_step")
             col.prop(self, "bake_anim_simplify_factor")
         else:
diff --git a/io_scene_fbx/export_fbx_bin.py b/io_scene_fbx/export_fbx_bin.py
index 1e6aa38..cfb5768 100644
--- a/io_scene_fbx/export_fbx_bin.py
+++ b/io_scene_fbx/export_fbx_bin.py
@@ -1850,6 +1850,7 @@ def fbx_animations_do(scene_data, ref_id, f_start, f_end, start_zero, objects=No
     scene = scene_data.scene
     meshes = scene_data.data_meshes
     force_keying = scene_data.settings.bake_anim_use_all_bones
+    force_sek = scene_data.settings.bake_anim_force_startend_keying
 
     if objects is not None:
         # Add bones and duplis!
@@ -1874,9 +1875,9 @@ def fbx_animations_do(scene_data, ref_id, f_start, f_end, start_zero, objects=No
         ACNW = AnimationCurveNodeWrapper
         loc, rot, scale, _m, _mr = ob_obj.fbx_object_tx(scene_data)
         rot_deg = tuple(convert_rad_to_deg_iter(rot))
-        animdata_ob[ob_obj] = (ACNW(ob_obj.key, 'LCL_TRANSLATION', ob_obj.is_bone and force_keying, loc),
-                               ACNW(ob_obj.key, 'LCL_ROTATION', ob_obj.is_bone and force_keying, rot_deg),
-                               ACNW(ob_obj.key, 'LCL_SCALING', ob_obj.is_bone and force_keying, scale))
+        animdata_ob[ob_obj] = (ACNW(ob_obj.key, 'LCL_TRANSLATION', ob_obj.is_bone and force_keying, force_sek, loc),
+                               ACNW(ob_obj.key, 'LCL_ROTATION', ob_obj.is_bone and force_keying, force_sek, rot_deg),
+                               ACNW(ob_obj.key, 'LCL_SCALING', ob_obj.is_bone and force_keying, force_sek, scale))
         p_rots[ob_obj] = rot
 
     animdata_shapes = OrderedDict()
@@ -1885,7 +1886,7 @@ def fbx_animations_do(scene_data, ref_id, f_start, f_end, start_zero, objects=No
         if not me.shape_keys.use_relative:
             continue
         for shape, (channel_key, geom_key, _shape_verts_co, _shape_verts_idx) in shapes.items():
-            acnode = AnimationCurveNodeWrapper(channel_key, 'SHAPE_KEY', False, (0.0,))
+            acnode = AnimationCurveNodeWrapper(channel_key, 'SHAPE_KEY', False, force_sek, (0.0,))
             # Sooooo happy to have to twist again like a mad snake... Yes, we need to write those curves twice. :/
             acnode.add_group(me_key, shape.name, shape.name, (shape.name,))
             animdata_shapes[channel_key] = (acnode, me, shape)
@@ -2817,6 +2818,7 @@ def save_single(operator, scene, filepath="",
                 bake_anim_use_all_actions=True,
                 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',
@@ -2881,7 +2883,7 @@ def save_single(operator, scene, filepath="",
         mesh_smooth_type, use_mesh_edges, use_tspace,
         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_step, bake_anim_simplify_factor, bake_anim_force_startend_keying,
         False, media_settings, use_custom_props,
     )
 
diff --git a/io_scene_fbx/fbx_utils.py b/io_scene_fbx/fbx_utils.py
index cb761dd..c4ae338 100644
--- a/io_scene_fbx/fbx_utils.py
+++ b/io_scene_fbx/fbx_utils.py
@@ -719,7 +719,9 @@ class AnimationCurveNodeWrapper:
     This class provides a same common interface for all (FBX-wise) AnimationCurveNode and AnimationCurve elements,
     and easy API to handle those.
     """
-    __slots__ = ('elem_keys', '_keys', 'default_values', 'fbx_group', 'fbx_gname', 'fbx_props', 'force_keying')
+    __slots__ = (
+        'elem_keys', '_keys', 'default_values', 'fbx_group', 'fbx_gname', 'fbx_props',
+        'force_keying', 'force_startend_keying')
 
     kinds = {
         'LCL_TRANSLATION': ("Lcl Translation", "T", ("X", "Y", "Z")),
@@ -728,13 +730,14 @@ class AnimationCurveNodeWrapper:
         'SHAPE_KEY': ("DeformPercent", "DeformPercent", ("DeformPercent",)),
     }
 
-    def __init__(self, elem_key, kind, force_keying, default_values=...):
+    def __init__(self, elem_key, kind, force_keying, force_startend_keying, default_values=...):
         self.elem_keys = [elem_key]
         assert(kind in self.kinds)
         self.fbx_group = [self.kinds[kind][0]]
         self.fbx_gname = [self.kinds[kind][1]]
         self.fbx_props = [self.kinds[kind][2]]
         self.force_keying = force_keying
+        self.force_startend_keying = force_startend_keying
         self._keys = []  # (frame, values, write_flags)
         if default_values is not ...:
             assert(len(default_values) == len(self.fbx_props[0]))
@@ -822,9 +825,10 @@ class AnimationCurveNodeWrapper:
             are_keyed[:] = [True] * len(are_keyed)
 
         # If we did key something, ensure first and last sampled values are keyed as well.
-        for idx, is_keyed in enumerate(are_keyed):
-            if is_keyed:
-                keys[0][2][idx] = keys[-1][2][idx] = True
+        if self.force_startend_keying:
+            for idx, is_keyed in enumerate(are_keyed):
+                if is_keyed:
+                    keys[0][2][idx] = keys[-1][2][idx] = True
 
     def get_final_data(self, scene, ref_id, force_keep=False):
         """
@@ -1200,7 +1204,7 @@ FBXExportSettings = namedtuple("FBXExportSettings", (
     "mesh_smooth_type", "use_mesh_edges", "use_tspace",
     "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_step", "bake_anim_simplify_factor", "bake_anim_force_startend_keying",
     "use_metadata", "media_settings", "use_custom_props",
 ))



More information about the Bf-extensions-cvs mailing list