Node Wrangler: refactor by splitting the script into several files #104463

Merged
Damien Picard merged 2 commits from pioverfour/blender-addons:dp_node_wrangler_refactor into main 2023-03-05 12:24:26 +01:00
6 changed files with 272 additions and 195 deletions
Showing only changes of commit c1382e3899 - Show all commits

View File

@ -125,9 +125,11 @@ class NWMergeNodesMenu(Menu, NWBase):
props.mode = 'MIX'
props.merge_type = 'ALPHAOVER'
class NWMergeGeometryMenu(Menu, NWBase):
bl_idname = "NODE_MT_nw_merge_geometry_menu"
bl_label = "Merge Selected Nodes using Geometry Nodes"
def draw(self, context):
layout = self.layout
# The boolean node + Join Geometry node
@ -136,6 +138,7 @@ class NWMergeGeometryMenu(Menu, NWBase):
props.mode = type
props.merge_type = 'GEOMETRY'
class NWMergeShadersMenu(Menu, NWBase):
bl_idname = "NODE_MT_nw_merge_shaders_menu"
bl_label = "Merge Selected Nodes using Shaders"
@ -172,7 +175,10 @@ class NWConnectionListOutputs(Menu, NWBase):
for index, output in enumerate(n1.outputs):
# Only show sockets that are exposed.
if output.enabled:
layout.operator(operators.NWCallInputsMenu.bl_idname, text=output.name, icon="RADIOBUT_OFF").from_socket=index
layout.operator(
operators.NWCallInputsMenu.bl_idname,
text=output.name,
icon="RADIOBUT_OFF").from_socket = index
class NWConnectionListInputs(Menu, NWBase):
@ -407,9 +413,11 @@ def draw_switch_category_submenu(self, context):
# APPENDAGES TO EXISTING UI
#
def select_parent_children_buttons(self, context):
layout = self.layout
layout.operator(operators.NWSelectParentChildren.bl_idname, text="Select frame's members (children)").option = 'CHILD'
layout.operator(operators.NWSelectParentChildren.bl_idname,
text="Select frame's members (children)").option = 'CHILD'
layout.operator(operators.NWSelectParentChildren.bl_idname, text="Select parent frame").option = 'PARENT'
@ -479,6 +487,7 @@ classes = (
NWSwitchNodeTypeMenu,
)
def register():
from bpy.utils import register_class
for cls in classes:

View File

@ -94,7 +94,8 @@ class NWLazyMix(Operator, NWBase):
args = (self, context, 'MIX')
# Add the region OpenGL drawing callback
# draw in view space with 'POST_VIEW' and 'PRE_VIEW'
self._handle = bpy.types.SpaceNodeEditor.draw_handler_add(draw_callback_nodeoutline, args, 'WINDOW', 'POST_PIXEL')
self._handle = bpy.types.SpaceNodeEditor.draw_handler_add(
draw_callback_nodeoutline, args, 'WINDOW', 'POST_PIXEL')
self.mouse_path = []
@ -152,7 +153,7 @@ class NWLazyConnect(Operator, NWBase):
original_sel = []
original_unsel = []
for node in nodes:
if node.select == True:
if node.select:
node.select = False
original_sel.append(node)
else:
@ -199,7 +200,8 @@ class NWLazyConnect(Operator, NWBase):
args = (self, context, mode)
# Add the region OpenGL drawing callback
# draw in view space with 'POST_VIEW' and 'PRE_VIEW'
self._handle = bpy.types.SpaceNodeEditor.draw_handler_add(draw_callback_nodeoutline, args, 'WINDOW', 'POST_PIXEL')
self._handle = bpy.types.SpaceNodeEditor.draw_handler_add(
draw_callback_nodeoutline, args, 'WINDOW', 'POST_PIXEL')
self.mouse_path = []
@ -216,12 +218,18 @@ class NWDeleteUnused(Operator, NWBase):
bl_label = 'Delete Unused Nodes'
bl_options = {'REGISTER', 'UNDO'}
delete_muted: BoolProperty(name="Delete Muted", description="Delete (but reconnect, like Ctrl-X) all muted nodes", default=True)
delete_frames: BoolProperty(name="Delete Empty Frames", description="Delete all frames that have no nodes inside them", default=True)
delete_muted: BoolProperty(
name="Delete Muted",
description="Delete (but reconnect, like Ctrl-X) all muted nodes",
default=True)
delete_frames: BoolProperty(
name="Delete Empty Frames",
description="Delete all frames that have no nodes inside them",
default=True)
def is_unused_node(self, node):
end_types = ['OUTPUT_MATERIAL', 'OUTPUT', 'VIEWER', 'COMPOSITE', \
'SPLITVIEWER', 'OUTPUT_FILE', 'LEVELS', 'OUTPUT_LIGHT', \
end_types = ['OUTPUT_MATERIAL', 'OUTPUT', 'VIEWER', 'COMPOSITE',
'SPLITVIEWER', 'OUTPUT_FILE', 'LEVELS', 'OUTPUT_LIGHT',
'OUTPUT_WORLD', 'GROUP_INPUT', 'GROUP_OUTPUT', 'FRAME']
if node.type in end_types:
return False
@ -245,7 +253,7 @@ class NWDeleteUnused(Operator, NWBase):
# Store selection
selection = []
for node in nodes:
if node.select == True:
if node.select:
selection.append(node.name)
for node in nodes:
@ -362,12 +370,14 @@ class NWSwapLinks(Operator, NWBase):
try:
links.new(n2.outputs[connection[0]], connection[1])
except:
self.report({'WARNING'}, "Some connections have been lost due to differing numbers of output sockets")
self.report({'WARNING'},
"Some connections have been lost due to differing numbers of output sockets")
for connection in n2_outputs:
try:
links.new(n1.outputs[connection[0]], connection[1])
except:
self.report({'WARNING'}, "Some connections have been lost due to differing numbers of output sockets")
self.report({'WARNING'},
"Some connections have been lost due to differing numbers of output sockets")
else:
if n1.outputs or n2.outputs:
self.report({'WARNING'}, "One of the nodes has no outputs!")
@ -505,7 +515,7 @@ class NWPreviewNode(Operator, NWBase):
# if viewer output is already used but leads to the same socket we can still use it
is_used = self.is_socket_used_other_mats(socket)
if is_used:
if connect_socket == None:
if connect_socket is None:
continue
groupout = get_group_output_node(node.node_tree)
groupout_input = groupout.inputs[i]
@ -541,7 +551,7 @@ class NWPreviewNode(Operator, NWBase):
def get_shader_output_node(self, tree):
for node in tree.nodes:
if node.type == self.shader_output_type and node.is_active_output == True:
if node.type == self.shader_output_type and node.is_active_output:
return node
@classmethod
@ -697,7 +707,8 @@ class NWPreviewNode(Operator, NWBase):
link_end = output_socket
while tree.nodes.active != active:
node = tree.nodes.active
index = self.ensure_viewer_socket(node,'NodeSocketGeometry', connect_socket=active.outputs[out_i] if node.node_tree.nodes.active == active else None)
index = self.ensure_viewer_socket(
node, 'NodeSocketGeometry', connect_socket=active.outputs[out_i] if node.node_tree.nodes.active == active else None)
link_start = node.outputs[index]
node_socket = node.node_tree.outputs[index]
if node_socket in delete_sockets:
@ -718,7 +729,6 @@ class NWPreviewNode(Operator, NWBase):
force_update(context)
return {'FINISHED'}
# What follows is code for the shader editor
output_types = [x.nodetype for x in
get_nodes_from_category('Output', context)]
@ -773,7 +783,8 @@ class NWPreviewNode(Operator, NWBase):
link_end = output_socket
while tree.nodes.active != active:
node = tree.nodes.active
index = self.ensure_viewer_socket(node, socket_type, connect_socket=active.outputs[out_i] if node.node_tree.nodes.active == active else None)
index = self.ensure_viewer_socket(
node, socket_type, connect_socket=active.outputs[out_i] if node.node_tree.nodes.active == active else None)
link_start = node.outputs[index]
node_socket = node.node_tree.outputs[index]
if node_socket in delete_sockets:
@ -836,7 +847,7 @@ class NWFrameSelected(Operator, NWBase):
nodes, links = get_nodes_links(context)
selected = []
for node in nodes:
if node.select == True:
if node.select:
selected.append(node)
bpy.ops.node.add_node(type='NodeFrame')
@ -970,8 +981,10 @@ class NWSwitchNodeType(Operator, NWBase):
for the_type in types_order_one:
if socket.type == the_type:
# create values for sockets['INPUTS'][the_type] and sockets['OUTPUTS'][the_type]
# entry structure: (index_in_type, socket_index, socket_name, socket_default_value, socket_links)
sockets[in_out_name][the_type].append((len(sockets[in_out_name][the_type]), i, the_name, dval, socket_links))
# entry structure: (index_in_type, socket_index, socket_name,
# socket_default_value, socket_links)
sockets[in_out_name][the_type].append(
(len(sockets[in_out_name][the_type]), i, the_name, dval, socket_links))
# Check which of the types in inputs/outputs is considered to be "main".
# Set values of sockets['INPUTS']['MAIN'] and sockets['OUTPUTS']['MAIN']
for type_check in types_order_one:
@ -1156,7 +1169,9 @@ class NWMergeNodes(Operator, NWBase):
# Search for the first node which had output links that do not create
# a cycle, which we can then reconnect afterwards.
if prev_links == [] and node.outputs[0].is_linked:
prev_links = [link for link in node.outputs[0].links if not NWMergeNodes.link_creates_cycle(link, selected_nodes)]
prev_links = [
link for link in node.outputs[0].links if not NWMergeNodes.link_creates_cycle(
link, selected_nodes)]
# Get the index of the socket, the last one is a multi input, and is thus used repeatedly
# To get the placement to look right we need to reverse the order in which we connect the
# outputs to the multi input socket.
@ -1268,7 +1283,14 @@ class NWMergeNodes(Operator, NWBase):
if selected_mix and selected_math and merge_type == 'AUTO':
selected_mix += selected_math
selected_math = []
for nodes_list in [selected_mix, selected_shader, selected_geometry, selected_math, selected_vector, selected_z, selected_alphaover]:
for nodes_list in [
selected_mix,
selected_shader,
selected_geometry,
selected_math,
selected_vector,
selected_z,
selected_alphaover]:
if not nodes_list:
continue
count_before = len(nodes)
@ -1285,8 +1307,9 @@ class NWMergeNodes(Operator, NWBase):
else:
node_type = 'GeometryNode'
if merge_position == 'CENTER':
loc_y = ((nodes_list[len(nodes_list) - 1][2]) + (nodes_list[len(nodes_list) - 2][2])) / 2 # average yloc of last two nodes (lowest two)
if nodes_list[len(nodes_list) - 1][-1] == True: # if last node is hidden, mix should be shifted up a bit
# average yloc of last two nodes (lowest two)
loc_y = ((nodes_list[len(nodes_list) - 1][2]) + (nodes_list[len(nodes_list) - 2][2])) / 2
if nodes_list[len(nodes_list) - 1][-1]: # if last node is hidden, mix should be shifted up a bit
if do_hide:
loc_y += 40
else:
@ -1356,11 +1379,13 @@ class NWMergeNodes(Operator, NWBase):
elif nodes_list == selected_geometry:
if mode in ('JOIN', 'MIX'):
add_type = node_type + 'JoinGeometry'
add = self.merge_with_multi_input(nodes_list, merge_position, do_hide, loc_x, links, nodes, add_type,[0])
add = self.merge_with_multi_input(
nodes_list, merge_position, do_hide, loc_x, links, nodes, add_type, [0])
else:
add_type = node_type + 'MeshBoolean'
indices = [0, 1] if mode == 'DIFFERENCE' else [1]
add = self.merge_with_multi_input(nodes_list, merge_position, do_hide, loc_x, links, nodes, add_type,indices)
add = self.merge_with_multi_input(
nodes_list, merge_position, do_hide, loc_x, links, nodes, add_type, indices)
add.operation = mode
was_multi = True
break
@ -1406,7 +1431,8 @@ class NWMergeNodes(Operator, NWBase):
# "last" node has been added as first, so its index is count_before.
last_add = nodes[count_before]
# Create list of invalid indexes.
invalid_nodes = [nodes[n[0]] for n in (selected_mix + selected_math + selected_shader + selected_z + selected_geometry)]
invalid_nodes = [nodes[n[0]]
for n in (selected_mix + selected_math + selected_shader + selected_z + selected_geometry)]
# Special case:
# Two nodes were selected and first selected has no output links, second selected has output links.
@ -1484,7 +1510,7 @@ class NWBatchChangeNodes(Operator, NWBase):
operation = self.operation
for node in context.selected_nodes:
if node.type == 'MIX_RGB' or (node.bl_idname == 'ShaderNodeMix' and node.data_type == 'RGBA'):
if not blend_type in [nav[0] for nav in navs]:
if blend_type not in [nav[0] for nav in navs]:
node.blend_type = blend_type
else:
if blend_type == 'NEXT':
@ -1503,7 +1529,7 @@ class NWBatchChangeNodes(Operator, NWBase):
node.blend_type = blend_types[index - 1][0]
if node.type == 'MATH' or node.bl_idname == 'ShaderNodeMath':
if not operation in [nav[0] for nav in navs]:
if operation not in [nav[0] for nav in navs]:
node.operation = operation
else:
if operation == 'NEXT':
@ -1599,7 +1625,11 @@ class NWCopySettings(Operator, NWBase):
# Report nodes that are not valid
valid_node_names = [n.name for n in valid_nodes]
not_valid_names = list(set(selected_node_names) - set(valid_node_names))
self.report({'INFO'}, "Ignored {} (not of the same type as {})".format(", ".join(not_valid_names), node_active.name))
self.report(
{'INFO'},
"Ignored {} (not of the same type as {})".format(
", ".join(not_valid_names),
node_active.name))
# Reference original
orig = node_active
@ -1664,7 +1694,11 @@ class NWCopySettings(Operator, NWBase):
orig.select = True
node_tree.nodes.active = orig
self.report({'INFO'}, "Successfully copied attributes from {} to: {}".format(orig.name, ", ".join(success_names)))
self.report(
{'INFO'},
"Successfully copied attributes from {} to: {}".format(
orig.name,
", ".join(success_names)))
return {'FINISHED'}
@ -1772,7 +1806,10 @@ class NWAddTextureSetup(Operator, NWBase):
bl_description = "Add Texture Node Setup to Selected Shaders"
bl_options = {'REGISTER', 'UNDO'}
add_mapping: BoolProperty(name="Add Mapping Nodes", description="Create coordinate and mapping nodes for the texture (ignored for selected texture nodes)", default=True)
add_mapping: BoolProperty(
name="Add Mapping Nodes",
description="Create coordinate and mapping nodes for the texture (ignored for selected texture nodes)",
default=True)
@classmethod
def poll(cls, context):
@ -2076,7 +2113,8 @@ class NWAddPrincipledSetup(Operator, NWBase, ImportHelper):
# If more than one texture add reroute node in between
reroute = nodes.new(type='NodeReroute')
texture_nodes.append(reroute)
tex_coords = Vector((texture_nodes[0].location.x, sum(n.location.y for n in texture_nodes)/len(texture_nodes)))
tex_coords = Vector((texture_nodes[0].location.x,
sum(n.location.y for n in texture_nodes) / len(texture_nodes)))
reroute.location = tex_coords + Vector((-50, -120))
for texture_node in texture_nodes:
link = links.new(texture_node.inputs[0], reroute.outputs[0])
@ -2316,7 +2354,8 @@ class NWAlignNodes(Operator, NWBase):
active_loc = copy(nodes.active.location) # make a copy, not a reference
# Check if nodes should be laid out horizontally or vertically
x_locs = [n.location.x + (n.dimensions.x / 2) for n in selection] # use dimension to get center of node, not corner
# use dimension to get center of node, not corner
x_locs = [n.location.x + (n.dimensions.x / 2) for n in selection]
y_locs = [n.location.y - (n.dimensions.y / 2) for n in selection]
x_range = max(x_locs) - min(x_locs)
y_range = max(y_locs) - min(y_locs)
@ -2351,7 +2390,8 @@ class NWAlignNodes(Operator, NWBase):
for node in selection:
node.location += active_loc_diff
else: # Position nodes centered around where they used to be
locs = ([n.location.x + (n.dimensions.x / 2) for n in selection]) if horizontal else ([n.location.y - (n.dimensions.y / 2) for n in selection])
locs = ([n.location.x + (n.dimensions.x / 2) for n in selection]
) if horizontal else ([n.location.y - (n.dimensions.y / 2) for n in selection])
new_mid = (max(locs) + min(locs)) / 2
for node in selection:
if horizontal:
@ -2594,7 +2634,6 @@ class NWAddSequence(Operator, NWBase, ImportHelper):
self.report({'ERROR'}, filename + " does not seem to be part of a sequence")
return {'CANCELLED'}
extension = filename.split('.')[-1]
reverse = without_ext[::-1] # reverse string
@ -2643,7 +2682,8 @@ class NWAddSequence(Operator, NWBase, ImportHelper):
img.name = name_with_hashes
node.image = img
image_user = node.image_user if tree.type == 'SHADER' else node
image_user.frame_offset = int(files[0][len(without_num)+len(directory):-1*(len(extension)+1)]) - 1 # separate the number from the file name of the first file
# separate the number from the file name of the first file
image_user.frame_offset = int(files[0][len(without_num) + len(directory):-1 * (len(extension) + 1)]) - 1
image_user.frame_duration = num_frames
return {'FINISHED'}
@ -2730,7 +2770,7 @@ class NWViewerFocus(bpy.types.Operator):
mlocy = event.mouse_region_y
select_node = bpy.ops.node.select(location=(mlocx, mlocy), extend=False)
if not 'FINISHED' in select_node: # only run if we're not clicking on a node
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

View File

@ -114,7 +114,11 @@ class NWNodeWrangler(bpy.types.AddonPreferences):
box = layout.box()
col = box.column(align=True)
col.prop(self, "show_principled_lists", text='Edit tags for auto texture detection in Principled BSDF setup', toggle=True)
col.prop(
self,
"show_principled_lists",
text='Edit tags for auto texture detection in Principled BSDF setup',
toggle=True)
if self.show_principled_lists:
tags = self.principled_tags
@ -157,6 +161,7 @@ class NWNodeWrangler(bpy.types.AddonPreferences):
keystr = "Ctrl " + keystr
row.label(text=keystr)
#
# REGISTER/UNREGISTER CLASSES AND KEYMAP ITEMS
#
@ -285,13 +290,20 @@ kmi_defs = (
(operators.NWLinkActiveToSelected.bl_idname, 'SEMI_COLON', 'PRESS', False, True, False,
(('replace', True), ('use_node_name', False), ('use_outputs_names', True),), "Link active to selected (Replace links, output names)"),
# CHANGE MIX FACTOR
(operators.NWChangeMixFactor.bl_idname, 'LEFT_ARROW', 'PRESS', False, False, True, (('option', -0.1),), "Reduce Mix Factor by 0.1"),
(operators.NWChangeMixFactor.bl_idname, 'RIGHT_ARROW', 'PRESS', False, False, True, (('option', 0.1),), "Increase Mix Factor by 0.1"),
(operators.NWChangeMixFactor.bl_idname, 'LEFT_ARROW', 'PRESS', False, True, True, (('option', -0.01),), "Reduce Mix Factor by 0.01"),
(operators.NWChangeMixFactor.bl_idname, 'RIGHT_ARROW', 'PRESS', False, True, True, (('option', 0.01),), "Increase Mix Factor by 0.01"),
(operators.NWChangeMixFactor.bl_idname, 'LEFT_ARROW', 'PRESS', True, True, True, (('option', 0.0),), "Set Mix Factor to 0.0"),
(operators.NWChangeMixFactor.bl_idname, 'RIGHT_ARROW', 'PRESS', True, True, True, (('option', 1.0),), "Set Mix Factor to 1.0"),
(operators.NWChangeMixFactor.bl_idname, 'NUMPAD_0', 'PRESS', True, True, True, (('option', 0.0),), "Set Mix Factor to 0.0"),
(operators.NWChangeMixFactor.bl_idname, 'LEFT_ARROW', 'PRESS', False,
False, True, (('option', -0.1),), "Reduce Mix Factor by 0.1"),
(operators.NWChangeMixFactor.bl_idname, 'RIGHT_ARROW', 'PRESS', False,
False, True, (('option', 0.1),), "Increase Mix Factor by 0.1"),
(operators.NWChangeMixFactor.bl_idname, 'LEFT_ARROW', 'PRESS', False,
True, True, (('option', -0.01),), "Reduce Mix Factor by 0.01"),
(operators.NWChangeMixFactor.bl_idname, 'RIGHT_ARROW', 'PRESS', False,
True, True, (('option', 0.01),), "Increase Mix Factor by 0.01"),
(operators.NWChangeMixFactor.bl_idname, 'LEFT_ARROW', 'PRESS',
True, True, True, (('option', 0.0),), "Set Mix Factor to 0.0"),
(operators.NWChangeMixFactor.bl_idname, 'RIGHT_ARROW', 'PRESS',
True, True, True, (('option', 1.0),), "Set Mix Factor to 1.0"),
(operators.NWChangeMixFactor.bl_idname, 'NUMPAD_0', 'PRESS',
True, True, True, (('option', 0.0),), "Set Mix Factor to 0.0"),
(operators.NWChangeMixFactor.bl_idname, 'ZERO', 'PRESS', True, True, True, (('option', 0.0),), "Set Mix Factor to 0.0"),
(operators.NWChangeMixFactor.bl_idname, 'NUMPAD_1', 'PRESS', True, True, True, (('option', 1.0),), "Mix Factor to 1.0"),
(operators.NWChangeMixFactor.bl_idname, 'ONE', 'PRESS', True, True, True, (('option', 1.0),), "Set Mix Factor to 1.0"),
@ -300,16 +312,19 @@ kmi_defs = (
# MODIFY LABEL (Alt Shift L)
(operators.NWModifyLabels.bl_idname, 'L', 'PRESS', False, True, True, None, "Modify node labels"),
# Copy Label from active to selected
(operators.NWCopyLabel.bl_idname, 'V', 'PRESS', False, True, False, (('option', 'FROM_ACTIVE'),), "Copy label from active to selected"),
(operators.NWCopyLabel.bl_idname, 'V', 'PRESS', False, True, False,
(('option', 'FROM_ACTIVE'),), "Copy label from active to selected"),
# DETACH OUTPUTS (Alt Shift D)
(operators.NWDetachOutputs.bl_idname, 'D', 'PRESS', False, True, True, None, "Detach outputs"),
# LINK TO OUTPUT NODE (O)
(operators.NWLinkToOutputNode.bl_idname, 'O', 'PRESS', False, False, False, None, "Link to output node"),
# SELECT PARENT/CHILDREN
# Select Children
(operators.NWSelectParentChildren.bl_idname, 'RIGHT_BRACKET', 'PRESS', False, False, False, (('option', 'CHILD'),), "Select children"),
(operators.NWSelectParentChildren.bl_idname, 'RIGHT_BRACKET', 'PRESS',
False, False, False, (('option', 'CHILD'),), "Select children"),
# Select Parent
(operators.NWSelectParentChildren.bl_idname, 'LEFT_BRACKET', 'PRESS', False, False, False, (('option', 'PARENT'),), "Select Parent"),
(operators.NWSelectParentChildren.bl_idname, 'LEFT_BRACKET', 'PRESS',
False, False, False, (('option', 'PARENT'),), "Select Parent"),
# Add Texture Setup
(operators.NWAddTextureSetup.bl_idname, 'T', 'PRESS', True, False, False, None, "Add texture setup"),
# Add Principled BSDF Texture Setup
@ -323,8 +338,10 @@ kmi_defs = (
# Swap Links
(operators.NWSwapLinks.bl_idname, 'S', 'PRESS', False, False, True, None, "Swap Links"),
# Preview Node
(operators.NWPreviewNode.bl_idname, 'LEFTMOUSE', 'PRESS', True, True, False, (('run_in_geometry_nodes', False),), "Preview node output"),
(operators.NWPreviewNode.bl_idname, 'LEFTMOUSE', 'PRESS', False, True, True, (('run_in_geometry_nodes', True),), "Preview node output"),
(operators.NWPreviewNode.bl_idname, 'LEFTMOUSE', 'PRESS', True, True,
False, (('run_in_geometry_nodes', False),), "Preview node output"),
(operators.NWPreviewNode.bl_idname, 'LEFTMOUSE', 'PRESS', False, True,
True, (('run_in_geometry_nodes', True),), "Preview node output"),
# Reload Images
(operators.NWReloadImages.bl_idname, 'R', 'PRESS', False, False, True, None, "Reload images"),
# Lazy Mix
@ -332,26 +349,35 @@ kmi_defs = (
# Lazy Connect
(operators.NWLazyConnect.bl_idname, 'RIGHTMOUSE', 'PRESS', False, False, True, (('with_menu', False),), "Lazy Connect"),
# Lazy Connect with Menu
(operators.NWLazyConnect.bl_idname, 'RIGHTMOUSE', 'PRESS', False, True, True, (('with_menu', True),), "Lazy Connect with Socket Menu"),
(operators.NWLazyConnect.bl_idname, 'RIGHTMOUSE', 'PRESS', False,
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
(operators.NWAlignNodes.bl_idname, 'EQUAL', 'PRESS', False, True, False, None, "Align selected nodes neatly in a row/column"),
(operators.NWAlignNodes.bl_idname, 'EQUAL', 'PRESS', False, True,
False, None, "Align selected nodes neatly in a row/column"),
# Reset Nodes (Back Space)
(operators.NWResetNodes.bl_idname, 'BACK_SPACE', 'PRESS', False, False, False, None, "Revert node back to default state, but keep connections"),
(operators.NWResetNodes.bl_idname, 'BACK_SPACE', 'PRESS', False, False,
False, None, "Revert node back to default state, but keep connections"),
# MENUS
('wm.call_menu', 'W', 'PRESS', False, True, False, (('name', interface.NodeWranglerMenu.bl_idname),), "Node Wrangler menu"),
('wm.call_menu', 'SLASH', 'PRESS', False, False, False, (('name', interface.NWAddReroutesMenu.bl_idname),), "Add Reroutes menu"),
('wm.call_menu', 'NUMPAD_SLASH', 'PRESS', False, False, False, (('name', interface.NWAddReroutesMenu.bl_idname),), "Add Reroutes menu"),
('wm.call_menu', 'BACK_SLASH', 'PRESS', False, False, False, (('name', interface.NWLinkActiveToSelectedMenu.bl_idname),), "Link active to selected (menu)"),
('wm.call_menu', 'C', 'PRESS', False, True, False, (('name', interface.NWCopyToSelectedMenu.bl_idname),), "Copy to selected (menu)"),
('wm.call_menu', 'S', 'PRESS', False, True, False, (('name', interface.NWSwitchNodeTypeMenu.bl_idname),), "Switch node type menu"),
('wm.call_menu', 'SLASH', 'PRESS', False, False, False,
(('name', interface.NWAddReroutesMenu.bl_idname),), "Add Reroutes menu"),
('wm.call_menu', 'NUMPAD_SLASH', 'PRESS', False, False, False,
(('name', interface.NWAddReroutesMenu.bl_idname),), "Add Reroutes menu"),
('wm.call_menu', 'BACK_SLASH', 'PRESS', False, False, False,
(('name', interface.NWLinkActiveToSelectedMenu.bl_idname),), "Link active to selected (menu)"),
('wm.call_menu', 'C', 'PRESS', False, True, False,
(('name', interface.NWCopyToSelectedMenu.bl_idname),), "Copy to selected (menu)"),
('wm.call_menu', 'S', 'PRESS', False, True, False,
(('name', interface.NWSwitchNodeTypeMenu.bl_idname),), "Switch node type menu"),
)
classes = (
NWPrincipledPreferences, NWNodeWrangler
)
def register():
from bpy.utils import register_class
for cls in classes:
@ -386,6 +412,7 @@ def register():
bpy.utils.register_class(switch_category_type)
def unregister():
for cat_types in switch_category_menus:
bpy.utils.unregister_class(cat_types)

View File

@ -3,6 +3,7 @@
import bpy
from math import hypot
def force_update(context):
context.space_data.node_tree.update_tag()
@ -205,7 +206,7 @@ def is_viewer_link(link, output_node):
def get_group_output_node(tree):
for node in tree.nodes:
if node.type == 'GROUP_OUTPUT' and node.is_active_output == True:
if node.type == 'GROUP_OUTPUT' and node.is_active_output:
return node