4

The Problem

Like many people, I use Render Region to lighten the load on viewport rendering by only rendering what's visible to the camera.

I also use Set Render Region (CtrlB) when I want to focus on just one specific area, and since all the samples get spent rendering that area, I can see that specific area more quickly.

The problem is that if you use Set Render Region and draw out a marquee selection, and then after that you want to resize the render region back to the camera bounds, you must Clear Render Region (CtrlAltB) and then re-enable Render Region by ticking the checkbox.

An animated GIF to illustrate the issue simply:

Switching between different render preview regions

The Question

Is there a way to re-map CtrlAltB to toggle between the marquee-selected region and the camera boundary region?

More Details

Examining the Info window, we can see that the syntax for enabling Render Region is bpy.context.scene.render.use_border = True

On the other hand, Set Render Region is bpy.ops.view3d.render_border(xmin=682, xmax=786, ymin=1248, ymax=1422)

And Clear Render Region is bpy.ops.view3d.clear_render_border()

Even though all three of these operations define the region to be rendered, they work differently. I have not found a way to toggle between two differently sized render regions (user-specified and camera bounds).

Mentalist
  • 19,092
  • 7
  • 94
  • 166

1 Answers1

4

'Render Region' Toggle

You can implement a custom Operator to toggle Render Region using a shortcut. In this case, all you'd have to do is finding a reliable way to set the state of RenderSettings.use_border:

enter image description here

The following demo based on the answers of How to easily toggle a Boolean property? and Create keyboard shortcut for an operator using python?:

toggle-render-region.py

# ##### BEGIN GPL LICENSE BLOCK #####
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software Foundation,
#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>

import bpy

bl_info = { "name": "Toggle Render Region Hotkey", "author": "brockmann", "version": (0, 1), "blender" : (2, 80, 0), "location": "3D View", "category": "3D View" }

class RR_OT_toggleRenderRegion(bpy.types.Operator): """Toggle Render Region in 3D View""" bl_idname = "view3d.toggle_render_region" bl_label = "Toggle Render Region" bl_options = {'REGISTER', 'UNDO'}

def execute(self, context):
    context.scene.render.use_border ^= 1
    return {'FINISHED'}


addon_keymaps = []

def register(): bpy.utils.register_class(RR_OT_toggleRenderRegion) addon_keymaps.clear()

# handle the keymap
wm = bpy.context.window_manager
kc = wm.keyconfigs.addon
if kc:
    km = wm.keyconfigs.addon.keymaps.new(name='3D View', space_type='VIEW_3D')
    #kmi = km.keymap_items.new(RR_OT_disableRenderRegion.bl_idname, type='B', value='PRESS', ctrl=True, shift=True)
    kmi = km.keymap_items.new(RR_OT_toggleRenderRegion.bl_idname, type='B', value='PRESS', ctrl=True, alt=True)
    addon_keymaps.append((km, kmi))

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

for km, kmi in addon_keymaps:
    km.keymap_items.remove(kmi)
addon_keymaps.clear()

if name == "main": register()

enter image description here

As mentioned by @batFINGER in the comments there is also a generic bpy.ops.wm.context_toggle() operator for convenience which allows to toggle any BoolProperty (also used for some of the default hotkeys in Blender).

toggle-render-region.py

 # ##### BEGIN GPL LICENSE BLOCK #####
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software Foundation,
#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>

import bpy

bl_info = { "name": "Toggle Render Region Hotkey", "author": "brockmann, batFINGER", "version": (0, 1), "blender" : (2, 80, 0), "location": "3D View", "category": "3D View" }

addon_keymaps = []

def register(): addon_keymaps.clear()

# handle the keymap
wm = bpy.context.window_manager
kc = wm.keyconfigs.addon
if kc:
    km = wm.keyconfigs.addon.keymaps.new(name='3D View', space_type='VIEW_3D')
    kmi = km.keymap_items.new(&quot;wm.context_toggle&quot;, type='B', value='PRESS', ctrl=True, alt=True)
    kmi.properties.data_path = &quot;scene.render.use_border&quot;
    addon_keymaps.append((km, kmi))

def unregister(): for km, kmi in addon_keymaps: km.keymap_items.remove(kmi) addon_keymaps.clear()

if name == "main": register()

If you'd like to edit the old shortcut manually without using an add-on, replace the identifier and the data_path for the old hotkey by wm.context_toggle and scene.render.use_border:

enter image description here


Toggle between 'Selection' and 'Camera Bounds'

If you'd like to toggle between the current selection and the camera bounds using a shortcut you'd have to implement a custom Operator as well as supplying a new scene property in order to store the coordinates and restore them if necessary:

enter image description here

custom-render-region.py

# ##### BEGIN GPL LICENSE BLOCK #####
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software Foundation,
#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>

import bpy

bl_info = { "name": "Custom Render Region", "author": "brockmann", "version": (0, 1), "blender" : (2, 80, 0), "location": "3D View", "category": "3D View" }

class RR_OT_customRenderRegion(bpy.types.Operator): """Custom Render Region""" bl_idname = "view3d.custom_render_region" bl_label = "Custom Render Region" bl_options = {'REGISTER', 'UNDO'}

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

    if rnd.border_min_x != 0 or rnd.border_min_y != 0 or \
        rnd.border_max_x != 1 or rnd.border_max_y != 1:
        # Store the values
        scene.custom_render_bounds = (
                rnd.border_min_x, 
                rnd.border_min_y, 
                rnd.border_max_x, 
                rnd.border_max_y)
        # Camera bounds
        rnd.border_min_x = rnd.border_min_y = 0
        rnd.border_max_x = rnd.border_max_y = 1

    else:
        # Set the values
        rnd.border_min_x = scene.custom_render_bounds[0]
        rnd.border_min_y = scene.custom_render_bounds[1]
        rnd.border_max_x = scene.custom_render_bounds[2]
        rnd.border_max_y = scene.custom_render_bounds[3]

    # Clear region if not in camera view
    if not context.space_data.region_3d.view_perspective == 'CAMERA':
        bpy.ops.view3d.clear_render_border()

    return {'FINISHED'}


addon_keymaps = []

def register(): bpy.types.Scene.custom_render_bounds = bpy.props.FloatVectorProperty(size=4) bpy.utils.register_class(RR_OT_customRenderRegion) addon_keymaps.clear()

# handle the keymap
wm = bpy.context.window_manager
kc = wm.keyconfigs.addon
if kc:
    km = wm.keyconfigs.addon.keymaps.new(name='3D View', space_type='VIEW_3D')
    kmi = km.keymap_items.new(
        RR_OT_customRenderRegion.bl_idname, type='B', 
        value='PRESS', 
        ctrl=True, 
        alt=True)
    addon_keymaps.append((km, kmi))

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

for km, kmi in addon_keymaps:
    km.keymap_items.remove(kmi)
addon_keymaps.clear()

if name == "main": register()

brockmann
  • 12,613
  • 4
  • 50
  • 93