Литвек - электронная библиотека >> Thomas Larsson >> Python и др. >> Введение в написание скриптов на Питоне для Блендера 2.5x. Примеры кода >> страница 4
__name__ == "__main__":

    run((0,0,0))


Режим редактирования против режима позы
Атрибуты костей, которые влияют на изначальную позу арматуры (голова, хвост, поворот, родитель, использование соединения, и т.п.), доступны только в режиме редактирования (использование кости в ob.data.edit bones), тогда как атрибуты, которые применяются при позировании, требуют, чтобы арматура была в режиме позы (использование кости в ob.pose.bones). Насколько я знаю, единственный способ переключаться между режимами редактирования и позы — с помощью вызова операторов

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

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

Поскольку операторы воздействуют на активный объект, мы должны удостовериться, что активен правильный объект, устанавливая bpy.context.scene.objects.active.

Этот скрипт копирует углы поворота roll из исходной оснастки (имя объекта 'SrcRig') в целевую оснастку (имя объектна 'TrgRig'). Обе арматуры должны иметь одинаковое число костей с идентичными именами.


Введение в написание скриптов на Питоне для Блендера 2.5x. Примеры кода. Иллюстрация № 11
#----------------------------------------------------------

# File copy_roll.py

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

import bpy


def copyRolls(src, trg):

    rolls = {} bpy.context.scene.objects.active = src

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

    for eb in src.data.edit_bones:

        rolls[eb.name] = eb.roll

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


    bpy.context.scene.objects.active = trg

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

    for eb in trg.data.edit_bones:

        oldRoll = eb.roll

        eb.roll = rolls[eb.name]

        print(eb.name, oldRoll, eb.roll)

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

    return


objects = bpy.context.scene.objects

copyRolls(objects['SrcRig'], objects['TrgRig'])


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

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


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

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

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


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

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

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


Введение в написание скриптов на Питоне для Блендера 2.5x. Примеры кода. Иллюстрация № 12
#----------------------------------------------------------

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