Dev:IT/2.5/Py/Scripts/Cookbook/Code snippets/Three ways to create objects

提供: wiki
移動先: 案内検索

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. Code Snippets Objects.png

#----------------------------------------------------------
# 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))