1

I'm looking for a way to be sure a script affect only f-curves that are showing up to the user in the graph editor (post filtering) for WYSIWYG style control.

In details: Currently I'm getting the actions from the objects directly after checking the properties of the graph editor (check if "show_only_selected" is on for exemple) in the graph editor, then try to get related actions from selected objects.

Problem is : With the filter show_only_selected toggled On in graph editor, In the case of armature selected, if some of it's bones are unselected there are hided in editor but still affected by the script (I get all the fcurves of the actions). Other animated properties might be affected while being invisible to the user or on the contrary being not affected while being visible.

A way to directly iterate on filtered f-curves would be really nice (if not necessary) to apply some script on what the user see/isolate.

Even more details in this blender artist thread :

Pullup
  • 145
  • 6

1 Answers1

1

context.selected_editable_fcurves

New to blender 2.79.1 is context.selected_editable_fcurves Test script. Prepends a toggle button to graph editor header. Runs update code on each toggle that will print the visible fcurves to console.

Edited to include all "visible" fcurves in the graph editor.

import bpy
from bpy.props import BoolProperty

def foo(self, context):
    selected = context.selected_editable_fcurves[:]
    bpy.ops.graph.select_all_toggle(invert=True)
    others = context.selected_editable_fcurves[:]
    others.extend(selected)
    others = set(others)
    print("-" * 72)
    print("%d selected of %d visible" % (len(selected), len(others)))
    for fc in others:
        fc.select = fc in selected
        print("action:", fc.id_data.name, 
              "data_path:", fc.data_path, 
              "{%d}" % fc.array_index,
              fc.select)

    return None

bpy.types.Scene.testfc = BoolProperty(update=foo)

def testfc(self, context):
    scene = context.scene
    self.layout.prop(scene, "testfc", toggle=True)

bpy.types.GRAPH_HT_header.prepend(testfc)

Even before this context attribute became available, the same thing could be done by deselecting all fcurves (using a.fcurves.foreach_set("select", [False] * len(a.fcurves))) in all actions, then selecting all with bpy.ops.graph.select_all_toggle, those selected will be the visible ones, and reinstating to original selection.

batFINGER
  • 84,216
  • 10
  • 108
  • 233
  • This is not exactly what I was looking for (since I want to get all the visible Fcurve, not selected only) But it's really interesting and might be super usefull ! When I use your script I get the Error : AttributeError: 'Context' object has no attribute 'selected_editable_fcurves'. in what context you suppose to get this ? I tried to find it manually in interactive console (with lines like bpy.context.window_manager.windows[0].screen.areas[8].spaces ...) but I could not found anything. – Pullup Oct 13 '17 at 14:46
  • Need to have version 2.79.1, but could use same method in prior versions, see edit on bottom of q. – batFINGER Oct 14 '17 at 13:44
  • The legendary BATfinger struck again ! I appreciate that you described a way to do this in older Blender version because I'm currently stuck in a 2.77 environment (yeah, I know...). Thank you. – Pullup Oct 16 '17 at 09:09
  • It looks like bpy.ops.graph.select_all_toggle(invert=True) has been replaced with bpy.ops.graph.select_all(action='INVERT') in 2.80! Also, if using filters in the graph editor results in NO visible fcurves, calling the select_all operator throws an incorrect context error! Any ideas on how to get around that? Thanks :) – andyV Dec 15 '18 at 03:56
  • Yep the selection has changed in API.. see here Will also need to use ob.select_set(True) . Hard to tell what issue is, Does the incorrect context error message give any clues? perhaps another question?. – batFINGER Dec 15 '18 at 08:10
  • \2.80\scripts\modules\bpy\ops.py", line 200, in __call__ ret = op_call(self.idname_py(), None, kw) Operator bpy.ops.graph.select_all.poll() failed, context is incorrect Calling the operator directly from the keymap with no curves visible doesn't throw an error, but calling it through script does. – andyV Dec 15 '18 at 08:55
  • To clarify If the operator is being invoked from the text editor or py console then the context area type will not be 'GRAPH_EDITOR' and will need to be overidden. If there is no need to run the op from another space (other than testing) wouldn't be too concerned. (can wrap context.area.type = toggle around the script.. or as in answer add button to space. See https://blender.stackexchange.com/a/6105/15543 – batFINGER Dec 15 '18 at 09:06
  • I'm calling it from within the graph editor. I put your script in a basic graph editor operator and added it to the graph editor keymap. So, it should be in the right context but I could be wrong. Also the script works with no errors as long as there's at least one visible curve in the editor. – andyV Dec 15 '18 at 09:29
  • 1
    Cool, pays to check. Could be a bug.(shrug) (and if so) may be easier in short term to use try except for that case. – batFINGER Dec 15 '18 at 09:38