0

Problem:

I need an example of an operator that is used for baking image texture using Blender's bpy.ops.bake. I need to have it running modal to prevent Blender's UI from freezing, a progress bar to display the baking progress, and an option to cancel the execution if ESC pressed.

kemplerart
  • 610
  • 1
  • 10

1 Answers1

2

Found the desired answer in Modal Baking Operator by @Carnerio. Editing my code to fit the needs.

import bpy

class ModalTimerOperator(bpy.types.Operator): bl_idname = "wm.modal_timer_operator" bl_label = "Modal Timer Operator" _timer = None _img = None

def modal(self, context, event):
    if event.type == 'ESC':
        self.cancel(context)
        return {'CANCELLED'}

    if event.type == 'TIMER':
        if self._img.is_dirty: # <--- Wait until the image is marked as dirty
            self.finish(context)
            return {'FINISHED'}

    return {'PASS_THROUGH'}

def execute(self, context):
    if context.scene.render.engine != 'CYCLES':
        context.scene.render.engine = 'CYCLES'

    self._img = bpy.data.images[0]
    self.report({'INFO'}, "Execute")

    result = bpy.ops.object.bake('INVOKE_DEFAULT')
    if result != {'RUNNING_MODAL'}:
        self.report({'WARNING'}, "Failed to start baking")
        return {'FINISHED'}

    wm = context.window_manager
    self._timer = wm.event_timer_add(0.5, window=context.window)
    wm.modal_handler_add(self)
    return {'RUNNING_MODAL'}

def cancel(self, context):
    self.report({'INFO'}, "Baking map cancelled")

def finish(self, context):
    wm = context.window_manager
    wm.event_timer_remove(self._timer)
    self.report({'INFO'}, "Baking map completed")

def register(): bpy.utils.register_class(ModalTimerOperator)

def unregister(): bpy.utils.unregister_class(ModalTimerOperator)

if name == "main": register() #bpy.ops.wm.modal_timer_operator()

kemplerart
  • 610
  • 1
  • 10