Thomas Larsson - Введение в написание скриптов на Питоне для Блендера 2.5x. Примеры кода Страница 14

Тут можно читать бесплатно Thomas Larsson - Введение в написание скриптов на Питоне для Блендера 2.5x. Примеры кода. Жанр: Компьютеры и Интернет / Программирование, год неизвестен. Так же Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте «WorldBooks (МирКниг)» или прочесть краткое содержание, предисловие (аннотацию), описание и ознакомиться с отзывами (комментариями) о произведении.
Thomas Larsson - Введение в написание скриптов на Питоне для Блендера 2.5x. Примеры кода

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

Прочтите описание перед тем, как прочитать онлайн книгу «Thomas Larsson - Введение в написание скриптов на Питоне для Блендера 2.5x. Примеры кода» бесплатно полную версию:
Третье издание, расширенное и обновлённое для Blender 2.57

Thomas Larsson - Введение в написание скриптов на Питоне для Блендера 2.5x. Примеры кода читать онлайн бесплатно

Thomas Larsson - Введение в написание скриптов на Питоне для Блендера 2.5x. Примеры кода - читать книгу онлайн бесплатно, автор Thomas Larsson

         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. Однако длинные сообщения трудно вписываются в ограниченное пространство информационной панели.

Перейти на страницу:
Вы автор?
Жалоба
Все книги на сайте размещаются его пользователями. Приносим свои глубочайшие извинения, если Ваша книга была опубликована без Вашего на то согласия.
Напишите нам, и мы в срочном порядке примем меры.
Комментарии / Отзывы
    Ничего не найдено.