From 569de2fe717d521169e8281e5877b51fd7d75480 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Wed, 8 Apr 2020 22:47:30 +0200 Subject: [PATCH 01/43] Less global updates --- core/socket_data.py | 20 ++++-- core/sockets.py | 6 +- core/update_system.py | 16 +++-- node_tree.py | 95 +++++++++++++++++++++----- nodes/modifier_make/sweep_modulator.py | 2 +- nodes/number/easing.py | 2 +- nodes/scene/blenddata_to_svdata2.py | 2 +- nodes/scene/instancer.py | 2 +- nodes/scene/instancer_MK2.py | 2 +- nodes/scene/objects_mk3.py | 2 +- nodes/scene/particles_MK2.py | 2 +- nodes/text/stethoscope_v28.py | 2 +- nodes/text/text_in_mk2.py | 2 +- nodes/viz/console_node.py | 2 +- nodes/viz/empty_out.py | 2 +- nodes/viz/vd_draw_experimental.py | 2 +- nodes/viz/vd_matrix.py | 2 +- nodes/viz/viewer_idx28.py | 2 +- nodes/viz/viewer_texture.py | 2 +- nodes/viz/viewer_texture_lite.py | 2 +- nodes/viz/viewer_waveform_output.py | 2 +- 21 files changed, 125 insertions(+), 46 deletions(-) diff --git a/core/socket_data.py b/core/socket_data.py index 7df8d0932..fa92cce9b 100644 --- a/core/socket_data.py +++ b/core/socket_data.py @@ -66,6 +66,18 @@ def SvGetSocketInfo(socket): return str(len(data)) return '' +def SvForgetSocket(socket): + """sets socket data for socket""" + global socket_data_cache + if data_structure.DEBUG_MODE: + if not socket.is_output: + warning(f"{socket.node.name} forgetting input socket: {socket.name}") + if not socket.is_linked: + warning(f"{socket.node.name} forgetting unconncted socket: {socket.name}") + s_id = socket.socket_id + s_ng = socket.id_data.name + print("forgetting") + socket_data_cache[s_ng].pop(s_id, None) def SvSetSocket(socket, out): """sets socket data for socket""" @@ -110,7 +122,7 @@ def SvGetSocket(socket, deepcopy=True): class SvNoDataError(LookupError): def __init__(self, socket=None, node=None, msg=None): - + self.extra_message = msg if msg else "" if node is None and socket is not None: @@ -127,16 +139,16 @@ class SvNoDataError(LookupError): return "SvNoDataError" else: return f"No data passed into socket '{self.socket.name}'" - + def __repr__(self): return self.get_message() - + def __str__(self): return repr(self) def __unicode__(self): return repr(self) - + def __format__(self, spec): return repr(self) diff --git a/core/sockets.py b/core/sockets.py index 944486266..d1dcbdd9f 100644 --- a/core/sockets.py +++ b/core/sockets.py @@ -26,7 +26,7 @@ from bpy.types import NodeTree, NodeSocket from sverchok.core.socket_conversions import DefaultImplicitConversionPolicy, is_vector_to_matrix from sverchok.core.socket_data import ( - SvGetSocketInfo, SvGetSocket, SvSetSocket, + SvGetSocketInfo, SvGetSocket, SvSetSocket, SvForgetSocket, SvNoDataError, sentinel) from sverchok.data_structure import ( @@ -114,6 +114,10 @@ class SvSocketCommon: """Set output data""" SvSetSocket(self, data) + def sv_forget(self): + """Delete socket memory""" + SvForgetSocket(self) + def replace_socket(self, new_type, new_name=None): """Replace a socket with a socket of new_type and keep links, return the new socket, the old reference might be invalid""" diff --git a/core/update_system.py b/core/update_system.py index 2d74de97f..59ec7a4e1 100644 --- a/core/update_system.py +++ b/core/update_system.py @@ -186,9 +186,9 @@ def separate_nodes(ng, links=None): node_set_list[-1].add(n) found_node_sets = [ns for ns in node_set_list if len(ns) > 1] - + if hasattr(ng, "sv_subtree_evaluation_order"): - sorting_type = ng.sv_subtree_evaluation_order + sorting_type = ng.sv_subtree_evaluation_order if sorting_type in {'X', 'Y'}: sort_index = 0 if sorting_type == "X" else 1 find_lowest = lambda ns: min(ng.nodes[n].absolute_location[sort_index] for n in ns) @@ -334,7 +334,7 @@ def do_update_general(node_list, nodes, procesed_nodes=set()): timings = [] graph = [] gather = graph.append - + total_time = 0 done_nodes = set(procesed_nodes) @@ -364,19 +364,19 @@ def do_update_general(node_list, nodes, procesed_nodes=set()): update_error_nodes(ng, node_name, err) #traceback.print_tb(err.__traceback__) exception("Node %s had exception: %s", node_name, err) - + if hasattr(ng, "sv_show_error_in_tree"): # not yet supported in monad trees.. if ng.sv_show_error_in_tree: error_text = traceback.format_exc() start_exception_drawing_with_bgl(ng, node_name, error_text, err) - + return None graphs.append(graph) if data_structure.DEBUG_MODE: debug("Node set updated in: %.4f seconds", total_time) - + return timings @@ -405,7 +405,7 @@ def build_update_list(ng=None): out = [make_update_list(ng, s, deps) for s in node_sets] update_cache[ng.name] = out partial_update_cache[ng.name] = {} - reset_socket_cache(ng) + # reset_socket_cache(ng) def process_to_node(node): @@ -430,6 +430,7 @@ def process_from_nodes(nodes): node_names = [node.name for node in nodes] ng = nodes[0].id_data update_list = make_tree_from_nodes(node_names, ng) + print(update_list) do_update(update_list, ng.nodes) @@ -458,6 +459,7 @@ def process_from_node(node): nodes = ng.nodes if not ng.sv_process: return + print(update_list) do_update(update_list, nodes) else: process_tree(ng) diff --git a/node_tree.py b/node_tree.py index 97be769ef..804fd1439 100644 --- a/node_tree.py +++ b/node_tree.py @@ -31,6 +31,7 @@ from sverchok import data_structure from sverchok.data_structure import get_other_socket from sverchok.core.update_system import ( + partial_update_cache, build_update_list, process_from_node, process_from_nodes, process_tree, @@ -94,7 +95,7 @@ def throttle_tree_update(node): self.inputs.new(...) self.outputs.new(...) - that's it. + that's it. """ try: @@ -118,7 +119,7 @@ def throttled(func): When a node has changed, like a mode-change leading to a socket change (remove, new) Blender will trigger nodetree.update. We want to ignore this trigger-event, and we do so by - - first throttling the update system. + - first throttling the update system. - then We execute the code that makes changes to the node/nodetree - then we end the throttle-state - we are then ready to process @@ -217,7 +218,7 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): # node.disable() def sv_process_tree_callback(self, context): - process_tree(self) + process_tree(self) sv_animate: BoolProperty(name="Animate", default=True, description='Animate this layout') sv_show: BoolProperty(name="Show", default=True, description='Show this layout', update=turn_off_ng) @@ -241,6 +242,10 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): sv_toggle_nodetree_props: BoolProperty(name="Toggle visibility of props", description="Show more properties for this node tree") + sv_links = {} + sv_linked_sockets = {} + sv_linked_output_sockets = {} + def on_draft_mode_changed(self, context): """ This is triggered when Draft mode of the tree is toggled. @@ -286,11 +291,51 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): @property def has_link_count_changed(self): link_count = len(self.links) - if not link_count == self.tree_link_count: + if not link_count == self.tree_link_count: # print('update event: link count changed', self.timestamp) self.tree_link_count = link_count return True + def fill_links_memory(self): + new_links = self.links.items() + self.sv_links[hash(self)] = self.links.items() + linked_sockets = [] + output_sockets = [] + for link in new_links: + linked_sockets.append((link[1].from_socket, link[1].to_socket)) + output_sockets.append(link[1].from_socket) + + self.sv_linked_sockets[hash(self)] = linked_sockets + self.sv_linked_output_sockets[hash(self)] = output_sockets + def use_link_memory(self): + + links_has_changed = self.sv_links[hash(self)] != self.links.items() + + if links_has_changed: + affected_nodes = [] + new_links = self.links.items() + linked_sockets = [] + output_sockets = [] + before_linked_sockets = self.sv_linked_sockets[hash(self)] + before_output_sockets = self.sv_linked_output_sockets[hash(self)] + + for link in new_links: + output_sockets.append(link[1].from_socket) + linked_sockets.append((link[1].from_socket, link[1].to_socket)) + if not (link[1].from_socket, link[1].to_socket) in before_linked_sockets: + if not link[1].from_socket in before_output_sockets: + affected_nodes.append(link[1].from_node) + affected_nodes.append(link[1].to_node) + print("Affected Nodes:", affected_nodes) + + self.sv_links[hash(self)] = self.links.items() + self.sv_linked_sockets[hash(self)] = linked_sockets + self.sv_linked_output_sockets[hash(self)] = output_sockets + + build_update_list(self) + if affected_nodes: + process_from_nodes(affected_nodes) + def update(self): ''' Tags tree for update for handle @@ -305,9 +350,16 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): return # print('svtree update', self.timestamp) - self.has_changed = True - # self.has_link_count_changed - self.process() + fill_memory_is_ready = hash(self) in self.sv_links.keys() + if fill_memory_is_ready: + print("memory_is_ready") + self.use_link_memory() + else: + print("filling link_memory") + self.fill_links_memory() + self.has_changed = True + # self.has_link_count_changed + self.process() def process_ani(self): """ @@ -331,7 +383,7 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): self.build_update_list() self.has_changed = False if self.is_frozen(): - # print('not processing: because self/tree.is_frozen') + # print('not processing: because self/tree.is_frozen') return if self.sv_process: process_tree(self) @@ -378,18 +430,18 @@ class SverchCustomTreeNode: def ensure_enums_have_no_space(self, enums=None): """ - enums: a list of property names to check. like self.current_op + enums: a list of property names to check. like self.current_op self.ensure_enums_have_no_space(enums=[current_op]) due to changes in EnumProperty defintion "laws" individual enum identifiers must not - contain spaces. This function takes a list of enums that the node currently holds, and + contain spaces. This function takes a list of enums that the node currently holds, and makes sure the stored enum has no spaces. """ for enum_property in enums: current_value = getattr(self, enum_property) if " " in current_value: - with self.sv_throttle_tree_update(): + with self.sv_throttle_tree_update(): setattr(self, enum_property, data_structure.no_space(current_value)) @@ -646,7 +698,7 @@ class SverchCustomTreeNode: ng = self.id_data ng.freeze() - + if hasattr(self, "sv_init"): try: @@ -706,12 +758,15 @@ class SverchCustomTreeNode: at the moment of node being copied. """ pass - + def free(self): """ - some nodes require additional operations upon node removal + This method is not supposed to be overriden in specific nodes. + Override sv_free() instead """ - + self.sv_free() + for s in self.outputs: + s.sv_forget() if hasattr(self, "has_3dview_props"): print("about to remove this node's props from Sv3DProps") try: @@ -719,6 +774,12 @@ class SverchCustomTreeNode: except: print(f'failed to remove {self.name} from tree={self.id_data.name}') + def sv_free(self): + """ + Override this method to do anything node-specific upon node removal + + """ + pass def wrapper_tracked_ui_draw_op(self, layout_element, operator_idname, **keywords): """ @@ -739,7 +800,7 @@ class SverchCustomTreeNode: def get_and_set_gl_scale_info(self, origin=None): """ - This function is called in sv_init in nodes that draw GL instructions to the nodeview, + This function is called in sv_init in nodes that draw GL instructions to the nodeview, the nodeview scale and dpi differs between users and must be queried to get correct nodeview x,y and dpi scale info. """ @@ -755,7 +816,7 @@ class SverchCustomTreeNode: classes = [ - SverchCustomTree, + SverchCustomTree, SvLinkNewNodeInput, SvGenericUITooltipOperator ] diff --git a/nodes/modifier_make/sweep_modulator.py b/nodes/modifier_make/sweep_modulator.py index 1cf09f654..9e6c3a378 100644 --- a/nodes/modifier_make/sweep_modulator.py +++ b/nodes/modifier_make/sweep_modulator.py @@ -206,7 +206,7 @@ class SvSweepModulator(bpy.types.Node, SverchCustomTreeNode): self.outputs['Edges'].sv_set([e]) self.outputs['Faces'].sv_set([f]) - def free(self): + def sv_free(self): set_sv_depsgraph_need(False) diff --git a/nodes/number/easing.py b/nodes/number/easing.py index 9fe53d43b..5d39cfb26 100644 --- a/nodes/number/easing.py +++ b/nodes/number/easing.py @@ -244,7 +244,7 @@ class SvEasingNode(bpy.types.Node, SverchCustomTreeNode): } nvBGL.callback_enable(n_id, draw_data) - def free(self): + def sv_free(self): nvBGL.callback_disable(node_id(self)) def sv_copy(self, node): diff --git a/nodes/scene/blenddata_to_svdata2.py b/nodes/scene/blenddata_to_svdata2.py index 03aaf065b..6cb69da46 100644 --- a/nodes/scene/blenddata_to_svdata2.py +++ b/nodes/scene/blenddata_to_svdata2.py @@ -51,7 +51,7 @@ class SvObjectToMeshNodeMK2(bpy.types.Node, SverchCustomTreeNode): row = layout.row() row.prop(self, "modifiers", text="Post modifiers") - def free(self): + def sv_free(self): set_sv_depsgraph_need(False) def process(self): diff --git a/nodes/scene/instancer.py b/nodes/scene/instancer.py index 16e9dd3a8..f91ada7bc 100644 --- a/nodes/scene/instancer.py +++ b/nodes/scene/instancer.py @@ -186,7 +186,7 @@ class SvInstancerNode(bpy.types.Node, SverchCustomTreeNode): objects.remove(obj) - # def free(self): + # def sv_free(self): # # self.remove_non_updated_objects(-1) # # or remove content of associated collection...undecided, lets see what # # people expect... diff --git a/nodes/scene/instancer_MK2.py b/nodes/scene/instancer_MK2.py index 71c6fd621..6af0cc12e 100644 --- a/nodes/scene/instancer_MK2.py +++ b/nodes/scene/instancer_MK2.py @@ -179,7 +179,7 @@ class SvInstancerNodeMK2(bpy.types.Node, SverchCustomTreeNode): objects.remove(obj) - # def free(self): + # def sv_free(self): # # self.remove_non_updated_objects(-1) # # or remove content of associated collection...undecided, lets see what # # people expect... diff --git a/nodes/scene/objects_mk3.py b/nodes/scene/objects_mk3.py index 41e350fb9..b60561b98 100644 --- a/nodes/scene/objects_mk3.py +++ b/nodes/scene/objects_mk3.py @@ -223,7 +223,7 @@ class SvObjectsNodeMK3(bpy.types.Node, SverchCustomTreeNode): def get_materials_from_mesh(self, mesh): return [face.material_index for face in mesh.polygons[:]] - def free(self): + def sv_free(self): set_sv_depsgraph_need(False) def process(self): diff --git a/nodes/scene/particles_MK2.py b/nodes/scene/particles_MK2.py index 10ee47bbf..17445f196 100644 --- a/nodes/scene/particles_MK2.py +++ b/nodes/scene/particles_MK2.py @@ -81,7 +81,7 @@ class SvParticlesMK2Node(bpy.types.Node, SverchCustomTreeNode): if outV.is_linked: outV.sv_set([[i.velocity[:] for i in Plist] for Plist in listobj]) - def free(self): + def sv_free(self): set_sv_depsgraph_need(False) def register(): diff --git a/nodes/text/stethoscope_v28.py b/nodes/text/stethoscope_v28.py index c33c0019b..2f3b21a42 100644 --- a/nodes/text/stethoscope_v28.py +++ b/nodes/text/stethoscope_v28.py @@ -223,7 +223,7 @@ class SvStethoscopeNodeMK2(bpy.types.Node, SverchCustomTreeNode): } nvBGL.callback_enable(n_id, draw_data) - def free(self): + def sv_free(self): nvBGL.callback_disable(node_id(self)) diff --git a/nodes/text/text_in_mk2.py b/nodes/text/text_in_mk2.py index 667dbdfe3..156a56876 100644 --- a/nodes/text/text_in_mk2.py +++ b/nodes/text/text_in_mk2.py @@ -223,7 +223,7 @@ class SvTextInNodeMK2(bpy.types.Node, SverchCustomTreeNode, CommonTextMixinIO): def sv_copy(self, node): self.n_id = '' - def free(self): + def sv_free(self): # free potentially lots of data n_id = node_id(self) pop_all_data(self, n_id) diff --git a/nodes/viz/console_node.py b/nodes/viz/console_node.py index 41672acdb..2f03d58f9 100644 --- a/nodes/viz/console_node.py +++ b/nodes/viz/console_node.py @@ -566,7 +566,7 @@ class SvConsoleNode(bpy.types.Node, SverchCustomTreeNode, SvNodeViewDrawMixin): height = self.num_rows * 32 return (x, y, width, height) - def free(self): + def sv_free(self): nvBGL2.callback_disable(node_id(self)) # self.delete_texture() diff --git a/nodes/viz/empty_out.py b/nodes/viz/empty_out.py index 97d105e2e..a3d2505cd 100644 --- a/nodes/viz/empty_out.py +++ b/nodes/viz/empty_out.py @@ -108,7 +108,7 @@ class SvEmptyOutNode(bpy.types.Node, SverchCustomTreeNode): empty = self.create_empty() self.label = empty.name - def free(self): + def sv_free(self): if self.auto_remove: empty = self.find_empty() if empty: diff --git a/nodes/viz/vd_draw_experimental.py b/nodes/viz/vd_draw_experimental.py index 01a4edcf5..dc09c4858 100644 --- a/nodes/viz/vd_draw_experimental.py +++ b/nodes/viz/vd_draw_experimental.py @@ -635,7 +635,7 @@ class SvVDExperimental(bpy.types.Node, SverchCustomTreeNode): except: print('vd basic lines update holdout', self.n_id) - def free(self): + def sv_free(self): callback_disable(node_id(self)) diff --git a/nodes/viz/vd_matrix.py b/nodes/viz/vd_matrix.py index 3531e0e96..a2977a451 100644 --- a/nodes/viz/vd_matrix.py +++ b/nodes/viz/vd_matrix.py @@ -155,7 +155,7 @@ class SvMatrixViewer28(bpy.types.Node, SverchCustomTreeNode): callback_enable(self.n_id, draw_data, overlay='POST_VIEW') callback_enable(self.n_id+'__2D', draw_data_2d, overlay='POST_PIXEL') - def free(self): + def sv_free(self): callback_disable(node_id(self)) callback_disable(node_id(self) + '__2D') diff --git a/nodes/viz/viewer_idx28.py b/nodes/viz/viewer_idx28.py index d3ddcd629..78eceba37 100644 --- a/nodes/viz/viewer_idx28.py +++ b/nodes/viz/viewer_idx28.py @@ -293,7 +293,7 @@ class SvIDXViewer28(bpy.types.Node, SverchCustomTreeNode): callback_enable(n_id, draw_data, overlay='POST_PIXEL') - def free(self): + def sv_free(self): callback_disable(node_id(self)) def sv_copy(self, node): diff --git a/nodes/viz/viewer_texture.py b/nodes/viz/viewer_texture.py index e3703efc8..50c4d1e99 100644 --- a/nodes/viz/viewer_texture.py +++ b/nodes/viz/viewer_texture.py @@ -432,7 +432,7 @@ class SvTextureViewerNode(bpy.types.Node, SverchCustomTreeNode): width, height = [width * scale, height * scale] return x, y, width, height - def free(self): + def sv_free(self): nvBGL2.callback_disable(node_id(self)) self.delete_texture() diff --git a/nodes/viz/viewer_texture_lite.py b/nodes/viz/viewer_texture_lite.py index c4ef1a6d1..0a1c556de 100644 --- a/nodes/viz/viewer_texture_lite.py +++ b/nodes/viz/viewer_texture_lite.py @@ -152,7 +152,7 @@ class SvTextureViewerNodeLite(bpy.types.Node, SverchCustomTreeNode): width, height = [width * scale, height * scale] return x, y, width, height - def free(self): + def sv_free(self): nvBGL2.callback_disable(node_id(self)) self.delete_texture() diff --git a/nodes/viz/viewer_waveform_output.py b/nodes/viz/viewer_waveform_output.py index cea97acdc..c8cde4e71 100644 --- a/nodes/viz/viewer_waveform_output.py +++ b/nodes/viz/viewer_waveform_output.py @@ -519,7 +519,7 @@ class SvWaveformViewer(bpy.types.Node, SverchCustomTreeNode): nvBGL.callback_enable(self.n_id, draw_data) - def free(self): + def sv_free(self): nvBGL.callback_disable(node_id(self)) def sv_copy(self, node): -- GitLab From a8d7508c899f3ad07937c25d6bd9bbd9c548dceb Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Thu, 9 Apr 2020 03:07:11 +0200 Subject: [PATCH 02/43] dont process during import --- node_tree.py | 11 ++++++++++- utils/sv_IO_panel_tools.py | 8 ++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/node_tree.py b/node_tree.py index 804fd1439..4932362bf 100644 --- a/node_tree.py +++ b/node_tree.py @@ -308,7 +308,15 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): self.sv_linked_sockets[hash(self)] = linked_sockets self.sv_linked_output_sockets[hash(self)] = output_sockets def use_link_memory(self): + if self.configuring_new_node: + # print('skipping global process during node init') + return + if self.is_frozen(): + # print('not processing: because self/tree.is_frozen') + return + if not self.sv_process: + return links_has_changed = self.sv_links[hash(self)] != self.links.items() if links_has_changed: @@ -335,7 +343,7 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): build_update_list(self) if affected_nodes: process_from_nodes(affected_nodes) - + def update(self): ''' Tags tree for update for handle @@ -385,6 +393,7 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): if self.is_frozen(): # print('not processing: because self/tree.is_frozen') return + if self.sv_process: process_tree(self) diff --git a/utils/sv_IO_panel_tools.py b/utils/sv_IO_panel_tools.py index 63445e924..d53bce2ee 100644 --- a/utils/sv_IO_panel_tools.py +++ b/utils/sv_IO_panel_tools.py @@ -737,12 +737,14 @@ def import_tree(ng, fullpath='', nodes_json=None, create_texts=True, center=None if center is not None: center_nodes(nodes_to_import, center) groups_to_import = nodes_json.get('groups', {}) + previous_state = ng.sv_process + ng.sv_process = False add_groups(groups_to_import) # this return is not used yet name_remap = add_nodes(ng, nodes_to_import, nodes, create_texts) - # now connect them / prevent unnecessary updates ng.freeze(hard=True) + # now connect them / prevent unnecessary updates make_links(update_lists, name_remap) # set frame parents ''' @@ -751,9 +753,11 @@ def import_tree(ng, fullpath='', nodes_json=None, create_texts=True, center=None # clean up old_nodes.scan_for_old(ng) ng.unfreeze(hard=True) - + ng.sv_process = True ng.update() ng.update_tag() + ng.sv_process = previous_state + # ---- read files (.json or .zip) or straight json data ----- -- GitLab From 47a4b2fa43e1760e211b1ad47e7fbcc13200f7c9 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Thu, 9 Apr 2020 17:03:05 +0200 Subject: [PATCH 03/43] hash(self) to tree_id --- node_tree.py | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/node_tree.py b/node_tree.py index 4932362bf..37ef12f3f 100644 --- a/node_tree.py +++ b/node_tree.py @@ -245,7 +245,12 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): sv_links = {} sv_linked_sockets = {} sv_linked_output_sockets = {} - + tree_id: StringProperty(default="") + @property + def get_tree_id(self): + if not self.tree_id: + self.tree_id = str(hash(self) ^ hash(time.monotonic())) + return self.tree_id def on_draft_mode_changed(self, context): """ This is triggered when Draft mode of the tree is toggled. @@ -297,16 +302,17 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): return True def fill_links_memory(self): + tree_id = self.get_tree_id new_links = self.links.items() - self.sv_links[hash(self)] = self.links.items() + self.sv_links[tree_id] = self.links.items() linked_sockets = [] output_sockets = [] for link in new_links: linked_sockets.append((link[1].from_socket, link[1].to_socket)) output_sockets.append(link[1].from_socket) - self.sv_linked_sockets[hash(self)] = linked_sockets - self.sv_linked_output_sockets[hash(self)] = output_sockets + self.sv_linked_sockets[tree_id] = linked_sockets + self.sv_linked_output_sockets[tree_id] = output_sockets def use_link_memory(self): if self.configuring_new_node: # print('skipping global process during node init') @@ -317,15 +323,17 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): if not self.sv_process: return - links_has_changed = self.sv_links[hash(self)] != self.links.items() + + tree_id = self.get_tree_id + links_has_changed = self.sv_links[tree_id] != self.links.items() if links_has_changed: affected_nodes = [] new_links = self.links.items() linked_sockets = [] output_sockets = [] - before_linked_sockets = self.sv_linked_sockets[hash(self)] - before_output_sockets = self.sv_linked_output_sockets[hash(self)] + before_linked_sockets = self.sv_linked_sockets[tree_id] + before_output_sockets = self.sv_linked_output_sockets[tree_id] for link in new_links: output_sockets.append(link[1].from_socket) @@ -336,9 +344,9 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): affected_nodes.append(link[1].to_node) print("Affected Nodes:", affected_nodes) - self.sv_links[hash(self)] = self.links.items() - self.sv_linked_sockets[hash(self)] = linked_sockets - self.sv_linked_output_sockets[hash(self)] = output_sockets + self.sv_links[tree_id] = self.links.items() + self.sv_linked_sockets[tree_id] = linked_sockets + self.sv_linked_output_sockets[tree_id] = output_sockets build_update_list(self) if affected_nodes: -- GitLab From 14233874cf3c36d845a3d5db5951c83017366f21 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Fri, 10 Apr 2020 01:32:43 +0200 Subject: [PATCH 04/43] works when opening --- core/handlers.py | 25 ++++++++++++++++++++++--- core/socket_data.py | 12 ++++++------ core/sockets.py | 13 +++++++++---- core/update_system.py | 8 +++++++- node_tree.py | 15 +++++++++++---- 5 files changed, 55 insertions(+), 18 deletions(-) diff --git a/core/handlers.py b/core/handlers.py index 3131d22ef..7aa7e989c 100644 --- a/core/handlers.py +++ b/core/handlers.py @@ -6,8 +6,8 @@ from bpy.app.handlers import persistent from sverchok import old_nodes from sverchok import data_structure from sverchok.core import upgrade_nodes, undo_handler_node_count - - +from sverchok.core.update_system import sv_first_run, set_first_run +import sverchok.core.update_system as us from sverchok.ui import color_def, bgl_callback_nodeview, bgl_callback_3dview from sverchok.utils import app_handler_ops from sverchok.utils.logging import debug @@ -162,12 +162,26 @@ def sv_clean(scene): data_structure.sv_Vars = {} data_structure.temp_handle = {} +@persistent +def sv_pre_load(scene): + print("sv_pre_load") + sv_clean(scene) + + + set_first_run(True) + global sv_first_run + print("FR",sv_first_run) + @persistent def sv_post_load(scene): """ Upgrade nodes, apply preferences and do an update. """ + print("post_load") + + set_first_run(False) + print('first_run', us.sv_first_run) # ensure current nodeview view scale / location parameters reflect users' system settings from sverchok import node_tree node_tree.SverchCustomTreeNode.get_and_set_gl_scale_info(None, "sv_post_load") @@ -179,8 +193,10 @@ def sv_post_load(scene): sv_types = {'SverchCustomTreeType', 'SverchGroupTreeType'} sv_trees = list(ng for ng in bpy.data.node_groups if ng.bl_idname in sv_types and ng.nodes) + print("old_load") for ng in sv_trees: ng.freeze(True) + ng.sv_process = False try: old_nodes.load_old(ng) except: @@ -192,6 +208,7 @@ def sv_post_load(scene): traceback.print_exc() ng.unfreeze(True) + ng.sv_process = True addon_name = data_structure.SVERCHOK_NAME addon = bpy.context.preferences.addons.get(addon_name) if addon and hasattr(addon, "preferences"): @@ -200,7 +217,9 @@ def sv_post_load(scene): color_def.apply_theme() for ng in sv_trees: + print("post_load_update") if ng.bl_idname == 'SverchCustomTreeType' and ng.nodes: + ng.sv_links={} ng.update() @@ -227,7 +246,7 @@ def set_frame_change(mode): handler_dict = { 'undo_pre': sv_handler_undo_pre, 'undo_post': sv_handler_undo_post, - 'load_pre': sv_clean, + 'load_pre': sv_pre_load, 'load_post': sv_post_load, 'depsgraph_update_pre': sv_main_handler } diff --git a/core/socket_data.py b/core/socket_data.py index fa92cce9b..9c7db8579 100644 --- a/core/socket_data.py +++ b/core/socket_data.py @@ -47,7 +47,7 @@ def sv_deep_copy(lst): def SvGetSocketInfo(socket): """returns string to show in socket label""" global socket_data_cache - ng = socket.id_data.name + ng = socket.id_data.get_tree_id if socket.is_output: s_id = socket.socket_id @@ -75,7 +75,7 @@ def SvForgetSocket(socket): if not socket.is_linked: warning(f"{socket.node.name} forgetting unconncted socket: {socket.name}") s_id = socket.socket_id - s_ng = socket.id_data.name + s_ng = socket.id_data.get_tree_id print("forgetting") socket_data_cache[s_ng].pop(s_id, None) @@ -88,7 +88,7 @@ def SvSetSocket(socket, out): if not socket.is_linked: warning(f"{socket.node.name} setting unconncted socket: {socket.name}") s_id = socket.socket_id - s_ng = socket.id_data.name + s_ng = socket.id_data.get_tree_id if s_ng not in socket_data_cache: socket_data_cache[s_ng] = {} socket_data_cache[s_ng][s_id] = out @@ -104,7 +104,7 @@ def SvGetSocket(socket, deepcopy=True): if socket.is_linked: other = socket.other s_id = other.socket_id - s_ng = other.id_data.name + s_ng = other.id_data.get_tree_id if s_ng not in socket_data_cache: raise LookupError if s_id in socket_data_cache[s_ng]: @@ -161,7 +161,7 @@ def get_output_socket_data(node, output_socket_name): global socket_data_cache - tree_name = node.id_data.name + tree_name = node.id_data.get_tree_id socket = node.outputs[output_socket_name] socket_id = socket.socket_id if tree_name not in socket_data_cache: @@ -176,4 +176,4 @@ def reset_socket_cache(ng): Reset socket cache either for node group. """ global socket_data_cache - socket_data_cache[ng.name] = {} + socket_data_cache[ng.get_tree_id] = {} diff --git a/core/sockets.py b/core/sockets.py index d1dcbdd9f..5e55295b5 100644 --- a/core/sockets.py +++ b/core/sockets.py @@ -18,7 +18,7 @@ # ##### END GPL LICENSE BLOCK ##### import math - +import time import bpy from bpy.props import StringProperty, BoolProperty, FloatVectorProperty, IntProperty, FloatProperty from bpy.types import NodeTree, NodeSocket @@ -52,7 +52,6 @@ def process_from_socket(self, context): """Update function of exposed properties in Sockets""" self.node.process_node(context) - class SvSocketCommon: """ Base class for all Sockets """ use_prop: BoolProperty(default=False) @@ -64,7 +63,7 @@ class SvSocketCommon: prop_name: StringProperty(default='', description="For displaying node property in socket UI") quicklink_func_name: StringProperty(default="", name="quicklink_func_name") - + socket_id_m: StringProperty(default="") def get_prop_name(self): if self.node and self.node.does_support_draft_mode() and hasattr(self.node.id_data, 'sv_draft') and self.node.id_data.sv_draft: prop_name_draft = self.node.draft_properties_mapping.get(self.prop_name, None) @@ -86,7 +85,13 @@ class SvSocketCommon: @property def socket_id(self): """Id of socket used by data_cache""" - return str(hash(self.id_data.name + self.node.name + self.identifier)) + if not self.socket_id_m: + self.socket_id_m = str(hash(self) ^ hash(time.monotonic())) + # self.socket_id_m.set(str(hash(self) ^ hash(time.monotonic()))) + # self.set("socket_id_m", str(hash(self) ^ hash(time.monotonic()))) + return self.socket_id_m + + # return str(hash(self.id_data.get_tree_id + self.node.node_id + self.identifier)) @property def index(self): diff --git a/core/update_system.py b/core/update_system.py index 59ec7a4e1..dd2a6cb66 100644 --- a/core/update_system.py +++ b/core/update_system.py @@ -36,7 +36,13 @@ graphs = [] no_data_color = (1, 0.3, 0) exception_color = (0.8, 0.0, 0) - +sv_first_run = True +def set_first_run(value): + global sv_first_run + sv_first_run = value +def get_first_run(): + global sv_first_run + return sv_first_run def update_error_colors(self, context): global no_data_color global exception_color diff --git a/node_tree.py b/node_tree.py index 37ef12f3f..01e88d486 100644 --- a/node_tree.py +++ b/node_tree.py @@ -36,7 +36,9 @@ from sverchok.core.update_system import ( process_from_node, process_from_nodes, process_tree, get_update_lists, update_error_nodes, - get_original_node_color) + get_original_node_color, + sv_first_run, + get_first_run) from sverchok.core.socket_conversions import DefaultImplicitConversionPolicy @@ -326,7 +328,7 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): tree_id = self.get_tree_id links_has_changed = self.sv_links[tree_id] != self.links.items() - + print(links_has_changed) if links_has_changed: affected_nodes = [] new_links = self.links.items() @@ -360,13 +362,16 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): # this is a no-op if there's no drawing clear_exception_drawing_with_bgl(self.nodes) - + print("UFR", get_first_run()) + if get_first_run(): + return if self.skip_tree_update: # print('throttled update from context manager') return # print('svtree update', self.timestamp) - fill_memory_is_ready = hash(self) in self.sv_links.keys() + tree_id = self.get_tree_id + fill_memory_is_ready = tree_id in self.sv_links.keys() if fill_memory_is_ready: print("memory_is_ready") self.use_link_memory() @@ -429,6 +434,8 @@ class SverchCustomTreeNode: # E.g., draft_properties_mapping = dict(count = 'count_draft'). draft_properties_mapping = dict() + n_id : StringProperty(default="") + @classmethod def poll(cls, ntree): return ntree.bl_idname in ['SverchCustomTreeType', 'SverchGroupTreeType'] -- GitLab From 16bf0b1b1db804bb707d59294874770872bd2c28 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Fri, 10 Apr 2020 23:59:40 +0200 Subject: [PATCH 05/43] lets forget undo by the moment --- core/sockets.py | 12 ++++++++---- node_tree.py | 8 +++++--- utils/sv_IO_panel_tools.py | 7 +++++-- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/core/sockets.py b/core/sockets.py index 5e55295b5..4740f1136 100644 --- a/core/sockets.py +++ b/core/sockets.py @@ -63,6 +63,7 @@ class SvSocketCommon: prop_name: StringProperty(default='', description="For displaying node property in socket UI") quicklink_func_name: StringProperty(default="", name="quicklink_func_name") + # socket_id_m: StringProperty(default="") socket_id_m: StringProperty(default="") def get_prop_name(self): if self.node and self.node.does_support_draft_mode() and hasattr(self.node.id_data, 'sv_draft') and self.node.id_data.sv_draft: @@ -85,12 +86,15 @@ class SvSocketCommon: @property def socket_id(self): """Id of socket used by data_cache""" - if not self.socket_id_m: - self.socket_id_m = str(hash(self) ^ hash(time.monotonic())) + # if not self.socket_id_m: + # try: + # self.socket_id_m = str(hash(self) ^ hash(time.monotonic())) + # except: + # return str(hash(self) ^ hash(time.monotonic())) # self.socket_id_m.set(str(hash(self) ^ hash(time.monotonic()))) # self.set("socket_id_m", str(hash(self) ^ hash(time.monotonic()))) - return self.socket_id_m - + # return self.socket_id_m + return str(hash(self.id_data.name + self.node.name + self.identifier)) # return str(hash(self.id_data.get_tree_id + self.node.node_id + self.identifier)) @property diff --git a/node_tree.py b/node_tree.py index 01e88d486..0f176a755 100644 --- a/node_tree.py +++ b/node_tree.py @@ -342,9 +342,11 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): linked_sockets.append((link[1].from_socket, link[1].to_socket)) if not (link[1].from_socket, link[1].to_socket) in before_linked_sockets: if not link[1].from_socket in before_output_sockets: - affected_nodes.append(link[1].from_node) - affected_nodes.append(link[1].to_node) - print("Affected Nodes:", affected_nodes) + if not link[1].from_node in affected_nodes: + affected_nodes.append(link[1].from_node) + if not link[1].to_node in affected_nodes: + affected_nodes.append(link[1].to_node) + print("Affected Nodes:", [n.name for n in affected_nodes]) self.sv_links[tree_id] = self.links.items() self.sv_linked_sockets[tree_id] = linked_sockets diff --git a/utils/sv_IO_panel_tools.py b/utils/sv_IO_panel_tools.py index d53bce2ee..cced9cb64 100644 --- a/utils/sv_IO_panel_tools.py +++ b/utils/sv_IO_panel_tools.py @@ -607,6 +607,7 @@ def add_node_to_tree(nodes, n, nodes_to_import, name_remap, create_texts): if not node: raise Exception("It seems no valid node was created for this Monad {0}".format(node_ref)) else: + print(bl_idname) node = nodes.new(bl_idname) except Exception as err: @@ -640,12 +641,14 @@ def add_nodes(ng, nodes_to_import, nodes, create_texts): ''' name_remap = {} ng.limited_init = True + ng.skip_tree_update = True try: for n in sorted(nodes_to_import): + print(n, ng.sv_process, ng.skip_tree_update) add_node_to_tree(nodes, n, nodes_to_import, name_remap, create_texts) except Exception as err: exception(err) - + ng.skip_tree_update = False ng.limited_init = False return name_remap @@ -753,7 +756,7 @@ def import_tree(ng, fullpath='', nodes_json=None, create_texts=True, center=None # clean up old_nodes.scan_for_old(ng) ng.unfreeze(hard=True) - ng.sv_process = True + # ng.sv_process = True ng.update() ng.update_tag() ng.sv_process = previous_state -- GitLab From ef1a63970f4cffeb1a4be8c5c827dbb0dc6d0f80 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Sat, 11 Apr 2020 16:16:33 +0200 Subject: [PATCH 06/43] sv_links in monad too --- node_tree.py | 23 +++++++++++------------ utils/sv_IO_panel_tools.py | 4 +--- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/node_tree.py b/node_tree.py index 0f176a755..e890e76bf 100644 --- a/node_tree.py +++ b/node_tree.py @@ -144,7 +144,15 @@ class SvNodeTreeCommon(object): has_changed: BoolProperty(default=False) limited_init: BoolProperty(default=False) skip_tree_update: BoolProperty(default=False) - + sv_links = {} + sv_linked_sockets = {} + sv_linked_output_sockets = {} + tree_id: StringProperty(default="") + @property + def get_tree_id(self): + if not self.tree_id: + self.tree_id = str(hash(self) ^ hash(time.monotonic())) + return self.tree_id def build_update_list(self): build_update_list(self) @@ -244,15 +252,7 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): sv_toggle_nodetree_props: BoolProperty(name="Toggle visibility of props", description="Show more properties for this node tree") - sv_links = {} - sv_linked_sockets = {} - sv_linked_output_sockets = {} - tree_id: StringProperty(default="") - @property - def get_tree_id(self): - if not self.tree_id: - self.tree_id = str(hash(self) ^ hash(time.monotonic())) - return self.tree_id + def on_draft_mode_changed(self, context): """ This is triggered when Draft mode of the tree is toggled. @@ -328,7 +328,7 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): tree_id = self.get_tree_id links_has_changed = self.sv_links[tree_id] != self.links.items() - print(links_has_changed) + print('links_has_changed', links_has_changed) if links_has_changed: affected_nodes = [] new_links = self.links.items() @@ -364,7 +364,6 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): # this is a no-op if there's no drawing clear_exception_drawing_with_bgl(self.nodes) - print("UFR", get_first_run()) if get_first_run(): return if self.skip_tree_update: diff --git a/utils/sv_IO_panel_tools.py b/utils/sv_IO_panel_tools.py index cced9cb64..04b5d0c55 100644 --- a/utils/sv_IO_panel_tools.py +++ b/utils/sv_IO_panel_tools.py @@ -607,7 +607,6 @@ def add_node_to_tree(nodes, n, nodes_to_import, name_remap, create_texts): if not node: raise Exception("It seems no valid node was created for this Monad {0}".format(node_ref)) else: - print(bl_idname) node = nodes.new(bl_idname) except Exception as err: @@ -644,7 +643,6 @@ def add_nodes(ng, nodes_to_import, nodes, create_texts): ng.skip_tree_update = True try: for n in sorted(nodes_to_import): - print(n, ng.sv_process, ng.skip_tree_update) add_node_to_tree(nodes, n, nodes_to_import, name_remap, create_texts) except Exception as err: exception(err) @@ -756,7 +754,7 @@ def import_tree(ng, fullpath='', nodes_json=None, create_texts=True, center=None # clean up old_nodes.scan_for_old(ng) ng.unfreeze(hard=True) - # ng.sv_process = True + ng.sv_process = True ng.update() ng.update_tag() ng.sv_process = previous_state -- GitLab From d54966e832df828947fd560beb4454ab1097674b Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Sat, 11 Apr 2020 22:49:40 +0200 Subject: [PATCH 07/43] import is working --- node_tree.py | 5 +++-- utils/sv_IO_panel_tools.py | 15 ++++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/node_tree.py b/node_tree.py index e890e76bf..0f72ddf4d 100644 --- a/node_tree.py +++ b/node_tree.py @@ -336,7 +336,7 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): output_sockets = [] before_linked_sockets = self.sv_linked_sockets[tree_id] before_output_sockets = self.sv_linked_output_sockets[tree_id] - + print(before_linked_sockets) for link in new_links: output_sockets.append(link[1].from_socket) linked_sockets.append((link[1].from_socket, link[1].to_socket)) @@ -378,7 +378,8 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): self.use_link_memory() else: print("filling link_memory") - self.fill_links_memory() + if self.sv_process: + self.fill_links_memory() self.has_changed = True # self.has_link_count_changed self.process() diff --git a/utils/sv_IO_panel_tools.py b/utils/sv_IO_panel_tools.py index 04b5d0c55..aabf56bd1 100644 --- a/utils/sv_IO_panel_tools.py +++ b/utils/sv_IO_panel_tools.py @@ -433,7 +433,7 @@ def perform_scripted_node_inject(node, node_ref): node.load() -def perform_profile_node_inject(node, node_ref): +def perform_profixle_node_inject(node, node_ref): texts = bpy.data.texts new_text = texts.new(node_ref['params']['filename']) new_text.from_string(node_ref['path_file']) @@ -707,9 +707,10 @@ def import_tree(ng, fullpath='', nodes_json=None, create_texts=True, center=None def make_links(update_lists, name_remap): print_update_lists(update_lists) - + print(ng.sv_linked_sockets) failed_connections = [] for link in update_lists: + print(ng.sv_process) try: ng.links.new(*resolve_socket(*link, name_dict=name_remap)) except Exception as err: @@ -743,18 +744,22 @@ def import_tree(ng, fullpath='', nodes_json=None, create_texts=True, center=None ng.sv_process = False add_groups(groups_to_import) # this return is not used yet name_remap = add_nodes(ng, nodes_to_import, nodes, create_texts) - + print('DDD') ng.freeze(hard=True) + print('CCC') # now connect them / prevent unnecessary updates make_links(update_lists, name_remap) - + print('BBB') # set frame parents ''' place_frames(ng, nodes_json, name_remap) - + print('AAAAA') # clean up old_nodes.scan_for_old(ng) + print(ng.sv_linked_sockets) ng.unfreeze(hard=True) + ng.sv_process = True + ng.update() ng.update_tag() ng.sv_process = previous_state -- GitLab From 29293c7f3a8c8768a523d01da1c89b1a0011a751 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Sat, 11 Apr 2020 22:54:40 +0200 Subject: [PATCH 08/43] less printing? --- node_tree.py | 8 ++++---- utils/sv_IO_panel_tools.py | 10 ++++------ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/node_tree.py b/node_tree.py index 0f72ddf4d..5e65ef9de 100644 --- a/node_tree.py +++ b/node_tree.py @@ -328,7 +328,7 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): tree_id = self.get_tree_id links_has_changed = self.sv_links[tree_id] != self.links.items() - print('links_has_changed', links_has_changed) + # print('links_has_changed', links_has_changed) if links_has_changed: affected_nodes = [] new_links = self.links.items() @@ -346,7 +346,7 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): affected_nodes.append(link[1].from_node) if not link[1].to_node in affected_nodes: affected_nodes.append(link[1].to_node) - print("Affected Nodes:", [n.name for n in affected_nodes]) + # print("Affected Nodes:", [n.name for n in affected_nodes]) self.sv_links[tree_id] = self.links.items() self.sv_linked_sockets[tree_id] = linked_sockets @@ -374,10 +374,10 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): tree_id = self.get_tree_id fill_memory_is_ready = tree_id in self.sv_links.keys() if fill_memory_is_ready: - print("memory_is_ready") + # print("memory_is_ready") self.use_link_memory() else: - print("filling link_memory") + # print("filling link_memory") if self.sv_process: self.fill_links_memory() self.has_changed = True diff --git a/utils/sv_IO_panel_tools.py b/utils/sv_IO_panel_tools.py index aabf56bd1..18ebe144e 100644 --- a/utils/sv_IO_panel_tools.py +++ b/utils/sv_IO_panel_tools.py @@ -707,10 +707,8 @@ def import_tree(ng, fullpath='', nodes_json=None, create_texts=True, center=None def make_links(update_lists, name_remap): print_update_lists(update_lists) - print(ng.sv_linked_sockets) failed_connections = [] for link in update_lists: - print(ng.sv_process) try: ng.links.new(*resolve_socket(*link, name_dict=name_remap)) except Exception as err: @@ -744,15 +742,15 @@ def import_tree(ng, fullpath='', nodes_json=None, create_texts=True, center=None ng.sv_process = False add_groups(groups_to_import) # this return is not used yet name_remap = add_nodes(ng, nodes_to_import, nodes, create_texts) - print('DDD') + ng.freeze(hard=True) - print('CCC') + # now connect them / prevent unnecessary updates make_links(update_lists, name_remap) - print('BBB') + # set frame parents ''' place_frames(ng, nodes_json, name_remap) - print('AAAAA') + # clean up old_nodes.scan_for_old(ng) print(ng.sv_linked_sockets) -- GitLab From c2611552b1ec85c0308873eea46d7a9473d62c29 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Sun, 12 Apr 2020 17:15:25 +0200 Subject: [PATCH 09/43] too much code --- utils/sv_IO_panel_tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/sv_IO_panel_tools.py b/utils/sv_IO_panel_tools.py index 18ebe144e..066eab74a 100644 --- a/utils/sv_IO_panel_tools.py +++ b/utils/sv_IO_panel_tools.py @@ -433,7 +433,7 @@ def perform_scripted_node_inject(node, node_ref): node.load() -def perform_profixle_node_inject(node, node_ref): +def perform_profile_node_inject(node, node_ref): texts = bpy.data.texts new_text = texts.new(node_ref['params']['filename']) new_text.from_string(node_ref['path_file']) -- GitLab From ac15b8d41b977ec569a3cc330f405b7484693865 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Sun, 12 Apr 2020 17:23:59 +0200 Subject: [PATCH 10/43] maybe it was that --- utils/sv_IO_panel_tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/sv_IO_panel_tools.py b/utils/sv_IO_panel_tools.py index 066eab74a..8a3439e1e 100644 --- a/utils/sv_IO_panel_tools.py +++ b/utils/sv_IO_panel_tools.py @@ -753,7 +753,7 @@ def import_tree(ng, fullpath='', nodes_json=None, create_texts=True, center=None # clean up old_nodes.scan_for_old(ng) - print(ng.sv_linked_sockets) + ng.unfreeze(hard=True) ng.sv_process = True -- GitLab From cd0644d919c65faa454adf85fb93f15fe30b37ec Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Tue, 14 Apr 2020 00:10:00 +0200 Subject: [PATCH 11/43] monad learns to walk --- core/monad.py | 30 ++++----- core/socket_data.py | 8 ++- node_tree.py | 156 +++++++++++++++++++++++++++++--------------- 3 files changed, 123 insertions(+), 71 deletions(-) diff --git a/core/monad.py b/core/monad.py index 30c353b9b..2a12ae874 100644 --- a/core/monad.py +++ b/core/monad.py @@ -70,20 +70,20 @@ def monad_make_unique(node): Create a new version of the monad class (duplicate but unique) This will attempt to store the duplicate in a json using create_dict_of_tree (from the Gist IO). - The upside is that this will test the pack/unpack routine continuously. - The downside is that this will likely expose all the shortcommings that we don't know + The upside is that this will test the pack/unpack routine continuously. + The downside is that this will likely expose all the shortcommings that we don't know about because it wasn't being tested extensively. """ node_tree = node.id_data nodes = node_tree.nodes - # generate a new copy of monad group node. using ( copy? ) + # generate a new copy of monad group node. using ( copy? ) monad_group = bpy.data.node_groups[node.monad.name] new_monad_group = monad_group.copy() - new_cls_name = make_new_classname(new_monad_group) + new_cls_name = make_new_classname(new_monad_group) - # the new tree dict will contain information about 1 node only, and + # the new tree dict will contain information about 1 node only, and # the node_group too (at the moment) but the node_group data can be ignored. layout_json = create_dict_of_tree(ng=node_tree, identified_node=node) @@ -105,8 +105,8 @@ def monad_make_unique(node): """ notions..: - - if (original instance has no connections) then + + if (original instance has no connections) then replace it outright. else if mode=='replace': @@ -121,7 +121,7 @@ def monad_make_unique(node): """ # return newly generated node! - return (set(node_tree.nodes) ^ pre_nodes).pop() + return (set(node_tree.nodes) ^ pre_nodes).pop() @@ -216,9 +216,9 @@ class SverchGroupTree(NodeTree, SvNodeTreeCommon): prop_settings = self.int_props.add() else: return None - + new_name = generate_name(make_valid_identifier(other.name), cls_dict) - prop_settings.prop_name = new_name + prop_settings.prop_name = new_name prop_settings.set_settings({"name": other.name}) socket.prop_name = new_name return new_name @@ -358,7 +358,7 @@ class SverchGroupTree(NodeTree, SvNodeTreeCommon): cls_dict = {} if not self.cls_bl_idname: - + # the monad cls_bl_idname needs to be unique and cannot change monad_base_name = make_valid_identifier(self.name) monad_itentifier = id(self) ^ random.randint(0, 4294967296) @@ -524,7 +524,7 @@ class SvGroupNodeExp: cA.prop(self, "vectorize", toggle=True) cB.active = self.vectorize cB.prop(self, "split", toggle=True) - + c2 = layout.column() row = c2.row(align=True) row.prop(self, "loop_me", text='Loop', toggle=True) @@ -545,7 +545,7 @@ class SvGroupNodeExp: def get_nodes_to_process(self, out_node_name): """ - nodes not indirectly / directly contributing to the data we eventually pass to "monad.output_node" + nodes not indirectly / directly contributing to the data we eventually pass to "monad.output_node" are discarded if only `self.monad.outputs_node.name` is passed in endpoints_nodes. The exceptions are nodes that we use for debugging inside the monad. At present SvDebugPrint instances @@ -567,7 +567,7 @@ class SvGroupNodeExp: elif self.loop_me: self.process_looped(self.loops) return - + print("processing monad") monad = self.monad in_node = monad.input_node out_node = monad.output_node @@ -632,7 +632,7 @@ class SvGroupNodeExp: out_node = monad.output_node for index, data in enumerate(sockets_data_in): - in_node.outputs[index].sv_set(data) + in_node.outputs[index].sv_set(data) node_names = self.get_nodes_to_process(out_node.name) ul = make_tree_from_nodes(node_names, monad, down=False) diff --git a/core/socket_data.py b/core/socket_data.py index 9c7db8579..6e85bf114 100644 --- a/core/socket_data.py +++ b/core/socket_data.py @@ -76,8 +76,12 @@ def SvForgetSocket(socket): warning(f"{socket.node.name} forgetting unconncted socket: {socket.name}") s_id = socket.socket_id s_ng = socket.id_data.get_tree_id - print("forgetting") - socket_data_cache[s_ng].pop(s_id, None) + print("forgetting", socket) + # if s_ng in socket_data_cache.keys(): + try: + socket_data_cache[s_ng].pop(s_id, None) + except KeyError: + print("it was never there") def SvSetSocket(socket, out): """sets socket data for socket""" diff --git a/node_tree.py b/node_tree.py index 5e65ef9de..dae59492b 100644 --- a/node_tree.py +++ b/node_tree.py @@ -144,9 +144,11 @@ class SvNodeTreeCommon(object): has_changed: BoolProperty(default=False) limited_init: BoolProperty(default=False) skip_tree_update: BoolProperty(default=False) + configuring_new_node: BoolProperty(name="indicate node initialization", default=False) sv_links = {} sv_linked_sockets = {} sv_linked_output_sockets = {} + sv_linked_input_sockets = {} tree_id: StringProperty(default="") @property def get_tree_id(self): @@ -203,6 +205,102 @@ class SvNodeTreeCommon(object): res.append(ng) return res + def fill_links_memory(self): + tree_id = self.get_tree_id + new_links = self.links.items() + self.sv_links[tree_id] = self.links.items() + linked_sockets = [] + input_sockets = [] + output_sockets = [] + for link in new_links: + linked_sockets.append((link[1].from_socket, link[1].to_socket)) + output_sockets.append(link[1].from_socket) + + self.sv_linked_sockets[tree_id] = linked_sockets + self.sv_linked_output_sockets[tree_id] = output_sockets + self.sv_linked_input_sockets[tree_id] = input_sockets + + def use_link_memory(self): + if self.configuring_new_node: + # print('skipping global process during node init') + return + if self.is_frozen(): + # print('not processing: because self/tree.is_frozen') + return + + if not self.sv_process: + return + + tree_id = self.get_tree_id + links_has_changed = self.sv_links[tree_id] != self.links.items() + print('links_has_changed', links_has_changed) + if links_has_changed: + affected_nodes = [] + new_links = self.links.items() + linked_sockets = [] + input_sockets = [] + output_sockets = [] + before_linked_sockets = self.sv_linked_sockets[tree_id] + before_input_sockets = self.sv_linked_input_sockets[tree_id] + before_output_sockets = self.sv_linked_output_sockets[tree_id] + for link in new_links: + + input_sockets.append(link[1].to_socket) + output_sockets.append(link[1].from_socket) + linked_sockets.append((link[1].from_socket, link[1].to_socket)) + + if not (link[1].from_socket, link[1].to_socket) in before_linked_sockets: + if not link[1].from_socket in before_output_sockets: + if not link[1].from_node in affected_nodes: + affected_nodes.append(link[1].from_node) + if not link[1].to_node in affected_nodes: + affected_nodes.append(link[1].to_node) + # print("Affected Nodes:", [n.name for n in affected_nodes]) + for socket in before_input_sockets: + try: + name = socket.node.name + if not socket in input_sockets: + affected_nodes.append(socket.node) + except AttributeError: + pass + + self.sv_links[tree_id] = self.links.items() + self.sv_linked_sockets[tree_id] = linked_sockets + self.sv_linked_output_sockets[tree_id] = output_sockets + self.sv_linked_input_sockets[tree_id] = input_sockets + + build_update_list(self) + if affected_nodes: + process_from_nodes(affected_nodes) + return True + else: + return False + else: + affected_groups = [] + for node in self.nodes: + if 'SvGroupNode' in node.bl_idname: + subtree = node.monad + tree_id = subtree.get_tree_id + fill_memory_is_ready = tree_id in subtree.sv_links.keys() + if fill_memory_is_ready: + print("monad memory_is_ready") + has_been_updated = subtree.use_link_memory() + if has_been_updated: + affected_groups.append(node) + else: + print("filling monad link_memory") + # if subtree.sv_process: + subtree.fill_links_memory() + subtree.has_changed = True + has_been_updated = True + # self.has_link_count_changed + node.process() + print(node.name) + if affected_groups: + process_from_nodes(affected_groups) + return True + else: + return False class SvGenericUITooltipOperator(bpy.types.Operator): arg: StringProperty() @@ -289,7 +387,7 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): update=on_draft_mode_changed) tree_link_count: IntProperty(name='keep track of current link count', default=0) - configuring_new_node: BoolProperty(name="indicate node initialization", default=False) + @property def timestamp(self): @@ -303,58 +401,8 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): self.tree_link_count = link_count return True - def fill_links_memory(self): - tree_id = self.get_tree_id - new_links = self.links.items() - self.sv_links[tree_id] = self.links.items() - linked_sockets = [] - output_sockets = [] - for link in new_links: - linked_sockets.append((link[1].from_socket, link[1].to_socket)) - output_sockets.append(link[1].from_socket) - self.sv_linked_sockets[tree_id] = linked_sockets - self.sv_linked_output_sockets[tree_id] = output_sockets - def use_link_memory(self): - if self.configuring_new_node: - # print('skipping global process during node init') - return - if self.is_frozen(): - # print('not processing: because self/tree.is_frozen') - return - - if not self.sv_process: - return - tree_id = self.get_tree_id - links_has_changed = self.sv_links[tree_id] != self.links.items() - # print('links_has_changed', links_has_changed) - if links_has_changed: - affected_nodes = [] - new_links = self.links.items() - linked_sockets = [] - output_sockets = [] - before_linked_sockets = self.sv_linked_sockets[tree_id] - before_output_sockets = self.sv_linked_output_sockets[tree_id] - print(before_linked_sockets) - for link in new_links: - output_sockets.append(link[1].from_socket) - linked_sockets.append((link[1].from_socket, link[1].to_socket)) - if not (link[1].from_socket, link[1].to_socket) in before_linked_sockets: - if not link[1].from_socket in before_output_sockets: - if not link[1].from_node in affected_nodes: - affected_nodes.append(link[1].from_node) - if not link[1].to_node in affected_nodes: - affected_nodes.append(link[1].to_node) - # print("Affected Nodes:", [n.name for n in affected_nodes]) - - self.sv_links[tree_id] = self.links.items() - self.sv_linked_sockets[tree_id] = linked_sockets - self.sv_linked_output_sockets[tree_id] = output_sockets - - build_update_list(self) - if affected_nodes: - process_from_nodes(affected_nodes) def update(self): ''' @@ -374,10 +422,10 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): tree_id = self.get_tree_id fill_memory_is_ready = tree_id in self.sv_links.keys() if fill_memory_is_ready: - # print("memory_is_ready") - self.use_link_memory() + print("memory_is_ready") + has_been_updated = self.use_link_memory() else: - # print("filling link_memory") + print("filling link_memory") if self.sv_process: self.fill_links_memory() self.has_changed = True -- GitLab From aa5f5eb4d4b205ab90871f5f0f8b95355384fb36 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Tue, 14 Apr 2020 21:13:34 +0200 Subject: [PATCH 12/43] reset error nodes and not running monad if not output sockets connected --- core/monad.py | 2 ++ node_tree.py | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/core/monad.py b/core/monad.py index 2a12ae874..1e808a80d 100644 --- a/core/monad.py +++ b/core/monad.py @@ -559,6 +559,8 @@ class SvGroupNodeExp: return endpoint_nodes def process(self): + if not any(s.is_linked for s in self.outputs): + return if not self.monad: return if self.vectorize: diff --git a/node_tree.py b/node_tree.py index dae59492b..10b001d07 100644 --- a/node_tree.py +++ b/node_tree.py @@ -38,7 +38,8 @@ from sverchok.core.update_system import ( get_update_lists, update_error_nodes, get_original_node_color, sv_first_run, - get_first_run) + get_first_run, + reset_error_nodes) from sverchok.core.socket_conversions import DefaultImplicitConversionPolicy @@ -140,7 +141,7 @@ class SvNodeTreeCommon(object): ''' Common methods shared between Sverchok node trees ''' - + sv_process: BoolProperty(name="Process", default=True, description='Process layout') has_changed: BoolProperty(default=False) limited_init: BoolProperty(default=False) skip_tree_update: BoolProperty(default=False) @@ -234,6 +235,7 @@ class SvNodeTreeCommon(object): tree_id = self.get_tree_id links_has_changed = self.sv_links[tree_id] != self.links.items() print('links_has_changed', links_has_changed) + reset_error_nodes(self) if links_has_changed: affected_nodes = [] new_links = self.links.items() @@ -331,7 +333,7 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): sv_animate: BoolProperty(name="Animate", default=True, description='Animate this layout') sv_show: BoolProperty(name="Show", default=True, description='Show this layout', update=turn_off_ng) sv_bake: BoolProperty(name="Bake", default=True, description='Bake this layout') - sv_process: BoolProperty(name="Process", default=True, description='Process layout') + sv_user_colors: StringProperty(default="") sv_show_error_in_tree: BoolProperty( -- GitLab From b8ffca5efd675968b96eb9339711e8dc88489d4b Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Wed, 15 Apr 2020 18:49:39 +0200 Subject: [PATCH 13/43] support for nodetree renaming --- core/sockets.py | 3 ++- node_tree.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/sockets.py b/core/sockets.py index 1fecf9e30..b6aab3919 100644 --- a/core/sockets.py +++ b/core/sockets.py @@ -94,7 +94,8 @@ class SvSocketCommon: # self.socket_id_m.set(str(hash(self) ^ hash(time.monotonic()))) # self.set("socket_id_m", str(hash(self) ^ hash(time.monotonic()))) # return self.socket_id_m - return str(hash(self.id_data.name + self.node.name + self.identifier)) + # return str(hash(self.id_data.name + self.node.name + self.identifier)) + return str(hash(self.node.node_id + self.identifier)) # return str(hash(self.id_data.get_tree_id + self.node.node_id + self.identifier)) @property diff --git a/node_tree.py b/node_tree.py index 10b001d07..135d35b74 100644 --- a/node_tree.py +++ b/node_tree.py @@ -774,7 +774,7 @@ class SverchCustomTreeNode: ng = self.id_data ng.freeze() - + self.n_id = str(hash(self) ^ hash(time.monotonic())) if hasattr(self, "sv_init"): try: -- GitLab From b7effc080e645957e62ff46c87722ad7549e3d55 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Thu, 16 Apr 2020 21:31:19 +0200 Subject: [PATCH 14/43] support for undo and reroutes --- core/handlers.py | 44 ++++++++----- core/update_system.py | 24 ++++++-- node_tree.py | 140 ++++++++++++++++++++++++++++-------------- 3 files changed, 143 insertions(+), 65 deletions(-) diff --git a/core/handlers.py b/core/handlers.py index 7aa7e989c..78db94ae5 100644 --- a/core/handlers.py +++ b/core/handlers.py @@ -55,7 +55,6 @@ def has_frame_changed(scene): @persistent def sv_handler_undo_pre(scene): - print('called undo pre') from sverchok.core import undo_handler_node_count @@ -65,23 +64,33 @@ def sv_handler_undo_pre(scene): @persistent def sv_handler_undo_post(scene): - print('called undo post') + # this function appears to be hoisted into an environment that does not have the same locals() # hence this dict must be imported. (jan 2019) from sverchok.core import undo_handler_node_count num_to_test_against = 0 + links_changed = False for ng in sverchok_trees(): num_to_test_against += len(ng.nodes) + tree_id = ng.get_tree_id + if tree_id in ng.sv_links.keys(): + links_changed = links_changed or ng.sv_links[tree_id] != ng.bl_links_to_sv_links() # only perform clean if the undo event triggered # a difference in total node count among trees. - if not (undo_handler_node_count['sv_groups'] == num_to_test_against): + if links_changed or not (undo_handler_node_count['sv_groups'] == num_to_test_against): print('looks like a node was removed, cleaning') sv_clean(scene) + for ng in sverchok_trees(): + tree_id = ng.get_tree_id + if tree_id in ng.sv_node_dict: + ng.sv_node_dict[tree_id]={} + for node in ng.nodes: + ng.sv_node_dict[tree_id][node.node_id] = node + ng.has_changed = True sv_main_handler(scene) - undo_handler_node_count['sv_groups'] = 0 @@ -95,7 +104,7 @@ def sv_update_handler(scene): for ng in sverchok_trees(): try: - # print('sv_update_handler') + ng.process_ani() except Exception as e: print('Failed to update:', str(e)) #name, @@ -140,12 +149,13 @@ def sv_main_handler(scene): if depsgraph_need: sv_depsgraph = bpy.context.evaluated_depsgraph_get() for ng in sverchok_trees(): + # if P (sv_process is False, we can skip this node tree. if not ng.sv_process: continue if ng.has_changed: - print('depsgraph_update_pre called - ng.has_changed -> ') + ng.process() pre_running = False @@ -164,24 +174,23 @@ def sv_clean(scene): @persistent def sv_pre_load(scene): - print("sv_pre_load") + sv_clean(scene) set_first_run(True) global sv_first_run - print("FR",sv_first_run) + @persistent def sv_post_load(scene): """ Upgrade nodes, apply preferences and do an update. """ - print("post_load") + set_first_run(False) - print('first_run', us.sv_first_run) # ensure current nodeview view scale / location parameters reflect users' system settings from sverchok import node_tree node_tree.SverchCustomTreeNode.get_and_set_gl_scale_info(None, "sv_post_load") @@ -193,7 +202,7 @@ def sv_post_load(scene): sv_types = {'SverchCustomTreeType', 'SverchGroupTreeType'} sv_trees = list(ng for ng in bpy.data.node_groups if ng.bl_idname in sv_types and ng.nodes) - print("old_load") + for ng in sv_trees: ng.freeze(True) ng.sv_process = False @@ -217,9 +226,9 @@ def sv_post_load(scene): color_def.apply_theme() for ng in sv_trees: - print("post_load_update") + if ng.bl_idname == 'SverchCustomTreeType' and ng.nodes: - ng.sv_links={} + ng.sv_links = {} ng.update() @@ -242,13 +251,20 @@ def set_frame_change(mode): elif mode == "PRE": pre.append(sv_update_handler) +# def sv_depsgraph_update_post(scene): +# print('sv_depsgraph_update_post') +# depsgraph = bpy.context.evaluated_depsgraph_get() +# print("nodetree", depsgraph.id_type_updated('NODETREE')) +# print("material",depsgraph.id_type_updated('MATERIAL')) +# print("items",depsgraph.ids.items()) handler_dict = { 'undo_pre': sv_handler_undo_pre, 'undo_post': sv_handler_undo_post, 'load_pre': sv_pre_load, 'load_post': sv_post_load, - 'depsgraph_update_pre': sv_main_handler + 'depsgraph_update_pre': sv_main_handler, + # 'depsgraph_update_post': sv_depsgraph_update_post } diff --git a/core/update_system.py b/core/update_system.py index dd2a6cb66..4a370ff00 100644 --- a/core/update_system.py +++ b/core/update_system.py @@ -78,16 +78,19 @@ def make_dep_dict(node_tree, down=False): # a link is considered valid without a to_socket # or a from_socket. proctects against a blender crash # see https://github.com/nortikin/sverchok/issues/493 + if not (link.to_socket and link.from_socket): ng.links.remove(link) raise ValueError("Invalid link found!, please report this file") - if not link.is_valid: - return collections.defaultdict(set) # this happens more often than one might think + # it seems to work even with invalid links, maybe beacuse sverchok update is indepentent from blender update + # if not link.is_valid: + # return collections.defaultdict(set) # this happens more often than one might think if link.is_hidden: continue key, value = (link.from_node.name, link.to_node.name) if down else (link.to_node.name, link.from_node.name) deps[key].add(value) + for name, var_name in wifi_out_nodes: other = wifi_dict.get(var_name) if not other: @@ -220,6 +223,7 @@ def make_tree_from_nodes(node_names, tree, down=True): # build downwards links, this should be cached perhaps node_links = make_dep_dict(ng, down) + while current_node: for node in node_links[current_node]: if node not in out_set: @@ -320,6 +324,17 @@ def reset_error_node(ng, name): del error_nodes[name] ng["error nodes"] = str(error_nodes) +def reset_error_some_nodes(ng, names): + if "error nodes" in ng: + error_nodes = ast.literal_eval(ng["error nodes"]) + for name in names: + node = ng.nodes.get(name) + if node: + if name in error_nodes: + node.use_custom_color, node.color = error_nodes[name] + del error_nodes[name] + ng["error nodes"] = str(error_nodes) + def reset_error_nodes(ng): if "error nodes" in ng: error_nodes = ast.literal_eval(ng["error nodes"]) @@ -436,7 +451,8 @@ def process_from_nodes(nodes): node_names = [node.name for node in nodes] ng = nodes[0].id_data update_list = make_tree_from_nodes(node_names, ng) - print(update_list) + # print("process_from_nodes", update_list) + reset_error_some_nodes(ng, update_list) do_update(update_list, ng.nodes) @@ -465,7 +481,7 @@ def process_from_node(node): nodes = ng.nodes if not ng.sv_process: return - print(update_list) + # print(update_list) do_update(update_list, nodes) else: process_tree(ng) diff --git a/node_tree.py b/node_tree.py index 135d35b74..e22b651ca 100644 --- a/node_tree.py +++ b/node_tree.py @@ -21,6 +21,8 @@ import sys import time from contextlib import contextmanager import textwrap +import collections + import bpy from bpy.props import StringProperty, BoolProperty, FloatVectorProperty, IntProperty, EnumProperty @@ -42,7 +44,7 @@ from sverchok.core.update_system import ( reset_error_nodes) from sverchok.core.socket_conversions import DefaultImplicitConversionPolicy - +from sverchok.core.socket_data import socket_data_cache from sverchok.core.node_defaults import set_defaults_if_defined from sverchok.utils import get_node_class_reference @@ -135,7 +137,17 @@ def throttled(func): return wrapper_update +# Declaring namedtuple() +Sv_Link = collections.namedtuple('sv_link',['from_node_id', 'to_node_id', 'from_socket_id', 'to_socket_id']) +def get_output_socket_id(socket): + if socket.node.bl_idname == 'NodeReroute': + if socket.node.inputs[0].is_linked: + return get_output_socket_id(socket.node.inputs[0].links[0].from_socket) + else: + return None, None + else: + return socket.socket_id, socket.node.node_id class SvNodeTreeCommon(object): ''' @@ -146,10 +158,11 @@ class SvNodeTreeCommon(object): limited_init: BoolProperty(default=False) skip_tree_update: BoolProperty(default=False) configuring_new_node: BoolProperty(name="indicate node initialization", default=False) + sv_node_dict = {} sv_links = {} - sv_linked_sockets = {} sv_linked_output_sockets = {} sv_linked_input_sockets = {} + sv_linked_inputted_nodes = {} tree_id: StringProperty(default="") @property def get_tree_id(self): @@ -205,21 +218,40 @@ class SvNodeTreeCommon(object): if ng.bl_idname in {'SverchCustomTreeType', 'SverchGroupTreeType'}: res.append(ng) return res + def bl_links_to_sv_links(self): + + sv_links=[] + for link in self.links.items(): + if not link[1].to_socket.node.bl_idname == 'NodeReroute': + #recursive function to override reroutes + output_socket, output_node = get_output_socket_id(link[1].from_socket) + if output_socket: + sv_link = Sv_Link( + from_node_id=output_node, + to_node_id=link[1].to_socket.node.node_id, + from_socket_id=output_socket, + to_socket_id=link[1].to_socket.socket_id ) + sv_links.append(sv_link) + # sv_links.append((output_socket, link[1].to_socket.socket_id)) + return sv_links def fill_links_memory(self): tree_id = self.get_tree_id new_links = self.links.items() - self.sv_links[tree_id] = self.links.items() - linked_sockets = [] + new_sv_links = self.bl_links_to_sv_links() + self.sv_links[tree_id] = new_sv_links + + inputted_nodes = [] input_sockets = [] output_sockets = [] - for link in new_links: - linked_sockets.append((link[1].from_socket, link[1].to_socket)) - output_sockets.append(link[1].from_socket) + for sv_link in new_sv_links: + inputted_nodes.append(sv_link.to_node_id) + input_sockets.append(sv_link.to_socket_id) + output_sockets.append(sv_link.from_socket_id) - self.sv_linked_sockets[tree_id] = linked_sockets self.sv_linked_output_sockets[tree_id] = output_sockets self.sv_linked_input_sockets[tree_id] = input_sockets + self.sv_linked_inputted_nodes[tree_id] = inputted_nodes def use_link_memory(self): if self.configuring_new_node: @@ -233,71 +265,72 @@ class SvNodeTreeCommon(object): return tree_id = self.get_tree_id - links_has_changed = self.sv_links[tree_id] != self.links.items() - print('links_has_changed', links_has_changed) - reset_error_nodes(self) + new_sv_links = self.bl_links_to_sv_links() + links_has_changed = self.sv_links[tree_id] != new_sv_links + + # print('links_has_changed', links_has_changed) + # reset_error_nodes(self) if links_has_changed: affected_nodes = [] new_links = self.links.items() - linked_sockets = [] input_sockets = [] + inputted_nodes = [] output_sockets = [] - before_linked_sockets = self.sv_linked_sockets[tree_id] + before_input_sockets = self.sv_linked_input_sockets[tree_id] + before_inputted_nodes = self.sv_linked_inputted_nodes[tree_id] before_output_sockets = self.sv_linked_output_sockets[tree_id] - for link in new_links: - - input_sockets.append(link[1].to_socket) - output_sockets.append(link[1].from_socket) - linked_sockets.append((link[1].from_socket, link[1].to_socket)) - - if not (link[1].from_socket, link[1].to_socket) in before_linked_sockets: - if not link[1].from_socket in before_output_sockets: - if not link[1].from_node in affected_nodes: - affected_nodes.append(link[1].from_node) - if not link[1].to_node in affected_nodes: - affected_nodes.append(link[1].to_node) - # print("Affected Nodes:", [n.name for n in affected_nodes]) - for socket in before_input_sockets: - try: - name = socket.node.name - if not socket in input_sockets: - affected_nodes.append(socket.node) - except AttributeError: - pass - - self.sv_links[tree_id] = self.links.items() - self.sv_linked_sockets[tree_id] = linked_sockets + for sv_link in new_sv_links: + inputted_nodes.append(sv_link.to_node_id) + input_sockets.append(sv_link.to_socket_id) + output_sockets.append(sv_link.from_socket_id) + if not sv_link in self.sv_links[tree_id]: + if not sv_link.from_socket_id in before_output_sockets: + if not sv_link.from_node_id in affected_nodes: + affected_nodes.append(sv_link.from_node_id) + if not sv_link.to_node_id in affected_nodes: + affected_nodes.append(sv_link.to_node_id) + + + for node_id, socket in zip(before_inputted_nodes, before_input_sockets): + if not socket in input_sockets: + #if the node has been deleted it is not affected + if node_id in self.sv_node_dict[tree_id]: + affected_nodes.append(node_id) + + + self.sv_links[tree_id] = new_sv_links + self.sv_linked_inputted_nodes[tree_id] = inputted_nodes self.sv_linked_output_sockets[tree_id] = output_sockets self.sv_linked_input_sockets[tree_id] = input_sockets build_update_list(self) if affected_nodes: - process_from_nodes(affected_nodes) + node_list = [self.sv_node_dict[tree_id][node_id] for node_id in affected_nodes] + # print("Affected Nodes:", [n.name for n in node_list]) + process_from_nodes(node_list) return True else: return False else: - affected_groups = [] + affected_groups = [] for node in self.nodes: if 'SvGroupNode' in node.bl_idname: subtree = node.monad tree_id = subtree.get_tree_id fill_memory_is_ready = tree_id in subtree.sv_links.keys() if fill_memory_is_ready: - print("monad memory_is_ready") + # print("monad memory_is_ready") has_been_updated = subtree.use_link_memory() if has_been_updated: affected_groups.append(node) else: - print("filling monad link_memory") - # if subtree.sv_process: + # print("filling monad link_memory") + subtree.fill_links_memory() subtree.has_changed = True - has_been_updated = True - # self.has_link_count_changed node.process() - print(node.name) + if affected_groups: process_from_nodes(affected_groups) return True @@ -424,10 +457,10 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): tree_id = self.get_tree_id fill_memory_is_ready = tree_id in self.sv_links.keys() if fill_memory_is_ready: - print("memory_is_ready") + # print("memory_is_ready") has_been_updated = self.use_link_memory() else: - print("filling link_memory") + # print("filling link_memory") if self.sv_process: self.fill_links_memory() self.has_changed = True @@ -761,6 +794,16 @@ class SverchCustomTreeNode: def sv_init(self, context): self.create_sockets() + def load_in_node_dict(self): + # print('loading in node_dict') + self.n_id = str(hash(self) ^ hash(time.monotonic())) + tree = self.id_data + tree_id = tree.get_tree_id + + if tree_id not in tree.sv_node_dict: + tree.sv_node_dict[tree_id] = {} + tree.sv_node_dict[tree_id][self.n_id] = self + def init(self, context): """ this function is triggered upon node creation, @@ -774,7 +817,7 @@ class SverchCustomTreeNode: ng = self.id_data ng.freeze() - self.n_id = str(hash(self) ^ hash(time.monotonic())) + self.load_in_node_dict() if hasattr(self, "sv_init"): try: @@ -823,10 +866,12 @@ class SverchCustomTreeNode: This method is not supposed to be overriden in specific nodes. Override sv_copy() instead. """ + # self.n_id = str(hash(self) ^ hash(time.monotonic())) settings = get_original_node_color(self.id_data, original.name) if settings is not None: self.use_custom_color, self.color = settings self.sv_copy(original) + self.load_in_node_dict() def sv_copy(self, original): """ @@ -843,6 +888,7 @@ class SverchCustomTreeNode: self.sv_free() for s in self.outputs: s.sv_forget() + del self.id_data.sv_node_dict[self.id_data.get_tree_id][self.n_id] if hasattr(self, "has_3dview_props"): print("about to remove this node's props from Sv3DProps") try: -- GitLab From e5e394ce93040dfbb29708b9a3f42012ea9583eb Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Thu, 16 Apr 2020 21:45:22 +0200 Subject: [PATCH 15/43] keeping old node_ids --- node_tree.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/node_tree.py b/node_tree.py index e22b651ca..ae59d20bf 100644 --- a/node_tree.py +++ b/node_tree.py @@ -796,13 +796,14 @@ class SverchCustomTreeNode: def load_in_node_dict(self): # print('loading in node_dict') - self.n_id = str(hash(self) ^ hash(time.monotonic())) + # self.n_id = str(hash(self) ^ hash(time.monotonic())) + n_id = self.node_id tree = self.id_data tree_id = tree.get_tree_id if tree_id not in tree.sv_node_dict: tree.sv_node_dict[tree_id] = {} - tree.sv_node_dict[tree_id][self.n_id] = self + tree.sv_node_dict[tree_id][n_id] = self def init(self, context): """ @@ -871,6 +872,7 @@ class SverchCustomTreeNode: if settings is not None: self.use_custom_color, self.color = settings self.sv_copy(original) + self.n_id = "" self.load_in_node_dict() def sv_copy(self, original): -- GitLab From 082abd118fde5af7774d0144bb3aa97ab3c2750b Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Fri, 17 Apr 2020 22:24:54 +0200 Subject: [PATCH 16/43] get_tree_id to tree_id --- core/handlers.py | 4 ++-- core/socket_data.py | 12 ++++++------ core/sockets.py | 2 +- node_tree.py | 22 +++++++++++----------- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/core/handlers.py b/core/handlers.py index 78db94ae5..c066562b3 100644 --- a/core/handlers.py +++ b/core/handlers.py @@ -74,7 +74,7 @@ def sv_handler_undo_post(scene): links_changed = False for ng in sverchok_trees(): num_to_test_against += len(ng.nodes) - tree_id = ng.get_tree_id + tree_id = ng.tree_id if tree_id in ng.sv_links.keys(): links_changed = links_changed or ng.sv_links[tree_id] != ng.bl_links_to_sv_links() @@ -84,7 +84,7 @@ def sv_handler_undo_post(scene): print('looks like a node was removed, cleaning') sv_clean(scene) for ng in sverchok_trees(): - tree_id = ng.get_tree_id + tree_id = ng.tree_id if tree_id in ng.sv_node_dict: ng.sv_node_dict[tree_id]={} for node in ng.nodes: diff --git a/core/socket_data.py b/core/socket_data.py index 6e85bf114..14c070352 100644 --- a/core/socket_data.py +++ b/core/socket_data.py @@ -47,7 +47,7 @@ def sv_deep_copy(lst): def SvGetSocketInfo(socket): """returns string to show in socket label""" global socket_data_cache - ng = socket.id_data.get_tree_id + ng = socket.id_data.tree_id if socket.is_output: s_id = socket.socket_id @@ -75,7 +75,7 @@ def SvForgetSocket(socket): if not socket.is_linked: warning(f"{socket.node.name} forgetting unconncted socket: {socket.name}") s_id = socket.socket_id - s_ng = socket.id_data.get_tree_id + s_ng = socket.id_data.tree_id print("forgetting", socket) # if s_ng in socket_data_cache.keys(): try: @@ -92,7 +92,7 @@ def SvSetSocket(socket, out): if not socket.is_linked: warning(f"{socket.node.name} setting unconncted socket: {socket.name}") s_id = socket.socket_id - s_ng = socket.id_data.get_tree_id + s_ng = socket.id_data.tree_id if s_ng not in socket_data_cache: socket_data_cache[s_ng] = {} socket_data_cache[s_ng][s_id] = out @@ -108,7 +108,7 @@ def SvGetSocket(socket, deepcopy=True): if socket.is_linked: other = socket.other s_id = other.socket_id - s_ng = other.id_data.get_tree_id + s_ng = other.id_data.tree_id if s_ng not in socket_data_cache: raise LookupError if s_id in socket_data_cache[s_ng]: @@ -165,7 +165,7 @@ def get_output_socket_data(node, output_socket_name): global socket_data_cache - tree_name = node.id_data.get_tree_id + tree_name = node.id_data.tree_id socket = node.outputs[output_socket_name] socket_id = socket.socket_id if tree_name not in socket_data_cache: @@ -180,4 +180,4 @@ def reset_socket_cache(ng): Reset socket cache either for node group. """ global socket_data_cache - socket_data_cache[ng.get_tree_id] = {} + socket_data_cache[ng.tree_id] = {} diff --git a/core/sockets.py b/core/sockets.py index b6aab3919..f6c4b61aa 100644 --- a/core/sockets.py +++ b/core/sockets.py @@ -96,7 +96,7 @@ class SvSocketCommon: # return self.socket_id_m # return str(hash(self.id_data.name + self.node.name + self.identifier)) return str(hash(self.node.node_id + self.identifier)) - # return str(hash(self.id_data.get_tree_id + self.node.node_id + self.identifier)) + # return str(hash(self.id_data.tree_id + self.node.node_id + self.identifier)) @property def index(self): diff --git a/node_tree.py b/node_tree.py index ae59d20bf..d889661dc 100644 --- a/node_tree.py +++ b/node_tree.py @@ -163,12 +163,12 @@ class SvNodeTreeCommon(object): sv_linked_output_sockets = {} sv_linked_input_sockets = {} sv_linked_inputted_nodes = {} - tree_id: StringProperty(default="") + tree_id_memory: StringProperty(default="") @property - def get_tree_id(self): - if not self.tree_id: - self.tree_id = str(hash(self) ^ hash(time.monotonic())) - return self.tree_id + def tree_id(self): + if not self.tree_id_memory: + self.tree_id_memory = str(hash(self) ^ hash(time.monotonic())) + return self.tree_id_memory def build_update_list(self): build_update_list(self) @@ -236,7 +236,7 @@ class SvNodeTreeCommon(object): return sv_links def fill_links_memory(self): - tree_id = self.get_tree_id + tree_id = self.tree_id new_links = self.links.items() new_sv_links = self.bl_links_to_sv_links() self.sv_links[tree_id] = new_sv_links @@ -264,7 +264,7 @@ class SvNodeTreeCommon(object): if not self.sv_process: return - tree_id = self.get_tree_id + tree_id = self.tree_id new_sv_links = self.bl_links_to_sv_links() links_has_changed = self.sv_links[tree_id] != new_sv_links @@ -317,7 +317,7 @@ class SvNodeTreeCommon(object): for node in self.nodes: if 'SvGroupNode' in node.bl_idname: subtree = node.monad - tree_id = subtree.get_tree_id + tree_id = subtree.tree_id fill_memory_is_ready = tree_id in subtree.sv_links.keys() if fill_memory_is_ready: # print("monad memory_is_ready") @@ -454,7 +454,7 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): return # print('svtree update', self.timestamp) - tree_id = self.get_tree_id + tree_id = self.tree_id fill_memory_is_ready = tree_id in self.sv_links.keys() if fill_memory_is_ready: # print("memory_is_ready") @@ -799,7 +799,7 @@ class SverchCustomTreeNode: # self.n_id = str(hash(self) ^ hash(time.monotonic())) n_id = self.node_id tree = self.id_data - tree_id = tree.get_tree_id + tree_id = tree.tree_id if tree_id not in tree.sv_node_dict: tree.sv_node_dict[tree_id] = {} @@ -890,7 +890,7 @@ class SverchCustomTreeNode: self.sv_free() for s in self.outputs: s.sv_forget() - del self.id_data.sv_node_dict[self.id_data.get_tree_id][self.n_id] + del self.id_data.sv_node_dict[self.id_data.tree_id][self.n_id] if hasattr(self, "has_3dview_props"): print("about to remove this node's props from Sv3DProps") try: -- GitLab From 1867434b307ed97611fbf70df5123d1431b7e957 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Sat, 18 Apr 2020 17:54:45 +0200 Subject: [PATCH 17/43] refactoring use_link_memory --- node_tree.py | 141 ++++++++++++++++++++++++++++----------------------- 1 file changed, 77 insertions(+), 64 deletions(-) diff --git a/node_tree.py b/node_tree.py index d889661dc..750789903 100644 --- a/node_tree.py +++ b/node_tree.py @@ -149,6 +149,35 @@ def get_output_socket_id(socket): else: return socket.socket_id, socket.node.node_id +def get_new_linked_nodes(new_sv_links, before_sv_links, before_output_sockets): + affected_nodes = [] + for link in new_sv_links: + if not link in before_sv_links: + if not link.from_socket_id in before_output_sockets: + if not link.from_node_id in affected_nodes: + affected_nodes.append(link.from_node_id) + if not link.to_node_id in affected_nodes: + affected_nodes.append(link.to_node_id) + return affected_nodes + +def append_unlinked_nodes(before_inputted_nodes, before_input_sockets, input_sockets, affected_nodes, nodes_dict): + for node_id, socket in zip(before_inputted_nodes, before_input_sockets): + if not socket in input_sockets: + #if the node has been deleted it is not affected + if node_id in nodes_dict: + affected_nodes.append(node_id) + +def split_new_links_data(new_sv_links): + inputted_nodes = [] + input_sockets = [] + output_sockets = [] + for link in new_sv_links: + inputted_nodes.append(link.to_node_id) + input_sockets.append(link.to_socket_id) + output_sockets.append(link.from_socket_id) + + return inputted_nodes, input_sockets, output_sockets + class SvNodeTreeCommon(object): ''' Common methods shared between Sverchok node trees @@ -218,6 +247,7 @@ class SvNodeTreeCommon(object): if ng.bl_idname in {'SverchCustomTreeType', 'SverchGroupTreeType'}: res.append(ng) return res + def bl_links_to_sv_links(self): sv_links=[] @@ -241,96 +271,80 @@ class SvNodeTreeCommon(object): new_sv_links = self.bl_links_to_sv_links() self.sv_links[tree_id] = new_sv_links - inputted_nodes = [] - input_sockets = [] - output_sockets = [] - for sv_link in new_sv_links: - inputted_nodes.append(sv_link.to_node_id) - input_sockets.append(sv_link.to_socket_id) - output_sockets.append(sv_link.from_socket_id) - + inputted_nodes, input_sockets, output_sockets = split_new_links_data(new_sv_links) self.sv_linked_output_sockets[tree_id] = output_sockets self.sv_linked_input_sockets[tree_id] = input_sockets self.sv_linked_inputted_nodes[tree_id] = inputted_nodes - def use_link_memory(self): - if self.configuring_new_node: - # print('skipping global process during node init') - return - if self.is_frozen(): - # print('not processing: because self/tree.is_frozen') - return - if not self.sv_process: - return + def get_affected_groups(self): + affected_groups = [] + for node in self.nodes: + if 'SvGroupNode' in node.bl_idname: + subtree = node.monad + tree_id = subtree.tree_id + fill_memory_is_ready = tree_id in subtree.sv_links.keys() + if fill_memory_is_ready: + has_been_updated = subtree.use_link_memory() + else: + subtree.fill_links_memory() + subtree.has_changed = True + node.process() + has_been_updated = True + + if has_been_updated: + affected_groups.append(node) + return affected_groups + + def translate_node_id_to_node_name(self, affected_nodes): + tree_id = self.tree_id + return [self.sv_node_dict[tree_id][node_id] for node_id in affected_nodes if node_id in self.sv_node_dict[tree_id].keys()] + + + + def use_link_memory(self): + if self.configuring_new_node or self.is_frozen() or not self.sv_process: + return False tree_id = self.tree_id new_sv_links = self.bl_links_to_sv_links() - links_has_changed = self.sv_links[tree_id] != new_sv_links + before_sv_links = self.sv_links[tree_id] + links_has_changed = before_sv_links != new_sv_links - # print('links_has_changed', links_has_changed) - # reset_error_nodes(self) if links_has_changed: + affected_nodes = [] - new_links = self.links.items() - input_sockets = [] - inputted_nodes = [] - output_sockets = [] + new_inputted_nodes, new_input_sockets, new_output_sockets = split_new_links_data(new_sv_links) before_input_sockets = self.sv_linked_input_sockets[tree_id] before_inputted_nodes = self.sv_linked_inputted_nodes[tree_id] before_output_sockets = self.sv_linked_output_sockets[tree_id] - for sv_link in new_sv_links: - inputted_nodes.append(sv_link.to_node_id) - input_sockets.append(sv_link.to_socket_id) - output_sockets.append(sv_link.from_socket_id) - if not sv_link in self.sv_links[tree_id]: - if not sv_link.from_socket_id in before_output_sockets: - if not sv_link.from_node_id in affected_nodes: - affected_nodes.append(sv_link.from_node_id) - if not sv_link.to_node_id in affected_nodes: - affected_nodes.append(sv_link.to_node_id) - - for node_id, socket in zip(before_inputted_nodes, before_input_sockets): - if not socket in input_sockets: - #if the node has been deleted it is not affected - if node_id in self.sv_node_dict[tree_id]: - affected_nodes.append(node_id) + affected_nodes = get_new_linked_nodes(new_sv_links, before_sv_links, before_output_sockets) + append_unlinked_nodes( + before_inputted_nodes, + before_input_sockets, + new_input_sockets, + affected_nodes, + self.sv_node_dict[tree_id]) self.sv_links[tree_id] = new_sv_links - self.sv_linked_inputted_nodes[tree_id] = inputted_nodes - self.sv_linked_output_sockets[tree_id] = output_sockets - self.sv_linked_input_sockets[tree_id] = input_sockets + self.sv_linked_inputted_nodes[tree_id] = new_inputted_nodes + self.sv_linked_output_sockets[tree_id] = new_output_sockets + self.sv_linked_input_sockets[tree_id] = new_input_sockets build_update_list(self) + if affected_nodes: - node_list = [self.sv_node_dict[tree_id][node_id] for node_id in affected_nodes] - # print("Affected Nodes:", [n.name for n in node_list]) + node_list = self.translate_node_id_to_node_name(affected_nodes) process_from_nodes(node_list) return True else: return False else: - affected_groups = [] - for node in self.nodes: - if 'SvGroupNode' in node.bl_idname: - subtree = node.monad - tree_id = subtree.tree_id - fill_memory_is_ready = tree_id in subtree.sv_links.keys() - if fill_memory_is_ready: - # print("monad memory_is_ready") - has_been_updated = subtree.use_link_memory() - if has_been_updated: - affected_groups.append(node) - else: - # print("filling monad link_memory") - - subtree.fill_links_memory() - subtree.has_changed = True - node.process() + affected_groups = self.get_affected_groups() if affected_groups: process_from_nodes(affected_groups) return True @@ -795,8 +809,7 @@ class SverchCustomTreeNode: self.create_sockets() def load_in_node_dict(self): - # print('loading in node_dict') - # self.n_id = str(hash(self) ^ hash(time.monotonic())) + n_id = self.node_id tree = self.id_data tree_id = tree.tree_id -- GitLab From 1bbc65e09251087a85504335eaa312c0e818e334 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Sun, 19 Apr 2020 15:31:14 +0200 Subject: [PATCH 18/43] refactor to different files --- core/__init__.py | 9 +- core/handlers.py | 20 ++--- core/links.py | 190 +++++++++++++++++++++++++++++++++++++++++++ core/node_id_dict.py | 49 +++++++++++ core/sockets.py | 11 --- node_tree.py | 146 +++------------------------------ 6 files changed, 267 insertions(+), 158 deletions(-) create mode 100644 core/links.py create mode 100644 core/node_id_dict.py diff --git a/core/__init__.py b/core/__init__.py index 4bebe76bc..e8b9fab5f 100644 --- a/core/__init__.py +++ b/core/__init__.py @@ -10,7 +10,8 @@ root_modules = [ ] core_modules = [ - "monad_properties", "sv_custom_exceptions", "sockets", + "monad_properties", "sv_custom_exceptions", + "node_id_dict", "links", "sockets", "handlers", "update_system", "upgrade_nodes", "monad", "node_defaults" ] @@ -33,7 +34,7 @@ def sv_registration_utils(): pass -sv_registration_utils.register_all = sv_register_modules +sv_registration_utils.register_all = sv_register_modules sv_registration_utils.unregister_all = sv_unregister_modules @@ -110,9 +111,9 @@ def init_bookkeeping(sv_name): sverchok.data_structure.SVERCHOK_NAME = sv_name ascii_print.show_welcome() node_defaults.register_defaults() - auto_gather_node_classes() + auto_gather_node_classes() undo_handler_node_count = {} -undo_handler_node_count['sv_groups'] = 0 \ No newline at end of file +undo_handler_node_count['sv_groups'] = 0 diff --git a/core/handlers.py b/core/handlers.py index c066562b3..d0251fbee 100644 --- a/core/handlers.py +++ b/core/handlers.py @@ -8,6 +8,9 @@ from sverchok import data_structure from sverchok.core import upgrade_nodes, undo_handler_node_count from sverchok.core.update_system import sv_first_run, set_first_run import sverchok.core.update_system as us +from sverchok.core.links import sv_links_cache, bl_links_to_sv_links, empty_links_cache +from sverchok.core.node_id_dict import load_nodes_in_node_dict + from sverchok.ui import color_def, bgl_callback_nodeview, bgl_callback_3dview from sverchok.utils import app_handler_ops from sverchok.utils.logging import debug @@ -75,20 +78,17 @@ def sv_handler_undo_post(scene): for ng in sverchok_trees(): num_to_test_against += len(ng.nodes) tree_id = ng.tree_id - if tree_id in ng.sv_links.keys(): - links_changed = links_changed or ng.sv_links[tree_id] != ng.bl_links_to_sv_links() - + if tree_id in sv_links_cache: + links_changed = sv_links_cache[tree_id] != bl_links_to_sv_links(ng) + if links_changed: + break # only perform clean if the undo event triggered - # a difference in total node count among trees. + # a difference in total node count among trees or if links have changed. if links_changed or not (undo_handler_node_count['sv_groups'] == num_to_test_against): print('looks like a node was removed, cleaning') sv_clean(scene) for ng in sverchok_trees(): - tree_id = ng.tree_id - if tree_id in ng.sv_node_dict: - ng.sv_node_dict[tree_id]={} - for node in ng.nodes: - ng.sv_node_dict[tree_id][node.node_id] = node + load_nodes_in_node_dict(ng) ng.has_changed = True sv_main_handler(scene) undo_handler_node_count['sv_groups'] = 0 @@ -225,10 +225,10 @@ def sv_post_load(scene): if pref.apply_theme_on_open: color_def.apply_theme() + empty_links_cache() for ng in sv_trees: if ng.bl_idname == 'SverchCustomTreeType' and ng.nodes: - ng.sv_links = {} ng.update() diff --git a/core/links.py b/core/links.py new file mode 100644 index 000000000..9be6972da --- /dev/null +++ b/core/links.py @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# Declaring namedtuple() +import collections +from sverchok.core.update_system import ( + build_update_list, + process_from_nodes, + ) +from sverchok.core.node_id_dict import dict_of_node_tree, translate_node_id_to_node_name +SvLink = collections.namedtuple('SvLink', ['from_node_id', 'to_node_id', 'from_socket_id', 'to_socket_id']) + +sv_links_cache = {} +sv_linked_output_sockets_cache = {} +sv_linked_input_sockets_cache = {} +sv_linked_inputted_nodes_cache = {} + +def empty_links_cache(): + global sv_links_cache + sv_links_cache = {} + + +def link_cache_is_ready(node_tree): + return node_tree.tree_id in sv_links_cache + + +def get_output_socket_id(socket): + if socket.node.bl_idname == 'NodeReroute': + if socket.node.inputs[0].is_linked: + return get_output_socket_id(socket.node.inputs[0].links[0].from_socket) + else: + return None, None + else: + return socket.socket_id, socket.node.node_id + + +def get_new_linked_nodes(new_sv_links, before_sv_links, before_output_sockets): + affected_nodes = [] + for link in new_sv_links: + if not link in before_sv_links: + if not link.from_socket_id in before_output_sockets: + if not link.from_node_id in affected_nodes: + affected_nodes.append(link.from_node_id) + if not link.to_node_id in affected_nodes: + affected_nodes.append(link.to_node_id) + return affected_nodes + + +def get_new_unlinked_nodes(before_inputted_nodes, before_input_sockets, input_sockets, nodes_dict): + affected_nodes = [] + + for node_id, socket in zip(before_inputted_nodes, before_input_sockets): + if not socket in input_sockets: + #if the node has been deleted it is not affected + if node_id in nodes_dict: + affected_nodes.append(node_id) + + return affected_nodes + + +def split_new_links_data(new_sv_links): + inputted_nodes = [] + input_sockets = [] + output_sockets = [] + for link in new_sv_links: + inputted_nodes.append(link.to_node_id) + input_sockets.append(link.to_socket_id) + output_sockets.append(link.from_socket_id) + + return inputted_nodes, input_sockets, output_sockets + + +def bl_links_to_sv_links(node_tree): + + new_sv_links = [] + for link in node_tree.links: + if not link.to_socket.node.bl_idname == 'NodeReroute': + #recursive function to override reroutes + output_socket, output_node = get_output_socket_id(link.from_socket) + if output_socket: + sv_link = SvLink( + from_node_id=output_node, + to_node_id=link.to_socket.node.node_id, + from_socket_id=output_socket, + to_socket_id=link.to_socket.socket_id ) + new_sv_links.append(sv_link) + + return new_sv_links + + +def fill_links_memory(node_tree): + tree_id = node_tree.tree_id + new_sv_links = bl_links_to_sv_links(node_tree) + + inputted_nodes, input_sockets, output_sockets = split_new_links_data(new_sv_links) + + sv_links_cache[tree_id] = new_sv_links + sv_linked_output_sockets_cache[tree_id] = output_sockets + sv_linked_input_sockets_cache[tree_id] = input_sockets + sv_linked_inputted_nodes_cache[tree_id] = inputted_nodes + + +def get_affected_groups(node_tree): + affected_groups = [] + for node in node_tree.nodes: + if 'SvGroupNode' in node.bl_idname: + subtree = node.monad + tree_id = subtree.tree_id + fill_memory_is_ready = tree_id in sv_links_cache + if fill_memory_is_ready: + has_been_updated = use_link_memory(subtree) + else: + fill_links_memory(subtree) + subtree.has_changed = True + node.process() + has_been_updated = True + + if has_been_updated: + affected_groups.append(node) + return affected_groups + + +def use_link_memory(node_tree): + if node_tree.configuring_new_node or node_tree.is_frozen() or not node_tree.sv_process: + return False + + tree_id = node_tree.tree_id + new_sv_links = bl_links_to_sv_links(node_tree) + before_sv_links = sv_links_cache[tree_id] + links_has_changed = before_sv_links != new_sv_links + + if links_has_changed: + + affected_nodes = [] + + new_inputted_nodes, new_input_sockets, new_output_sockets = split_new_links_data(new_sv_links) + before_input_sockets = sv_linked_input_sockets_cache[tree_id] + before_inputted_nodes = sv_linked_inputted_nodes_cache[tree_id] + before_output_sockets = sv_linked_output_sockets_cache[tree_id] + + new_linked_nodes = get_new_linked_nodes( + new_sv_links, + before_sv_links, + before_output_sockets) + + new_unlinked_linked_nodes = get_new_unlinked_nodes( + before_inputted_nodes, + before_input_sockets, + new_input_sockets, + dict_of_node_tree(node_tree) + ) + affected_nodes = new_linked_nodes + new_unlinked_linked_nodes + + sv_links_cache[tree_id] = new_sv_links + sv_linked_inputted_nodes_cache[tree_id] = new_inputted_nodes + sv_linked_output_sockets_cache[tree_id] = new_output_sockets + sv_linked_input_sockets_cache[tree_id] = new_input_sockets + + build_update_list(node_tree) + + if affected_nodes: + node_list = translate_node_id_to_node_name(node_tree, affected_nodes) + process_from_nodes(node_list) + return True + else: + return False + else: + + affected_groups = get_affected_groups(node_tree) + if affected_groups: + process_from_nodes(affected_groups) + return True + else: + return False diff --git a/core/node_id_dict.py b/core/node_id_dict.py new file mode 100644 index 000000000..0f9161308 --- /dev/null +++ b/core/node_id_dict.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +sv_node_dict_cache = {} + +def translate_node_id_to_node_name(node_tree, affected_nodes): + tree_id = node_tree.tree_id + return [sv_node_dict_cache[tree_id][node_id] for node_id in affected_nodes if node_id in sv_node_dict_cache[tree_id]] + +def load_in_node_dict(node): + + n_id = node.node_id + tree = node.id_data + tree_id = node.id_data.tree_id + + if tree_id not in sv_node_dict_cache: + sv_node_dict_cache[tree_id] = {} + sv_node_dict_cache[tree_id][n_id] = node + +def delete_from_node_dict(node): + n_id = node.node_id + tree_id = node.id_data.tree_id + del sv_node_dict_cache[tree_id][n_id] + +def load_nodes_in_node_dict(node_tree): + tree_id = node_tree.tree_id + if tree_id in sv_node_dict_cache: + sv_node_dict_cache[tree_id] = {} + for node in node_tree.nodes: + sv_node_dict_cache[tree_id][node.node_id] = node + +def dict_of_node_tree(node_tree): + return sv_node_dict_cache[node_tree.tree_id] diff --git a/core/sockets.py b/core/sockets.py index c3046377f..ffa97eb54 100644 --- a/core/sockets.py +++ b/core/sockets.py @@ -93,17 +93,7 @@ class SvSocketCommon: @property def socket_id(self): """Id of socket used by data_cache""" - # if not self.socket_id_m: - # try: - # self.socket_id_m = str(hash(self) ^ hash(time.monotonic())) - # except: - # return str(hash(self) ^ hash(time.monotonic())) - # self.socket_id_m.set(str(hash(self) ^ hash(time.monotonic()))) - # self.set("socket_id_m", str(hash(self) ^ hash(time.monotonic()))) - # return self.socket_id_m - # return str(hash(self.id_data.name + self.node.name + self.identifier)) return str(hash(self.node.node_id + self.identifier)) - # return str(hash(self.id_data.tree_id + self.node.node_id + self.identifier)) @property def index(self): @@ -738,4 +728,3 @@ classes = [ ] register, unregister = bpy.utils.register_classes_factory(classes) - diff --git a/node_tree.py b/node_tree.py index 750789903..5786e0bd6 100644 --- a/node_tree.py +++ b/node_tree.py @@ -42,6 +42,12 @@ from sverchok.core.update_system import ( sv_first_run, get_first_run, reset_error_nodes) +from sverchok.core.links import ( + fill_links_memory, + use_link_memory, + link_cache_is_ready) +from sverchok.core.node_id_dict import load_in_node_dict, delete_from_node_dict + from sverchok.core.socket_conversions import DefaultImplicitConversionPolicy from sverchok.core.socket_data import socket_data_cache @@ -187,11 +193,6 @@ class SvNodeTreeCommon(object): limited_init: BoolProperty(default=False) skip_tree_update: BoolProperty(default=False) configuring_new_node: BoolProperty(name="indicate node initialization", default=False) - sv_node_dict = {} - sv_links = {} - sv_linked_output_sockets = {} - sv_linked_input_sockets = {} - sv_linked_inputted_nodes = {} tree_id_memory: StringProperty(default="") @property def tree_id(self): @@ -248,109 +249,6 @@ class SvNodeTreeCommon(object): res.append(ng) return res - def bl_links_to_sv_links(self): - - sv_links=[] - for link in self.links.items(): - if not link[1].to_socket.node.bl_idname == 'NodeReroute': - #recursive function to override reroutes - output_socket, output_node = get_output_socket_id(link[1].from_socket) - if output_socket: - sv_link = Sv_Link( - from_node_id=output_node, - to_node_id=link[1].to_socket.node.node_id, - from_socket_id=output_socket, - to_socket_id=link[1].to_socket.socket_id ) - sv_links.append(sv_link) - # sv_links.append((output_socket, link[1].to_socket.socket_id)) - return sv_links - - def fill_links_memory(self): - tree_id = self.tree_id - new_links = self.links.items() - new_sv_links = self.bl_links_to_sv_links() - self.sv_links[tree_id] = new_sv_links - - inputted_nodes, input_sockets, output_sockets = split_new_links_data(new_sv_links) - self.sv_linked_output_sockets[tree_id] = output_sockets - self.sv_linked_input_sockets[tree_id] = input_sockets - self.sv_linked_inputted_nodes[tree_id] = inputted_nodes - - - def get_affected_groups(self): - affected_groups = [] - for node in self.nodes: - if 'SvGroupNode' in node.bl_idname: - subtree = node.monad - tree_id = subtree.tree_id - fill_memory_is_ready = tree_id in subtree.sv_links.keys() - if fill_memory_is_ready: - has_been_updated = subtree.use_link_memory() - else: - subtree.fill_links_memory() - subtree.has_changed = True - node.process() - has_been_updated = True - - if has_been_updated: - affected_groups.append(node) - return affected_groups - - def translate_node_id_to_node_name(self, affected_nodes): - tree_id = self.tree_id - return [self.sv_node_dict[tree_id][node_id] for node_id in affected_nodes if node_id in self.sv_node_dict[tree_id].keys()] - - - - def use_link_memory(self): - if self.configuring_new_node or self.is_frozen() or not self.sv_process: - return False - - tree_id = self.tree_id - new_sv_links = self.bl_links_to_sv_links() - before_sv_links = self.sv_links[tree_id] - links_has_changed = before_sv_links != new_sv_links - - if links_has_changed: - - affected_nodes = [] - - new_inputted_nodes, new_input_sockets, new_output_sockets = split_new_links_data(new_sv_links) - before_input_sockets = self.sv_linked_input_sockets[tree_id] - before_inputted_nodes = self.sv_linked_inputted_nodes[tree_id] - before_output_sockets = self.sv_linked_output_sockets[tree_id] - - affected_nodes = get_new_linked_nodes(new_sv_links, before_sv_links, before_output_sockets) - - append_unlinked_nodes( - before_inputted_nodes, - before_input_sockets, - new_input_sockets, - affected_nodes, - self.sv_node_dict[tree_id]) - - self.sv_links[tree_id] = new_sv_links - self.sv_linked_inputted_nodes[tree_id] = new_inputted_nodes - self.sv_linked_output_sockets[tree_id] = new_output_sockets - self.sv_linked_input_sockets[tree_id] = new_input_sockets - - build_update_list(self) - - if affected_nodes: - node_list = self.translate_node_id_to_node_name(affected_nodes) - process_from_nodes(node_list) - return True - else: - return False - else: - - affected_groups = self.get_affected_groups() - if affected_groups: - process_from_nodes(affected_groups) - return True - else: - return False - class SvGenericUITooltipOperator(bpy.types.Operator): arg: StringProperty() bl_idname = "node.sv_generic_ui_tooltip" @@ -450,9 +348,6 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): self.tree_link_count = link_count return True - - - def update(self): ''' Tags tree for update for handle @@ -467,18 +362,12 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): # print('throttled update from context manager') return - # print('svtree update', self.timestamp) - tree_id = self.tree_id - fill_memory_is_ready = tree_id in self.sv_links.keys() - if fill_memory_is_ready: - # print("memory_is_ready") - has_been_updated = self.use_link_memory() + if link_cache_is_ready(self): + use_link_memory(self) else: - # print("filling link_memory") if self.sv_process: - self.fill_links_memory() + fill_links_memory(self) self.has_changed = True - # self.has_link_count_changed self.process() def process_ani(self): @@ -808,16 +697,6 @@ class SverchCustomTreeNode: def sv_init(self, context): self.create_sockets() - def load_in_node_dict(self): - - n_id = self.node_id - tree = self.id_data - tree_id = tree.tree_id - - if tree_id not in tree.sv_node_dict: - tree.sv_node_dict[tree_id] = {} - tree.sv_node_dict[tree_id][n_id] = self - def init(self, context): """ this function is triggered upon node creation, @@ -831,7 +710,7 @@ class SverchCustomTreeNode: ng = self.id_data ng.freeze() - self.load_in_node_dict() + load_in_node_dict(self) if hasattr(self, "sv_init"): try: @@ -886,7 +765,7 @@ class SverchCustomTreeNode: self.use_custom_color, self.color = settings self.sv_copy(original) self.n_id = "" - self.load_in_node_dict() + load_in_node_dict(self) def sv_copy(self, original): """ @@ -903,7 +782,8 @@ class SverchCustomTreeNode: self.sv_free() for s in self.outputs: s.sv_forget() - del self.id_data.sv_node_dict[self.id_data.tree_id][self.n_id] + delete_from_node_dict(self) + if hasattr(self, "has_3dview_props"): print("about to remove this node's props from Sv3DProps") try: -- GitLab From 199c96c2a7078be962134c1a8e6a011d3e18e0fe Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Mon, 20 Apr 2020 19:10:08 +0200 Subject: [PATCH 19/43] some renaming and test-fixing --- core/update_system.py | 2 +- node_tree.py | 4 ++-- utils/testing.py | 19 +++++++++---------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/core/update_system.py b/core/update_system.py index 4a370ff00..f8e3d9522 100644 --- a/core/update_system.py +++ b/core/update_system.py @@ -40,7 +40,7 @@ sv_first_run = True def set_first_run(value): global sv_first_run sv_first_run = value -def get_first_run(): +def is_first_run(): global sv_first_run return sv_first_run def update_error_colors(self, context): diff --git a/node_tree.py b/node_tree.py index 5786e0bd6..e15485122 100644 --- a/node_tree.py +++ b/node_tree.py @@ -40,7 +40,7 @@ from sverchok.core.update_system import ( get_update_lists, update_error_nodes, get_original_node_color, sv_first_run, - get_first_run, + is_first_run, reset_error_nodes) from sverchok.core.links import ( fill_links_memory, @@ -356,7 +356,7 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): # this is a no-op if there's no drawing clear_exception_drawing_with_bgl(self.nodes) - if get_first_run(): + if is_first_run(): return if self.skip_tree_update: # print('throttled update from context manager') diff --git a/utils/testing.py b/utils/testing.py index 3c8abb52e..6d5e7ba29 100644 --- a/utils/testing.py +++ b/utils/testing.py @@ -53,7 +53,7 @@ def generate_node_definition(node): tree = get_or_create_node_tree() node = create_node("{}", tree.name) """.format(node.bl_idname) - + for k, v in node.items(): result += "node.{} = {}\n".format(k, v) @@ -187,7 +187,7 @@ def run_all_tests(pattern=None): Run all existing test cases. Test cases are looked up under tests/ directory. """ - + if pattern is None: pattern = "*_tests.py" @@ -357,7 +357,7 @@ class SverchokTestCase(unittest.TestCase): for k, v in actual.items(): if k not in reference: raise AssertionError("Property `{}' is present is actual node {}, but is not present in reference".format(k, actual)) - if v != reference[k]: + if v != reference[k] and k !='n_id': raise AssertionError("Property `{}' has value `{}' in actual node {}, but in reference it has value `{}'".format(k, v, actual, reference[k])) for k in reference.keys(): @@ -389,7 +389,7 @@ class SverchokTestCase(unittest.TestCase): shape = list(arr1.shape) def compare(prev_indicies): - step = len(prev_indicies) + step = len(prev_indicies) if step == arr1.ndim: ind = tuple(prev_indicies) if precision is None: @@ -418,7 +418,7 @@ class SverchokTestCase(unittest.TestCase): level2 = get_data_nesting_level(data2) if level1 != level2: raise AssertionError("Nesting level of 1st data {} != nesting level of 2nd data {}".format(level1, level2)) - + def do_assert(d1, d2, idxs): if precision is not None: d1 = round(d1, precision) @@ -456,7 +456,7 @@ class SverchokTestCase(unittest.TestCase): #info("Expected data: %s", expected_data) self.assert_sverchok_data_equal(data, expected_data, precision=precision) #self.assertEquals(data, expected_data) - + @contextmanager def assert_prints_stdout(self, regexp): """ @@ -579,7 +579,7 @@ class ReferenceTreeTestCase(SverchokTestCase): raise Exception("ReferenceTreeTestCase subclass must have `reference_file_name' set") if self.reference_tree_name is None: self.reference_tree_name = "TestingTree" - + with self.assert_logs_no_errors(): self.tree = self.link_node_tree() @@ -619,7 +619,7 @@ class NodeProcessTestCase(EmptyTreeTestCase): return get_output_socket_data(self.node, output_name) except SvNoDataError: return None - + def assert_output_data_equals(self, output_name, expected_data, message=None): """ Assert that tested node has written expected_data to @@ -690,7 +690,7 @@ def make_skip_decorator(condition, message): # Here go decorators used to mark test to be executed only in certain conditions. # Example usage: -# +# # @manual_only # def test_something(self): # # This test will not be running on Travis CI, only in manual mode. @@ -856,4 +856,3 @@ if __name__ == "__main__": except Exception as e: print(e) sys.exit(1) - -- GitLab From a520a8972926e668a8316778f7ae277915a43b8c Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Mon, 20 Apr 2020 19:23:19 +0200 Subject: [PATCH 20/43] updating travis to 2.82 --- .travis.yml | 7 +++---- utils/testing.py | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index c660f1640..7f8871361 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,8 +11,8 @@ install: #set -x #set -e if [ $TRAVIS_BRANCH = "master" ] - then BLENDER_VERSION=2.80 - BLENDER_URL=https://ftp.nluug.nl/pub/graphics/blender/release/Blender2.80/blender-2.80-linux-glibc217-x86_64.tar.bz2 + then BLENDER_VERSION=2.82 + BLENDER_URL=https://ftp.nluug.nl/pub/graphics/blender/release/Blender2.82/blender-2.82a-linux64.tar.xz SVERCHOK_DIR=scripts/addons_contrib/sverchok else BLENDER_VERSION=2.79 BLENDER_URL=https://download.blender.org/release/Blender2.79/blender-2.79b-linux-glibc219-x86_64.tar.bz2 @@ -21,7 +21,7 @@ install: BLENDER_TAR=$(basename $BLENDER_URL) BLENDER_DIR=$(basename $BLENDER_URL .tar.bz2) if [ ! -f installation/blender/blender ] - then + then mkdir -p installation cd installation wget $BLENDER_URL @@ -73,4 +73,3 @@ deploy: cache: directories: - ${PWD}/installation - diff --git a/utils/testing.py b/utils/testing.py index 6d5e7ba29..b55e76818 100644 --- a/utils/testing.py +++ b/utils/testing.py @@ -357,7 +357,7 @@ class SverchokTestCase(unittest.TestCase): for k, v in actual.items(): if k not in reference: raise AssertionError("Property `{}' is present is actual node {}, but is not present in reference".format(k, actual)) - if v != reference[k] and k !='n_id': + if v != reference[k] and k != 'n_id': raise AssertionError("Property `{}' has value `{}' in actual node {}, but in reference it has value `{}'".format(k, v, actual, reference[k])) for k in reference.keys(): -- GitLab From 5115d24bedfe4a6450a8c10d55cc17f7e3f50dd3 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Mon, 20 Apr 2020 20:23:55 +0200 Subject: [PATCH 21/43] lets try again --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7f8871361..48472f9fa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ install: if [ $TRAVIS_BRANCH = "master" ] then BLENDER_VERSION=2.82 BLENDER_URL=https://ftp.nluug.nl/pub/graphics/blender/release/Blender2.82/blender-2.82a-linux64.tar.xz - SVERCHOK_DIR=scripts/addons_contrib/sverchok + SVERCHOK_DIR=scripts/addons/sverchok else BLENDER_VERSION=2.79 BLENDER_URL=https://download.blender.org/release/Blender2.79/blender-2.79b-linux-glibc219-x86_64.tar.bz2 SVERCHOK_DIR=scripts/addons/sverchok -- GitLab From da546d5c526023f4965a845c776a7f7952ed9ded Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Mon, 20 Apr 2020 20:42:02 +0200 Subject: [PATCH 22/43] maybe like this? --- .travis.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 48472f9fa..bf63e3574 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,12 +14,15 @@ install: then BLENDER_VERSION=2.82 BLENDER_URL=https://ftp.nluug.nl/pub/graphics/blender/release/Blender2.82/blender-2.82a-linux64.tar.xz SVERCHOK_DIR=scripts/addons/sverchok + BLENDER_TAR=$(basename $BLENDER_URL) + BLENDER_DIR=$(basename $BLENDER_URL .tar.xz) else BLENDER_VERSION=2.79 BLENDER_URL=https://download.blender.org/release/Blender2.79/blender-2.79b-linux-glibc219-x86_64.tar.bz2 SVERCHOK_DIR=scripts/addons/sverchok + BLENDER_TAR=$(basename $BLENDER_URL) + BLENDER_DIR=$(basename $BLENDER_URL .tar.bz2) fi - BLENDER_TAR=$(basename $BLENDER_URL) - BLENDER_DIR=$(basename $BLENDER_URL .tar.bz2) + if [ ! -f installation/blender/blender ] then mkdir -p installation -- GitLab From 7f6a25c3b261fce910b586a380fec50779af29ac Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Wed, 22 Apr 2020 01:13:29 +0200 Subject: [PATCH 23/43] moving links cache to class nd refactoring --- core/handlers.py | 21 ++++--- core/links.py | 127 ++++++++++++++++++++++++++++++++++++------ core/node_id_dict.py | 17 +++++- core/update_system.py | 4 ++ node_tree.py | 62 ++++++++++++++++++--- 5 files changed, 196 insertions(+), 35 deletions(-) diff --git a/core/handlers.py b/core/handlers.py index d0251fbee..96a0462a6 100644 --- a/core/handlers.py +++ b/core/handlers.py @@ -8,7 +8,7 @@ from sverchok import data_structure from sverchok.core import upgrade_nodes, undo_handler_node_count from sverchok.core.update_system import sv_first_run, set_first_run import sverchok.core.update_system as us -from sverchok.core.links import sv_links_cache, bl_links_to_sv_links, empty_links_cache +# from sverchok.core.links import empty_links_cache from sverchok.core.node_id_dict import load_nodes_in_node_dict from sverchok.ui import color_def, bgl_callback_nodeview, bgl_callback_3dview @@ -77,11 +77,15 @@ def sv_handler_undo_post(scene): links_changed = False for ng in sverchok_trees(): num_to_test_against += len(ng.nodes) - tree_id = ng.tree_id - if tree_id in sv_links_cache: - links_changed = sv_links_cache[tree_id] != bl_links_to_sv_links(ng) - if links_changed: - break + # tree_id = ng.tree_id + ng.update_sv_links() + links_changed = ng.links_have_changed() + if links_changed: + break + # if tree_id in sv_links_cache: + # links_changed = sv_links_cache[tree_id] != bl_links_to_sv_links(ng) + # if self.links_have_changed(): + # break # only perform clean if the undo event triggered # a difference in total node count among trees or if links have changed. if links_changed or not (undo_handler_node_count['sv_groups'] == num_to_test_against): @@ -198,6 +202,7 @@ def sv_post_load(scene): for monad in (ng for ng in bpy.data.node_groups if ng.bl_idname == 'SverchGroupTreeType'): if monad.input_node and monad.output_node: + load_nodes_in_node_dict(monad) monad.update_cls() sv_types = {'SverchCustomTreeType', 'SverchGroupTreeType'} @@ -216,7 +221,7 @@ def sv_post_load(scene): except: traceback.print_exc() ng.unfreeze(True) - + # load_nodes_in_node_dict(ng) ng.sv_process = True addon_name = data_structure.SVERCHOK_NAME addon = bpy.context.preferences.addons.get(addon_name) @@ -225,7 +230,7 @@ def sv_post_load(scene): if pref.apply_theme_on_open: color_def.apply_theme() - empty_links_cache() + # empty_links_cache() for ng in sv_trees: if ng.bl_idname == 'SverchCustomTreeType' and ng.nodes: diff --git a/core/links.py b/core/links.py index 9be6972da..df4be48a7 100644 --- a/core/links.py +++ b/core/links.py @@ -19,21 +19,116 @@ # Declaring namedtuple() import collections +from typing import NamedTuple from sverchok.core.update_system import ( build_update_list, process_from_nodes, ) from sverchok.core.node_id_dict import dict_of_node_tree, translate_node_id_to_node_name SvLink = collections.namedtuple('SvLink', ['from_node_id', 'to_node_id', 'from_socket_id', 'to_socket_id']) +class SvLink(NamedTuple): + from_node_id: str + to_node_id: str + from_socket_id: str + to_socket_id: str + @classmethod + def init_from_link(cls, link): + output_socket, output_node = get_output_socket_id(link.from_socket) + sv_link = cls( + from_node_id=output_node, + to_node_id=link.to_socket.node.node_id, + from_socket_id=output_socket, + to_socket_id=link.to_socket.socket_id ) + return sv_link + +# sv_links_new = {} +# sv_links_cache = {} +# output_sockets_cache = {} +# input_sockets_cache = {} +# inputted_nodes_cache = {} +# output_sockets_new = dict() +# input_sockets_new = dict() +# sv_linked_inputted_nodes_new = dict() +class SvLinks: + sv_links_new = {} + sv_links_cache = {} + output_sockets_cache = {} + input_sockets_cache = {} + inputted_nodes_cache = {} + output_sockets_new = dict() + input_sockets_new = dict() + inputted_nodes_new = dict() + + @classmethod + def get(cls, node_tree): + return cls.sv_links[node_tree] + + def start_dictionaries(self, tree_id): + self.sv_links_new[tree_id] = dict() + self.sv_links_cache[tree_id] = dict() + self.output_sockets_new[tree_id] = dict() + self.input_sockets_new[tree_id] = dict() + self.inputted_nodes_new[tree_id] = dict() + self.output_sockets_cache[tree_id] = dict() + self.input_sockets_cache[tree_id] = dict() + self.inputted_nodes_cache[tree_id] = dict() + + + def create_new_links(self, node_tree): + tree_id = node_tree.tree_id + if not node_tree.tree_id in self.sv_links_new: + self.start_dictionaries(node_tree.tree_id) + new_sv_links = bl_links_to_sv_links(node_tree) + self.sv_links_new[tree_id] = new_sv_links + new_inputted_nodes, new_input_sockets, new_output_sockets = split_new_links_data(new_sv_links) + self.output_sockets_new[tree_id] = new_output_sockets + self.input_sockets_new[tree_id] = new_input_sockets + self.inputted_nodes_new[tree_id] = new_inputted_nodes -sv_links_cache = {} -sv_linked_output_sockets_cache = {} -sv_linked_input_sockets_cache = {} -sv_linked_inputted_nodes_cache = {} -def empty_links_cache(): - global sv_links_cache - sv_links_cache = {} + def links_have_changed(self, node_tree): + return self.sv_links_new[node_tree.tree_id] != self.sv_links_cache[node_tree.tree_id] + + def store_links_cache(self, node_tree): + tree_id = node_tree.tree_id + self.sv_links_cache[node_tree.tree_id] = self.sv_links_new[node_tree.tree_id] + self.output_sockets_cache[tree_id] = self.output_sockets_new[tree_id] + self.input_sockets_cache[tree_id] = self.input_sockets_new[tree_id] + self.inputted_nodes_cache[tree_id] = self.inputted_nodes_new[tree_id] + + # @classmethod + # def get_new_linked_nodes(cls, tree_id): + + def get_nodes(self, node_tree): + tree_id = node_tree.tree_id + new_sv_links = self.sv_links_new[tree_id] + before_sv_links = self.sv_links_cache[tree_id] + # print(self.sv_links_cache[tree_id]) + if (self.sv_links_cache[tree_id]): + return node_tree.nodes + + affected_nodes = [] + + new_linked_nodes = get_new_linked_nodes( + new_sv_links, + before_sv_links, + self.output_sockets_cache[tree_id]) + + new_unlinked_linked_nodes = get_new_unlinked_nodes( + self.inputted_nodes_cache[tree_id], + self.input_sockets_cache[tree_id], + self.input_sockets_new[tree_id], + dict_of_node_tree(node_tree) + ) + affected_nodes = new_linked_nodes + new_unlinked_linked_nodes + node_list = translate_node_id_to_node_name(node_tree, affected_nodes) + print(node_list) + return node_list + # return get_nodes(node_tree) + +# def empty_links_cache(): +# global sv_links_cache +# sv_links_cache = {} def link_cache_is_ready(node_tree): @@ -111,9 +206,9 @@ def fill_links_memory(node_tree): inputted_nodes, input_sockets, output_sockets = split_new_links_data(new_sv_links) sv_links_cache[tree_id] = new_sv_links - sv_linked_output_sockets_cache[tree_id] = output_sockets - sv_linked_input_sockets_cache[tree_id] = input_sockets - sv_linked_inputted_nodes_cache[tree_id] = inputted_nodes + output_sockets_cache[tree_id] = output_sockets + input_sockets_cache[tree_id] = input_sockets + inputted_nodes_cache[tree_id] = inputted_nodes def get_affected_groups(node_tree): @@ -150,9 +245,9 @@ def use_link_memory(node_tree): affected_nodes = [] new_inputted_nodes, new_input_sockets, new_output_sockets = split_new_links_data(new_sv_links) - before_input_sockets = sv_linked_input_sockets_cache[tree_id] - before_inputted_nodes = sv_linked_inputted_nodes_cache[tree_id] - before_output_sockets = sv_linked_output_sockets_cache[tree_id] + before_input_sockets = input_sockets_cache[tree_id] + before_inputted_nodes = inputted_nodes_cache[tree_id] + before_output_sockets = output_sockets_cache[tree_id] new_linked_nodes = get_new_linked_nodes( new_sv_links, @@ -168,9 +263,9 @@ def use_link_memory(node_tree): affected_nodes = new_linked_nodes + new_unlinked_linked_nodes sv_links_cache[tree_id] = new_sv_links - sv_linked_inputted_nodes_cache[tree_id] = new_inputted_nodes - sv_linked_output_sockets_cache[tree_id] = new_output_sockets - sv_linked_input_sockets_cache[tree_id] = new_input_sockets + inputted_nodes_cache[tree_id] = new_inputted_nodes + output_sockets_cache[tree_id] = new_output_sockets + input_sockets_cache[tree_id] = new_input_sockets build_update_list(node_tree) diff --git a/core/node_id_dict.py b/core/node_id_dict.py index 0f9161308..dd7188ed6 100644 --- a/core/node_id_dict.py +++ b/core/node_id_dict.py @@ -39,11 +39,22 @@ def delete_from_node_dict(node): del sv_node_dict_cache[tree_id][n_id] def load_nodes_in_node_dict(node_tree): + print('loading_nodes_in_nodetree', node_tree.tree_id) tree_id = node_tree.tree_id - if tree_id in sv_node_dict_cache: - sv_node_dict_cache[tree_id] = {} - for node in node_tree.nodes: + # if tree_id in sv_node_dict_cache: + sv_node_dict_cache[tree_id] = {} + for node in node_tree.nodes: + try: + + # if node.bl_idname != 'NodeReroute': sv_node_dict_cache[tree_id][node.node_id] = node + except AttributeError: + pass + # print(node.bl_idname) + # print(sv_node_dict_cache[tree_id]) def dict_of_node_tree(node_tree): + print(node_tree.tree_id in sv_node_dict_cache) + if not node_tree.tree_id in sv_node_dict_cache: + load_nodes_in_node_dict(node_tree) return sv_node_dict_cache[node_tree.tree_id] diff --git a/core/update_system.py b/core/update_system.py index f8e3d9522..06c6038a6 100644 --- a/core/update_system.py +++ b/core/update_system.py @@ -448,6 +448,10 @@ def process_to_node(node): def process_from_nodes(nodes): + + if not nodes: + return + node_names = [node.name for node in nodes] ng = nodes[0].id_data update_list = make_tree_from_nodes(node_names, ng) diff --git a/node_tree.py b/node_tree.py index e15485122..3607c037b 100644 --- a/node_tree.py +++ b/node_tree.py @@ -45,7 +45,8 @@ from sverchok.core.update_system import ( from sverchok.core.links import ( fill_links_memory, use_link_memory, - link_cache_is_ready) + link_cache_is_ready, + SvLinks) from sverchok.core.node_id_dict import load_in_node_dict, delete_from_node_dict @@ -194,6 +195,7 @@ class SvNodeTreeCommon(object): skip_tree_update: BoolProperty(default=False) configuring_new_node: BoolProperty(name="indicate node initialization", default=False) tree_id_memory: StringProperty(default="") + sv_links = SvLinks() @property def tree_id(self): if not self.tree_id_memory: @@ -248,6 +250,34 @@ class SvNodeTreeCommon(object): if ng.bl_idname in {'SverchCustomTreeType', 'SverchGroupTreeType'}: res.append(ng) return res + def update_sv_links(self): + self.sv_links.create_new_links(self) + def links_have_changed(self): + return self.sv_links.links_have_changed(self) + def store_links_cache(self): + self.sv_links.store_links_cache(self) + def get_nodes(self): + return self.sv_links.get_nodes(self) + def get_groups(self): + affected_groups =[] + for node in self.nodes: + if 'SvGroupNode' in node.bl_idname: + sub_tree = node.monad + sub_tree.sv_update() + if sub_tree.has_changed: + affected_groups.append(node) + sub_tree.has_changed = False + return affected_groups + + def sv_update(self): + self.update_sv_links() + if self.links_have_changed(): + self.has_changed = True + build_update_list(self) + process_from_nodes(self.get_nodes()) + self.store_links_cache() + else: + process_from_nodes(self.get_groups()) class SvGenericUITooltipOperator(bpy.types.Operator): arg: StringProperty() @@ -348,6 +378,8 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): self.tree_link_count = link_count return True + + def update(self): ''' Tags tree for update for handle @@ -361,14 +393,28 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): if self.skip_tree_update: # print('throttled update from context manager') return + if self.configuring_new_node or self.is_frozen() or not self.sv_process: + return - if link_cache_is_ready(self): - use_link_memory(self) - else: - if self.sv_process: - fill_links_memory(self) - self.has_changed = True - self.process() + self.sv_update() + self.has_changed = False + # self.update_sv_links() + # print(self.links_have_changed()) + # # self.store_links_cache() + # if self.links_have_changed(): + # build_update_list(self) + # print(00) + # process_from_nodes(self.get_nodes()) + # self.store_links_cache() + # elif + + # if link_cache_is_ready(self): + # use_link_memory(self) + # else: + # if self.sv_process: + # fill_links_memory(self) + # self.has_changed = True + # self.process() def process_ani(self): """ -- GitLab From 401ac598421e43226214ddc3b3f3539a59d58df2 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Wed, 22 Apr 2020 18:33:28 +0200 Subject: [PATCH 24/43] more classing --- core/handlers.py | 7 +- core/links.py | 148 +++++++++---------------------------------- core/node_id_dict.py | 6 +- node_tree.py | 25 ++------ 4 files changed, 37 insertions(+), 149 deletions(-) diff --git a/core/handlers.py b/core/handlers.py index 96a0462a6..1f395fe03 100644 --- a/core/handlers.py +++ b/core/handlers.py @@ -82,12 +82,7 @@ def sv_handler_undo_post(scene): links_changed = ng.links_have_changed() if links_changed: break - # if tree_id in sv_links_cache: - # links_changed = sv_links_cache[tree_id] != bl_links_to_sv_links(ng) - # if self.links_have_changed(): - # break - # only perform clean if the undo event triggered - # a difference in total node count among trees or if links have changed. + if links_changed or not (undo_handler_node_count['sv_groups'] == num_to_test_against): print('looks like a node was removed, cleaning') sv_clean(scene) diff --git a/core/links.py b/core/links.py index df4be48a7..e0b586acf 100644 --- a/core/links.py +++ b/core/links.py @@ -17,7 +17,7 @@ # # ##### END GPL LICENSE BLOCK ##### -# Declaring namedtuple() + import collections from typing import NamedTuple from sverchok.core.update_system import ( @@ -25,12 +25,13 @@ from sverchok.core.update_system import ( process_from_nodes, ) from sverchok.core.node_id_dict import dict_of_node_tree, translate_node_id_to_node_name -SvLink = collections.namedtuple('SvLink', ['from_node_id', 'to_node_id', 'from_socket_id', 'to_socket_id']) + class SvLink(NamedTuple): from_node_id: str to_node_id: str from_socket_id: str to_socket_id: str + @classmethod def init_from_link(cls, link): output_socket, output_node = get_output_socket_id(link.from_socket) @@ -41,14 +42,23 @@ class SvLink(NamedTuple): to_socket_id=link.to_socket.socket_id ) return sv_link -# sv_links_new = {} -# sv_links_cache = {} -# output_sockets_cache = {} -# input_sockets_cache = {} -# inputted_nodes_cache = {} -# output_sockets_new = dict() -# input_sockets_new = dict() -# sv_linked_inputted_nodes_new = dict() + @classmethod + def init_from_links(cls, links): + new_sv_links = [] + for link in links: + if not link.to_socket.node.bl_idname == 'NodeReroute': + #recursive function to override reroutes + output_socket, output_node = get_output_socket_id(link.from_socket) + if output_socket: + sv_link = cls( + from_node_id=output_node, + to_node_id=link.to_socket.node.node_id, + from_socket_id=output_socket, + to_socket_id=link.to_socket.socket_id ) + new_sv_links.append(sv_link) + + return new_sv_links + class SvLinks: sv_links_new = {} sv_links_cache = {} @@ -59,10 +69,6 @@ class SvLinks: input_sockets_new = dict() inputted_nodes_new = dict() - @classmethod - def get(cls, node_tree): - return cls.sv_links[node_tree] - def start_dictionaries(self, tree_id): self.sv_links_new[tree_id] = dict() self.sv_links_cache[tree_id] = dict() @@ -78,7 +84,8 @@ class SvLinks: tree_id = node_tree.tree_id if not node_tree.tree_id in self.sv_links_new: self.start_dictionaries(node_tree.tree_id) - new_sv_links = bl_links_to_sv_links(node_tree) + + new_sv_links = SvLink.init_from_links(node_tree.links) self.sv_links_new[tree_id] = new_sv_links new_inputted_nodes, new_input_sockets, new_output_sockets = split_new_links_data(new_sv_links) self.output_sockets_new[tree_id] = new_output_sockets @@ -122,19 +129,9 @@ class SvLinks: ) affected_nodes = new_linked_nodes + new_unlinked_linked_nodes node_list = translate_node_id_to_node_name(node_tree, affected_nodes) - print(node_list) return node_list # return get_nodes(node_tree) -# def empty_links_cache(): -# global sv_links_cache -# sv_links_cache = {} - - -def link_cache_is_ready(node_tree): - return node_tree.tree_id in sv_links_cache - - def get_output_socket_id(socket): if socket.node.bl_idname == 'NodeReroute': if socket.node.inputs[0].is_linked: @@ -189,97 +186,12 @@ def bl_links_to_sv_links(node_tree): #recursive function to override reroutes output_socket, output_node = get_output_socket_id(link.from_socket) if output_socket: - sv_link = SvLink( - from_node_id=output_node, - to_node_id=link.to_socket.node.node_id, - from_socket_id=output_socket, - to_socket_id=link.to_socket.socket_id ) - new_sv_links.append(sv_link) - + # sv_link = SvLink( + # from_node_id=output_node, + # to_node_id=link.to_socket.node.node_id, + # from_socket_id=output_socket, + # to_socket_id=link.to_socket.socket_id ) + # new_sv_links.append(sv_link) + new_sv_links.append(SvLink.init_from_link(link)) + print(new_sv_links) return new_sv_links - - -def fill_links_memory(node_tree): - tree_id = node_tree.tree_id - new_sv_links = bl_links_to_sv_links(node_tree) - - inputted_nodes, input_sockets, output_sockets = split_new_links_data(new_sv_links) - - sv_links_cache[tree_id] = new_sv_links - output_sockets_cache[tree_id] = output_sockets - input_sockets_cache[tree_id] = input_sockets - inputted_nodes_cache[tree_id] = inputted_nodes - - -def get_affected_groups(node_tree): - affected_groups = [] - for node in node_tree.nodes: - if 'SvGroupNode' in node.bl_idname: - subtree = node.monad - tree_id = subtree.tree_id - fill_memory_is_ready = tree_id in sv_links_cache - if fill_memory_is_ready: - has_been_updated = use_link_memory(subtree) - else: - fill_links_memory(subtree) - subtree.has_changed = True - node.process() - has_been_updated = True - - if has_been_updated: - affected_groups.append(node) - return affected_groups - - -def use_link_memory(node_tree): - if node_tree.configuring_new_node or node_tree.is_frozen() or not node_tree.sv_process: - return False - - tree_id = node_tree.tree_id - new_sv_links = bl_links_to_sv_links(node_tree) - before_sv_links = sv_links_cache[tree_id] - links_has_changed = before_sv_links != new_sv_links - - if links_has_changed: - - affected_nodes = [] - - new_inputted_nodes, new_input_sockets, new_output_sockets = split_new_links_data(new_sv_links) - before_input_sockets = input_sockets_cache[tree_id] - before_inputted_nodes = inputted_nodes_cache[tree_id] - before_output_sockets = output_sockets_cache[tree_id] - - new_linked_nodes = get_new_linked_nodes( - new_sv_links, - before_sv_links, - before_output_sockets) - - new_unlinked_linked_nodes = get_new_unlinked_nodes( - before_inputted_nodes, - before_input_sockets, - new_input_sockets, - dict_of_node_tree(node_tree) - ) - affected_nodes = new_linked_nodes + new_unlinked_linked_nodes - - sv_links_cache[tree_id] = new_sv_links - inputted_nodes_cache[tree_id] = new_inputted_nodes - output_sockets_cache[tree_id] = new_output_sockets - input_sockets_cache[tree_id] = new_input_sockets - - build_update_list(node_tree) - - if affected_nodes: - node_list = translate_node_id_to_node_name(node_tree, affected_nodes) - process_from_nodes(node_list) - return True - else: - return False - else: - - affected_groups = get_affected_groups(node_tree) - if affected_groups: - process_from_nodes(affected_groups) - return True - else: - return False diff --git a/core/node_id_dict.py b/core/node_id_dict.py index dd7188ed6..cd154761e 100644 --- a/core/node_id_dict.py +++ b/core/node_id_dict.py @@ -45,13 +45,11 @@ def load_nodes_in_node_dict(node_tree): sv_node_dict_cache[tree_id] = {} for node in node_tree.nodes: try: - - # if node.bl_idname != 'NodeReroute': sv_node_dict_cache[tree_id][node.node_id] = node except AttributeError: + # it is a NodeReroute pass - # print(node.bl_idname) - # print(sv_node_dict_cache[tree_id]) + def dict_of_node_tree(node_tree): print(node_tree.tree_id in sv_node_dict_cache) diff --git a/node_tree.py b/node_tree.py index 3607c037b..74d6e039a 100644 --- a/node_tree.py +++ b/node_tree.py @@ -43,9 +43,6 @@ from sverchok.core.update_system import ( is_first_run, reset_error_nodes) from sverchok.core.links import ( - fill_links_memory, - use_link_memory, - link_cache_is_ready, SvLinks) from sverchok.core.node_id_dict import load_in_node_dict, delete_from_node_dict @@ -394,27 +391,13 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): # print('throttled update from context manager') return if self.configuring_new_node or self.is_frozen() or not self.sv_process: - return + return self.sv_update() self.has_changed = False - # self.update_sv_links() - # print(self.links_have_changed()) - # # self.store_links_cache() - # if self.links_have_changed(): - # build_update_list(self) - # print(00) - # process_from_nodes(self.get_nodes()) - # self.store_links_cache() - # elif - - # if link_cache_is_ready(self): - # use_link_memory(self) - # else: - # if self.sv_process: - # fill_links_memory(self) - # self.has_changed = True - # self.process() + + # self.has_changed = True + # self.process() def process_ani(self): """ -- GitLab From 0d97a498dbac0ee0373f19dbd71096a101781a37 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Wed, 22 Apr 2020 20:48:16 +0200 Subject: [PATCH 25/43] node_id_dict to class --- core/handlers.py | 14 ++--- core/links.py | 128 +++++++++++++++++-------------------------- core/node_id_dict.py | 74 ++++++++++++------------- node_tree.py | 56 +++++-------------- 4 files changed, 103 insertions(+), 169 deletions(-) diff --git a/core/handlers.py b/core/handlers.py index 1f395fe03..0a8824423 100644 --- a/core/handlers.py +++ b/core/handlers.py @@ -6,11 +6,7 @@ from bpy.app.handlers import persistent from sverchok import old_nodes from sverchok import data_structure from sverchok.core import upgrade_nodes, undo_handler_node_count -from sverchok.core.update_system import sv_first_run, set_first_run -import sverchok.core.update_system as us -# from sverchok.core.links import empty_links_cache -from sverchok.core.node_id_dict import load_nodes_in_node_dict - +from sverchok.core.update_system import set_first_run from sverchok.ui import color_def, bgl_callback_nodeview, bgl_callback_3dview from sverchok.utils import app_handler_ops from sverchok.utils.logging import debug @@ -82,12 +78,12 @@ def sv_handler_undo_post(scene): links_changed = ng.links_have_changed() if links_changed: break - + if links_changed or not (undo_handler_node_count['sv_groups'] == num_to_test_against): print('looks like a node was removed, cleaning') sv_clean(scene) for ng in sverchok_trees(): - load_nodes_in_node_dict(ng) + ng.nodes_dict.load_nodes(ng) ng.has_changed = True sv_main_handler(scene) undo_handler_node_count['sv_groups'] = 0 @@ -175,10 +171,8 @@ def sv_clean(scene): def sv_pre_load(scene): sv_clean(scene) - - set_first_run(True) - global sv_first_run + @persistent diff --git a/core/links.py b/core/links.py index e0b586acf..e01d41a0f 100644 --- a/core/links.py +++ b/core/links.py @@ -20,11 +20,53 @@ import collections from typing import NamedTuple -from sverchok.core.update_system import ( - build_update_list, - process_from_nodes, - ) -from sverchok.core.node_id_dict import dict_of_node_tree, translate_node_id_to_node_name + + +def get_output_socket_id(socket): + if socket.node.bl_idname == 'NodeReroute': + if socket.node.inputs[0].is_linked: + return get_output_socket_id(socket.node.inputs[0].links[0].from_socket) + else: + return None, None + else: + return socket.socket_id, socket.node.node_id + + +def get_new_linked_nodes(new_sv_links, before_sv_links, before_output_sockets): + affected_nodes = [] + for link in new_sv_links: + if not link in before_sv_links: + if not link.from_socket_id in before_output_sockets: + if not link.from_node_id in affected_nodes: + affected_nodes.append(link.from_node_id) + if not link.to_node_id in affected_nodes: + affected_nodes.append(link.to_node_id) + return affected_nodes + + +def get_new_unlinked_nodes(before_inputted_nodes, before_input_sockets, input_sockets, nodes_dict): + affected_nodes = [] + + for node_id, socket in zip(before_inputted_nodes, before_input_sockets): + if not socket in input_sockets: + #if the node has been deleted it is not affected + if node_id in nodes_dict: + affected_nodes.append(node_id) + + return affected_nodes + + +def split_new_links_data(new_sv_links): + inputted_nodes = [] + input_sockets = [] + output_sockets = [] + for link in new_sv_links: + inputted_nodes.append(link.to_node_id) + input_sockets.append(link.to_socket_id) + output_sockets.append(link.from_socket_id) + + return inputted_nodes, input_sockets, output_sockets + class SvLink(NamedTuple): from_node_id: str @@ -103,15 +145,12 @@ class SvLinks: self.input_sockets_cache[tree_id] = self.input_sockets_new[tree_id] self.inputted_nodes_cache[tree_id] = self.inputted_nodes_new[tree_id] - # @classmethod - # def get_new_linked_nodes(cls, tree_id): - def get_nodes(self, node_tree): tree_id = node_tree.tree_id new_sv_links = self.sv_links_new[tree_id] before_sv_links = self.sv_links_cache[tree_id] - # print(self.sv_links_cache[tree_id]) - if (self.sv_links_cache[tree_id]): + + if self.sv_links_cache[tree_id]: return node_tree.nodes affected_nodes = [] @@ -125,73 +164,8 @@ class SvLinks: self.inputted_nodes_cache[tree_id], self.input_sockets_cache[tree_id], self.input_sockets_new[tree_id], - dict_of_node_tree(node_tree) + node_tree.nodes_dict.get(node_tree) ) affected_nodes = new_linked_nodes + new_unlinked_linked_nodes - node_list = translate_node_id_to_node_name(node_tree, affected_nodes) + node_list = node_tree.nodes_dict.to_node_name(node_tree, affected_nodes) return node_list - # return get_nodes(node_tree) - -def get_output_socket_id(socket): - if socket.node.bl_idname == 'NodeReroute': - if socket.node.inputs[0].is_linked: - return get_output_socket_id(socket.node.inputs[0].links[0].from_socket) - else: - return None, None - else: - return socket.socket_id, socket.node.node_id - - -def get_new_linked_nodes(new_sv_links, before_sv_links, before_output_sockets): - affected_nodes = [] - for link in new_sv_links: - if not link in before_sv_links: - if not link.from_socket_id in before_output_sockets: - if not link.from_node_id in affected_nodes: - affected_nodes.append(link.from_node_id) - if not link.to_node_id in affected_nodes: - affected_nodes.append(link.to_node_id) - return affected_nodes - - -def get_new_unlinked_nodes(before_inputted_nodes, before_input_sockets, input_sockets, nodes_dict): - affected_nodes = [] - - for node_id, socket in zip(before_inputted_nodes, before_input_sockets): - if not socket in input_sockets: - #if the node has been deleted it is not affected - if node_id in nodes_dict: - affected_nodes.append(node_id) - - return affected_nodes - - -def split_new_links_data(new_sv_links): - inputted_nodes = [] - input_sockets = [] - output_sockets = [] - for link in new_sv_links: - inputted_nodes.append(link.to_node_id) - input_sockets.append(link.to_socket_id) - output_sockets.append(link.from_socket_id) - - return inputted_nodes, input_sockets, output_sockets - - -def bl_links_to_sv_links(node_tree): - - new_sv_links = [] - for link in node_tree.links: - if not link.to_socket.node.bl_idname == 'NodeReroute': - #recursive function to override reroutes - output_socket, output_node = get_output_socket_id(link.from_socket) - if output_socket: - # sv_link = SvLink( - # from_node_id=output_node, - # to_node_id=link.to_socket.node.node_id, - # from_socket_id=output_socket, - # to_socket_id=link.to_socket.socket_id ) - # new_sv_links.append(sv_link) - new_sv_links.append(SvLink.init_from_link(link)) - print(new_sv_links) - return new_sv_links diff --git a/core/node_id_dict.py b/core/node_id_dict.py index cd154761e..dbe4b8ee1 100644 --- a/core/node_id_dict.py +++ b/core/node_id_dict.py @@ -17,42 +17,38 @@ # # ##### END GPL LICENSE BLOCK ##### -sv_node_dict_cache = {} - -def translate_node_id_to_node_name(node_tree, affected_nodes): - tree_id = node_tree.tree_id - return [sv_node_dict_cache[tree_id][node_id] for node_id in affected_nodes if node_id in sv_node_dict_cache[tree_id]] - -def load_in_node_dict(node): - - n_id = node.node_id - tree = node.id_data - tree_id = node.id_data.tree_id - - if tree_id not in sv_node_dict_cache: - sv_node_dict_cache[tree_id] = {} - sv_node_dict_cache[tree_id][n_id] = node - -def delete_from_node_dict(node): - n_id = node.node_id - tree_id = node.id_data.tree_id - del sv_node_dict_cache[tree_id][n_id] - -def load_nodes_in_node_dict(node_tree): - print('loading_nodes_in_nodetree', node_tree.tree_id) - tree_id = node_tree.tree_id - # if tree_id in sv_node_dict_cache: - sv_node_dict_cache[tree_id] = {} - for node in node_tree.nodes: - try: - sv_node_dict_cache[tree_id][node.node_id] = node - except AttributeError: - # it is a NodeReroute - pass - - -def dict_of_node_tree(node_tree): - print(node_tree.tree_id in sv_node_dict_cache) - if not node_tree.tree_id in sv_node_dict_cache: - load_nodes_in_node_dict(node_tree) - return sv_node_dict_cache[node_tree.tree_id] +class SvNodesDict: + sv_node_dict_cache = {} + + def to_node_name(self, node_tree, affected_nodes): + tree_id = node_tree.tree_id + return [self.sv_node_dict_cache[tree_id][node_id] for node_id in affected_nodes if node_id in self.sv_node_dict_cache[tree_id]] + + def load_node(self, node): + + n_id = node.node_id + tree_id = node.id_data.tree_id + + if tree_id not in self.sv_node_dict_cache: + self.sv_node_dict_cache[tree_id] = {} + self.sv_node_dict_cache[tree_id][n_id] = node + + def forget_node(self, node): + n_id = node.node_id + tree_id = node.id_data.tree_id + del self.sv_node_dict_cache[tree_id][n_id] + + def load_nodes(self, node_tree): + tree_id = node_tree.tree_id + self.sv_node_dict_cache[tree_id] = {} + for node in node_tree.nodes: + try: + self.sv_node_dict_cache[tree_id][node.node_id] = node + except AttributeError: + # it is a NodeReroute + pass + + def get(self, node_tree): + if not node_tree.tree_id in self.sv_node_dict_cache: + self.load_nodes(node_tree) + return self.sv_node_dict_cache[node_tree.tree_id] diff --git a/node_tree.py b/node_tree.py index 74d6e039a..ea9478c9f 100644 --- a/node_tree.py +++ b/node_tree.py @@ -44,8 +44,7 @@ from sverchok.core.update_system import ( reset_error_nodes) from sverchok.core.links import ( SvLinks) -from sverchok.core.node_id_dict import load_in_node_dict, delete_from_node_dict - +from sverchok.core.node_id_dict import SvNodesDict from sverchok.core.socket_conversions import DefaultImplicitConversionPolicy from sverchok.core.socket_data import socket_data_cache @@ -141,46 +140,7 @@ def throttled(func): return wrapper_update -# Declaring namedtuple() -Sv_Link = collections.namedtuple('sv_link',['from_node_id', 'to_node_id', 'from_socket_id', 'to_socket_id']) -def get_output_socket_id(socket): - if socket.node.bl_idname == 'NodeReroute': - if socket.node.inputs[0].is_linked: - return get_output_socket_id(socket.node.inputs[0].links[0].from_socket) - else: - return None, None - else: - return socket.socket_id, socket.node.node_id - -def get_new_linked_nodes(new_sv_links, before_sv_links, before_output_sockets): - affected_nodes = [] - for link in new_sv_links: - if not link in before_sv_links: - if not link.from_socket_id in before_output_sockets: - if not link.from_node_id in affected_nodes: - affected_nodes.append(link.from_node_id) - if not link.to_node_id in affected_nodes: - affected_nodes.append(link.to_node_id) - return affected_nodes - -def append_unlinked_nodes(before_inputted_nodes, before_input_sockets, input_sockets, affected_nodes, nodes_dict): - for node_id, socket in zip(before_inputted_nodes, before_input_sockets): - if not socket in input_sockets: - #if the node has been deleted it is not affected - if node_id in nodes_dict: - affected_nodes.append(node_id) - -def split_new_links_data(new_sv_links): - inputted_nodes = [] - input_sockets = [] - output_sockets = [] - for link in new_sv_links: - inputted_nodes.append(link.to_node_id) - input_sockets.append(link.to_socket_id) - output_sockets.append(link.from_socket_id) - - return inputted_nodes, input_sockets, output_sockets class SvNodeTreeCommon(object): ''' @@ -193,6 +153,8 @@ class SvNodeTreeCommon(object): configuring_new_node: BoolProperty(name="indicate node initialization", default=False) tree_id_memory: StringProperty(default="") sv_links = SvLinks() + nodes_dict = SvNodesDict() + @property def tree_id(self): if not self.tree_id_memory: @@ -247,14 +209,19 @@ class SvNodeTreeCommon(object): if ng.bl_idname in {'SverchCustomTreeType', 'SverchGroupTreeType'}: res.append(ng) return res + def update_sv_links(self): self.sv_links.create_new_links(self) + def links_have_changed(self): return self.sv_links.links_have_changed(self) + def store_links_cache(self): self.sv_links.store_links_cache(self) + def get_nodes(self): return self.sv_links.get_nodes(self) + def get_groups(self): affected_groups =[] for node in self.nodes: @@ -739,7 +706,7 @@ class SverchCustomTreeNode: ng = self.id_data ng.freeze() - load_in_node_dict(self) + ng.nodes_dict.load_node(self) if hasattr(self, "sv_init"): try: @@ -809,9 +776,12 @@ class SverchCustomTreeNode: Override sv_free() instead """ self.sv_free() + for s in self.outputs: s.sv_forget() - delete_from_node_dict(self) + + node_tree = self.id_data + node_tree.nodes_dict.forget_node(self) if hasattr(self, "has_3dview_props"): print("about to remove this node's props from Sv3DProps") -- GitLab From 699217785ee67366da8b6d8db165519c75def452 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Wed, 22 Apr 2020 21:41:42 +0200 Subject: [PATCH 26/43] ups --- core/links.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/links.py b/core/links.py index e01d41a0f..04adf079f 100644 --- a/core/links.py +++ b/core/links.py @@ -150,7 +150,7 @@ class SvLinks: new_sv_links = self.sv_links_new[tree_id] before_sv_links = self.sv_links_cache[tree_id] - if self.sv_links_cache[tree_id]: + if not self.sv_links_cache[tree_id]: return node_tree.nodes affected_nodes = [] -- GitLab From 90b8ce0ba7999d00f491060bf9946f21b95f3f27 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Wed, 22 Apr 2020 23:31:48 +0200 Subject: [PATCH 27/43] back some whitespacing --- utils/testing.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/utils/testing.py b/utils/testing.py index b55e76818..cc652f99e 100644 --- a/utils/testing.py +++ b/utils/testing.py @@ -53,7 +53,7 @@ def generate_node_definition(node): tree = get_or_create_node_tree() node = create_node("{}", tree.name) """.format(node.bl_idname) - + for k, v in node.items(): result += "node.{} = {}\n".format(k, v) @@ -187,7 +187,7 @@ def run_all_tests(pattern=None): Run all existing test cases. Test cases are looked up under tests/ directory. """ - + if pattern is None: pattern = "*_tests.py" @@ -389,7 +389,7 @@ class SverchokTestCase(unittest.TestCase): shape = list(arr1.shape) def compare(prev_indicies): - step = len(prev_indicies) + step = len(prev_indicies) if step == arr1.ndim: ind = tuple(prev_indicies) if precision is None: @@ -418,7 +418,7 @@ class SverchokTestCase(unittest.TestCase): level2 = get_data_nesting_level(data2) if level1 != level2: raise AssertionError("Nesting level of 1st data {} != nesting level of 2nd data {}".format(level1, level2)) - + def do_assert(d1, d2, idxs): if precision is not None: d1 = round(d1, precision) @@ -456,7 +456,7 @@ class SverchokTestCase(unittest.TestCase): #info("Expected data: %s", expected_data) self.assert_sverchok_data_equal(data, expected_data, precision=precision) #self.assertEquals(data, expected_data) - + @contextmanager def assert_prints_stdout(self, regexp): """ @@ -579,7 +579,7 @@ class ReferenceTreeTestCase(SverchokTestCase): raise Exception("ReferenceTreeTestCase subclass must have `reference_file_name' set") if self.reference_tree_name is None: self.reference_tree_name = "TestingTree" - + with self.assert_logs_no_errors(): self.tree = self.link_node_tree() @@ -619,7 +619,7 @@ class NodeProcessTestCase(EmptyTreeTestCase): return get_output_socket_data(self.node, output_name) except SvNoDataError: return None - + def assert_output_data_equals(self, output_name, expected_data, message=None): """ Assert that tested node has written expected_data to @@ -690,7 +690,7 @@ def make_skip_decorator(condition, message): # Here go decorators used to mark test to be executed only in certain conditions. # Example usage: -# +# # @manual_only # def test_something(self): # # This test will not be running on Travis CI, only in manual mode. @@ -856,3 +856,4 @@ if __name__ == "__main__": except Exception as e: print(e) sys.exit(1) + -- GitLab From 59291b28e4835b9cdc8a8dd0e724febb1d9b53ea Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Wed, 22 Apr 2020 23:45:24 +0200 Subject: [PATCH 28/43] removed unused import and whitespace restored --- node_tree.py | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/node_tree.py b/node_tree.py index ea9478c9f..7b6643f12 100644 --- a/node_tree.py +++ b/node_tree.py @@ -21,8 +21,6 @@ import sys import time from contextlib import contextmanager import textwrap -import collections - import bpy from bpy.props import StringProperty, BoolProperty, FloatVectorProperty, IntProperty, EnumProperty @@ -33,7 +31,6 @@ from sverchok import data_structure from sverchok.data_structure import get_other_socket from sverchok.core.update_system import ( - partial_update_cache, build_update_list, process_from_node, process_from_nodes, process_tree, @@ -47,7 +44,7 @@ from sverchok.core.links import ( from sverchok.core.node_id_dict import SvNodesDict from sverchok.core.socket_conversions import DefaultImplicitConversionPolicy -from sverchok.core.socket_data import socket_data_cache + from sverchok.core.node_defaults import set_defaults_if_defined from sverchok.utils import get_node_class_reference @@ -103,7 +100,7 @@ def throttle_tree_update(node): self.inputs.new(...) self.outputs.new(...) - that's it. + that's it. """ try: @@ -127,7 +124,7 @@ def throttled(func): When a node has changed, like a mode-change leading to a socket change (remove, new) Blender will trigger nodetree.update. We want to ignore this trigger-event, and we do so by - - first throttling the update system. + - first throttling the update system. - then We execute the code that makes changes to the node/nodetree - then we end the throttle-state - we are then ready to process @@ -267,7 +264,7 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): # node.disable() def sv_process_tree_callback(self, context): - process_tree(self) + process_tree(self) sv_animate: BoolProperty(name="Animate", default=True, description='Animate this layout') sv_show: BoolProperty(name="Show", default=True, description='Show this layout', update=turn_off_ng) @@ -291,7 +288,6 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): sv_toggle_nodetree_props: BoolProperty(name="Toggle visibility of props", description="Show more properties for this node tree") - def on_draft_mode_changed(self, context): """ This is triggered when Draft mode of the tree is toggled. @@ -337,7 +333,7 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): @property def has_link_count_changed(self): link_count = len(self.links) - if not link_count == self.tree_link_count: + if not link_count == self.tree_link_count: # print('update event: link count changed', self.timestamp) self.tree_link_count = link_count return True @@ -388,9 +384,8 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): self.build_update_list() self.has_changed = False if self.is_frozen(): - # print('not processing: because self/tree.is_frozen') + # print('not processing: because self/tree.is_frozen') return - if self.sv_process: process_tree(self) @@ -438,18 +433,18 @@ class SverchCustomTreeNode: def ensure_enums_have_no_space(self, enums=None): """ - enums: a list of property names to check. like self.current_op + enums: a list of property names to check. like self.current_op self.ensure_enums_have_no_space(enums=[current_op]) due to changes in EnumProperty defintion "laws" individual enum identifiers must not - contain spaces. This function takes a list of enums that the node currently holds, and + contain spaces. This function takes a list of enums that the node currently holds, and makes sure the stored enum has no spaces. """ for enum_property in enums: current_value = getattr(self, enum_property) if " " in current_value: - with self.sv_throttle_tree_update(): + with self.sv_throttle_tree_update(): setattr(self, enum_property, data_structure.no_space(current_value)) @@ -755,7 +750,6 @@ class SverchCustomTreeNode: This method is not supposed to be overriden in specific nodes. Override sv_copy() instead. """ - # self.n_id = str(hash(self) ^ hash(time.monotonic())) settings = get_original_node_color(self.id_data, original.name) if settings is not None: self.use_custom_color, self.color = settings @@ -769,7 +763,7 @@ class SverchCustomTreeNode: at the moment of node being copied. """ pass - + def free(self): """ This method is not supposed to be overriden in specific nodes. @@ -816,7 +810,7 @@ class SverchCustomTreeNode: def get_and_set_gl_scale_info(self, origin=None): """ - This function is called in sv_init in nodes that draw GL instructions to the nodeview, + This function is called in sv_init in nodes that draw GL instructions to the nodeview, the nodeview scale and dpi differs between users and must be queried to get correct nodeview x,y and dpi scale info. """ @@ -832,7 +826,7 @@ class SverchCustomTreeNode: classes = [ - SverchCustomTree, + SverchCustomTree, SvLinkNewNodeInput, SvGenericUITooltipOperator ] -- GitLab From 4a6c2bbe27fe257de6ee7301b1221a7930abac5f Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Wed, 22 Apr 2020 23:55:25 +0200 Subject: [PATCH 29/43] removing unused import and whitespacing removal from sockets.py --- core/sockets.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/sockets.py b/core/sockets.py index ffa97eb54..fd55b796d 100644 --- a/core/sockets.py +++ b/core/sockets.py @@ -18,7 +18,7 @@ # ##### END GPL LICENSE BLOCK ##### import math -import time + import bpy from bpy.props import StringProperty, BoolProperty, FloatVectorProperty, IntProperty, FloatProperty from bpy.types import NodeTree, NodeSocket @@ -59,6 +59,7 @@ def process_from_socket(self, context): """Update function of exposed properties in Sockets""" self.node.process_node(context) + class SvSocketCommon: """ Base class for all Sockets """ use_prop: BoolProperty(default=False) @@ -70,8 +71,7 @@ class SvSocketCommon: prop_name: StringProperty(default='', description="For displaying node property in socket UI") quicklink_func_name: StringProperty(default="", name="quicklink_func_name") - # socket_id_m: StringProperty(default="") - socket_id_m: StringProperty(default="") + def get_prop_name(self): if self.node and self.node.does_support_draft_mode() and hasattr(self.node.id_data, 'sv_draft') and self.node.id_data.sv_draft: prop_name_draft = self.node.draft_properties_mapping.get(self.prop_name, None) @@ -728,3 +728,4 @@ classes = [ ] register, unregister = bpy.utils.register_classes_factory(classes) + -- GitLab From 4b059a177125d617f35387443c6901bc260473ac Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Thu, 23 Apr 2020 00:01:59 +0200 Subject: [PATCH 30/43] docstring and cleaning --- core/socket_data.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/socket_data.py b/core/socket_data.py index 14c070352..0399abcc6 100644 --- a/core/socket_data.py +++ b/core/socket_data.py @@ -67,7 +67,7 @@ def SvGetSocketInfo(socket): return '' def SvForgetSocket(socket): - """sets socket data for socket""" + """deletes socket data from cache""" global socket_data_cache if data_structure.DEBUG_MODE: if not socket.is_output: @@ -126,7 +126,7 @@ def SvGetSocket(socket, deepcopy=True): class SvNoDataError(LookupError): def __init__(self, socket=None, node=None, msg=None): - + self.extra_message = msg if msg else "" if node is None and socket is not None: @@ -143,16 +143,16 @@ class SvNoDataError(LookupError): return "SvNoDataError" else: return f"No data passed into socket '{self.socket.name}'" - + def __repr__(self): return self.get_message() - + def __str__(self): return repr(self) def __unicode__(self): return repr(self) - + def __format__(self, spec): return repr(self) -- GitLab From 0225f5366aa35c496f7fe1289628ea0f3bd7f778 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Thu, 23 Apr 2020 00:12:06 +0200 Subject: [PATCH 31/43] more PR cleaning --- core/monad.py | 64 +++++++++++++++++++++---------------------- core/socket_data.py | 2 -- core/update_system.py | 14 ++++++---- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/core/monad.py b/core/monad.py index d928f0675..f8f982d58 100644 --- a/core/monad.py +++ b/core/monad.py @@ -74,20 +74,20 @@ def monad_make_unique(node): Create a new version of the monad class (duplicate but unique) This will attempt to store the duplicate in a json using create_dict_of_tree (from the Gist IO). - The upside is that this will test the pack/unpack routine continuously. - The downside is that this will likely expose all the shortcommings that we don't know + The upside is that this will test the pack/unpack routine continuously. + The downside is that this will likely expose all the shortcommings that we don't know about because it wasn't being tested extensively. """ node_tree = node.id_data nodes = node_tree.nodes - # generate a new copy of monad group node. using ( copy? ) + # generate a new copy of monad group node. using ( copy? ) monad_group = bpy.data.node_groups[node.monad.name] new_monad_group = monad_group.copy() - new_cls_name = make_new_classname(new_monad_group) + new_cls_name = make_new_classname(new_monad_group) - # the new tree dict will contain information about 1 node only, and + # the new tree dict will contain information about 1 node only, and # the node_group too (at the moment) but the node_group data can be ignored. layout_json = create_dict_of_tree(ng=node_tree, identified_node=node) @@ -109,8 +109,8 @@ def monad_make_unique(node): """ notions..: - - if (original instance has no connections) then + + if (original instance has no connections) then replace it outright. else if mode=='replace': @@ -125,7 +125,7 @@ def monad_make_unique(node): """ # return newly generated node! - return (set(node_tree.nodes) ^ pre_nodes).pop() + return (set(node_tree.nodes) ^ pre_nodes).pop() @@ -177,12 +177,12 @@ class SverchGroupTree(NodeTree, SvNodeTreeCommon): # prop_dict['name'] = node.name + '|' + prop_name def get_stored_prop_names(self): - """ - - this will list all currently stored props for this monad / tree + """ + - this will list all currently stored props for this monad / tree - it reflects the state prior to acquisition of a new socket with prop. """ props = self.get_all_props() - return list(props['float_props'].keys()) + list(props['int_props'].keys()) + return list(props['float_props'].keys()) + list(props['int_props'].keys()) def add_prop_from(self, socket): @@ -213,7 +213,7 @@ class SverchGroupTree(NodeTree, SvNodeTreeCommon): if 'attr' in prop_dict: prop_dict.pop('attr') # this we store in prop_name anyway - + if 'update' in prop_dict: """ the node may be doing a tonne of stuff in a wrapped update, @@ -221,12 +221,12 @@ class SverchGroupTree(NodeTree, SvNodeTreeCommon): replace it with a reference to updateNode. i think this is a sane thing to ensure. """ prop_dict['update'] = updateNode - + if not 'name' in prop_dict: - """ - name is used exclusively for displaying name on the slider or label + """ + name is used exclusively for displaying name on the slider or label most properties will have this defined anyway, but just in case. - """ + """ regex = re.compile('[^a-z A-Z0-9]') prop_dict['name'] = regex.sub('', prop_name) print(f"monad: generated name for property function: {prop_name} -> {prop_dict['name']}") @@ -236,7 +236,7 @@ class SverchGroupTree(NodeTree, SvNodeTreeCommon): print("prop_dict:", prop_dict) # tells us the attributes of the property print("prop_name:", prop_name) # tells the socket / slider ui which prop to display # # and its associated 'name' attribute from the prop_dict - + if prop_func.__name__ == "FloatProperty": self.get_current_as_default(prop_dict, other.node, prop_name) prop_settings = self.float_props.add() @@ -262,22 +262,22 @@ class SverchGroupTree(NodeTree, SvNodeTreeCommon): new_name = prop_name_prefix + prop_name if has_monad_prop_names: new_name = ensure_unique(monad_prop_names, new_name) - + prop_settings.prop_name = new_name prop_settings.set_settings(prop_dict) socket.prop_name = new_name return new_name elif hasattr(other, "prop_type"): - + # if you are seeing errors with this and the other.node.bl_idname is not scriptnodelite # the fix will be here somewhere. print(f'{other.node} = other.node') print(f'{other.prop_type} = other.prop_type') - - if not any(substring in other.prop_type for substring in ["float", "int"]): - return None - + + if not any(substring in other.prop_type for substring in ["float", "int"]): + return None + if "float" in other.prop_type: prop_settings = self.float_props.add() prop_name_prefix = f"floats_{len(self.float_props)}_" @@ -288,18 +288,18 @@ class SverchGroupTree(NodeTree, SvNodeTreeCommon): new_name = prop_name_prefix + other.name if has_monad_prop_names: new_name = ensure_unique(monad_prop_names, new_name) - + # this name will be used as the attr name of the newly generated property for the shellnode - # essentially this is + # essentially this is # __annotations__[prop_name] = new property function prop_settings.prop_name = new_name - + custom_prop_dict = { "name": nice_ui_name(other.name), "update": updateNode } - # there are other nodes that use this technique, + # there are other nodes that use this technique, if other.node.bl_idname == "SvScriptNodeLite": prop_list = other.node.float_list if "float" in other.prop_type else other.node.int_list default = prop_list[other.prop_index] @@ -428,7 +428,7 @@ class SverchGroupTree(NodeTree, SvNodeTreeCommon): cls_dict = {} if not self.cls_bl_idname: - + # the monad cls_bl_idname needs to be unique and cannot change monad_base_name = make_valid_identifier(self.name) monad_itentifier = id(self) ^ random.randint(0, 4294967296) @@ -594,7 +594,7 @@ class SvGroupNodeExp: cA.prop(self, "vectorize", toggle=True) cB.active = self.vectorize cB.prop(self, "split", toggle=True) - + c2 = layout.column() row = c2.row(align=True) row.prop(self, "loop_me", text='Loop', toggle=True) @@ -615,7 +615,7 @@ class SvGroupNodeExp: def get_nodes_to_process(self, out_node_name): """ - nodes not indirectly / directly contributing to the data we eventually pass to "monad.output_node" + nodes not indirectly / directly contributing to the data we eventually pass to "monad.output_node" are discarded if only `self.monad.outputs_node.name` is passed in endpoints_nodes. The exceptions are nodes that we use for debugging inside the monad. At present SvDebugPrint instances @@ -639,7 +639,7 @@ class SvGroupNodeExp: elif self.loop_me: self.process_looped(self.loops) return - print("processing monad") + monad = self.monad in_node = monad.input_node out_node = monad.output_node @@ -704,7 +704,7 @@ class SvGroupNodeExp: out_node = monad.output_node for index, data in enumerate(sockets_data_in): - in_node.outputs[index].sv_set(data) + in_node.outputs[index].sv_set(data) node_names = self.get_nodes_to_process(out_node.name) ul = make_tree_from_nodes(node_names, monad, down=False) diff --git a/core/socket_data.py b/core/socket_data.py index 0399abcc6..0956bde18 100644 --- a/core/socket_data.py +++ b/core/socket_data.py @@ -76,8 +76,6 @@ def SvForgetSocket(socket): warning(f"{socket.node.name} forgetting unconncted socket: {socket.name}") s_id = socket.socket_id s_ng = socket.id_data.tree_id - print("forgetting", socket) - # if s_ng in socket_data_cache.keys(): try: socket_data_cache[s_ng].pop(s_id, None) except KeyError: diff --git a/core/update_system.py b/core/update_system.py index 06c6038a6..6862c795d 100644 --- a/core/update_system.py +++ b/core/update_system.py @@ -36,13 +36,17 @@ graphs = [] no_data_color = (1, 0.3, 0) exception_color = (0.8, 0.0, 0) + sv_first_run = True + def set_first_run(value): global sv_first_run sv_first_run = value + def is_first_run(): global sv_first_run return sv_first_run + def update_error_colors(self, context): global no_data_color global exception_color @@ -355,7 +359,7 @@ def do_update_general(node_list, nodes, procesed_nodes=set()): timings = [] graph = [] gather = graph.append - + total_time = 0 done_nodes = set(procesed_nodes) @@ -385,19 +389,19 @@ def do_update_general(node_list, nodes, procesed_nodes=set()): update_error_nodes(ng, node_name, err) #traceback.print_tb(err.__traceback__) exception("Node %s had exception: %s", node_name, err) - + if hasattr(ng, "sv_show_error_in_tree"): # not yet supported in monad trees.. if ng.sv_show_error_in_tree: error_text = traceback.format_exc() start_exception_drawing_with_bgl(ng, node_name, error_text, err) - + return None graphs.append(graph) if data_structure.DEBUG_MODE: debug("Node set updated in: %.4f seconds", total_time) - + return timings @@ -455,7 +459,6 @@ def process_from_nodes(nodes): node_names = [node.name for node in nodes] ng = nodes[0].id_data update_list = make_tree_from_nodes(node_names, ng) - # print("process_from_nodes", update_list) reset_error_some_nodes(ng, update_list) do_update(update_list, ng.nodes) @@ -485,7 +488,6 @@ def process_from_node(node): nodes = ng.nodes if not ng.sv_process: return - # print(update_list) do_update(update_list, nodes) else: process_tree(ng) -- GitLab From 4cb7cefd977e2100bdd25514a9b1e2b1075e94ce Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Thu, 23 Apr 2020 00:23:13 +0200 Subject: [PATCH 32/43] and more cleaning --- core/__init__.py | 6 +++--- core/handlers.py | 18 +++--------------- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/core/__init__.py b/core/__init__.py index e8b9fab5f..e9593a205 100644 --- a/core/__init__.py +++ b/core/__init__.py @@ -34,7 +34,7 @@ def sv_registration_utils(): pass -sv_registration_utils.register_all = sv_register_modules +sv_registration_utils.register_all = sv_register_modules sv_registration_utils.unregister_all = sv_unregister_modules @@ -111,9 +111,9 @@ def init_bookkeeping(sv_name): sverchok.data_structure.SVERCHOK_NAME = sv_name ascii_print.show_welcome() node_defaults.register_defaults() - auto_gather_node_classes() + auto_gather_node_classes() undo_handler_node_count = {} -undo_handler_node_count['sv_groups'] = 0 +undo_handler_node_count['sv_groups'] = 0 \ No newline at end of file diff --git a/core/handlers.py b/core/handlers.py index 0a8824423..4e1ac2bc0 100644 --- a/core/handlers.py +++ b/core/handlers.py @@ -144,13 +144,12 @@ def sv_main_handler(scene): if depsgraph_need: sv_depsgraph = bpy.context.evaluated_depsgraph_get() for ng in sverchok_trees(): - # if P (sv_process is False, we can skip this node tree. if not ng.sv_process: continue if ng.has_changed: - + print('depsgraph_update_pre called - ng.has_changed -> ') ng.process() pre_running = False @@ -174,14 +173,12 @@ def sv_pre_load(scene): set_first_run(True) - @persistent def sv_post_load(scene): """ Upgrade nodes, apply preferences and do an update. """ - set_first_run(False) # ensure current nodeview view scale / location parameters reflect users' system settings @@ -191,7 +188,6 @@ def sv_post_load(scene): for monad in (ng for ng in bpy.data.node_groups if ng.bl_idname == 'SverchGroupTreeType'): if monad.input_node and monad.output_node: - load_nodes_in_node_dict(monad) monad.update_cls() sv_types = {'SverchCustomTreeType', 'SverchGroupTreeType'} @@ -219,9 +215,7 @@ def sv_post_load(scene): if pref.apply_theme_on_open: color_def.apply_theme() - # empty_links_cache() for ng in sv_trees: - if ng.bl_idname == 'SverchCustomTreeType' and ng.nodes: ng.update() @@ -245,20 +239,14 @@ def set_frame_change(mode): elif mode == "PRE": pre.append(sv_update_handler) -# def sv_depsgraph_update_post(scene): -# print('sv_depsgraph_update_post') -# depsgraph = bpy.context.evaluated_depsgraph_get() -# print("nodetree", depsgraph.id_type_updated('NODETREE')) -# print("material",depsgraph.id_type_updated('MATERIAL')) -# print("items",depsgraph.ids.items()) + handler_dict = { 'undo_pre': sv_handler_undo_pre, 'undo_post': sv_handler_undo_post, 'load_pre': sv_pre_load, 'load_post': sv_post_load, - 'depsgraph_update_pre': sv_main_handler, - # 'depsgraph_update_post': sv_depsgraph_update_post + 'depsgraph_update_pre': sv_main_handler } -- GitLab From ec17d74b7b9d37d403aea5660145dd55d0c6386a Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Thu, 23 Apr 2020 00:29:18 +0200 Subject: [PATCH 33/43] and more cleaning 2 --- core/handlers.py | 8 ++++---- core/update_system.py | 4 +--- node_tree.py | 3 --- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/core/handlers.py b/core/handlers.py index 4e1ac2bc0..a4b1afaed 100644 --- a/core/handlers.py +++ b/core/handlers.py @@ -54,7 +54,7 @@ def has_frame_changed(scene): @persistent def sv_handler_undo_pre(scene): - + print('called undo pre') from sverchok.core import undo_handler_node_count for ng in sverchok_trees(): @@ -63,7 +63,7 @@ def sv_handler_undo_pre(scene): @persistent def sv_handler_undo_post(scene): - + print('called undo post') # this function appears to be hoisted into an environment that does not have the same locals() # hence this dict must be imported. (jan 2019) @@ -73,7 +73,6 @@ def sv_handler_undo_post(scene): links_changed = False for ng in sverchok_trees(): num_to_test_against += len(ng.nodes) - # tree_id = ng.tree_id ng.update_sv_links() links_changed = ng.links_have_changed() if links_changed: @@ -86,6 +85,7 @@ def sv_handler_undo_post(scene): ng.nodes_dict.load_nodes(ng) ng.has_changed = True sv_main_handler(scene) + undo_handler_node_count['sv_groups'] = 0 @@ -99,7 +99,7 @@ def sv_update_handler(scene): for ng in sverchok_trees(): try: - + # print('sv_update_handler') ng.process_ani() except Exception as e: print('Failed to update:', str(e)) #name, diff --git a/core/update_system.py b/core/update_system.py index 6862c795d..a93f7377e 100644 --- a/core/update_system.py +++ b/core/update_system.py @@ -94,7 +94,6 @@ def make_dep_dict(node_tree, down=False): key, value = (link.from_node.name, link.to_node.name) if down else (link.to_node.name, link.from_node.name) deps[key].add(value) - for name, var_name in wifi_out_nodes: other = wifi_dict.get(var_name) if not other: @@ -199,7 +198,7 @@ def separate_nodes(ng, links=None): node_set_list[-1].add(n) found_node_sets = [ns for ns in node_set_list if len(ns) > 1] - + if hasattr(ng, "sv_subtree_evaluation_order"): sorting_type = ng.sv_subtree_evaluation_order if sorting_type in {'X', 'Y'}: @@ -227,7 +226,6 @@ def make_tree_from_nodes(node_names, tree, down=True): # build downwards links, this should be cached perhaps node_links = make_dep_dict(ng, down) - while current_node: for node in node_links[current_node]: if node not in out_set: diff --git a/node_tree.py b/node_tree.py index 7b6643f12..d27c2f962 100644 --- a/node_tree.py +++ b/node_tree.py @@ -36,7 +36,6 @@ from sverchok.core.update_system import ( process_tree, get_update_lists, update_error_nodes, get_original_node_color, - sv_first_run, is_first_run, reset_error_nodes) from sverchok.core.links import ( @@ -338,8 +337,6 @@ class SverchCustomTree(NodeTree, SvNodeTreeCommon): self.tree_link_count = link_count return True - - def update(self): ''' Tags tree for update for handle -- GitLab From ebc9c0b995701690f4581279c99c0c38bdd069f4 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Thu, 23 Apr 2020 01:01:04 +0200 Subject: [PATCH 34/43] and more cleaning 3 --- core/handlers.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/handlers.py b/core/handlers.py index a4b1afaed..b11cde79a 100644 --- a/core/handlers.py +++ b/core/handlers.py @@ -206,7 +206,7 @@ def sv_post_load(scene): except: traceback.print_exc() ng.unfreeze(True) - # load_nodes_in_node_dict(ng) + ng.sv_process = True addon_name = data_structure.SVERCHOK_NAME addon = bpy.context.preferences.addons.get(addon_name) @@ -240,7 +240,6 @@ def set_frame_change(mode): pre.append(sv_update_handler) - handler_dict = { 'undo_pre': sv_handler_undo_pre, 'undo_post': sv_handler_undo_post, -- GitLab From aecab3cdebb3bbc550bb8c5b7c24a65c66753728 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Thu, 23 Apr 2020 16:44:01 +0200 Subject: [PATCH 35/43] import missing --- core/socket_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/socket_data.py b/core/socket_data.py index 0956bde18..7b8f76e51 100644 --- a/core/socket_data.py +++ b/core/socket_data.py @@ -17,7 +17,7 @@ # ##### END GPL LICENSE BLOCK ##### from sverchok import data_structure -from sverchok.utils.logging import warning, info +from sverchok.utils.logging import warning, info, debug ##################################### # socket data cache # -- GitLab From ffc00a7cda3e7f88e585732789f6806a947eacab Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Thu, 23 Apr 2020 22:25:16 +0200 Subject: [PATCH 36/43] bugfix from renaming --- node_tree.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node_tree.py b/node_tree.py index d27c2f962..5b3040d30 100644 --- a/node_tree.py +++ b/node_tree.py @@ -752,7 +752,7 @@ class SverchCustomTreeNode: self.use_custom_color, self.color = settings self.sv_copy(original) self.n_id = "" - load_in_node_dict(self) + self.id_data.nodes_dict.load_node(self) def sv_copy(self, original): """ -- GitLab From 861c0acee077f8f0bf33009fd649d86694f3fee8 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Thu, 23 Apr 2020 22:48:02 +0200 Subject: [PATCH 37/43] restore travis file --- .travis.yml | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index bf63e3574..c660f1640 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,20 +11,17 @@ install: #set -x #set -e if [ $TRAVIS_BRANCH = "master" ] - then BLENDER_VERSION=2.82 - BLENDER_URL=https://ftp.nluug.nl/pub/graphics/blender/release/Blender2.82/blender-2.82a-linux64.tar.xz - SVERCHOK_DIR=scripts/addons/sverchok - BLENDER_TAR=$(basename $BLENDER_URL) - BLENDER_DIR=$(basename $BLENDER_URL .tar.xz) + then BLENDER_VERSION=2.80 + BLENDER_URL=https://ftp.nluug.nl/pub/graphics/blender/release/Blender2.80/blender-2.80-linux-glibc217-x86_64.tar.bz2 + SVERCHOK_DIR=scripts/addons_contrib/sverchok else BLENDER_VERSION=2.79 BLENDER_URL=https://download.blender.org/release/Blender2.79/blender-2.79b-linux-glibc219-x86_64.tar.bz2 SVERCHOK_DIR=scripts/addons/sverchok - BLENDER_TAR=$(basename $BLENDER_URL) - BLENDER_DIR=$(basename $BLENDER_URL .tar.bz2) fi - + BLENDER_TAR=$(basename $BLENDER_URL) + BLENDER_DIR=$(basename $BLENDER_URL .tar.bz2) if [ ! -f installation/blender/blender ] - then + then mkdir -p installation cd installation wget $BLENDER_URL @@ -76,3 +73,4 @@ deploy: cache: directories: - ${PWD}/installation + -- GitLab From 142f8c8b087756d189e898fcf8ba73e9b4252998 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Thu, 23 Apr 2020 23:40:53 +0200 Subject: [PATCH 38/43] some security checks --- core/node_id_dict.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/core/node_id_dict.py b/core/node_id_dict.py index dbe4b8ee1..37326ff5b 100644 --- a/core/node_id_dict.py +++ b/core/node_id_dict.py @@ -18,11 +18,21 @@ # ##### END GPL LICENSE BLOCK ##### class SvNodesDict: + ''' + Class to store a dictionary to find nodes by node_id + ''' sv_node_dict_cache = {} - def to_node_name(self, node_tree, affected_nodes): + def to_node_name(self, node_tree, nodes_id): tree_id = node_tree.tree_id - return [self.sv_node_dict_cache[tree_id][node_id] for node_id in affected_nodes if node_id in self.sv_node_dict_cache[tree_id]] + if not node_tree.tree_id in self.sv_node_dict_cache: + self.load_nodes(node_tree) + node_dict = self.sv_node_dict_cache[tree_id] + nodes_name = [] + for node_id in nodes_id: + if node_id in node_dict: + nodes_name.append(node_dict[node_id]) + return nodes_name def load_node(self, node): -- GitLab From 9bb10c230a3d8ae86d99b083ce6a15ef2c97e50b Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Fri, 24 Apr 2020 19:05:36 +0200 Subject: [PATCH 39/43] lets look deeper --- core/links.py | 1 + 1 file changed, 1 insertion(+) diff --git a/core/links.py b/core/links.py index 04adf079f..f3739095b 100644 --- a/core/links.py +++ b/core/links.py @@ -168,4 +168,5 @@ class SvLinks: ) affected_nodes = new_linked_nodes + new_unlinked_linked_nodes node_list = node_tree.nodes_dict.to_node_name(node_tree, affected_nodes) + print(node_list) return node_list -- GitLab From 9fedfc932cb12230ae204befdd88159400e99989 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Fri, 24 Apr 2020 19:18:32 +0200 Subject: [PATCH 40/43] could this be? --- utils/sv_IO_panel_tools.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/sv_IO_panel_tools.py b/utils/sv_IO_panel_tools.py index 8a3439e1e..d24bf5b42 100644 --- a/utils/sv_IO_panel_tools.py +++ b/utils/sv_IO_panel_tools.py @@ -640,13 +640,13 @@ def add_nodes(ng, nodes_to_import, nodes, create_texts): ''' name_remap = {} ng.limited_init = True - ng.skip_tree_update = True + # ng.skip_tree_update = True try: for n in sorted(nodes_to_import): add_node_to_tree(nodes, n, nodes_to_import, name_remap, create_texts) except Exception as err: exception(err) - ng.skip_tree_update = False + # ng.skip_tree_update = False ng.limited_init = False return name_remap -- GitLab From d0b69857b46b240c891f05e56e3a4989709db51b Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Sun, 26 Apr 2020 17:20:06 +0200 Subject: [PATCH 41/43] looking inside --- nodes/modifier_make/adaptive_polygons_mk2.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nodes/modifier_make/adaptive_polygons_mk2.py b/nodes/modifier_make/adaptive_polygons_mk2.py index 9e94fd982..05686e6db 100644 --- a/nodes/modifier_make/adaptive_polygons_mk2.py +++ b/nodes/modifier_make/adaptive_polygons_mk2.py @@ -607,6 +607,7 @@ class SvAdaptivePolygonsNodeMk2(bpy.types.Node, SverchCustomTreeNode): # from it's bounding square to # [-1/2; 1/2] square. # Leave Z coordinate as it was. + print(donor.min_x, donor.max_x) x = self.map_bounds(donor.min_x, donor.max_x, v[X]) y = self.map_bounds(donor.min_y, donor.max_y, v[Y]) z = v[Z] -- GitLab From 1a44c92abb9c662fb89229376ddbd87759389e9c Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Sun, 26 Apr 2020 17:41:30 +0200 Subject: [PATCH 42/43] revert last commit --- nodes/modifier_make/adaptive_polygons_mk2.py | 1 - 1 file changed, 1 deletion(-) diff --git a/nodes/modifier_make/adaptive_polygons_mk2.py b/nodes/modifier_make/adaptive_polygons_mk2.py index 05686e6db..9e94fd982 100644 --- a/nodes/modifier_make/adaptive_polygons_mk2.py +++ b/nodes/modifier_make/adaptive_polygons_mk2.py @@ -607,7 +607,6 @@ class SvAdaptivePolygonsNodeMk2(bpy.types.Node, SverchCustomTreeNode): # from it's bounding square to # [-1/2; 1/2] square. # Leave Z coordinate as it was. - print(donor.min_x, donor.max_x) x = self.map_bounds(donor.min_x, donor.max_x, v[X]) y = self.map_bounds(donor.min_y, donor.max_y, v[Y]) z = v[Z] -- GitLab From 8b317f29f1e4558ac7ed7280088116c7d1aa33b8 Mon Sep 17 00:00:00 2001 From: Victor Doval <10011941+vicdoval@users.noreply.github.com> Date: Mon, 27 Apr 2020 00:04:02 +0200 Subject: [PATCH 43/43] removing update call in viewer idx node --- nodes/viz/viewer_idx28.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/nodes/viz/viewer_idx28.py b/nodes/viz/viewer_idx28.py index 78eceba37..cf4bb5fdc 100644 --- a/nodes/viz/viewer_idx28.py +++ b/nodes/viz/viewer_idx28.py @@ -157,11 +157,6 @@ class SvIDXViewer28(bpy.types.Node, SverchCustomTreeNode): colx.scale_x = little_width colx.prop(self, colprop, text="") - def update(self): - # used because this node should disable itself if no inputs. - n_id = node_id(self) - callback_disable(n_id) - def get_face_extras(self, geom): face_medians = [] face_normals = [] -- GitLab