Fix #104865: Adjust Node Wrangler for node socket interface API changes #104882

Merged
Jesse Yurkovich merged 1 commits from deadpin/blender-addons:fix104865-2 into main 2023-09-14 06:23:45 +02:00
2 changed files with 43 additions and 41 deletions

View File

@ -507,14 +507,19 @@ class NWPreviewNode(Operator, NWBase):
return True return True
return False return False
@classmethod
def get_output_sockets(cls, node_tree):
return [socket for socket in node_tree.interface.ui_items if socket.in_out in {'OUTPUT', 'BOTH'}]
def ensure_viewer_socket(self, node, socket_type, connect_socket=None): def ensure_viewer_socket(self, node, socket_type, connect_socket=None):
# check if a viewer output already exists in a node group otherwise create # check if a viewer output already exists in a node group otherwise create
if hasattr(node, "node_tree"): if hasattr(node, "node_tree"):
index = None viewer_socket = None
if len(node.node_tree.outputs): output_sockets = self.get_output_sockets(node.node_tree)
if len(output_sockets):
free_socket = None free_socket = None
for i, socket in enumerate(node.node_tree.outputs): for socket in output_sockets:
if is_viewer_socket(socket) and is_visible_socket(node.outputs[i]) and socket.type == socket_type: if is_viewer_socket(socket) and socket.socket_type == socket_type:
# if viewer output is already used but leads to the same socket we can still use it # 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) is_used = self.is_socket_used_other_mats(socket)
if is_used: if is_used:
@ -525,19 +530,18 @@ class NWPreviewNode(Operator, NWBase):
links = groupout_input.links links = groupout_input.links
if connect_socket not in [link.from_socket for link in links]: if connect_socket not in [link.from_socket for link in links]:
continue continue
index = i viewer_socket = socket
break break
if not free_socket: if not free_socket:
free_socket = i free_socket = socket
if not index and free_socket: if not viewer_socket and free_socket:
index = free_socket viewer_socket = free_socket
if not index: if not viewer_socket:
# create viewer socket # create viewer socket
node.node_tree.outputs.new(socket_type, viewer_socket_name) viewer_socket = node.node_tree.interface.new_socket(viewer_socket_name, in_out={'OUTPUT'}, socket_type=socket_type)
index = len(node.node_tree.outputs) - 1 viewer_socket.NWViewerSocket = True
node.node_tree.outputs[index].NWViewerSocket = True return viewer_socket
return index
def init_shader_variables(self, space, shader_type): def init_shader_variables(self, space, shader_type):
if shader_type == 'OBJECT': if shader_type == 'OBJECT':
@ -582,10 +586,9 @@ class NWPreviewNode(Operator, NWBase):
next_node = link.from_node next_node = link.from_node
external_socket = link.from_socket external_socket = link.from_socket
if hasattr(next_node, "node_tree"): if hasattr(next_node, "node_tree"):
for socket_index, s in enumerate(next_node.outputs): for socket_index, socket in enumerate(next_node.node_tree.interface.ui_items):
if s == external_socket: if socket.identifier == external_socket.identifier:
break break
socket = next_node.node_tree.outputs[socket_index]
if is_viewer_socket(socket) and socket not in sockets: if is_viewer_socket(socket) and socket not in sockets:
sockets.append(socket) sockets.append(socket)
# continue search inside of node group but restrict socket to where we came from # continue search inside of node group but restrict socket to where we came from
@ -599,11 +602,17 @@ class NWPreviewNode(Operator, NWBase):
if hasattr(node, "node_tree"): if hasattr(node, "node_tree"):
if node.node_tree is None: if node.node_tree is None:
continue continue
for socket in node.node_tree.outputs: for socket in cls.get_output_sockets(node.node_tree):
if is_viewer_socket(socket) and (socket not in sockets): if is_viewer_socket(socket) and (socket not in sockets):
sockets.append(socket) sockets.append(socket)
cls.scan_nodes(node.node_tree, sockets) cls.scan_nodes(node.node_tree, sockets)
@classmethod
def remove_socket(cls, tree, socket):
interface = tree.interface
interface.remove(socket)
interface.active_index = min(interface.active_index, len(interface.ui_items) - 1)
def link_leads_to_used_socket(self, link): def link_leads_to_used_socket(self, link):
# return True if link leads to a socket that is already used in this material # return True if link leads to a socket that is already used in this material
socket = get_internal_socket(link.to_socket) socket = get_internal_socket(link.to_socket)
@ -710,22 +719,22 @@ class NWPreviewNode(Operator, NWBase):
link_end = output_socket link_end = output_socket
while tree.nodes.active != active: while tree.nodes.active != active:
node = tree.nodes.active node = tree.nodes.active
index = self.ensure_viewer_socket( viewer_socket = self.ensure_viewer_socket(
node, 'NodeSocketGeometry', connect_socket=active.outputs[out_i] if node.node_tree.nodes.active == active else None) node, 'NodeSocketGeometry', connect_socket=active.outputs[out_i] if node.node_tree.nodes.active == active else None)
link_start = node.outputs[index] link_start = node.outputs[viewer_socket_name]
node_socket = node.node_tree.outputs[index] node_socket = viewer_socket
if node_socket in delete_sockets: if node_socket in delete_sockets:
delete_sockets.remove(node_socket) delete_sockets.remove(node_socket)
connect_sockets(link_start, link_end) connect_sockets(link_start, link_end)
# Iterate # Iterate
link_end = self.ensure_group_output(node.node_tree).inputs[index] link_end = self.ensure_group_output(node.node_tree).inputs[viewer_socket_name]
tree = tree.nodes.active.node_tree tree = tree.nodes.active.node_tree
connect_sockets(active.outputs[out_i], link_end) connect_sockets(active.outputs[out_i], link_end)
# Delete sockets # Delete sockets
for socket in delete_sockets: for socket in delete_sockets:
tree = socket.id_data tree = socket.id_data
tree.outputs.remove(socket) self.remove_socket(tree, socket)
nodes.active = active nodes.active = active
active.select = True active.select = True
@ -783,15 +792,15 @@ class NWPreviewNode(Operator, NWBase):
link_end = output_socket link_end = output_socket
while tree.nodes.active != active: while tree.nodes.active != active:
node = tree.nodes.active node = tree.nodes.active
index = self.ensure_viewer_socket( viewer_socket = self.ensure_viewer_socket(
node, socket_type, connect_socket=active.outputs[out_i] if node.node_tree.nodes.active == active else None) node, socket_type, connect_socket=active.outputs[out_i] if node.node_tree.nodes.active == active else None)
link_start = node.outputs[index] link_start = node.outputs[viewer_socket_name]
node_socket = node.node_tree.outputs[index] node_socket = viewer_socket
if node_socket in delete_sockets: if node_socket in delete_sockets:
delete_sockets.remove(node_socket) delete_sockets.remove(node_socket)
connect_sockets(link_start, link_end) connect_sockets(link_start, link_end)
# Iterate # Iterate
link_end = self.ensure_group_output(node.node_tree).inputs[index] link_end = self.ensure_group_output(node.node_tree).inputs[viewer_socket_name]
tree = tree.nodes.active.node_tree tree = tree.nodes.active.node_tree
connect_sockets(active.outputs[out_i], link_end) connect_sockets(active.outputs[out_i], link_end)
@ -799,7 +808,7 @@ class NWPreviewNode(Operator, NWBase):
for socket in delete_sockets: for socket in delete_sockets:
if not self.is_socket_used_other_mats(socket): if not self.is_socket_used_other_mats(socket):
tree = socket.id_data tree = socket.id_data
tree.outputs.remove(socket) self.remove_socket(tree, socket)
nodes.active = active nodes.active = active
active.select = True active.select = True

View File

@ -170,25 +170,18 @@ def get_internal_socket(socket):
# get the internal socket from a socket inside or outside the group # get the internal socket from a socket inside or outside the group
node = socket.node node = socket.node
if node.type == 'GROUP_OUTPUT': if node.type == 'GROUP_OUTPUT':
source_iterator = node.inputs iterator = node.id_data.interface.ui_items
iterator = node.id_data.outputs
elif node.type == 'GROUP_INPUT': elif node.type == 'GROUP_INPUT':
source_iterator = node.outputs iterator = node.id_data.interface.ui_items
iterator = node.id_data.inputs
elif hasattr(node, "node_tree"): elif hasattr(node, "node_tree"):
if socket.is_output: iterator = node.node_tree.interface.ui_items
source_iterator = node.outputs
iterator = node.node_tree.outputs
else:
source_iterator = node.inputs
iterator = node.node_tree.inputs
else: else:
return None return None
for i, s in enumerate(source_iterator): for s in iterator:
if s == socket: if s.identifier == socket.identifier:
break return s
return iterator[i] return iterator[0]
def is_viewer_link(link, output_node): def is_viewer_link(link, output_node):