2016-09-20 3 views
0

У меня есть следующий код:Пользовательских Прекратить модальный оператор 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 

На этом этапе я хочу закончить модальный оператор.

 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"} 

Но если я положил возвращение { «Finished»} вместо возврата { «RUNNING_MODAL»} блендер Сбои или замерзает, есть ли способ, чтобы положить конец оператора?

ответ

0

Во-первых, пример, который вы показываете, не является модным оператором. Модальный оператор - это тот, который позволяет обновлять 3DView, поскольку пользовательский ввод изменяет то, что делает оператор. Примером модального оператора является инструмент ножа, после его запуска он изменяет окончательный результат на основе ввода пользователя во время его работы.

Вопрос, который у вас есть с вашим примером, заключается в том, что вы выполняете неправильные задачи в invoke и modal. 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() называется цикл создает куб в каждом месте, что приводит к множественным кубов созданных в каждой позиции.

+0

И как я могу сделать модальный оператор, который выполняет код без необходимости нажатия любой клавиши или мыши, что-то вроде оператора реального времени? – Fabrizio

+0

Некоторым действиям необходимо запустить оператор, ключ или кнопку, после запуска он будет продолжаться, пока модальный возвращает 'RUNNING_MODAL'. Вам не нужно использовать события key или mouse внутри модального(), но вы должны остановить или отменить на каком-либо событии. Если вы не хотите, чтобы пользовательский ввод запускал ваш скрипт, посмотрите [bpy.app.handlers] (https://www.blender.org/api/blender_python_api_current/bpy.app.handlers.html) – sambler

Смежные вопросы