Dev:IT/2.5/Py/Scripts/Cookbook/Code snippets/Three ways to create objects
Tre modi per creare oggetti
Gli esempi mostrano che un oggetto può essere creato in modi differenti.
Metodo Data
Questo metodo imita strettamente come i dati vengono memorizzati internamente in Blender.
- Aggiungi i dati e poi l'oggetto. Per una mesh:
me = bpy.data.meshes.new(meshName)
ob = bpy.data.objects.new(obName, me)
e per un'armatura:
amt = bpy.data.armatures.new(amtname)
ob = bpy.data.objects.new(obname, amt)
- Collega l'oggetto alla scena corrente e rendilo attivo. Opzionalmente possiamo rendere l'oggetto appena creato attivo o selezionato. Questo codice è uguale per tutti i tipi di oggetto.
scn = bpy.context.scene
scn.objects.link(ob)
scn.objects.active = ob
ob.select = True
- Compila i dati. Nel caso della mesh, aggiungiamo la lista dei vertici e delle facce.
me.from_pydata(verts, [], faces)
Nel caso dell'armatura, andiamo in Edit Mode e aggiungiamo un osso.
bpy.ops.object.mode_set(mode='EDIT')
bone = amt.edit_bones.new('Bone')
bone.head = (0,0,0)
bone.tail = (0,0,1)
- nfine, di solito, è necessario aggiornare i dati modificati. Nel caso della mesh, chiameremo esplicitamente la funzione update.
me.update()
L'armatura è implicitamente aggiornata quando torni in Object Mode.
bpy.ops.object.mode_set(mode='OBJECT')
Metodo con operatore
Il metodo con operatore, aggiunge un oggetto e il suo data block contemporaneamente. Il data block è vuoto, e dovrà essere riempito con i dati reali in seguito.
- Aggiungi l'oggetto con l'operatore
bpy.ops.object.add
. Questo si prende cura di fare automaticamente le cose che abbiamo dovuto fare manualmente con il metodo Data: crea i dati dell'oggetto (per es. la mesh o l'armatura) collega l'oggetto alla scena, rende attivo e selezionato l'oggetto. Dall'altro lato dobbiamo recuperare l'oggetto e i suoi dati. Questo è semplice, perchébpy.context.data
punta sempre sull'oggetto attivo.
Per aggiungere una mesh dobbiamo
bpy.ops.object.add(type='MESH')
ob = bpy.context.object
me = ob.data
mentre per aggiungere un'armatura:
bpy.ops.object.add(
type='ARMATURE',
enter_editmode=True,
location=origin)
ob = bpy.context.object
amt = ob.data
- Come per il metodo Data, devi compilare con dati reali e aggiornare, prima di usarlo. Per una mesh aggiungiamo vertici e facce:
me.from_pydata(verts, [], faces)
me.update()
mentre per un'armatura aggiungiamo un osso:
bone = amt.edit_bones.new('Bone')
bone.head = (0,0,0)
bone.tail = (0,0,1)
bpy.ops.object.mode_set(mode='OBJECT')
Notare che non ci serve entrare in Edit Mode in maniera esplicita, in quanto l'armatura entra in Edit Mode nel momento della creazione.
Metodo con primitive
Se vuoi creare un oggetto di tipo primitiva, c'è un metodo che le può creare con le proprietà desiderate.
- Per creare una mesh piramide
bpy.ops.mesh.primitive_cone_add(
vertices=4,
radius=1,
depth=1,
cap_end=True)
mentre il codice seguente aggiunge un armatura con un singolo osso;
bpy.ops.object.armature_add()
bpy.ops.transform.translate(value=origin)
- Come nel metodo con operatore, dobbiamo recuperare l'oggetto appena creato con
bpy.context.object
.
ob = bpy.context.object
me = ob.data
Confronto
Il metodo con primitive è il più semplice, ma lavora solo se è disponibile una primitiva adatta. Nel programma di esempio, viene creata una mesh piramide leggermente diversa da quella creata con gli altri due metodi, la base non è un singolo quadrato, ma è composta da quatro triangoli con un vertice comune al centro della base. Gli altri due metodi sono più o meno equivalenti.
Una primitiva, non necessariemente deve essere semplice, ci sono primitive per la creazione di una scimmia o di uno scheletro umano. Comunque il metodo con primitive è sempre limitato a oggetti prefabbricati.
Useremo tutti e tre i metodi negli esempi seguenti.
#----------------------------------------------------------
# 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))