def check_reroutes_sockets(self): """ Fix reroute sockets type For now it does work properly in first update because all new sockets even if they have links have `is_linked` attribute with False value at next update events all works perfectly (skip first update?) There is hope this will be fixed https://developer.blender.org/T82390 """ tree = Tree(self) socket_job = [] Requirements = namedtuple('Requirements', [ 'left_n_i', 'left_s_i', 'left_t', 'reroute_n_i', 'right_n_is', 'right_s_is' ]) # analytical part, it's impossible to use Tree structure and modify the tree for node in tree.sorted_walk(tree.output_nodes): # walk should be sorted in case if reroute nodes are going one after other if node.bl_tween.bl_idname == 'NodeReroute': rer_in_s = node.inputs[0] rer_out_s = node.outputs[0] if rer_in_s.links: left_s = rer_in_s.linked_sockets[0] left_type = left_s.type if hasattr( left_s, 'type') else left_s.bl_tween.bl_idname if left_type != rer_in_s.bl_tween.bl_idname: rer_out_s.type = left_type socket_job.append( Requirements( left_s.node.index, left_s.index, left_type, node.index, [ s.node.index for s in rer_out_s.linked_sockets ], [s.index for s in rer_out_s.linked_sockets])) # regenerating sockets for props in socket_job: left_s = self.nodes[props.left_n_i].outputs[props.left_s_i] reroute = self.nodes[props.reroute_n_i] # handle input socket in_s = reroute.inputs.new(props.left_t, left_s.name) self.links.new(in_s, left_s) reroute.inputs.remove(reroute.inputs[0]) # handle output sockets out_s = reroute.outputs.new(props.left_t, left_s.name) for right_n_i, right_s_i in zip(props.right_n_is, props.right_s_is): left_s = self.nodes[right_n_i].inputs[right_s_i] self.links.new(left_s, out_s) reroute.outputs.remove(reroute.outputs[0])
def group_global_handler() -> Generator[Node]: """ It should find changes and update group nodes After that update system of main trees should update themselves meanwhile group nodes should be switched off because they already was updated """ for bl_tree in (t for t in bpy.data.node_groups if t.bl_idname == 'SvGroupTree'): # for now it always update all trees todo should be optimized later (keep in mind, trees can become outdated) ContextTrees.update_tree(bl_tree) for bl_tree in (t for t in bpy.data.node_groups if t.bl_idname == 'SverchCustomTreeType'): outdated_group_nodes = set() tree = Tree(bl_tree) for node in tree.sorted_walk(tree.output_nodes): if hasattr(node.bl_tween, 'updater'): group_updater = node.bl_tween.updater(is_input_changed=False) # just searching inner changes try: # it should return only nodes which should be updated while True: yield next(group_updater) except CancelError: group_updater.throw(CancelError) except StopIteration as stop_error: sub_tree_changed, error = stop_error.value if sub_tree_changed: outdated_group_nodes.add(node.bl_tween) # passing running to update system of main tree if outdated_group_nodes: outdated_group_nodes = list(outdated_group_nodes) active_states = [n.is_active for n in outdated_group_nodes] try: [n.toggle_active(False) for n in outdated_group_nodes] bl_tree.update_nodes(list(outdated_group_nodes)) except Exception: traceback.print_exc() finally: [n.toggle_active(s, to_update=False) for s, n in zip(active_states, outdated_group_nodes)]