__name__ == "__main__":
run((0,0,0))
#---------------------------------------------------------- # 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'])
• Объект привязывается к текущей сцене и делается активным. Дополнительно, мы можем сделать вновь созданный объект активным или выбранным. Этот код одинаков для всех типов объектов. 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,
Режим редактирования против режима позы
Атрибуты костей, которые влияют на изначальную позу арматуры (голова, хвост, поворот, родитель, использование соединения, и т.п.), доступны только в режиме редактирования (использование кости в 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'). Обе арматуры должны иметь одинаковое число костей с идентичными именами.#---------------------------------------------------------- # 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
Сравнение
Метод примитивов самый простой, но он работает только в том случае, когда нужный примитив доступен. Даже в программе примера, он создает меш пирамиды, который отличается от созданных другими двумя методами: основание не является единственным четырёхугольником, а состоит из четырех треугольников с общей точкой в середине основания. Другие два метода более-менее эквивалентны. Примитив не обязан быть особенно простым; есть примитивы для создания меша обезьяны или человеческая оснастка. Но метод примитивов всегда ограничен заготовленными объектами. Мы используем все три метода в примерах в этой заметке.#---------------------------------------------------------- # 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,