Thomas Larsson - Введение в написание скриптов на Питоне для Блендера 2.5x. Примеры кода
return{'FINISHED'}
# Удаление кнопки
class OBJECT_OT_DeleteButton(bpy.types.Operator):
bl_idname = "swatches.delete"
bl_label = "Delete swatch"
def execute(self, context):
global theSwatches
n = findSwatch(context.object.my_swatch)
theSwatches.pop(n)
setSwatches()
return{'FINISHED'}
# Регистрация
bpy.utils.register_module(__name__)
Объявление оператора и добавление его в менюОператоры, которые нам до сих пор попадались, были простыми кнопками. В этой программе мы делаем более сложный оператор, который создаёт искривленный цилиндр.
Для вызова оператора нажмите Пробел и наберите "Add twisted cylinder"; Блендер предлагает сопоставляемые имена операторов во время набора. Цилиндр имеет несколько опций, которые появятся в области Tool props (ниже секции Tools), сразу после создания цилиндра. Их можно интерактивно модифицировать, и результат немедленно отобразится в 3D-виде.
Последняя часть скрипта регистрирует его. Вместо нажатия клавиши Пробел, теперь можно вызывать скрипт гораздо более удобным образом из подменю Add » Mesh. Если бы мы использовали append (добавить) вместо prepend (предварять) в функции register(), вызов появился бы внизу вместо верхнего меню.
#----------------------------------------------------------
# File twisted.py
#----------------------------------------------------------
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', скрипт войдёт в бесконечный цикл, и Вам придётся перезапускать Блендер.
Модальный оператор определяет два специальных метода с именами __init()__ и __del()__, которые вызываются, когда модальная операция начинается и прекращается, соответственно.
Запустите скрипт. Активный объект перемещается по плоскости XY при перемещении мыши. Скрипт также создает панель с кнопкой, нажатием на которую Вы также можете выполнить модальный оператор.
#----------------------------------------------------------
# File modal.py
# from API documentation
#----------------------------------------------------------
import bpy
class MyModalOperator(bpy.types.Operator):
bl_idname = "mine.modal_op"
bl_label = "Move in XY plane"
def __init__(self):
print("Start moving")
def __del__(self):
print("Moved from (%d %d) to (%d %d)" %
(self.init_x, self.init_y, self.x, self.y))
def execute(self, context):
context.object.location.x = self.x / 100.0
context.object.location.y = self.y / 100.0
def modal(self, context, event):
if event.type == 'MOUSEMOVE': # Применение
self.x = event.mouse_x
self.y = event.mouse_y
self.execute(context)
elif event.type == 'LEFTMOUSE': # Подтверждение
return {'FINISHED'}
elif event.type in ('RIGHTMOUSE', 'ESC'): # Отмена
return {'CANCELLED'}
return {'RUNNING_MODAL'}
def invoke(self, context, event):
self.x = event.mouse_x
self.y = event.mouse_y
self.init_x = self.x
self.init_y = self.y
self.execute(context)
print(context.window_manager.modal_handler_add(self))
return {'RUNNING_MODAL'}
#
# Панель в районе tools
#
class MyModalPanel(bpy.types.Panel):
bl_label = "My modal operator"
bl_space_type = "VIEW_3D"
bl_region_type = "TOOLS"
def draw(self, context):
self.layout.operator("mine.modal_op")
# Регистрация
bpy.utils.register_module(__name__)
# Автоматически перемещает активный объект при запуске
bpy.ops.mine.modal_op('INVOKE_DEFAULT')
Invoke (вызов) против execute (выполнения)Этот скрипт иллюстрирует разницу между invoke (вызывать) и execute (выполнять). Вызываемое (invoking) событие является аргументом функции Operator.invoke, который устанавливает два свойства целого типа x и y для положения мыши и вызывает функцию Operator.execute. Как альтернатива, мы можем выполнить (execute) оператор и явно установить x и y: bpy.ops.wm.mouse_position(’EXEC_DEFAULT’, x=20, y=66)
Вместо вывода координат мыши в окно терминала, информация отправляется в информационную панель в верхнем правом углу. Это хорошее место для отображения краткого уведомления, так как пользователю не придется искать его в другом окне, тем более, что терминал/DOS-окно отображается не во всех версиях Blender. Однако длинные сообщения трудно вписываются в ограниченное пространство информационной панели.
Откройте для себя мир чтения на siteknig.com - месте, где каждая книга оживает прямо в браузере. Здесь вас уже ждёт произведение Thomas Larsson - Введение в написание скриптов на Питоне для Блендера 2.5x. Примеры кода, относящееся к жанру Программирование. Никаких регистраций, никаких преград - только вы и история, доступная в полном формате. Наш литературный портал создан для тех, кто любит комфорт: хотите читать с телефона - пожалуйста; предпочитаете ноутбук - идеально! Все книги открываются моментально и представлены полностью, без сокращений и скрытых страниц. Каталог жанров поможет вам быстро найти что-то по настроению: увлекательный роман, динамичное фэнтези, глубокую классику или лёгкое чтение перед сном. Мы ежедневно расширяем библиотеку, добавляя новые произведения, чтобы вам всегда было что открыть "на потом". Сегодня на siteknig.com доступно более 200000 книг - и каждая готова стать вашей новой любимой. Просто выбирайте, открывайте и наслаждайтесь чтением там, где вам удобно.


