#----------------------------------------------------------
# File chain.py
# Creates an array modifier and applies it# Update to API rev. 36523
#----------------------------------------------------------
import bpy
import math
from math import pi
def run(origin):
# Добавление единственного звена цепи к сцене
bpy.ops.mesh.primitive_torus_add(
#major_radius=1,
#minor_radius=0.25,
major_segments=12,
minor_segments=8,
use_abso=True,
abso_major_rad=1,
abso_minor_rad=0.6,
location=(0,0,0),
rotation=(0,0,0))
# Масштабирование тора вдоль оси x
ob = bpy.context.object
ob.scale = (0.7, 1, 1)
bpy.ops.object.transform_apply(scale=True)
# Создание пустышки
bpy.ops.object.add(
type='EMPTY',
location=(0,1.2,0.2),
rotation=(pi/2, pi/4, pi/2))
empty = bpy.context.object
# Звено цепи снова делается активным
scn = bpy.context.scene
scn.objects.active = ob
# Добавление модификатора
mod = ob.modifiers.new('Chain', 'ARRAY')
mod.fit_type = 'FIXED_COUNT'
mod.count = 10
mod.use_relative_offset = 0
mod.use_object_offset = True
mod.offset_object = empty
# Применение модификатора
bpy.ops.object.visual_transform_apply()
bpy.ops.object.modifier_apply(apply_as='DATA', modifier='Chain')
# Перемещение цепи на место
bpy.ops.transform.translate(value=origin)
# Пустышка больше не нужна
scn.objects.unlink(empty)
del(empty)
return
if __name__ == "__main__":
run((0,3,0))
Арматуры
Эта программа создаёт арматуру.
#---------------------------------------------------
# File armature.py
#---------------------------------------------------
import bpy, math
from mathutils import Vector, Matrix
def createRig(name, origin, boneTable):
# Создание арматуры и объекта
bpy.ops.object.add(
type='ARMATURE',
enter_editmode=True,
location=origin)
ob = bpy.context.object
ob.show_x_ray = True
ob.name = name
amt = ob.data
amt.name = name+'Amt'
amt.show_axes = True
# Создание костей
bpy.ops.object.mode_set(mode='EDIT')
for (bname, pname, vector) in boneTable:
bone = amt.edit_bones.new(bname)
if pname:
parent = amt.edit_bones[pname]
bone.parent = parent
bone.head = parent.tail
bone.use_connect = False
(trans, rot, scale) = parent.matrix.decompose()
else:
bone.head = (0,0,0)
rot = Matrix.Translation((0,0,0)) # Матрица идентичности
bone.tail = Vector(vector) * rot + bone.head
bpy.ops.object.mode_set(mode='OBJECT')
return ob
def poseRig(ob, poseTable):
bpy.context.scene.objects.active = ob
bpy.ops.object.mode_set(mode='POSE')
deg2rad = 2*math.pi/360
for (bname, axis, angle) in poseTable:
pbone = ob.pose.bones[bname]
# Установка режима вращения в Euler XYZ (Эйлерово),
# легче для понимания, чем кватернионы по-умолчанию
pbone.rotation_mode = 'XYZ'
# Косяк в документации: Euler.rotate(angle,axis):
# оси в ['x','y','z'] а не ['X','Y','Z']
pbone.rotation_euler.rotate_axis(axis, angle*deg2rad)
bpy.ops.object.mode_set(mode='OBJECT')
return
def run(origo):
origin = Vector(origo)
# Таблица костей в форме (кость, родитель, вектор)
# Вектор дан в локальных координатах
boneTable1 = [
('Base', None, (1,0,0)),
('Mid', 'Base', (1,0,0)),
('Tip', 'Mid', (0,0,1))
]
bent = createRig('Bent', origin, boneTable1)
# Вторая оснастка является прямой линией, то есть кости проходят вдоль локальной оси Y
boneTable2 = [
('Base', None, (1,0,0)),
('Mid', 'Base', (0,0.5,0)),
('Mid2', 'Mid', (0,0.5,0)),
('Tip', 'Mid2', (0,1,0))
]
straight = createRig('Straight', origin+Vector((0,2,0)), boneTable2)
# Поза второй остнастки
poseTable2 = [
('Base', 'X', 90),
('Mid2', 'Z', 45),
('Tip', 'Y', -45)
]
poseRig(straight, poseTable2)
# Поза первой остнастки
poseTable1 = [
('Tip', 'Y', 45),
('Mid', 'Y', 45),
('Base', 'Y', 45)
]
poseRig(bent, poseTable1)
return
if __name__ == "__main__":
run((0,5,0))
Эта программа добавляет арматуру и меш. Арматура имеет три кости (Base (базовая), Mid (средняя), Tip (конечная)) и ограничения: