Adding to BPY

I need to add some operators to BPY that will allow the UI to manipulate the new data that AnimData can hold in my build.

What I’m thinking to do is add some straightfoward methods directly to bpy.types.AnimData that would allow for the functionality I need, but I can’t seem to find it. Does anyone know where the AnimData Python-object is located? Does the Python-object translate into the C-based bAction at all?

i don’t think an operator relates somehow to a bpy.types.* type, in python it would be bpy.ops.anim.* for instance, not related to the animation_data object (no one of its methods, that would be low-level, operators aren’t)

Which files hold the operators, then? I’m looking through the Python-folder in a rush, and the ones I’m reading don’t have anything looking even remotely similar to what I need.

Some operators are define in c, some are defined in python.

>>> bpy.ops.anim.keyframe_insert.get_rna()
<bpy_struct, ANIM_OT_keyframe_insert at 0x00000000>

search file content: “\2.66\scripts” ANIM_OT_keyframe_insert: no results
search file content: “\source\blender” ANIM_OT_keyframe_insert:

anim_intern.h
anim_ops.c
armature_ops.c
interface_anim.c
interface_handlers.c
keyframing.c
object_ops.c
outliner_ops.c

Operator in c are usually define in the editors _ops.c file.

This ones in source\blender\editors\animation\keyframing.c

void ANIM_OT_keyframe_insert(wmOperatorType *ot)
{
    /* .. */
}

you can add operators to anim data in python.

“anim.my_operator”

you should be able to add pointer properties to, havnt checked though.

bpy.types.AnimData()
bpy.types.AnimDataDrivers()
bpy.types.AnimViz()
bpy.types.AnimVizMotionPaths()
bpy.types.AnimVizOnionSkinning()

Python ops are mostly here:
Blender\2.66\scripts\startup\bl_operators\

For C-ops, it’s not enough to code the operator itself, you also need to register it, e.g.:
WM_operatortype_append(ANIM_OT_change_frame);

That should make it available also to python.

I tried adding a property to AnimData.
Its a bit different.

script

import bpy
bpy.types.AnimData.my_int = bpy.props.IntProperty(default=3)
bpy.types.Scene.test = bpy.data.objects['Cube'].animation_data.my_int

console

&gt;&gt;&gt; bpy.data.objects['Cube'].animation_data.my_int
(&lt;built-in function IntProperty&gt;, {'default': 3, 'attr': 'test'})

&gt;&gt;&gt; bpy.context.scene.test
3

..

&gt;&gt;&gt; bpy.data.objects['Cube'].animation_data.my_int[0]
&lt;built-in function IntProperty&gt;

&gt;&gt;&gt; bpy.data.objects['Cube'].animation_data.my_int[1]
{'default': 3, 'attr': 'test'}

..

&gt;&gt;&gt; bpy.data.objects['Cube'].animation_data.my_int(
my_int()
tuple() -&gt; empty tuple
tuple(iterable) -&gt; tuple initialized from iterable's items
If the argument is a tuple, the return value is the same object.

&gt;&gt;&gt; bpy.data.objects['Cube'].animation_data.my_int[0](
my_int[0](name="", description="", default=0, min=-sys.maxint, max=sys.maxint, soft_min=-sys.maxint, soft_max=sys.maxint, step=1, options={'ANIMATABLE'}, subtype='NONE', update=None, get=None, set=None)
.. function:: IntProperty(name="", description="", default=0, min=-sys.maxint, max=sys.maxint, soft_min=-sys.maxint, soft_max=sys.maxint, step=1, options={'ANIMATABLE'}, subtype='NONE', update=None, get=None, set=None)
Returns a new int property definition.
:arg name: Name used in the user interface.
:type name: string
:arg description: Text used for the tooltip and api documentation.
:type description: string
:arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].
:type options: set
:arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].
:type subtype: string
:arg update: function to be called when this value is modified,
   This function must take 2 values (self, context) and return None.
   *Warning* there are no safety checks to avoid infinite recursion.
:type update: function

&gt;&gt;&gt; bpy.data.objects['Cube'].animation_data.my_int[1](
my_int[1]()
dict() -&gt; new empty dictionary
dict(mapping) -&gt; new dictionary initialized from a mapping object's
    (key, value) pairs
dict(iterable) -&gt; new dictionary initialized as if via:
    d = {}
    for k, v in iterable:
        d[k] = v
dict(**kwargs) -&gt; new dictionary initialized with the name=value pairs
    in the keyword argument list.  For example:  dict(one=1, two=2)

python operator.

script

import bpy

class ANIM_OT_my_operator(bpy.types.Operator):
    bl_idname = "anim.my_operator"
    bl_label = "My Operator"

    def execute(self, context):

        # code

        return{'FINISHED'}

bpy.utils.register_class(ANIM_OT_my_operator)

console

&gt;&gt;&gt; bpy.ops.anim.my_operator()
{'FINISHED'}

(<built-in function *Property>, {…}) means that this type doesn’t support custom properties

‘Does the Python-object translate into the C-based bAction at all?’

&gt;&gt;&gt; bpy.types.Action
&gt;&gt;&gt; bpy.data.actions
&gt;&gt;&gt; bpy.context.active_object.animation_data.action

&gt;&gt;&gt; bpy.data.actions['CubeAction'].fcurves    // c: ListBase curves;    // FCurve        curves
&gt;&gt;&gt; bpy.data.actions['CubeAction'].groups    // c: ListBase groups;    // bActionGroup    groups

How do I go about adding to the Python version of Action? Where is it located?

I’m thinking it wiser to make the new data viewable within the UI first, then mimic game properties moreso than keyframing.

Add some keyframes before trying to access animation_data.

This is global Action property.

script

import bpy
bpy.types.Action.my_int = bpy.props.IntProperty(default=2)

console

>>> bpy.context.active_object.animation_data.action.my_int
2

keyframes are added to channels or groups which are a set of channels (keyingsets).

Location.Z

>>> bpy.context.active_object.animation_data.action.groups[‘Location’].channels[2].

What I’m doing has nothing to do with keyframing: the time-based logic I’m implementing is a wholly independent component of the action.