WIP: Compositor Viewer shortcuts prototype #105268

Closed
Habib Gahbiche wants to merge 1 commits from zazizizou/blender-addons:com-wrangler-viewer-shortcuts into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
2 changed files with 139 additions and 0 deletions

View File

@ -20,6 +20,7 @@ from mathutils import Vector
from os import path from os import path
from glob import glob from glob import glob
from copy import copy from copy import copy
import json
from itertools import chain from itertools import chain
from .interface import NWConnectionListInputs, NWConnectionListOutputs from .interface import NWConnectionListInputs, NWConnectionListOutputs
@ -486,6 +487,54 @@ class NWAddAttrNode(Operator, NWBase):
return {'FINISHED'} return {'FINISHED'}
class NWFastPreview(Operator):
bl_idname = "node.nw_fast_preview"
bl_label = "Fast Preview"
bl_description = "Preview favorite nodes by pressing 1, 2, 3, 4 and 5"
bl_options = {'REGISTER', 'UNDO'}
# Workaround: simulating a dict with json.loads() and json.dumps()
Review

You can store the dict directly here, I don’t think you need to bother serializing to a property.

You can store the dict directly here, I don’t think you need to bother serializing to a property.
Review

That didn't seem to work. I think it has to be a property for it to be persistent throughout the lifetime of the operator.

That didn't seem to work. I think it has to be a property for it to be persistent throughout the lifetime of the operator.
node_preview_map : StringProperty(name="")
update_map : BoolProperty(default=False)
viewer_index : IntProperty()
@classmethod
def poll(self, context):
return bpy.ops.node.link_viewer.poll()
def execute(self, context):
nodes, _ = get_nodes_links(context)
if self.node_preview_map != '':
temp_dict = json.loads(self.node_preview_map)
else:
temp_dict = {}
selected_nodes = context.selected_nodes
if self.update_map:
if len(selected_nodes) > 0:
n1 = selected_nodes[0]
temp_dict[self.viewer_index] = n1.name
self.node_preview_map = json.dumps(temp_dict)
bpy.ops.node.link_viewer()
Review

With a slight modification of NWPreviewNode, you could use this to make it work in shader trees as well:

                if context.space_data.tree_type in {'CompositorNodeTree', 'GeometryNodeTree'}:
                    bpy.ops.node.link_viewer()
                elif context.space_data.tree_type == 'ShaderNodeTree':
                    bpy.ops.node.nw_preview_node()

@@ -764,6 +764,8 @@ class NWPreviewNode(Operator, NWBase):
         if 'FINISHED' not in select_node:  # only run if mouse click is on a node
             return {'CANCELLED'}
 
+    def execute(self, context):
+        space = context.space_data
         base_node_tree = space.node_tree
         active_tree = context.space_data.edit_tree
         path = context.space_data.path
With a slight modification of `NWPreviewNode`, you could use this to make it work in shader trees as well: ```python if context.space_data.tree_type in {'CompositorNodeTree', 'GeometryNodeTree'}: bpy.ops.node.link_viewer() elif context.space_data.tree_type == 'ShaderNodeTree': bpy.ops.node.nw_preview_node() ``` --- ```diff @@ -764,6 +764,8 @@ class NWPreviewNode(Operator, NWBase): if 'FINISHED' not in select_node: # only run if mouse click is on a node return {'CANCELLED'} + def execute(self, context): + space = context.space_data base_node_tree = space.node_tree active_tree = context.space_data.edit_tree path = context.space_data.path ```
self.report({'INFO'}, "Set node %s to shortcut %i" % (n1.name, self.viewer_index))
else:
self.report({'ERROR'}, "No previews to set. Reason: No nodes selected.")
else:
if str(self.viewer_index) in temp_dict:
if temp_dict[str(self.viewer_index)] in nodes:
n = nodes[temp_dict[str(self.viewer_index)]]
n.select = True
nodes.active = n
bpy.ops.node.link_viewer()
n.select = False
return {'FINISHED'}
class NWPreviewNode(Operator, NWBase): class NWPreviewNode(Operator, NWBase):
bl_idname = "node.nw_preview_node" bl_idname = "node.nw_preview_node"
bl_label = "Preview Node" bl_label = "Preview Node"
@ -2592,6 +2641,63 @@ class NWAddMultipleImages(Operator, NWBase, ImportHelper):
return {'FINISHED'} return {'FINISHED'}
class NWViewerFocus(bpy.types.Operator):
Review

I think this was added back by mistake?

I think this was added back by mistake?
"""Set the viewer tile center to the mouse position"""
bl_idname = "node.nw_viewer_focus"
bl_label = "Viewer Focus"
x: bpy.props.IntProperty()
y: bpy.props.IntProperty()
@classmethod
def poll(cls, context):
return (nw_check(cls, context)
and nw_check_space_type(cls, context, {'CompositorNodeTree'}))
def execute(self, context):
return {'FINISHED'}
def invoke(self, context, event):
render = context.scene.render
space = context.space_data
percent = render.resolution_percentage * 0.01
nodes, links = get_nodes_links(context)
viewers = [n for n in nodes if n.type == 'VIEWER']
if viewers:
mlocx = event.mouse_region_x
mlocy = event.mouse_region_y
select_node = bpy.ops.node.select(location=(mlocx, mlocy), extend=False)
if 'FINISHED' not in select_node: # only run if we're not clicking on a node
region_x = context.region.width
region_y = context.region.height
region_center_x = context.region.width / 2
region_center_y = context.region.height / 2
bd_x = render.resolution_x * percent * space.backdrop_zoom
bd_y = render.resolution_y * percent * space.backdrop_zoom
backdrop_center_x = (bd_x / 2) - space.backdrop_offset[0]
backdrop_center_y = (bd_y / 2) - space.backdrop_offset[1]
margin_x = region_center_x - backdrop_center_x
margin_y = region_center_y - backdrop_center_y
abs_mouse_x = (mlocx - margin_x) / bd_x
abs_mouse_y = (mlocy - margin_y) / bd_y
for node in viewers:
node.center_x = abs_mouse_x
node.center_y = abs_mouse_y
else:
return {'PASS_THROUGH'}
return self.execute(context)
class NWSaveViewer(bpy.types.Operator, ExportHelper): class NWSaveViewer(bpy.types.Operator, ExportHelper):
"""Save the current viewer node to an image file""" """Save the current viewer node to an image file"""
bl_idname = "node.nw_save_viewer" bl_idname = "node.nw_save_viewer"
@ -2759,6 +2865,7 @@ classes = (
NWSwapLinks, NWSwapLinks,
NWResetBG, NWResetBG,
NWAddAttrNode, NWAddAttrNode,
NWFastPreview,
NWPreviewNode, NWPreviewNode,
NWFrameSelected, NWFrameSelected,
NWReloadImages, NWReloadImages,
@ -2781,6 +2888,7 @@ classes = (
NWCallInputsMenu, NWCallInputsMenu,
NWAddSequence, NWAddSequence,
NWAddMultipleImages, NWAddMultipleImages,
NWViewerFocus,
NWSaveViewer, NWSaveViewer,
NWResetNodes, NWResetNodes,
) )

View File

@ -338,6 +338,35 @@ kmi_defs = (
False, (('run_in_geometry_nodes', False),), "Preview node output"), False, (('run_in_geometry_nodes', False),), "Preview node output"),
(operators.NWPreviewNode.bl_idname, 'LEFTMOUSE', 'PRESS', False, True, (operators.NWPreviewNode.bl_idname, 'LEFTMOUSE', 'PRESS', False, True,
True, (('run_in_geometry_nodes', True),), "Preview node output"), True, (('run_in_geometry_nodes', True),), "Preview node output"),
# Fast Preview
(operators.NWFastPreview.bl_idname, 'ONE', 'PRESS', False, False, False,
(('viewer_index', 1), ('update_map', False)), "Fast Preview"),
(operators.NWFastPreview.bl_idname, 'ONE', 'PRESS', True, False, False,
(('viewer_index', 1), ('update_map', True)), "Fast Preview"),
(operators.NWFastPreview.bl_idname, 'TWO', 'PRESS', False, False, False,
(('viewer_index', 2), ('update_map', False)), "Fast Preview"),
(operators.NWFastPreview.bl_idname, 'TWO', 'PRESS', True, False, False,
(('viewer_index', 2), ('update_map', True)), "Fast Preview"),
(operators.NWFastPreview.bl_idname, 'THREE', 'PRESS', False, False, False,
(('viewer_index', 3), ('update_map', False)), "Fast Preview"),
(operators.NWFastPreview.bl_idname, 'THREE', 'PRESS', True, False, False,
(('viewer_index', 3), ('update_map', True)), "Fast Preview"),
(operators.NWFastPreview.bl_idname, 'FOUR', 'PRESS', False, False, False,
(('viewer_index', 4), ('update_map', False)), "Fast Preview"),
(operators.NWFastPreview.bl_idname, 'FOUR', 'PRESS', True, False, False,
(('viewer_index', 4), ('update_map', True)), "Fast Preview"),
(operators.NWFastPreview.bl_idname, 'FIVE', 'PRESS', False, False, False,
(('viewer_index', 5), ('update_map', False)), "Fast Preview"),
(operators.NWFastPreview.bl_idname, 'FIVE', 'PRESS', True, False, False,
(('viewer_index', 5), ('update_map', True)), "Fast Preview"),
# Reload Images # Reload Images
(operators.NWReloadImages.bl_idname, 'R', 'PRESS', False, False, True, None, "Reload images"), (operators.NWReloadImages.bl_idname, 'R', 'PRESS', False, False, True, None, "Reload images"),
# Lazy Mix # Lazy Mix
@ -347,6 +376,8 @@ kmi_defs = (
# Lazy Connect with Menu # Lazy Connect with Menu
(operators.NWLazyConnect.bl_idname, 'RIGHTMOUSE', 'PRESS', False, (operators.NWLazyConnect.bl_idname, 'RIGHTMOUSE', 'PRESS', False,
True, True, (('with_menu', True),), "Lazy Connect with Socket Menu"), True, True, (('with_menu', True),), "Lazy Connect with Socket Menu"),
# Viewer Tile Center
(operators.NWViewerFocus.bl_idname, 'LEFTMOUSE', 'DOUBLE_CLICK', False, False, False, None, "Set Viewers Tile Center"),
# Align Nodes # Align Nodes
(operators.NWAlignNodes.bl_idname, 'EQUAL', 'PRESS', False, True, (operators.NWAlignNodes.bl_idname, 'EQUAL', 'PRESS', False, True,
False, None, "Align selected nodes neatly in a row/column"), False, None, "Align selected nodes neatly in a row/column"),