diff --git a/core/handlers.py b/core/handlers.py index ac7961d1708554999259d5e69523e080df1bb3b7..347c3897dd2c1435bf0f0ea7cd818472d03bfa48 100644 --- a/core/handlers.py +++ b/core/handlers.py @@ -6,6 +6,8 @@ from bpy.app.handlers import persistent from sverchok import old_nodes from sverchok import data_structure from sverchok.core import upgrade_nodes, upgrade_group +from sverchok.utils.context_managers import hard_freeze +from sverchok.core.update_system import process_from_node from sverchok.ui import ( viewer_draw, @@ -17,7 +19,7 @@ from sverchok.ui import ( color_def ) - +objects_nodes_set = {'ObjectsNode', 'ObjectsNodeMK2', 'SvObjectsNodeMK3'} _state = {'frame': None} def sverchok_trees(): @@ -78,6 +80,43 @@ def sv_main_handler(scene): ng.process() +@persistent +def sv_object_live_update(scene): + # This handler is created especially for objects in nodes. When live updated is enabled in 3d panel this handler + # detects user changes of objects and call process of appropriate objects in node. + if not scene.SvShowIn3D_active: + return + + obj_nodes = [] + for ng in bpy.data.node_groups: + # search of objects in nodes + if ng.bl_idname == 'SverchCustomTreeType': + if ng.sv_process: + nodes = [] + for n in ng.nodes: + if n.bl_idname in objects_nodes_set: + nodes.append(n) + if nodes: + obj_nodes.append(nodes) + + for nodes in obj_nodes: + # Nodes of current node tree + for node in nodes: + for i in node.object_names: + # object_names is collections of names of objects of SvObjectsNodeMK3 + try: + obj = bpy.data.objects[i.name] + except KeyError: + continue + if obj.is_updated or obj.is_updated_data or obj.data.is_updated: + # check changes of object + with hard_freeze(node): + # freeze node tree for avoiding updating whole nodes of the tree + # print('calling process on:', node.name, node.id_data) + process_from_node(node) + # calling process_from_node switch node tree condition to has changed, that is not true + node.id_data.has_changed = False + @persistent def sv_clean(scene): """ @@ -178,6 +217,7 @@ def register(): bpy.app.handlers.load_pre.append(sv_clean) bpy.app.handlers.load_post.append(sv_post_load) bpy.app.handlers.scene_update_pre.append(sv_main_handler) + bpy.app.handlers.scene_update_post.append(sv_object_live_update) data_structure.setup_init() addon_name = data_structure.SVERCHOK_NAME addon = bpy.context.user_preferences.addons.get(addon_name) @@ -191,4 +231,5 @@ def unregister(): bpy.app.handlers.load_pre.remove(sv_clean) bpy.app.handlers.load_post.remove(sv_post_load) bpy.app.handlers.scene_update_pre.remove(sv_main_handler) + bpy.app.handlers.scene_update_post.remove(sv_object_live_update) set_frame_change(None) diff --git a/settings.py b/settings.py index 100c9a3fcb715c71c9a761463f47e52e962751b7..e77de78f5a6ee18f5a8c3b84ee42cf89b7319602 100644 --- a/settings.py +++ b/settings.py @@ -160,9 +160,6 @@ class SverchokPreferences(AddonPreferences): over_sized_buttons = BoolProperty( default=False, name="Big buttons", description="Very big buttons") - enable_live_objin = BoolProperty( - description="Objects in edit mode will be updated in object-in Node") - render_scale = FloatProperty( default=1.0, min=0.01, step=0.01, description='default render scale') @@ -234,7 +231,6 @@ class SverchokPreferences(AddonPreferences): col1.label(text="UI:") col1.prop(self, "show_icons") col1.prop(self, "over_sized_buttons") - col1.prop(self, "enable_live_objin", text='Enable Live Object-In') col1.prop(self, "external_editor", text="Ext Editor") col1.prop(self, "real_sverchok_path", text="Src Directory") diff --git a/ui/sv_panels.py b/ui/sv_panels.py index e9e3ef525fb63e3cc003e6180f337ac88e934923..15973d69e500189db88f468368396b5e424f29ff 100644 --- a/ui/sv_panels.py +++ b/ui/sv_panels.py @@ -21,90 +21,7 @@ from bpy.props import StringProperty, BoolProperty, FloatProperty import sverchok from sverchok.utils.sv_update_utils import version_and_sha -from sverchok.core.update_system import process_from_node from sverchok.utils import profile -from sverchok.utils.context_managers import hard_freeze - -objects_nodes_set = {'ObjectsNode', 'ObjectsNodeMK2', 'SvObjectsNodeMK3'} - - -class Sv3DViewObjInUpdater(bpy.types.Operator, object): - """Operator which runs its self from a timer""" - bl_idname = "wm.sv_obj_modal_update" - bl_label = "start n stop obj updating" - - _timer = None - mode = StringProperty(default='') - node_name = StringProperty(default='') - node_group = StringProperty(default='') - speed = FloatProperty(default=1 / 13) - - def modal(self, context, event): - - if not context.scene.SvShowIn3D_active: - self.cancel(context) - return {'FINISHED'} - - if not (event.type == 'TIMER'): - return {'PASS_THROUGH'} - - obj_nodes = [] - for ng in bpy.data.node_groups: - if ng.bl_idname == 'SverchCustomTreeType': - if ng.sv_process: - nodes = [] - for n in ng.nodes: - if n.bl_idname in objects_nodes_set: - nodes.append(n) - if nodes: - obj_nodes.append(nodes) - - ''' reaches here only if event is TIMER and self.active ''' - for nodes in obj_nodes: - # Nodes of current node tree - for node in nodes: - for i in node.object_names: - # object_names is collections of names of objects of SvObjectsNodeMK3 - try: - obj = bpy.data.objects[i.name] - except KeyError: - continue - if obj.is_updated or obj.is_updated_data or obj.data.is_updated: - # check changes of object - with hard_freeze(node): - # freeze node tree for avoiding updating whole nodes of the tree - # print('calling process on:', node.name, node.id_data) - process_from_node(node) - # calling process_from_node switch node tree condition to has changed, that is not true - node.id_data.has_changed = False - - return {'PASS_THROUGH'} - - def event_dispatcher(self, context, type_op): - if type_op == 'start': - context.scene.SvShowIn3D_active = True - - # rate can only be set in event_timer_add (I think...) - # self.speed = 1 / context.node.updateRate - - wm = context.window_manager - self._timer = wm.event_timer_add(self.speed, context.window) - wm.modal_handler_add(self) - - if type_op == 'end': - context.scene.SvShowIn3D_active = False - - def execute(self, context): - # n = context.node - # self.node_name = context.node.name - # self.node_group = context.node.id_data.name - - self.event_dispatcher(context, self.mode) - return {'RUNNING_MODAL'} - - def cancel(self, context): - wm = context.window_manager - wm.event_timer_remove(self._timer) class Sv3DPanel(bpy.types.Panel): @@ -120,16 +37,15 @@ class Sv3DPanel(bpy.types.Panel): layout = self.layout little_width = 0.12 - addon = context.user_preferences.addons.get(sverchok.__name__) - if addon.preferences.enable_live_objin: - - # Live Update Modal trigger. - row = layout.row() - OP = 'wm.sv_obj_modal_update' - if context.scene.SvShowIn3D_active: - row.operator(OP, text='Stop live update', icon='CANCEL').mode = 'end' - else: - row.operator(OP, text='Start live update', icon='EDIT').mode = 'start' + # Live Update Modal trigger. + row = layout.row() + if context.scene.SvShowIn3D_active: + text = 'Stop live update' + icon = 'CANCEL' + else: + text = 'Start live update' + icon = 'EDIT' + row.prop(context.scene, 'SvShowIn3D_active', text=text, icon=icon) col = layout.column(align=True) row = col.row(align=True) @@ -384,7 +300,6 @@ class SverchokToolsMenu(bpy.types.Panel): sv_tools_classes = [ - Sv3DViewObjInUpdater, SverchokToolsMenu, Sv3DPanel, ]