Import/Perf: setting fcurve interpolation is very slow
See original GitHub issueThis loop that sets the interpolation on all keyframes in an fcurve typically takes up alone around 40-60% of the time spent importing animations.
Since the interpolation
property is a string, we can’t foreach_set it and, AFAICT by looking through the docs or other importers, there’s no other way to set this that’s faster. (You may remember my abortive attempt to use the prefs for it in #867.)
I was wondering if it would be possible to ask upstream in Blender for some kind of help with this. Either pointing out an existing API or adding a new one. I don’t know what the best way to do it would be. For glTF we don’t need full element-level granularity like foreach_set gives, we could just use, for example, a new interpolation
arg in keyframe_points.add
that sets the same interpolation on all added points. For example, these patches
Patch for Blender
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index d5449a69cf6..843e30c9133 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -985,7 +985,7 @@ static BezTriple *rna_FKeyframe_points_insert(
return NULL;
}
-static void rna_FKeyframe_points_add(ID *id, FCurve *fcu, Main *bmain, int tot)
+static void rna_FKeyframe_points_add(ID *id, FCurve *fcu, Main *bmain, int tot, int ipo)
{
if (tot > 0) {
BezTriple *bezt;
@@ -998,7 +998,7 @@ static void rna_FKeyframe_points_add(ID *id, FCurve *fcu, Main *bmain, int tot)
while (tot--) {
/* defaults, no userprefs gives predictable results for API */
bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
- bezt->ipo = BEZT_IPO_BEZ;
+ bezt->ipo = ipo;
bezt->h1 = bezt->h2 = HD_AUTO_ANIM;
bezt++;
}
@@ -2220,6 +2220,12 @@ static void rna_def_fcurve_keyframe_points(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_int(
func, "count", 1, 0, INT_MAX, "Number", "Number of points to add to the spline", 0, INT_MAX);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ parm = RNA_def_enum(func,
+ "interpolation",
+ rna_enum_beztriple_interpolation_mode_items,
+ BEZT_IPO_BEZ,
+ "",
+ "interpolation of added keyframes");
func = RNA_def_function(srna, "remove", "rna_FKeyframe_points_remove");
RNA_def_function_ui_description(func, "Remove keyframe from an F-Curve");
Patch for us
diff --git a/addons/io_scene_gltf2/blender/imp/gltf2_blender_animation_utils.py b/addons/io_scene_gltf2/blender/imp/gltf2_blender_animation_utils.py
index 2d0d856..f4a96f6 100644
--- a/addons/io_scene_gltf2/blender/imp/gltf2_blender_animation_utils.py
+++ b/addons/io_scene_gltf2/blender/imp/gltf2_blender_animation_utils.py
@@ -58,25 +58,15 @@ def make_fcurve(action, co, data_path, index=0, group_name=None, interpolation=N
group = action.groups[group_name]
fcurve.group = group
- fcurve.keyframe_points.add(len(co) // 2)
+ ipo = {
+ 'STEP': 'CONSTANT',
+ 'LINEAR': 'LINEAR',
+ 'CUBICSPLINE': 'BEZIER',
+ }.get(interpolation)
+
+ fcurve.keyframe_points.add((len(co) // 2), interpolation=ipo)
fcurve.keyframe_points.foreach_set('co', co)
- # Setting interpolation
- if interpolation == 'CUBICSPLINE':
- for kf in fcurve.keyframe_points:
- kf.interpolation = 'BEZIER'
- kf.handle_right_type = 'AUTO'
- kf.handle_left_type = 'AUTO'
- else:
- if interpolation == 'LINEAR':
- blender_interpolation = 'LINEAR'
- elif interpolation == 'STEP':
- blender_interpolation = 'CONSTANT'
- else:
- blender_interpolation = 'LINEAR'
- for kf in fcurve.keyframe_points:
- kf.interpolation = blender_interpolation
-
fcurve.update() # force updating tangents (this may change when tangent will be managed)
return fcurve
would make setting the interpolation basically free for us.
Issue Analytics
- State:
- Created 3 years ago
- Comments:6 (3 by maintainers)
Top GitHub Comments
See https://developer.blender.org/D8808 too
@julienduroure Perfect!