затенение
for f in me.faces:
f.use_smooth = (f.center[0] < 0)
if __name__ == "__main__": run((0,0,0))
#---------------------------------------------------------- # File uvs.py #---------------------------------------------------------- import bpy import os
def createMesh(origin): # Создание меша и объекта me = bpy.data.meshes.new('TetraMesh') ob = bpy.data.objects.new('Tetra', me) ob.location = origin # Привязка объекта к сцене scn = bpy.context.scene scn.objects.link(ob) scn.objects.active = ob scn.update()
# Списки вершин и граней verts = [ (1.41936, 1.41936, -1), (0.589378, -1.67818, -1), (-1.67818, 0.58938, -1), (0, 0, 1) ] faces = [(1,0,3), (3,2,1), (3,0,2), (0,1,2)] # Создание меша из передаваемых списков вершин, рёбер, граней. # Или рёбра или грани должны быть [], или Вам нужны проблемы me.from_pydata(verts, [], faces)
# Обновление меша с новыми данными me.update(calc_edges=True)
# Первый текстурный слой: Главная UV текстура (UVMain) texFaces = [ [(0.6,0.6), (1,1), (0,1)], [(0,1), (0.6,0), (0.6,0.6)], [(0,1), (0,0), (0.6,0)], [(1,1), (0.6,0.6), (0.6,0)] ] uvMain = createTextureLayer("UVMain", me, texFaces)
# Второй текстурный слой: проекция спереди (UVFront) texFaces = [ [(0.732051,0), (1,0), (0.541778,1)], [(0.541778,1), (0,0), (0.732051,0)], [(0.541778,1), (1,0), (0,0)], [(1,0), (0.732051,0), (0,0)] ] uvFront = createTextureLayer("UVFront", me, texFaces)
# Третий текстурный слой: Умная проекция bpy.ops.mesh.uv_texture_add() uvCyl = me.uv_textures.active uvCyl.name = 'UVCyl' bpy.ops.object.mode_set(mode='EDIT') bpy.ops.uv.cylinder_project() bpy.ops.object.mode_set(mode='OBJECT')
# Хотим сделать Главный слой активным, но, кажется, это не работает - TBF me.uv_textures.active = uvMain me.uv_texture_clone = uvMain uvMain.active_render = True uvFront.active_render = False uvCyl.active_render = False return ob
def createTextureLayer(name, me, texFaces): uvtex = me.uv_textures.new() uvtex.name = name for n,tf in enumerate(texFaces): datum = uvtex.data[n] datum.uv1 = tf[0] datum.uv2 = tf[1] datum.uv3 = tf[2] return uvtex
def createMaterial(): # Создание текстуры image из картинки. Измените здесь, если # каталог snippet расположен не в Вашем домашнем каталоге. realpath = os.path.expanduser('~/snippets/textures/color.png') tex = bpy.data.textures.new('ColorTex', type = 'IMAGE') tex.image = bpy.data.images.load(realpath) tex.use_alpha = True
# Создание незатеняемого материала и MTex mat = bpy.data.materials.new('TexMat') mat.use_shadeless = True mtex = mat.texture_slots.add() mtex.texture = tex mtex.texture_coords = 'UV' mtex.use_map_color_diffuse = True return mat
def run(origin): ob = createMesh(origin) mat = createMaterial() ob.data.materials.append(mat) return
if __name__ == "__main__": run((0,0,0))
#-------------------------------------------------- # File ob_action.py #-------------------------------------------------- import bpy import math
def run(origin): # Установка начала и конца анимации scn = bpy.context.scene scn.frame_start = 11 scn.frame_end = 200
# Создание ico-сферы bpy.ops.mesh.primitive_ico_sphere_add(location=origin) ob = bpy.context.object
# Вставка ключевых кадров с operator code (кодом оператора ???) # Объект должен быть выбранным автоматически z = 10 t = 1 for n in range(5): t += 10 bpy.ops.anim.change_frame(frame = t) bpy.ops.transform.translate(value=(2, 0, z)) bpy.ops.anim.keyframe_insert_menu(type='Location') t += 10 bpy.ops.anim.change_frame(frame = t) bpy.ops.transform.translate(value=(2, 0, -z)) bpy.ops.anim.keyframe_insert_menu(type='Location') z *= 0.67
action = ob.animation_data.action
# Создание словаря с графиком FCurves типа location (позиция) fcus = {} for fcu in action.fcurves: if fcu.data_path == 'location': fcus[fcu.array_index] = fcu print(fcus.items())
# Добавление новых ключевых точек к x и z kpts_x = fcus[0].keyframe_points kpts_z = fcus[2].keyframe_points (x0,y0,z0) = origin omega = 2*math.pi/20 z *= 0.67 for t in range(101, 201): xt = 20 + 0.2*(t-101) zt = z*(1-math.cos(omega*(t - 101))) z *= 0.98 kpts_z.insert(t, zt+z0, options={'FAST'}) kpts_x.insert(t, xt+x0)
# Изменение типа экстраполяции и интерполяции # для кривой X на линейный fcus[0].extrapolation = 'LINEAR' for kp in kpts_x: kp.interpolation = 'LINEAR'
# Позиция Y - константа и может быть удалена action.fcurves.remove(fcus[1]) bpy.ops.object.paths_calculate() return
if __name__ == "__main__": run((0,0,10)) bpy.ops.screen.animation_play(reverse=False, sync=False)
#-------------------------------------------------- # File pose_action.py #-------------------------------------------------- import bpy import math
def run(origin): # Установка начала и конца анимации scn = bpy.context.scene scn.frame_start = 1 scn.frame_end = 250
# Создание арматуры и объекта bpy.ops.object.armature_add() ob = bpy.context.object amt = ob.data
# Переименование первой кости и создание второй кости bpy.ops.object.mode_set(mode='EDIT') base = amt.edit_bones['Bone'] base.name = 'Base' tip = amt.edit_bones.new('Tip') tip.head = (0,0,1) tip.tail = (0,0,2) tip.parent = base tip.use_connect = True
# Установка позиции объекта в режиме объектов bpy.ops.object.mode_set(mode='OBJECT') ob.location=origin
# Установка Эйлерова режима вращения (Euler ZYX) bpy.ops.object.mode_set(mode='POSE') pbase = ob.pose.bones['Base'] pbase.rotation_mode = 'ZYX' ptip = ob.pose.bones['Tip'] ptip.rotation_mode = 'ZYX'
# Вставка 26 ключевых кадров для двух вращений FCurves # Последний ключевой кадр будет вовне дипазона анимации
for n in range(26): pbase.keyframe_insert( 'rotation_euler', index=0, frame=n, group='Base') ptip.keyframe_insert( 'rotation_euler', index=2, frame=n, group='Tip')
# Получение FCurves из вновь созданного действия action = ob.animation_data.action fcus = {} for fcu in action.fcurves: bone = fcu.data_path.split('"')[1] fcus[(bone, fcu.array_index)] = fcu
# Модификация ключевых точек baseKptsRotX = fcus[('Base', 0)].keyframe_points tipKptsRotZ = fcus[('Tip', 2)].keyframe_points
omega = 2*math.pi/250 for n in range(26): t = 10*n phi = omega*t kp = baseKptsRotX[n] kp.co =
if __name__ == "__main__": run((0,0,0))
Слои UV-раскладки
Эта программа добавляет два UV-слоя к мешу.#---------------------------------------------------------- # File uvs.py #---------------------------------------------------------- import bpy import os
def createMesh(origin): # Создание меша и объекта me = bpy.data.meshes.new('TetraMesh') ob = bpy.data.objects.new('Tetra', me) ob.location = origin # Привязка объекта к сцене scn = bpy.context.scene scn.objects.link(ob) scn.objects.active = ob scn.update()
# Списки вершин и граней verts = [ (1.41936, 1.41936, -1), (0.589378, -1.67818, -1), (-1.67818, 0.58938, -1), (0, 0, 1) ] faces = [(1,0,3), (3,2,1), (3,0,2), (0,1,2)] # Создание меша из передаваемых списков вершин, рёбер, граней. # Или рёбра или грани должны быть [], или Вам нужны проблемы me.from_pydata(verts, [], faces)
# Обновление меша с новыми данными me.update(calc_edges=True)
# Первый текстурный слой: Главная UV текстура (UVMain) texFaces = [ [(0.6,0.6), (1,1), (0,1)], [(0,1), (0.6,0), (0.6,0.6)], [(0,1), (0,0), (0.6,0)], [(1,1), (0.6,0.6), (0.6,0)] ] uvMain = createTextureLayer("UVMain", me, texFaces)
# Второй текстурный слой: проекция спереди (UVFront) texFaces = [ [(0.732051,0), (1,0), (0.541778,1)], [(0.541778,1), (0,0), (0.732051,0)], [(0.541778,1), (1,0), (0,0)], [(1,0), (0.732051,0), (0,0)] ] uvFront = createTextureLayer("UVFront", me, texFaces)
# Третий текстурный слой: Умная проекция bpy.ops.mesh.uv_texture_add() uvCyl = me.uv_textures.active uvCyl.name = 'UVCyl' bpy.ops.object.mode_set(mode='EDIT') bpy.ops.uv.cylinder_project() bpy.ops.object.mode_set(mode='OBJECT')
# Хотим сделать Главный слой активным, но, кажется, это не работает - TBF me.uv_textures.active = uvMain me.uv_texture_clone = uvMain uvMain.active_render = True uvFront.active_render = False uvCyl.active_render = False return ob
def createTextureLayer(name, me, texFaces): uvtex = me.uv_textures.new() uvtex.name = name for n,tf in enumerate(texFaces): datum = uvtex.data[n] datum.uv1 = tf[0] datum.uv2 = tf[1] datum.uv3 = tf[2] return uvtex
def createMaterial(): # Создание текстуры image из картинки. Измените здесь, если # каталог snippet расположен не в Вашем домашнем каталоге. realpath = os.path.expanduser('~/snippets/textures/color.png') tex = bpy.data.textures.new('ColorTex', type = 'IMAGE') tex.image = bpy.data.images.load(realpath) tex.use_alpha = True
# Создание незатеняемого материала и MTex mat = bpy.data.materials.new('TexMat') mat.use_shadeless = True mtex = mat.texture_slots.add() mtex.texture = tex mtex.texture_coords = 'UV' mtex.use_map_color_diffuse = True return mat
def run(origin): ob = createMesh(origin) mat = createMaterial() ob.data.materials.append(mat) return
if __name__ == "__main__": run((0,0,0))
Действия (Actions) и управляющие элементы (drivers)
Действие объекта
Прыгающий мяч.#-------------------------------------------------- # File ob_action.py #-------------------------------------------------- import bpy import math
def run(origin): # Установка начала и конца анимации scn = bpy.context.scene scn.frame_start = 11 scn.frame_end = 200
# Создание ico-сферы bpy.ops.mesh.primitive_ico_sphere_add(location=origin) ob = bpy.context.object
# Вставка ключевых кадров с operator code (кодом оператора ???) # Объект должен быть выбранным автоматически z = 10 t = 1 for n in range(5): t += 10 bpy.ops.anim.change_frame(frame = t) bpy.ops.transform.translate(value=(2, 0, z)) bpy.ops.anim.keyframe_insert_menu(type='Location') t += 10 bpy.ops.anim.change_frame(frame = t) bpy.ops.transform.translate(value=(2, 0, -z)) bpy.ops.anim.keyframe_insert_menu(type='Location') z *= 0.67
action = ob.animation_data.action
# Создание словаря с графиком FCurves типа location (позиция) fcus = {} for fcu in action.fcurves: if fcu.data_path == 'location': fcus[fcu.array_index] = fcu print(fcus.items())
# Добавление новых ключевых точек к x и z kpts_x = fcus[0].keyframe_points kpts_z = fcus[2].keyframe_points (x0,y0,z0) = origin omega = 2*math.pi/20 z *= 0.67 for t in range(101, 201): xt = 20 + 0.2*(t-101) zt = z*(1-math.cos(omega*(t - 101))) z *= 0.98 kpts_z.insert(t, zt+z0, options={'FAST'}) kpts_x.insert(t, xt+x0)
# Изменение типа экстраполяции и интерполяции # для кривой X на линейный fcus[0].extrapolation = 'LINEAR' for kp in kpts_x: kp.interpolation = 'LINEAR'
# Позиция Y - константа и может быть удалена action.fcurves.remove(fcus[1]) bpy.ops.object.paths_calculate() return
if __name__ == "__main__": run((0,0,10)) bpy.ops.screen.animation_play(reverse=False, sync=False)
Действие позирования костей
Эта программа создает арматуру с двумя костями, которые вращаются по некоторым сложным кривым.#-------------------------------------------------- # File pose_action.py #-------------------------------------------------- import bpy import math
def run(origin): # Установка начала и конца анимации scn = bpy.context.scene scn.frame_start = 1 scn.frame_end = 250
# Создание арматуры и объекта bpy.ops.object.armature_add() ob = bpy.context.object amt = ob.data
# Переименование первой кости и создание второй кости bpy.ops.object.mode_set(mode='EDIT') base = amt.edit_bones['Bone'] base.name = 'Base' tip = amt.edit_bones.new('Tip') tip.head = (0,0,1) tip.tail = (0,0,2) tip.parent = base tip.use_connect = True
# Установка позиции объекта в режиме объектов bpy.ops.object.mode_set(mode='OBJECT') ob.location=origin
# Установка Эйлерова режима вращения (Euler ZYX) bpy.ops.object.mode_set(mode='POSE') pbase = ob.pose.bones['Base'] pbase.rotation_mode = 'ZYX' ptip = ob.pose.bones['Tip'] ptip.rotation_mode = 'ZYX'
# Вставка 26 ключевых кадров для двух вращений FCurves # Последний ключевой кадр будет вовне дипазона анимации
for n in range(26): pbase.keyframe_insert( 'rotation_euler', index=0, frame=n, group='Base') ptip.keyframe_insert( 'rotation_euler', index=2, frame=n, group='Tip')
# Получение FCurves из вновь созданного действия action = ob.animation_data.action fcus = {} for fcu in action.fcurves: bone = fcu.data_path.split('"')[1] fcus[(bone, fcu.array_index)] = fcu
# Модификация ключевых точек baseKptsRotX = fcus[('Base', 0)].keyframe_points tipKptsRotZ = fcus[('Tip', 2)].keyframe_points
omega = 2*math.pi/250 for n in range(26): t = 10*n phi = omega*t kp = baseKptsRotX[n] kp.co =