|
|
@@ -12,6 +12,20 @@ from bpy.types import NodeGroupInput, NodeGroupOutput, NodeSocket
|
|
|
from .readtree import execution_error_cleanup
|
|
|
|
|
|
class SchemaSolver:
|
|
|
+ __slots__ = (
|
|
|
+ "all_nodes", "node", "solved", "tree",
|
|
|
+ "uuid", "error_popups", "signature",
|
|
|
+ "schema_nodes", "solved_nodes",
|
|
|
+ "incoming_connections", "outgoing_connections",
|
|
|
+ "constant_in", "constant_out",
|
|
|
+ "array_input_connections", "array_output_connections",
|
|
|
+ "nested_schemas", "autogenerated_nodes",
|
|
|
+ "held_links", "tree_path_names",
|
|
|
+ "autogen_path_names", "is_node_group",
|
|
|
+ "index_link", "solve_length", "index",
|
|
|
+ "interfaces", "index_str", "prev_index_str",
|
|
|
+ "current_interface", "next_interface"
|
|
|
+ )
|
|
|
def __init__(self, schema_dummy, nodes, ui_node, signature=None, error_popups=False):
|
|
|
self.all_nodes = nodes # this is the parsed tree from Mantis
|
|
|
self.node = schema_dummy
|
|
|
@@ -24,16 +38,11 @@ class SchemaSolver:
|
|
|
self.signature = signature
|
|
|
else:
|
|
|
self.signature = self.node.signature
|
|
|
- self.schema_nodes={}
|
|
|
- self.solved_nodes = {}
|
|
|
- self.incoming_connections = {}
|
|
|
- self.outgoing_connections = {}
|
|
|
- self.constant_in = {}
|
|
|
- self.constant_out = {}
|
|
|
- self.array_input_connections = {}
|
|
|
- self.array_output_connections = {}
|
|
|
- self.nested_schemas = {}
|
|
|
- self.autogenerated_nodes = {}
|
|
|
+ self.schema_nodes={}; self.solved_nodes = {}
|
|
|
+ self.incoming_connections = {}; self.outgoing_connections = {}
|
|
|
+ self.constant_in = {}; self.constant_out = {}
|
|
|
+ self.array_input_connections = {}; self.array_output_connections = {}
|
|
|
+ self.nested_schemas = {}; self.autogenerated_nodes = {}
|
|
|
self.held_links = []
|
|
|
self.tree_path_names = [*self.node.signature] # same tree as the schema node
|
|
|
self.autogen_path_names = ['SCHEMA_AUTOGENERATED', *self.node.signature[1:]]
|
|
|
@@ -51,12 +60,14 @@ class SchemaSolver:
|
|
|
self.solve_length = self.node.evaluate_input("Schema Length")
|
|
|
# I'm making this a property of the solver because the solver's data is modified as it solves each iteration
|
|
|
self.index = 0
|
|
|
+ self.interfaces = []
|
|
|
|
|
|
prWhite(f"\nExpanding schema {self.tree.name} in node {self.node.signature}"
|
|
|
f" with length {self.solve_length}.")
|
|
|
|
|
|
self.init_schema_links()
|
|
|
- self.set_index_strings()
|
|
|
+ self.generate_interface_nodes()
|
|
|
+ self.set_schema_per_interation_constants()
|
|
|
|
|
|
# Sort the multi-input nodes in reverse order of ID, this ensures that they are
|
|
|
# read in the order they were created
|
|
|
@@ -86,15 +97,6 @@ class SchemaSolver:
|
|
|
mantis_node = SchemaConstOutput(signature=signature, base_tree=self.node.base_tree, parent_schema_node=self.node)
|
|
|
self.schema_nodes[signature] = mantis_node
|
|
|
|
|
|
- # Using lambdas here causes a lot of function calls, should be optimized out
|
|
|
- # since after all this only needs to change when the index updates
|
|
|
- def set_index_strings(self):
|
|
|
- self.index_str = '.'+str(self.uuid)+'.'+str(self.index).zfill(4)
|
|
|
- self.prev_index_str = '.'+str(self.uuid)+'.'+str(self.index-1).zfill(4)
|
|
|
- if self.is_node_group:
|
|
|
- self.index_str = ''
|
|
|
- self.prev_index_str = ''
|
|
|
-
|
|
|
def init_schema_links(self,):
|
|
|
""" Sort and store the links to/from the Schema group node."""
|
|
|
for item in self.tree.interface.items_tree:
|
|
|
@@ -142,7 +144,53 @@ class SchemaSolver:
|
|
|
if out_links := self.node.outputs[item.identifier].links:
|
|
|
self.array_output_connections[item.identifier] = out_links.copy()
|
|
|
|
|
|
-
|
|
|
+ # Using lambdas here causes a lot of function calls, should be optimized out
|
|
|
+ # since after all this only needs to change when the index updates
|
|
|
+ def set_schema_per_interation_constants(self):
|
|
|
+ self.index_str = '.'+str(self.uuid)+'.'+str(self.index).zfill(4)
|
|
|
+ self.prev_index_str = '.'+str(self.uuid)+'.'+str(self.index-1).zfill(4)
|
|
|
+ self.current_interface = self.interfaces[self.index]
|
|
|
+ self.next_interface = self.interfaces[self.index + 1] # this is guaranteed
|
|
|
+ if self.is_node_group:
|
|
|
+ self.index_str = ''; self.prev_index_str = ''
|
|
|
+
|
|
|
+ def generate_interface_nodes(self):
|
|
|
+ from ..internal_nodes import GroupInterface
|
|
|
+ # One input interface per iteration, and one output interface
|
|
|
+ items_tree = self.tree.interface.items_tree
|
|
|
+ for i in range(self.solve_length): # one input per
|
|
|
+ index_str = "."+str(i).zfill(4) # self.index_str
|
|
|
+ name = 'InputInterface'+index_str
|
|
|
+ if i == 0: in_out = 'SCHEMA_INPUT'
|
|
|
+ else: in_out = 'SCHEMA_BETWEEN'
|
|
|
+ signature = (*self.autogen_path_names, name)
|
|
|
+ interface = GroupInterface(signature=signature, base_tree=self.tree, in_out=in_out,
|
|
|
+ ui_node=None, items_tree=items_tree)
|
|
|
+ # add the index and length socket constants
|
|
|
+ interface.parameters['Index'] = i
|
|
|
+ if i == 0:
|
|
|
+ interface.parameters['Length'] = self.solve_length
|
|
|
+ # the GroupInterface will initialize with the right sockets, but we still have to link them
|
|
|
+
|
|
|
+ if in_out == 'SCHEMA_INPUT': # Take the links into the schema and plug them here
|
|
|
+ for item in items_tree:
|
|
|
+ if item.item_type == 'PANEL': continue
|
|
|
+ if (mantis_link := self.constant_in.get(item.name)):
|
|
|
+ mantis_link.from_node.outputs[mantis_link.from_socket].connect(interface, item.identifier)
|
|
|
+ # for mantis_link in self.array_input_connections.get(item.name, []):
|
|
|
+ # mantis_link.from_node.outputs[mantis_link.from_socket].connect(interface, item.identifier)
|
|
|
+ if (mantis_link := self.incoming_connections.get(item.name)):
|
|
|
+ mantis_link.from_node.outputs[mantis_link.from_socket].connect(interface, item.identifier)
|
|
|
+ self.interfaces.append(interface)
|
|
|
+ # solved nodes will get added to the outer all_nodes later
|
|
|
+ self.solved_nodes[signature]=interface
|
|
|
+
|
|
|
+ # now do the output
|
|
|
+ signature = (*self.autogen_path_names, "OutputInterface")
|
|
|
+ interface = GroupInterface(signature=signature, base_tree=self.tree,
|
|
|
+ in_out='OUTPUT', ui_node=None, items_tree=items_tree)
|
|
|
+ self.interfaces.append(interface)
|
|
|
+ self.solved_nodes[signature]=interface
|
|
|
|
|
|
def is_node_deeper_nested(self, queried_node, compare_node):
|
|
|
return len(compare_node.signature) < len(queried_node.signature)
|
|
|
@@ -206,20 +254,9 @@ class SchemaSolver:
|
|
|
|
|
|
if (not can_remove_socket_for_autogen(to_node, ui_link.to_socket.name)) or \
|
|
|
to_node.node_type in ['DUMMY', 'DUMMY_SCHEMA']:
|
|
|
- from .readtree import autogen_node
|
|
|
- unique_name = "".join([
|
|
|
- ui_link.to_socket.node.name+self.index_str,
|
|
|
- ui_link.from_socket.name, ui_link.from_socket.identifier,
|
|
|
- "==>", ui_link.to_socket.name, ui_link.to_socket.identifier,],)
|
|
|
- signature = ("MANTIS_AUTOGENERATED", *self.tree_path_names[1:-1], unique_name)
|
|
|
- from_node = self.all_nodes.get(signature)
|
|
|
- if not from_node:
|
|
|
- from_node = autogen_node(self.node.base_tree, ui_link.from_socket,
|
|
|
- signature=signature, mContext=self.node.mContext)
|
|
|
- from_node.parameters = {ui_link.from_socket.name:index}
|
|
|
- frame_mantis_nodes[signature]=from_node; self.solved_nodes[signature]=from_node
|
|
|
- self.all_nodes[signature]=from_node
|
|
|
- _connection = from_node.outputs[ui_link.from_socket.name].connect(node=to_node, socket=ui_link.to_socket.identifier)
|
|
|
+ from_node = self.current_interface
|
|
|
+ connection = from_node.outputs[ui_link.from_socket.name].connect(node=to_node, socket=ui_link.to_socket.identifier)
|
|
|
+ connection.is_hierarchy = False # For now this is the easiest way to do this
|
|
|
return
|
|
|
# Since the index is already determined, it is safe to remove the socket and just keep the value.
|
|
|
to_node.parameters[ui_link.to_socket.name] = index
|
|
|
@@ -570,7 +607,7 @@ class SchemaSolver:
|
|
|
SchemaIncomingConnection,)
|
|
|
from ..utilities.utilities import clear_reroutes, link_mantis_nodes
|
|
|
from ..base_definitions import array_output_types
|
|
|
- self.set_index_strings()
|
|
|
+ self.set_schema_per_interation_constants()
|
|
|
frame_mantis_nodes = {}
|
|
|
|
|
|
# Later we have to run bPrepare() on these guys, so we make the deque and fill it now.
|
|
|
@@ -804,7 +841,6 @@ class SchemaSolver:
|
|
|
for index in range(self.solve_length):
|
|
|
self.index = index
|
|
|
frame_mantis_nodes = self.solve_iteration()
|
|
|
- self.set_index_strings()
|
|
|
for sig, mantis_node in frame_mantis_nodes.items():
|
|
|
if mantis_node.node_type == 'DUMMY_SCHEMA':
|
|
|
self.nested_schemas[sig] = mantis_node
|