zoukankan      html  css  js  c++  java
  • Blender插件之操作器(Operator)实战

    前言

    在Blender中, 操作器(Operator)是它的核心. 用户通过各种操作器来创建和操作场景中的物体.

    操作器对象继承自 class bpy.types.Operator(bpy_struct)

    下面通过代码实例来学习它, 以下代码来源于https://docs.blender.org/api/2.79/bpy.types.Operator.html
    #### 1 最简单的Operator
    简单的信息打印
    import bpy
    
    class HelloWorldOperator(bpy.types.Operator):
        bl_idname = "yy.hello_world"
        bl_label = "Minimal Operator"
    
        def execute(self, context):
            print("Hello World!")
            return {'FINISHED'}
    
    bpy.utils.register_class(HelloWorldOperator)
    
    # test call to the newly defined operator
    bpy.ops.yy.hello_world()
    
    #### 2 Invoke
    Operator.invoke用于在调用operator时从上下文初始化operator。
    Operator.invoke is used to initialize the operator from the context at the moment the operator is called.
    import bpy
    
    
    class SimpleMouseOperator(bpy.types.Operator):
        """ This operator shows the mouse location,
            this string is used for the tooltip and API docs
        """
        bl_idname = "wm.mouse_position"
        bl_label = "Invoke Mouse Operator"
    
        x = bpy.props.IntProperty()
        y = bpy.props.IntProperty()
    
        def execute(self, context):
            # rather than printing, use the report function,
            # this way the message appears in the header,
            self.report({'INFO'}, "Mouse coords are %d %d" % (self.x, self.y))
            return {'FINISHED'}
    
        def invoke(self, context, event):
            self.x = event.mouse_x
            self.y = event.mouse_y
            return self.execute(context)
    
    bpy.utils.register_class(SimpleMouseOperator)
    
    # Test call to the newly defined operator.
    # Here we call the operator and invoke it, meaning that the settings are taken
    # from the mouse.
    bpy.ops.wm.mouse_position('INVOKE_DEFAULT')
    
    # Another test call, this time call execute() directly with pre-defined settings.
    bpy.ops.wm.mouse_position('EXEC_DEFAULT', x=20, y=66)
    #### 3 调用文件选择器
    Opens a file selector with an operator. The string properties ‘filepath’, ‘filename’, ‘directory’ and a ‘files’ collection are assigned
    when present in the operator Notice the invoke function calls a window manager method and returns {'RUNNING_MODAL'},
    this means the file selector stays open and the operator does not exit immediately after invoke finishes.
    import bpy
    
    
    class ExportSomeData(bpy.types.Operator):
        """Test exporter which just writes hello world"""
        bl_idname = "export.some_data"
        bl_label = "Export Some Data"
    
        filepath = bpy.props.StringProperty(subtype="FILE_PATH")
    
        @classmethod
        def poll(cls, context):
            return context.object is not None
    
        def execute(self, context):
            file = open(self.filepath, 'r')
            print(file.read())
            file.close()
            #file.write("Hello World " + context.object.name)
            return {'FINISHED'}
    
        def invoke(self, context, event):
            context.window_manager.fileselect_add(self)
            return {'RUNNING_MODAL'}
    
    
    # Only needed if you want to add into a dynamic menu
    def menu_func(self, context):
        self.layout.operator_context = 'INVOKE_DEFAULT'
        self.layout.operator(ExportSomeData.bl_idname, text="Text Export Operator")
    
    # Register and add to the file selector
    bpy.utils.register_class(ExportSomeData)
    bpy.types.INFO_MT_file_export.append(menu_func)
    
    
    # test call
    bpy.ops.export.some_data('INVOKE_DEFAULT')
    #### 4 对话框
    import bpy
    
    
    class DialogOperator(bpy.types.Operator):
        bl_idname = "object.dialog_operator"
        bl_label = "Simple Dialog Operator"
    
        my_float = bpy.props.FloatProperty(name="Some Floating Point")
        my_bool = bpy.props.BoolProperty(name="Toggle Option")
        my_string = bpy.props.StringProperty(name="String Value")
    
        def execute(self, context):
            message = "Popup Values: %f, %d, '%s'" % 
                (self.my_float, self.my_bool, self.my_string)
            self.report({'INFO'}, message)
            return {'FINISHED'}
    
        def invoke(self, context, event):
            wm = context.window_manager
            return wm.invoke_props_dialog(self)
    
    
    bpy.utils.register_class(DialogOperator)
    
    # test call
    bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
    #### 5 自定义绘图
    By default operator properties use an automatic user interface layout. If you need more control you can create your own layout with a Operator.draw function.
    import bpy
    
    
    class CustomDrawOperator(bpy.types.Operator):
        bl_idname = "object.custom_draw"
        bl_label = "Simple Modal Operator"
    
        filepath = bpy.props.StringProperty(subtype="FILE_PATH")
    
        my_float = bpy.props.FloatProperty(name="Float")
        my_bool = bpy.props.BoolProperty(name="Toggle Option")
        my_string = bpy.props.StringProperty(name="String Value")
    
        def execute(self, context):
            print("Test", self)
            return {'FINISHED'}
    
        def invoke(self, context, event):
            wm = context.window_manager
            return wm.invoke_props_dialog(self)
    
        def draw(self, context):
            layout = self.layout
            col = layout.column()
            col.label(text="Custom Interface!")
    
            row = col.row()
            row.prop(self, "my_float")
            row.prop(self, "my_bool")
    
            col.prop(self, "my_string")
    
    bpy.utils.register_class(CustomDrawOperator)
    
    # test call
    bpy.ops.object.custom_draw('INVOKE_DEFAULT')
    #### 6 Modal执行
    This operator defines a Operator.modal function that will keep being run to handle events until it returns {'FINISHED'} or {'CANCELLED'}.
    import bpy
    
    
    class ModalOperator(bpy.types.Operator):
        bl_idname = "object.modal_operator"
        bl_label = "Simple Modal Operator"
    
        def __init__(self):
            print("Start")
    
        def __del__(self):
            print("End")
    
        def execute(self, context):
            context.object.location.x = self.value / 100.0
            return {'FINISHED'}
    
        def modal(self, context, event):
            if event.type == 'MOUSEMOVE':  # Apply
                self.value = event.mouse_x
                self.execute(context)
            elif event.type == 'LEFTMOUSE':  # Confirm
                return {'FINISHED'}
            elif event.type in {'RIGHTMOUSE', 'ESC'}:  # Cancel
                context.object.location.x = self.init_loc_x
                return {'CANCELLED'}
    
            return {'RUNNING_MODAL'}
    
        def invoke(self, context, event):
            self.init_loc_x = context.object.location.x
            self.value = event.mouse_x
            self.execute(context)
    
            context.window_manager.modal_handler_add(self)
            return {'RUNNING_MODAL'}
    
    
    bpy.utils.register_class(ModalOperator)
    
    # test call
    bpy.ops.object.modal_operator('INVOKE_DEFAULT')
  • 相关阅读:
    http经典解析
    js实现canvas保存图片为png格式并下载到本地
    你所不知的 CSS ::before 和 ::after 伪元素用法
    js自动下载
    CSS 实现隐藏滚动条同时又可以滚动
    checkbox与文字对齐
    利用html2canvas截图,得到base64上传ajax
    bootstrap-datepicker简单使用
    移动端禁止滚动
    h5移动网页唤起App
  • 原文地址:https://www.cnblogs.com/yaoyu126/p/9310857.html
Copyright © 2011-2022 走看看