def sv_post_load(scene): """ Upgrade nodes, apply preferences and do an update. THe update order is next: 1. pre_load handler 2. update methods of trees in a file 3. post_load handler 4. evaluate trees from main tree handler post_load handler is also called when Blender is first ran The method should initialize Sverchok parts which are required by loaded tree """ from sverchok import node_tree, settings # ensure current nodeview view scale / location parameters reflect users' system settings node_tree.SverchCustomTree.update_gl_scale_info(None, "sv_post_load") # register and mark old and dependent nodes with catch_log_error(): if any(not n.is_registered_node_type() for ng in BlTrees().sv_trees for n in ng.nodes): old_nodes.register_all() old_nodes.mark_all() dummy_nodes.register_all() dummy_nodes.mark_all() with catch_log_error(): settings.apply_theme_if_necessary() # when a file is opened as a startup file update method of its trees is not called (Blender inconsistency??) for tree in BlTrees().sv_main_trees: tree.update()
def sv_handler_undo_post(scene): # It also can be called during work of Blender operators - https://developer.blender.org/T89546 # 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 for ng in sverchok_trees(): num_to_test_against += len(ng.nodes) if undo_handler_node_count['sv_groups'] != num_to_test_against: debug('looks like a node was removed, cleaning') sv_clean(scene) sv_main_handler(scene) undo_handler_node_count['sv_groups'] = 0 import sverchok.core.group_handlers as gh gh.GroupContextTrees.reset_data() # todo repeat the logic from main tree? # ideally we would like to recalculate all from scratch # but with heavy trees user can be scared of pressing undo button # I consider changes in tree topology as most common case # but if properties or work of some viewer node (removing generated objects) was effected by undo # only recalculating of all can restore the adequate state of a tree for tree in BlTrees().sv_main_trees: tree.update() # the tree could changed by undo event
def sv_post_load(scene): """ Upgrade nodes, apply preferences and do an update. THe update order is next: 1. pre_load handler 2. update methods of trees in a file 3. post_load handler post_load handler is also called when Blender is first ran The method should remove throttling trees made in pre_load event, initialize Sverchok parts which are required by loaded tree and update all Sverchok trees """ from sverchok import node_tree, settings # ensure current nodeview view scale / location parameters reflect users' system settings node_tree.SverchCustomTree.update_gl_scale_info(None, "sv_post_load") # register and mark old and dependent nodes with catch_log_error(): if any(not n.is_registered_node_type() for ng in BlTrees().sv_trees for n in ng.nodes): old_nodes.register_all() old_nodes.mark_all() dummy_nodes.register_all() dummy_nodes.mark_all() with catch_log_error(): settings.apply_theme_if_necessary() # release all trees and update them set_first_run(False) build_update_list() process_tree()
def sv_main_handler(scene): """ On depsgraph update (pre) """ global pre_running global sv_depsgraph global depsgraph_need # when this handler is called from inside another call to this handler we end early # to avoid stack overflow. if pre_running: return pre_running = True if depsgraph_need: sv_depsgraph = bpy.context.evaluated_depsgraph_get() pre_running = False # When the Play Animation is on this trigger is executed once. Such event # should be suppressed because it repeats animation trigger. When Play # animation is on and user changes something in the scene this trigger is # only called if frame rate is equal to maximum. if bpy.context.screen.is_animation_playing: return for ng in BlTrees().sv_main_trees: ng.scene_update()
def execute(self, context): try: bpy.context.window.cursor_set("WAIT") for tree in BlTrees().sv_main_trees: tree.force_update() finally: bpy.context.window.cursor_set("DEFAULT") return {'FINISHED'}
def _update(self): """Calculate relationships between group trees and main trees""" self._group_main.clear() self._entry_nodes.clear() for tree in BlTrees().sv_main_trees: for gr_tree, gr_node in self._walk(tree): self._group_main[gr_tree].add(tree) self._entry_nodes[tree][gr_tree].add(gr_node) self.is_updated = True
def apply_theme(ng=None): """ Apply theme colors """ if ng is None: for ng in BlTrees().sv_trees: apply_theme(ng) else: for node in ng.nodes: if node.sv_default_color: node.use_custom_color = True node.color = node.sv_default_color
def _finish(self): """Cleanups. Also triggers scene handler and mark trees to skip it""" self._report_progress() del self._main_area # this only need to trigger scene changes handler again # todo should be proved that this is right location to call from bpy.context.scene.update_tag() # this indicates that process of the tree is finished and next scene event can be skipped # the scene trigger will try to update all trees, so they all should be marked for t in BlTrees().sv_main_trees: t['SKIP_UPDATE'] = True gc.enable() debug(f'Global update - {int((time() - self._start_time) * 1000)}ms') del self._start_time
def _update_sockets(self): self._id_sock.clear() for tree in BlTrees().sv_trees: for node in tree.nodes: for sock in chain(node.inputs, node.outputs): if sock.bl_idname in { 'NodeSocketVirtual', 'NodeSocketColor' }: continue if sock.socket_id in self._id_sock: ds = self._id_sock[sock.socket_id] debug( f"SOCKET ID DUPLICATION: " f"1 - {ds.id_data.name} {ds.node.name=} {ds.name=}" f"2 - {sock.id_data.name} {node.name=} {sock.name=}" ) self._id_sock[sock.socket_id] = sock
def global_updater(event_type: str) -> Generator[Node, None, None]: """Find all Sverchok main trees and run their handlers and update their UI if necessary update_ui of group trees will be called only if they opened in one of tree editors update_ui of main trees will be called if they are opened or was changed during the update event""" # grab trees from active node group editors trees_ui_to_update = set() if bpy.context.screen: # during animation rendering can be None for area in bpy.context.screen.areas: if area.ui_type == BlTrees.MAIN_TREE_ID: if area.spaces[0].path: # filter editors without active tree trees_ui_to_update.add(area.spaces[0].path[-1].node_tree) for bl_tree in BlTrees().sv_main_trees: was_changed = False # update only trees which should be animated (for performance improvement in case of many trees) if event_type == TreeEvent.FRAME_CHANGE: if bl_tree.sv_animate: was_changed = yield from tree_updater(bl_tree) # tree should be updated any way elif event_type == TreeEvent.FORCE_UPDATE and 'FORCE_UPDATE' in bl_tree: del bl_tree['FORCE_UPDATE'] was_changed = yield from tree_updater(bl_tree) # this seems the event upon some changes in the tree, skip tree if the property is switched off else: if bl_tree.sv_process: was_changed = yield from tree_updater(bl_tree) # it has sense to call this here if you press update all button or creating group tree from selected if was_changed: bl_tree.update_ui() # this only will update UI of main trees trees_ui_to_update.discard( bl_tree) # protection from double updating # this will update all opened trees (in group editors) # regardless whether the trees was changed or not, including group nodes for bl_tree in trees_ui_to_update: args = [bl_tree.get_update_path() ] if BlTree(bl_tree).is_group_tree else [] bl_tree.update_ui(*args)
def modal(self, context, event): if not context.scene.SvShowIn3D_active: self.cancel(context) return {'FINISHED'} elif not (event.type == 'TIMER'): return {'PASS_THROUGH'} ''' reaches here only if event is TIMER and self.active ''' objects_nodes_set = { 'ObjectsNode', 'ObjectsNodeMK2', 'SvObjectsNodeMK3', 'SvExNurbsInNode', 'SvBezierInNode', 'SvGetObjectsData', 'SvObjectsNodeMK3' } for ng in BlTrees().sv_main_trees: ng.update_nodes( (n for n in ng.nodes if n.bl_idname in objects_nodes_set), cancel=False) return {'PASS_THROUGH'}
def mark_all(): """Add frames with deprecated label to all deprecated nodes if necessary""" for node in (n for t in BlTrees().sv_trees for n in t.nodes): if node.bl_idname in dummy_nodes_dict: mark_dummy(node)
def mark_all(): """Add frames with deprecated label to all deprecated nodes if necessary""" for node in (n for t in BlTrees().sv_trees for n in t.nodes): if node.bl_idname in old_bl_idnames: mark_old(node)