Чтение онлайн

ЖАНРЫ

Введение в написание скриптов на Питоне для Блендера 2.5x. Примеры кода

Larsson Thomas

Шрифт:

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

import bpy, math

def addTwistedCylinder(context, r, nseg, vstep, nplanes, twist):

# Функция создания цилиндра

verts = []

faces = []

w = 2*math.pi/nseg

a = 0

da = twist*math.pi/180

for j in range(nplanes+1):

z = j*vstep

a += da

for i in range(nseg):

verts.append((r*math.cos(w*i+a), r*math.sin(w*i+a), z))

if j > 0:

i0 = (j-1)*nseg

i1 = j*nseg

for i in range(1, nseg):

faces.append((i0+i-1, i0+i, i1+i, i1+i-1))

faces.append((i0+nseg-1, i0, i1, i1+nseg-1))

me = bpy.data.meshes.new("TwistedCylinder")

me.from_pydata(verts, [], faces)

ob = bpy.data.objects.new("TwistedCylinder", me)

context.scene.objects.link(ob)

context.scene.objects.active = ob return ob 

#

#
Интерфейс пользователя

#

from bpy.props import * 

class MESH_OT_primitive_twisted_cylinder_add(bpy.types.Operator):

'''Add a twisted cylinder'''

bl_idname = "mesh.primitive_twisted_cylinder_add"

bl_label = "Add twisted cylinder"

bl_options = {'REGISTER', 'UNDO'}

radius = FloatProperty(name="Radius",

default=1.0, min=0.01, max=100.0)

nseg = IntProperty(name="Major Segments",

description="Number of segments for one layer",

default=12, min=3, max=256)

vstep = FloatProperty(name="Vertical step",

description="Distance between subsequent planes",

default=1.0, min=0.01, max=100.0)

nplanes = IntProperty(name="Planes",

description="Number of vertical planes",

default=4, min=2, max=256)

twist = FloatProperty(name="Twist angle",

description="Angle between subsequent planes (degrees)"
,

default=15, min=0, max=90)

location = FloatVectorProperty(name="Location")

rotation = FloatVectorProperty(name="Rotation")

# Заметьте: вращение (Rotation) в радианах!

def execute(self, context):

ob = addTwistedCylinder(context, self.radius, self.nseg, self.vstep,

self.nplanes, self.twist)

ob.location = self.location

ob.rotation_euler = self.rotation

#context.scene.objects.link(ob)

#context.scene.objects.active = ob

return {'FINISHED'}

#

#
Регистрация

# Делает возможным иметь доступ к скрипту из меню Add > Mesh

#

def menu_func(self, context):

self.layout.operator("mesh.primitive_twisted_cylinder_add",

text="Twisted cylinder",

icon='MESH_TORUS')

def register:

bpy.utils.register_module(__name__)

bpy.types.INFO_MT_mesh_add.prepend(menu_func)

def unregister:

bpy.utils.unregister_module(__name__)

bpy.types.INFO_MT_mesh_add.remove(menu_func)

if __name__ == "__main__":

register

Модальный оператор

Следующий пример взят прямо из документации по API, как и последующие несколько примеров.

Модальный оператор определяет функцию

Operator.modal
которая при запуске обрабатывает события, пока не вернёт
'FINISHED'
или
'CANCELLED'
. Grab (сдвиг), Rotate (вращение), Scale (масштабирование) и Fly-Mode (режим полёта) - примеры модальных операторов. Они особенно полезны для интерактивных инструментов, ваш оператор может иметь собственное состояние, в котором клавиши переключают опции работы оператора.

Когда вызывается оператор в этом примере, он добавляет модального обработчика к себе с помощью вызова

context.window_manager.modal_handler_add(self)
. После этого активный объект продолжает перемещаться по плоскости XY, повторяя перемещения мыши. Для того, чтобы выйти, нажмите кнопку мыши или клавишу Esc.

Модальный метод обрабатывает три типа событий:

1. Перемещение мыши перемещает активный объект.

2. Нажатие ЛКМ для подтверждения и выхода в нормальный режим. Объект оставляется в своей новой позиции.

3. Нажатие ПКМ или клавиши Esc, чтобы отменить и выйти в нормальный режим. Объект возвращается в свою первоначальную позицию.

Важно, чтобы был некоторый способ выходить в нормальный режим. Если функция modal всегда возвращает 'RUNNING_MODAL', скрипт войдёт в бесконечный цикл, и Вам придётся перезапускать Блендер.

Поделиться с друзьями: