I’m attempting to create some additional nodes for the Animation Nodes add-on which allow me to describe a kinematic structure with nodes, with the code inside handling the details of implementing this in an armature.
The short story. Can I…
- Edit an armature (bones: add, move, set parents…) without going into edit mode (to access the edit_bones objects?
- Create a node for Animation Nodes that isn’t run repeatedly all the time but only when something in the node tree has changed?
The long story…
My prototype (script to run straight from the text editor) works great.
import bpy
from mathutils import Vector
# select the armature to work with
obj = bpy.data.objects['ArmatureObject']
arm = obj.data
bpy.ops.object.mode_set(mode='EDIT')
for bone in arm.edit_bones:
arm.edit_bones.remove(bone)
root = arm.edit_bones.new('root')
root.head = [0, 0, 0]
root.tail = [0, 0, 1]
bone1 = arm.edit_bones.new('bone1')
bone1.head = root.tail
bone1.tail = bone1.head + Vector([0 , 1.5, 1]) # fixed in armaturelocal coords
bone1.parent = root
bone1.use_connect = True
bone1.use_inherit_scale = False
bone2 = arm.edit_bones.new('bone2')
bone2.head = bone1.tail
bone2.tail = bone1.matrix*(Vector([0, bone1.length, 0]) + Vector([0, 1, 0])) # relative to bone1! Puts the new tail along that second vector but in the coordinate frame of bone1
bone2.parent = bone1
bone2.use_connect = True
bone2.use_inherit_scale = False
bone2.align_roll(Vector([1, 0, 0])) # TODO need to think more about this one
# back to object mode
bpy.ops.object.mode_set(mode='OBJECT')
So I started trying to implement these as custom new nodes for Animation Nodes, starting with a node that “resets” the armature so that the subsequent nodes will each add a couple bones. But this is being re-run all the time - not only CPU inefficient, but also the constant switching between object and edit mode prevents me from switching the armature to pose mode to work with it. (also it turns out I’m not selecting the armature so bpy.ops knows about it so the node tree crashes if I select any other objects). So I’m hoping that there’s a way to not have to change the armature into Edit Mode to change the bones… or there’s some way to have Animation Nodes not run al the time, but only when there’s a change to the node tee.
Anybody have ideas on this? Thanks,
import bpy
from ... base_types import AnimationNode
class ArmInit(bpy.types.Node, AnimationNode):
bl_idname = "an_ArmInitNode"
bl_label = "Armature Init"
def create(self):
# Type Name Identifier
self.newInput("Object", "Armature Object", "obj")
def execute(self, obj):
if obj is None:
return
bpy.ops.object.mode_set(mode='EDIT')
for bone in obj.data.edit_bones:
obj.data.edit_bones.remove(bone)
root = obj.data.edit_bones.new('root')
root.head = [0, 0, 0]
root.tail = [0, 0, 1]
bpy.ops.object.mode_set(mode='OBJECT')