From BlenderWiki
Three ways to create objects
The examples covered so far show that object can be created from Python using different paradigms.
Data method
The data method closely mimics how data are stored internally in Blender.
- Add the data, and then the object. For a mesh:
me = bpy.data.meshes.new(meshName) ob = bpy.data.objects.new(obName, me)
and for an armature:
amt = bpy.data.armatures.new(amtname) ob = bpy.data.objects.new(obname, amt)
- Link the object to the current scene and make it active. Optionally, we can make the newly created object active or selected. This code is the same for all kinds of objects.
scn = bpy.context.scene scn.objects.link(ob) scn.objects.active = ob ob.select = True
- Fill in the data. In the mesh case, we add the lists of vertices and faces.
me.from_pydata(verts, [], faces)
In the armature case, we switch to edit mode and add a bone.
bpy.ops.object.mode_set(mode='EDIT') bone = amt.edit_bones.new('Bone') bone.head = (0,0,0) bone.tail = (0,0,1)
- Finally, it is usually necessary to update the modified data. In the mesh case, we call an update function explicity.
me.update()
The armature is implicitly update when we switch to object mode.
bpy.ops.object.mode_set(mode='OBJECT')
Operator method
The operator method adds an object and a data block at the same time. The data block is currently empty, and needs to be filled with actual data later.
- Add the object with the
bpy.ops.object.addoperator. This automatically takes care of several things that we had to do manually in the data method: it creates object data (i.e. the mesh or armature), links the object to the scene, makes it active and selects the object. On the other hand, we must now retrieve the object and its data. This is straightforward becausebpy.context.dataalways points to the active object.
To add a mesh object, we do
bpy.ops.object.add(type='MESH') ob = bpy.context.object me = ob.data
and to add an armature:
bpy.ops.object.add( type='ARMATURE', enter_editmode=True, location=origin) ob = bpy.context.object amt = ob.data
- As in the data method, the actual data must be filled in and updated before use. For a mesh we add the verts and faces:
me.from_pydata(verts, [], faces) me.update()
and for an armature we add a bone:
bone = amt.edit_bones.new('Bone') bone.head = (0,0,0) bone.tail = (0,0,1) bpy.ops.object.mode_set(mode='OBJECT')
Note that we do not need to explicitly enter edit mode, because the armature entered edit mode already on creation.
Primitive method
If we want to make an object of a primitive type, there may exist an operator which creates the primitive with the desired properties.
- A cone is in fact approximated by a pyramid.
To create a pyramid mesh with 4 sides:
bpy.ops.mesh.primitive_cone_add( vertices=4, radius=1, depth=1, cap_end=True)
whereas the following code adds a armature with a single bone;
bpy.ops.object.armature_add() bpy.ops.transform.translate(value=origin)
- As in the operator method, we then retrieve the newly create object from
bpy.context.object.
ob = bpy.context.object me = ob.data
Comparison
The primitive method is simplest, but it only works when a suitable primitive is available. Even in the example program, it creates a pyramid mesh which is slightly different from the other two methods; the base is not a single quad, but rather consists of four triangles with a common point in the middle of the base. The other two methods are more or less equivalent.
A primitive does not need to be particularly simple; there are primitives for creating a monkey mesh or a human rig. But the primitive method is always limited to prefabricated objects.
We use all three methods in the examples in this note.
#---------------------------------------------------------- # File objects.py #---------------------------------------------------------- import bpy import mathutils from mathutils import Vector def createMeshFromData(name, origin, verts, faces): # Create mesh and object me = bpy.data.meshes.new(name+'Mesh') ob = bpy.data.objects.new(name, me) ob.location = origin ob.show_name = True # Link object to scene and make active scn = bpy.context.scene scn.objects.link(ob) scn.objects.active = ob ob.select = True # Create mesh from given verts, faces. me.from_pydata(verts, [], faces) # Update mesh with new data me.update() return ob def createMeshFromOperator(name, origin, verts, faces): bpy.ops.object.add( type='MESH', enter_editmode=False, location=origin) ob = bpy.context.object ob.name = name ob.show_name = True me = ob.data me.name = name+'Mesh' # Create mesh from given verts, faces. me.from_pydata(verts, [], faces) # Update mesh with new data me.update() # Set object mode bpy.ops.object.mode_set(mode='OBJECT') return ob def createMeshFromPrimitive(name, origin): bpy.ops.mesh.primitive_cone_add( vertices=4, radius=1, depth=1, cap_end=True, view_align=False, enter_editmode=False, location=origin, rotation=(0, 0, 0)) ob = bpy.context.object ob.name = name ob.show_name = True me = ob.data me.name = name+'Mesh' return ob def createArmatureFromData(name, origin): # Create armature and object amt = bpy.data.armatures.new(name+'Amt') ob = bpy.data.objects.new(name, amt) ob.location = origin ob.show_name = True # Link object to scene and make active scn = bpy.context.scene scn.objects.link(ob) scn.objects.active = ob ob.select = True # Create single bone bpy.ops.object.mode_set(mode='EDIT') bone = amt.edit_bones.new('Bone') bone.head = (0,0,0) bone.tail = (0,0,1) bpy.ops.object.mode_set(mode='OBJECT') return ob def createArmatureFromOperator(name, origin): bpy.ops.object.add( type='ARMATURE', enter_editmode=True, location=origin) ob = bpy.context.object ob.name = name ob.show_name = True amt = ob.data amt.name = name+'Amt' # Create single bone bone = amt.edit_bones.new('Bone') bone.head = (0,0,0) bone.tail = (0,0,1) bpy.ops.object.mode_set(mode='OBJECT') return ob def createArmatureFromPrimitive(name, origin): bpy.ops.object.armature_add() bpy.ops.transform.translate(value=origin) ob = bpy.context.object ob.name = name ob.show_name = True amt = ob.data amt.name = name+'Amt' return ob def run(origo): origin = Vector(origo) (x,y,z) = (0.707107, 0.258819, 0.965926) verts = ((x,x,-1), (x,-x,-1), (-x,-x,-1), (-x,x,-1), (0,0,1)) faces = ((1,0,4), (4,2,1), (4,3,2), (4,0,3), (0,1,2,3)) cone1 = createMeshFromData('DataCone', origin, verts, faces) cone2 = createMeshFromOperator('OpsCone', origin+Vector((0,2,0)), verts, faces) cone3 = createMeshFromPrimitive('PrimCone', origin+Vector((0,4,0))) rig1 = createArmatureFromData('DataRig', origin+Vector((0,6,0))) rig2 = createArmatureFromOperator('OpsRig', origin+Vector((0,8,0))) rig3 = createArmatureFromPrimitive('PrimRig', origin+Vector((0,10,0))) return if __name__ == "__main__": run((0,0,0))