2016-09-20 33 views
0

我有以下代码:自定义完一个模式操作搅拌机的Python

class audio_visualizer_create(bpy.types.Operator): 
    bl_idname = "myop.audio_visualizer_create" 
    bl_label = "Audio Visualizer Create" 
    bl_description = "" 
    bl_options = {"REGISTER"} 


    @classmethod 
    def poll(cls, context): 
     return True 

    def invoke(self, context, event): 
     context.window_manager.modal_handler_add(self) 
     scene = bpy.context.scene 




     ##VARIABLES 
     type = scene.audio_visualizer_type 
     subtype = scene.audio_visualizer_subtype 
     axis = scene.audio_visualizer_axis 
     object = scene.audio_visualizer_other_sample_object 
     scalex = scene.audio_visualizer_sample_object_scale[0] 
     scaley = scene.audio_visualizer_sample_object_scale[1] 
     scalez = scene.audio_visualizer_sample_object_scale[2] 
     object = scene.audio_visualizer_other_sample_object 
     bars = scene.audio_visualizer_bars_number 

     print(bars) 
     print(scaley) 
     print(scene.audio_visualizer_bars_distance_weight) 

     ##GETTING THE OBJECT 
     if object == "OTHER": 
      object = scene.audio_visualizer_other_sample_object 

     ##Setting Up the bars 
     total_lenght = (scaley*bars) + (scene.audio_visualizer_bars_distance_weight/100*(bars-1)) 

     for i in range(0, bars): 
      bpy.ops.mesh.primitive_cube_add(radius=1, view_align=False, enter_editmode=False, location=(0, 0, 0), layers=bpy.context.scene.layers) 
      bpy.context.object.scale = (scalex,scaley,scalez) 
      bpy.context.object.location.y = total_lenght/bars*i 


     is_finished = True 

在这一点上我要完成的模态操作。

 return {"RUNNING_MODAL"} 

    def modal(self, context, event): 


     if event.type in {"ESC"}: 
      print("You've Cancelled The Operation.") 

      return {"CANCELLED"} 

     if event.type in {"MIDDLEMOUSE", "RIGHTMOUSE", "LEFTMOUSE"}: 
      return {"FINISHED"} 

     return {"FINISHED"} 

但是如果我把,而不是返回{“RUNNING_MODAL”}搅拌机崩溃或死机返回{“结束”},有什么办法来结束操作?

回答

0

首先,您展示的示例没有从模态运算符中受益。模态操作符是允许更新3DView的操作符,因为用户输入会改变操作员的操作。模态操作员的一个例子是刀具工具,一旦启动,它将在运行时根据用户输入更改最终结果。

你在你的例子中遇到的问题是你在调用和模态中做错了任务。 invoke()应调用modal_handler_add()并返回{"RUNNING_MODAL"}表示modal()应该在操作员仍在运行时调用。 modal()应该执行数据更改,当它仍在工作时返回{"RUNNING_MODAL"},当完成时返回{"FINISHED"}{"CANCELLED"}

对于模态运算符,modal()就像一个循环,每次调用模态都会执行部分任务,在每次调用之间更新视口并收集用户输入。您可以向操作员类添加属性以在每个模态调用之间保存状态信息。

当您移动鼠标,增加了立方体的简单模式的例子 -

class audio_visualizer_create(bpy.types.Operator): 
    bl_idname = "myop.audio_visualizer_create" 
    bl_label = "Audio Visualizer Create" 
    bl_options = {"REGISTER"} 

    first_mouse_x = bpy.props.IntProperty() 
    first_value = bpy.props.FloatProperty() 

    def modal(self, context, event): 
     delta = 0 
     if event.type == 'MOUSEMOVE': 
      delta = event.mouse_x - self.first_mouse_x 
     elif event.type in ['LEFTMOUSE','RIGHTMOUSE','ESC']: 
      return {'FINISHED'} 

     for i in range(delta//5): 
      bpy.ops.mesh.primitive_cube_add(radius=1) 
      s = i*0.1 
      bpy.context.object.scale = (s,s,s) 
      bpy.context.object.location.y = i 

     return {"RUNNING_MODAL"} 

    def invoke(self, context, event): 
     self.first_mouse_x = event.mouse_x 
     self.first_value = 0.0 
     context.window_manager.modal_handler_add(self) 

     return {"RUNNING_MODAL"} 

在这个例子中的缺陷 - 每次modal()被称为for循环产生在每个位置的立方体,从而导致多个立方体在每个位置创建。

+0

而我怎么能做一个模式运算符执行代码,而不需要按任何键或鼠标,像一个实时操作员? – Fabrizio

+0

某些动作需要启动运算符,键或按钮,一旦启动,它将继续,而模态返回'RUNNING_MODAL'您不必在模态()中使用键或鼠标事件 - 但是您应该停止或取消某些事件。如果您不希望用户输入来启动您的脚本,请查看[bpy.app.handlers](https://www.blender.org/api/blender_python_api_current/bpy.app.handlers.html) – sambler