question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Import/Perf: setting fcurve interpolation is very slow

See original GitHub issue

This 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:closed
  • Created 3 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
juliendurourecommented, Sep 11, 2020
0reactions
scurestcommented, Sep 11, 2020

@julienduroure Perfect!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Interpolation Modes | MotionBuilder 2022
When you set multiple keyframes for a property, MotionBuilder automatically interpolates the animation between the keyframes.
Read more >
How to change to constant interpolation mode from a python ...
If the script seems to behave slowly, it might not be the interpolation but the way the ... Setting the interpolation type at...
Read more >
How Can I Set the Interpolation of a F-Curve via Python ...
It's a long winding path to the fcurves ;), but once you get there it is quick to work with. Starting with the...
Read more >
Blender 2.8 Elastic Keyframe Interpolation and Sine F-curve ...
Animate 5 basic types of Elastic and Oscillating motion using keyframe and f-curve modifiers. Also learn to use Simple Deform, Screw, ...
Read more >
Curve interpolation methods in Motion - Apple Support
In Motion, you can use curve interpolation to set the shape of curves between keyframes. ... so a value change begins more slowly...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found