Три способа создания объектов

Примеры, которые мы изучали до сих пор, показывают, что объект можно создавать в Питоне с использованием различных парадигм.


Метод данных

• Метод данных тщательно подражает тому, как данные сохраняются непосредственно в Блендере.

Добавляются данные, и затем объект. Для меша:

me = bpy.data.meshes.new(meshName) 

ob = bpy.data.objects.new(obName, me)

и для арматуры:

amt = bpy.data.armatures.new(amtname) 

ob = bpy.data.objects.new(obname, amt)


• Объект привязывается к текущей сцене и делается активным. Дополнительно, мы можем сделать вновь созданный объект активным или выбранным. Этот код одинаков для всех типов объектов.

scn = bpy.context.scene 

scn.objects.link(ob) 

scn.objects.active = ob 

ob.select = True


• Заполняются данные. В случае меша, мы добавляем списки вершин и граней.

me.from_pydata(verts, [], faces)

В случае арматуры, мы переключаем в режим редактирования и добавляем кость.

bpy.ops.object.mode_set(mode='EDIT') 

bone = amt.edit_bones.new('Bone') 

bone.head = (0,0,0) 

bone.tail = (0,0,1)


• Наконец, обычно необходимо обновить модифицированные данные. В случае меша, мы явно вызываем функцию update.

me.update()

У арматуры подразумевается обновление, когда мы переключаем её в режим объектов.

bpy.ops.object.mode_set(mode='OBJECT')


Операторный Метод

Операторный метод добавляет объект и блок данных одновременно. Блок данных к при этом будет пустым, и должен быть заполнен позже фактическими данными.


• Добавляется объект с помощью оператора bpy.ops.object.add. Он автоматически заботится о нескольких вещах, которые мы должны были делать вручную в методе данных: он создает данные объекта (то есть меш или арматуру), привязывает объект к сцене, делает его активным и выбирает объект. С другой стороны, теперь мы должны извлечь объект и данные. Это просто, поскольку bpy.context.object всегда указывает на активный объект.

Чтобы добавить меш-объект, мы делаем

bpy.ops.object.add(type='MESH') 

ob = bpy.context.object 

me = ob.data

и для добавления арматуры:

bpy.ops.object.add( 

type='ARMATURE', 

enter_editmode=True, 

location=origin) 

ob = bpy.context.object 

amt = ob.data


• Как и в методе данных, объект нужно заполнить фактическими данными и обновить перед использованием. Для меша мы добавляем вершины и грани:

me.from_pydata(verts, [], faces) 

me.update()

а для арматуры мы добавляем кость:

bone = amt.edit_bones.new('Bone') 

bone.head = (0,0,0) 

bone.tail = (0,0,1) 

bpy.ops.object.mode_set(mode='OBJECT')

Заметьте, что нам не нужно явно входить в режим редактирования, поскольку арматура вошла в него уже при создании.


Метод примитивов

Если мы хотим сделать объект типа одного из примитивов, может существовать оператор, который создаёт примитив с желаемыми свойствами.


• Конус фактически аппроксимируется пирамидой.

Для создания меша пирамиды с 4 сторонами:

bpy.ops.mesh.primitive_cone_add( 

vertices=4,

radius=1, 

depth=1, 

cap_end=True)

тогда как следующий код добавляет арматуру с единственной костью:

bpy.ops.object.armature_add() 

bpy.ops.transform.translate(value=origin)


• Как и в операторном методе, мы затем извлекаем вновь созданный объект из

bpy.context.object
.

ob = bpy.context.object 

me = ob.data


Сравнение

Метод примитивов самый простой, но он работает только в том случае, когда нужный примитив доступен. Даже в программе примера, он создает меш пирамиды, который отличается от созданных другими двумя методами: основание не является единственным четырёхугольником, а состоит из четырех треугольников с общей точкой в середине основания. Другие два метода более-менее эквивалентны.

Примитив не обязан быть особенно простым; есть примитивы для создания меша обезьяны или человеческая оснастка. Но метод примитивов всегда ограничен заготовленными объектами.

Мы используем все три метода в примерах в этой заметке.



#---------------------------------------------------------- 

# File objects.py 

#---------------------------------------------------------- 

import bpy

import mathutils 

from mathutils import Vector  


def createMeshFromData(name, origin, verts, faces):

   # Создание меша и объекта

   me = bpy.data.meshes.new(name+'Mesh')

   ob = bpy.data.objects.new(name, me)

   ob.location = origin ob.show_name = True


   # Привязка объекта к сцене, он становится активным

   scn = bpy.context.scene

   scn.objects.link(ob)

   scn.objects.active = ob

   ob.select = True


   # Создание меша из полученных verts (вершин), faces (граней).

   me.from_pydata(verts, [], faces)

   # Обновление меша с новыми данными

   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'


   # Создание меша из полученных verts (вершин), faces (граней).

   me.from_pydata(verts, [], faces)

   # Обновление меша с новыми данными

   me.update()

   # Установка режима объектов

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

   # Создание меша и объекта

   amt = bpy.data.armatures.new(name+'Amt')

   ob = bpy.data.objects.new(name, amt)

   ob.location = origin

   ob.show_name = True


   # Привязка объекта к сцене, он становится активным

   scn = bpy.context.scene

   scn.objects.link(ob)

   scn.objects.active = ob

   ob.select = True


   # Создание одиночной кости

   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'


   # Создание одиночной кости

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



Загрузка...