7
$\begingroup$

how do you create an armature in Blender Python 2.7x without using bpy.ops? With meshes I would use something like

mesh = bpy.data.meshes.new(name)
object = bpy.data.objects.new(name, mesh)
bpy.context.scene.objects.link(object)
mesh.from_pydata(verts, [], faces)

I can do something similar with armatures however how do I make the actual bone body? In the outliner I can see the armature object but there is only an origin point in the scene. When using dir on the armature I don’t see an option along the lines of from_pydata.

pivot_bone = bpy.data.armatures.new('spam')
object = bpy.data.objects.new(name, pivot_bone)
bpy.context.scene.objects.link(object)
print(dir(pivot_bone))

Ultimately I would like to use Python to create a custom bone shape.

$\endgroup$

1 Answer 1

11
$\begingroup$

Fairly sure that mesh data is the only one that offers from_pyData for others we need to manually position items as we create them, which we can do by reading the py data.

Armatures can get confusing, there are bones as well as edit bones that contain the basic armature structure and properties and then there are pose bones that stores constraints and animation data for all the action.

Different data paths are used to access different bone data -

obj = bpy.data.objects['Armature']
obj.data.edit_bones # adding, deleting, positioning bones
obj.data.bones # adjusting bone properties
obj.pose.bones # adding constraints, custom shapes...

An example of adding some bones and creating a custom mesh then setting it as the custom shape for one of the bones -

import bpy, bmesh

arm_obj = bpy.data.objects['Armature']
# must be in edit mode to add bones
bpy.context.scene.objects.active = arm_obj
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
edit_bones = arm_obj.data.edit_bones

b = edit_bones.new('bone1')
# a new bone will have zero length and not be kept
# move the head/tail to keep the bone
b.head = (1.0, 1.0, 0.0)
b.tail = (1.0, 1.0, 1.0)

b = edit_bones.new('bone2')
b.head = (1.0, 2.0, 0.0)
b.tail = (1.0, 2.0, 1.0)

# exit edit mode to save bones so they can be used in pose mode
bpy.ops.object.mode_set(mode='OBJECT')

# make the custom bone shape
bm = bmesh.new()
bmesh.ops.create_circle(bm, cap_ends=False, diameter=0.2, segments=8)
me = bpy.data.meshes.new("Mesh")
bm.to_mesh(me)
bm.free()
b2_shape = bpy.data.objects.new("bone2_shape", me)
bpy.context.scene.objects.link(b2_shape)
b2_shape.layers = [False]*19+[True]

# use pose.bones for custom shape
arm_obj.pose.bones['bone2'].custom_shape = b2_shape
# use data.bones for show_wire
arm_obj.data.bones['bone2'].show_wire = True
$\endgroup$
3
  • $\begingroup$ If you try to add a custom shape to the same bone Blender returns error 'key "" not found', is there a way around this? I’m only making one bone, not multiple. 'bpy.data.objects['Armature'].pose.bones['Armature'].custom_shape = b2_shape' $\endgroup$ Apr 30, 2016 at 17:49
  • $\begingroup$ Actually I think I'm just confusing myself now. I put up a script based off what you have shown on pastbin pastebin.com/Vs5cAq9S. It makes an armature, adds a bone, creates a mesh, then tries to apply the mesh as a custom bone shape which doesn’t work. $\endgroup$ Apr 30, 2016 at 19:04
  • 1
    $\begingroup$ You need to exit armature edit mode before the non-edit bones can be seen to add the custom shape. You will also find that armature_object == armature_data $\endgroup$
    – sambler
    May 1, 2016 at 4:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .