Page MenuHome

Added Action.fcurves.find(data_path, array_index=0)
ClosedPublic

Authored by Sybren A. Stüvel (sybren) on Jul 21 2015, 2:54 PM.

Details

Summary

Finding a specific F-Curve is often needed in Python, and usually
consists of a construct like:

[fcurve
 for fcurve in ob.animation_data.action.fcurves
 if fcurve.data_path == "location"][1]

This can now be written as
ob.animation_data.action.fcurves.find('location', 1)

This new function Action.fcurves.find() is still O(N) in the number
of FCurves in the Action, but at least it allows us to remove
boiler-plate code. It is also faster than the Python equivalent, as
only the found F-Curve is converted to Python.

Diff Detail

Repository
rB Blender

Event Timeline

Sybren A. Stüvel (sybren) retitled this revision from to Added Action.fcurves.find(data_path, array_index=0).
Sybren A. Stüvel (sybren) updated this object.

Here's a blend file that demonstrates the feature's use:


Just run the script in the text editor and check the console output.

Joshua Leung (aligorith) requested changes to this revision.Jul 21 2015, 3:13 PM
Joshua Leung (aligorith) edited edge metadata.
Joshua Leung (aligorith) added inline comments.
source/blender/makesrna/intern/rna_action.c
130

Since you're not directly adding a FCurve, it may be better to just use list_find_fcurve directly (in the same way that verify_fcurve does now).

130

Another useful thing you could consider doing is to restrict the search to a FCurve from a particular group instead. You'd want the group name operator to be optional - if not provided, it uses the action's full set of fcurves as you're doing now.

Then this code becomes something like:

bActionGroup *agrp = BKE_action_group_find_name(act, groupname);
if (agrp) {
  return list_find_fcurve(&agrp->channels, data_path, index);
}
else {
  return list_find_fcurve(&act->curves, data_path, index);
}
604

I can see why adding this hint would be nice to have. However, since these same methods are used everywhere anyway (i.e. via the UI, etc.) I think everyone should have a fair idea of what the general performance is like.

This revision now requires changes to proceed.Jul 21 2015, 3:13 PM
source/blender/makesrna/intern/rna_action.c
130

Unfortunately, this doesn't work (I just tried). agrp->channels points to the first channel in the group. However, list_find_fcurve will keep iterating until it finds NULL, which is the last channel in the action. This means that such a search would only limit itself to the channels in the group and all subsequent channels. Fixing this would require keeping track of the last channel in the group as well, and limiting the search to that too. However, that seems like excessive work just to get this to work.

604

I agree that everybody should know that; however, for people that aren't intimitely familiar with Blender's structure, it might be a bit of a surprise that such a lookup is O(n) and not O(log n) or even O(1).

Sybren A. Stüvel (sybren) edited edge metadata.

Using list_find_fcurve

Sybren A. Stüvel (sybren) marked an inline comment as done.Jul 21 2015, 3:46 PM
Joshua Leung (aligorith) edited edge metadata.
Joshua Leung (aligorith) added inline comments.
source/blender/makesrna/intern/rna_action.c
129

Use c-style comment here

130

Oops... indeed, forgot about that issue. Ok, it's still fine without that extra filtering option :)

This revision is now accepted and ready to land.Jul 21 2015, 3:50 PM
Sybren A. Stüvel (sybren) edited edge metadata.

C-style comment

This revision was automatically updated to reflect the committed changes.
Sybren A. Stüvel (sybren) marked an inline comment as done.