自定义结束模态运算符 Blender Python
Custom End a Modal operator Blender 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
At this Point i want to finish the Modal Operator.
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"}
但是如果我把 return {"FINISHED"} 而不是 return {"RUNNING_MODAL"} blender 崩溃或冻结,有没有办法结束操作员?
首先,您展示的示例并没有从模态运算符中获益。模态运算符允许 3DView 在用户输入改变运算符的操作时更新。模态运算符的一个示例是刀工具,一旦启动它就会根据用户输入更改最终结果,同时它是 运行.
您的示例存在的问题是您在调用和模态中执行了错误的任务。 invoke()
应调用 modal_handler_add()
和 return {"RUNNING_MODAL"}
以表示应在运算符仍为 运行 时调用 modal()
。 modal()
应该执行数据更改,returning {"RUNNING_MODAL"}
当它还在工作时 {"FINISHED"}
或 {"CANCELLED"}
当它完成时。
对于模态运算符,modal()
就像一个循环,每次调用模态都会执行部分任务,并在每次调用之间更新视口并收集用户输入。您向运算符添加属性 class 以保存每个模态调用之间的状态信息。
移动鼠标时添加立方体的简单模态示例 -
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 循环都会在每个位置创建一个立方体,从而导致在每个位置创建多个立方体。
我有以下代码:
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
At this Point i want to finish the Modal Operator.
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"}
但是如果我把 return {"FINISHED"} 而不是 return {"RUNNING_MODAL"} blender 崩溃或冻结,有没有办法结束操作员?
首先,您展示的示例并没有从模态运算符中获益。模态运算符允许 3DView 在用户输入改变运算符的操作时更新。模态运算符的一个示例是刀工具,一旦启动它就会根据用户输入更改最终结果,同时它是 运行.
您的示例存在的问题是您在调用和模态中执行了错误的任务。 invoke()
应调用 modal_handler_add()
和 return {"RUNNING_MODAL"}
以表示应在运算符仍为 运行 时调用 modal()
。 modal()
应该执行数据更改,returning {"RUNNING_MODAL"}
当它还在工作时 {"FINISHED"}
或 {"CANCELLED"}
当它完成时。
对于模态运算符,modal()
就像一个循环,每次调用模态都会执行部分任务,并在每次调用之间更新视口并收集用户输入。您向运算符添加属性 class 以保存每个模态调用之间的状态信息。
移动鼠标时添加立方体的简单模态示例 -
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 循环都会在每个位置创建一个立方体,从而导致在每个位置创建多个立方体。