2.8+ Script/shortcut to pause cycles viewport preview

Being the owner of a valiant but slow machine, for a long time I’ve been using a keyboard shortcut to pause and resume cycles’ rendered viewport preview. It’s set up with wm.context_toggle as identifier and scene.cycles.preview_pause as context.

cycles_preview_shortcut

It had quirk of not updating the UI button until you hovered it, but it worked as intended, immediately toggling the preview state.

Python equivalent for quick testing:

import bpy

bpy.context.scene.cycles.preview_pause = False #True if you want to pause

Unfortunately, I can’t get it to work on 2.80 and later. The script runs without errors, the button changes state when you hover it but the actual preview state doesn’t change.

The INFO panel shows the python for this action should be the same from 2.79 and earlier, and Blender acknowledges that the preview_pause state changed, so what’s going on here? Is there some new attribute setting being changed under the 2.8+ hood that I’m missing?

cycles_preview_button
(two manual clicks interposed by a Run Script)

Looked into this a bit. Seems the toggle from python is being deferred until scene.tag_update() is manually called.

bpy.ops.wm.context_toggle won’t do that, so you’d need a custom operator.

Anyway, this could get you started:

import bpy

class CYCLES_OT_preview_pause(bpy.types.Operator):
    bl_idname = "cycles.preview_pause"
    bl_label = "Cycles Preview Pause"

    @classmethod
    def poll(cls, context):
        return context.engine == 'CYCLES'

    def execute(self, context):
        scene = context.scene

        scene.cycles.preview_pause ^= True
        scene.update_tag()

        # Update header icon.
        for area in context.screen.areas:
            if area.type != 'VIEW_3D':
                continue
            area.regions[1].tag_redraw()

        return {'FINISHED'}

if __name__ == "__main__":
    bpy.utils.register_class(CYCLES_OT_preview_pause)
    bpy.ops.cycles.preview_pause()
1 Like

@iceythe you’re awesome! Thank you!

I can’t overstate how I missed that functionality. Just yesterday I forgot to pause the preview before rendering a complex scene and watching the mouse cursor crawl its way to the button was no fun. You just removed a major nuisance from my workflow. :open_hands:

Going from the script to a shortcut was a breeze. For those wanting the same:

  1. Run the script above. You can drop the bpy.ops.cycles.preview_pause() if you wish since you only need to register the class, but you’ll need to run it once every Blender clean start, so add it to start file and check “Register” or create an addon.
  2. Go Edit > Preferences > Keymap as usual and add a new shortcut to either Object mode > Object Mode (Global) or 3D View > 3D View (Global). Write cycles.preview_pause in the identifier field, pick your shortcut, save it and you’re good to go!

cycles_preview_shortcut__custom_script

BONUS STEP: A shortcut added to the Object mode will only work when you hove the Object Mode tab of the 3D view. You can add the same shortcut to other views like Image > Image (Global)—so you can also pause the preview while hovering the Image view when rendering something.