|
|
@@ -286,6 +286,35 @@ def solve_schema_to_tree(nc, all_nc, roots=[]):
|
|
|
# PARSE NODE TREE #
|
|
|
# *** # *** # *** # *** # *** # *** # *** # *** # *** # *** # *** # *** # *** # *** #
|
|
|
|
|
|
+from .utilities import get_all_dependencies
|
|
|
+def get_schema_length_dependencies(node):
|
|
|
+ """ Find all of the nodes that the Schema Length input depends on. """
|
|
|
+ # the deps recursively from the from_nodes connected to Schema Length
|
|
|
+ deps = []
|
|
|
+ # return get_all_dependencies(node)
|
|
|
+ inp = node.inputs.get("Schema Length")
|
|
|
+ if not inp:
|
|
|
+ inp = node.inputs.get("Array")
|
|
|
+ # this way we can handle Schema and Array Get nodes with one function
|
|
|
+ # ... since I may add more in the future this is not a robust solution HACK
|
|
|
+ for l in inp.links:
|
|
|
+ deps.extend(get_all_dependencies(l.from_node))
|
|
|
+ if inp := node.inputs.get("Index"):
|
|
|
+ for l in inp.links:
|
|
|
+ deps.extend(get_all_dependencies(l.from_node))
|
|
|
+ # now get the auto-generated simple inputs. These should not really be there but I haven't figured out how to set things directly yet lol
|
|
|
+ for inp in node.inputs.values():
|
|
|
+ for l in inp.links:
|
|
|
+ if "MANTIS_AUTOGENERATED" in l.from_node.signature:
|
|
|
+ # l.from_node.bPrepare() # try this...
|
|
|
+ # l.from_node.prepared = True; l.from_node.executed = True
|
|
|
+ deps.extend([l.from_node]) # why we need this lol
|
|
|
+
|
|
|
+ return deps
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
def parse_tree(base_tree):
|
|
|
from uuid import uuid4 # do this here?
|
|
|
base_tree.execution_id = uuid4().__str__() # set this, it may be used by nodes during execution
|
|
|
@@ -334,7 +363,6 @@ def parse_tree(base_tree):
|
|
|
if isinstance(nc, UtilityArrayGet):
|
|
|
arrays.append(nc)
|
|
|
|
|
|
- from .utilities import get_all_dependencies
|
|
|
from collections import deque
|
|
|
unsolved_schema = deque()
|
|
|
solve_only_these = []; solve_only_these.extend(list(all_schema.values()))
|
|
|
@@ -347,10 +375,10 @@ def parse_tree(base_tree):
|
|
|
break
|
|
|
else:
|
|
|
init_schema_dependencies(schema, all_nc)
|
|
|
- solve_only_these.extend(get_all_dependencies(schema))
|
|
|
+ solve_only_these.extend(get_schema_length_dependencies(schema))
|
|
|
unsolved_schema.append(schema)
|
|
|
for array in arrays:
|
|
|
- solve_only_these.extend(get_all_dependencies(array))
|
|
|
+ solve_only_these.extend(get_schema_length_dependencies(array))
|
|
|
solve_only_these.extend(arrays)
|
|
|
schema_solve_done = set()
|
|
|
|
|
|
@@ -360,12 +388,12 @@ def parse_tree(base_tree):
|
|
|
|
|
|
while(solve_layer):
|
|
|
n = solve_layer.pop()
|
|
|
- if n not in solve_only_these:
|
|
|
+ if n not in solve_only_these: # removes the unneeded node from the solve-layer
|
|
|
continue
|
|
|
|
|
|
- if n.signature in all_schema.keys() and n.signature:
|
|
|
+ if n.signature in all_schema.keys():
|
|
|
for dep in n.hierarchy_dependencies:
|
|
|
- if dep not in schema_solve_done:
|
|
|
+ if dep not in schema_solve_done and (dep in solve_only_these):
|
|
|
solve_layer.appendleft(n)
|
|
|
break
|
|
|
else:
|
|
|
@@ -393,6 +421,7 @@ def parse_tree(base_tree):
|
|
|
solve_layer.appendleft(conn)
|
|
|
if unsolved_schema:
|
|
|
raise RuntimeError("Failed to resolve all schema declarations")
|
|
|
+ # I had a problem with this looping forever. I think it is resolved... but I don't know lol
|
|
|
|
|
|
all_nc = list(all_nc.values()).copy()
|
|
|
kept_nc = {}
|
|
|
@@ -574,9 +603,20 @@ def execute_tree(nodes, base_tree, context):
|
|
|
# exe_order = {}; i=0
|
|
|
executed = []
|
|
|
|
|
|
-
|
|
|
+ # check for cycles here by keeping track of the number of times a node has been visited.
|
|
|
+ visited={}
|
|
|
+ check_max_len=len(nodes)**2 # seems too high but safe. In a well-ordered graph, I guess this number should be less than the number of nodes.
|
|
|
+
|
|
|
while(xForm_pass):
|
|
|
n = xForm_pass.pop()
|
|
|
+ if visited.get(n.signature):
|
|
|
+ visited[n.signature]+=1
|
|
|
+ else:
|
|
|
+ visited[n.signature]=0
|
|
|
+ if visited[n.signature] > check_max_len:
|
|
|
+ prRed("There is a cycle in the graph somewhere. Fix it!")
|
|
|
+ # we're trying to solve the halting problem at this point.. don't do that.
|
|
|
+ # TODO find a better way! there are algo's for this but they will require using a different solving algo, too
|
|
|
if n.prepared:
|
|
|
continue
|
|
|
if n.node_type not in ['XFORM', 'UTILITY']:
|