Skip to content

Instantly share code, notes, and snippets.

@sonygod
Created December 14, 2021 03:32
Show Gist options
  • Save sonygod/8f2aa225fc60015cd131fad902a61a1e to your computer and use it in GitHub Desktop.
Save sonygod/8f2aa225fc60015cd131fad902a61a1e to your computer and use it in GitHub Desktop.
blender bake progress
import bpy, _bpy
class WM_OT_bake_report(bpy.types.Operator):
bl_idname = "wm.bake_report"
bl_label = "Bake Report"
bl_options = {'INTERNAL'}
queue_position: bpy.props.IntProperty()
queue_size: bpy.props.IntProperty()
def execute(self, context):
p = self.queue_position
s = self.queue_size
self.report({'INFO'}, f"{round(100 * p / s)}%")
return {'FINISHED'}
class WM_OT_set_finished(bpy.types.Operator):
bl_idname = "wm.bake_set_finished"
bl_label = "Bake Set Finished"
bl_options = {'INTERNAL'}
def execute(self, context):
# this is the last operator to run in the bake queue
# signal the modal operator to end
WM_OT_bake_modal._ready = True
return {'FINISHED'}
def get_macro():
class OBJECT_OT_bake_macro(bpy.types.Macro):
bl_idname = "object.bake_macro"
bl_label = "Bake Macro"
bl_options = {'INTERNAL'}
# unregister any previous macro
if hasattr(bpy.types, "OBJECT_OT_bake_macro"):
bpy.utils.unregister_class(bpy.types.OBJECT_OT_bake_macro)
bpy.utils.register_class(OBJECT_OT_bake_macro)
return OBJECT_OT_bake_macro
# bake operator
class WM_OT_bake_modal(bpy.types.Operator):
bl_idname = "wm.bake_modal"
bl_label = "Bake Modal"
def modal(self, context, event):
# keep checking the attribute
if getattr(__class__, '_ready', False):
__class__._ready = False
context.window_manager.event_timer_remove(self.timer)
self.report({'INFO'}, "Finished")
print("Done")
return {'FINISHED'}
return {'PASS_THROUGH'}
def invoke(self, context, event):
# macro is a container that lets
# us define any number of sub-operators
macro = get_macro()
# we can add sub-operators to a list for easy access
bake_queue = []
# let's do 16 bakes
num_bakes = 16
for i in range(num_bakes):
bake = _bpy.ops.macro_define(macro, 'OBJECT_OT_bake')
bake_queue.append(bake)
# add a progress report operator
report = _bpy.ops.macro_define(macro, 'WM_OT_bake_report')
report.properties.queue_size = num_bakes
report.properties.queue_position = i
# set some bake properties
bake_queue[0].properties.margin = 24
# define a last operator that tells the modal to end
_bpy.ops.macro_define(macro, 'WM_OT_bake_set_finished')
# the macro container is ready. remember
# to use 'INVOKE_DEFAULT' to keep the ui responsive
bpy.ops.object.bake_macro('INVOKE_DEFAULT')
__class__._ready = False
wm = context.window_manager
# a timer is needed to jumpstart each successive macro
self.timer = wm.event_timer_add(0.1, window=context.window)
wm.modal_handler_add(self)
return {'RUNNING_MODAL'}
def register():
bpy.utils.register_class(WM_OT_bake_report)
bpy.utils.register_class(WM_OT_set_finished)
bpy.utils.register_class(WM_OT_bake_modal)
if __name__ == '__main__':
register()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment