diff options
-rw-r--r-- | mesh_snap_utilities_line/__init__.py | 7 | ||||
-rw-r--r-- | mesh_snap_utilities_line/common_classes.py | 179 | ||||
-rw-r--r-- | mesh_snap_utilities_line/ops_line.py | 2 | ||||
-rw-r--r-- | mesh_snap_utilities_line/preferences.py | 2 | ||||
-rw-r--r-- | mesh_snap_utilities_line/snap_context_l/__init__.py | 34 | ||||
-rw-r--r-- | mesh_snap_utilities_line/snap_context_l/mesh_drawing.py | 6 |
6 files changed, 112 insertions, 118 deletions
diff --git a/mesh_snap_utilities_line/__init__.py b/mesh_snap_utilities_line/__init__.py index d03046cc..dc086540 100644 --- a/mesh_snap_utilities_line/__init__.py +++ b/mesh_snap_utilities_line/__init__.py @@ -105,7 +105,7 @@ def register_snap_tools(): tools[:index] += None, tool_line - del tools + del tool, tools, index keyconfigs = bpy.context.window_manager.keyconfigs kc_defaultconf = keyconfigs.get("blender") @@ -126,8 +126,7 @@ def unregister_snap_tools(): tools.pop(index) tools.remove(tool_line) - del tools - del index + del tools, index keyconfigs = bpy.context.window_manager.keyconfigs defaultmap = keyconfigs.get("blender").keymaps @@ -144,7 +143,7 @@ def unregister_snap_tools(): # Addon Registraion classes = ( - preferences.SnapUtilitiesLinePreferences, + preferences.SnapUtilitiesPreferences, ops_line.SnapUtilitiesLine, common_classes.VIEW3D_OT_rotate_custom_pivot, common_classes.VIEW3D_OT_zoom_custom_target, diff --git a/mesh_snap_utilities_line/common_classes.py b/mesh_snap_utilities_line/common_classes.py index ae763828..a096415d 100644 --- a/mesh_snap_utilities_line/common_classes.py +++ b/mesh_snap_utilities_line/common_classes.py @@ -504,13 +504,12 @@ class SnapUtilities: 'LEFT_SHIFT': 'shift', } - snap_widget = None - snap_widget_refcnt = 0 + snapwidgets = [] constrain = None @staticmethod def set_contrain(context, key): - widget = SnapUtilities.snap_widget + widget = SnapUtilities.snapwidgets[-1] if SnapUtilities.snapwidgets else None if SnapUtilities.constrain == key: SnapUtilities.constrain = None return @@ -518,34 +517,51 @@ class SnapUtilities: SnapUtilities.constrain = key - def visible_objects_and_duplis(self, context): - if self.preferences.outer_verts: - for obj in context.visible_objects: - yield (obj, obj.matrix_world) + def snap_context_update(self, context): + def visible_objects_and_duplis(): + if self.preferences.outer_verts: + for obj in context.visible_objects: + yield (obj, obj.matrix_world) + + if obj.instance_type == 'COLLECTION': + mat = obj.matrix_world.copy() + for ob in obj.instance_collection.objects: + yield (ob, mat @ ob.matrix_world) + else: + for obj in context.objects_in_mode_unique_data: + yield (obj, obj.matrix_world) - if obj.instance_type == 'COLLECTION': - mat = obj.matrix_world.copy() - for ob in obj.instance_collection.objects: - yield (ob, mat @ ob.matrix_world) - else: - for obj in context.objects_in_mode_unique_data: - yield (obj, obj.matrix_world) + self.sctx.clear_snap_objects() + for obj, matrix in visible_objects_and_duplis(): + self.sctx.add_obj(obj, matrix) def snap_context_init(self, context, snap_edge_and_vert = True): from .snap_context_l import global_snap_context_get #Create Snap Context - self.sctx = global_snap_context_get(context.region, context.space_data) + self.sctx = global_snap_context_get(context.depsgraph, context.region, context.space_data) self.sctx.set_pixel_dist(12) self.sctx.use_clip_planes(True) - widget = self.snap_widget + if SnapUtilities.snapwidgets: + widget = SnapUtilities.snapwidgets[-1] - if widget is not None: + self.snap_obj = widget.snap_obj + self.bm = widget.bm + self.geom = widget.geom + self.type = widget.type + self.location = widget.location self.preferences = widget.preferences self.draw_cache = widget.draw_cache else: + #init these variables to avoid errors + self.snap_obj = None + self.bm = None + self.geom = None + self.type = 'OUT' + self.location = Vector() + preferences = context.preferences.addons[__package__].preferences self.preferences = preferences #Init DrawCache @@ -568,7 +584,8 @@ class SnapUtilities: self.snap_face = not (snap_edge_and_vert and (shading.show_xray or shading.type == 'WIREFRAME')) - self.snap_context_update(context) + self.sctx.set_snap_mode( + self.snap_vert, self.snap_edge, self.snap_face) #Configure the unit of measure unit_system = context.scene.unit_settings.system @@ -579,31 +596,6 @@ class SnapUtilities: self.incremental = bpy.utils.units.to_value( unit_system, 'LENGTH', str(self.preferences.incremental)) - def snap_context_update(self, context): - self.sctx.set_snap_mode( - self.snap_vert, self.snap_edge, self.snap_face) - - self.sctx.clear_snap_objects() - - for obj, matrix in self.visible_objects_and_duplis(context): - self.sctx.add_obj(obj, matrix) - - widget = self.snap_widget - - if widget: - self.snap_obj = widget.snap_obj - self.bm = widget.bm - self.geom = widget.geom - self.type = widget.type - self.location = widget.location - else: - #init these variables to avoid errors - self.snap_obj = None - self.bm = None - self.geom = None - self.type = 'OUT' - self.location = Vector() - def snap_to_grid(self): if self.type == 'OUT' and self.preferences.increments_grid: loc = self.location / self.rd @@ -612,6 +604,7 @@ class SnapUtilities: round(loc.z))) * self.rd def snap_context_free(self): + self.sctx = None del self.sctx del self.bm @@ -636,7 +629,18 @@ class SnapUtilities: # return False -class SnapWidgetCommon: +class SnapWidgetCommon(SnapUtilities): + snap_to_update = False + + def handler(self, scene): + cls = SnapWidgetCommon + if cls.snap_to_update is False: + last_operator = self.wm_operators[-1] if self.wm_operators else None + if (not last_operator or + last_operator.name not in {'Select', 'Loop Select', '(De)select All'}): + cls.snap_to_update = self.depsgraph.id_type_updated('MESH') or\ + self.depsgraph.id_type_updated('OBJECT') + def draw_point_and_elem(self): if self.bm: if self.bm.is_valid and self.geom.is_valid: @@ -648,33 +652,49 @@ class SnapWidgetCommon: self.draw_cache.draw(self.type, self.location, None, None, None) - def init_snap_widget(self, context, snap_edge_and_vert = True): + def init_snapwidget(self, context, snap_edge_and_vert = True): self.snap_context_init(context, snap_edge_and_vert) + self.snap_context_update(context) self.mode = context.mode - self.wm_operators = context.window_manager.operators - self.last_operator = self.wm_operators[-1] if self.wm_operators else None self.last_mval = None + self.wm_operators = context.window_manager.operators + self.depsgraph = context.depsgraph + bpy.app.handlers.depsgraph_update_post.append(self.handler) + SnapWidgetCommon.snap_to_update = False + + SnapUtilities.snapwidgets.append(self) + + def end_snapwidget(self): + SnapUtilities.snapwidgets.remove(self) + + #from .snap_context_l import global_snap_context_get + #sctx = global_snap_context_get(None, None, None) + + StructRNA = bpy.types.bpy_struct + sctx = super(StructRNA, self).__getattribute__("sctx") + if sctx and not SnapUtilities.snapwidgets: + sctx.clear_snap_objects() + + handler = super(StructRNA, self).__getattribute__("handler") + bpy.app.handlers.depsgraph_update_post.remove(handler) + def update_snap(self, context, mval): if self.last_mval == mval: return -1 else: self.last_mval = mval - last_operator = self.wm_operators[-1] if self.wm_operators else None - if last_operator != self.last_operator: - if (not last_operator or - last_operator.name not in {'Select', 'Loop Select', '(De)select All'}): - ## Something has changed since the last time. - # Has the mesh been changed? - # In the doubt lets clear the snap context. - self.sctx.update_all() - - self.last_operator = last_operator + if (SnapWidgetCommon.snap_to_update): + ## Something has changed since the last time. + # Has the mesh been changed? + # In the doubt lets clear the snap context. + self.snap_context_update(context) + SnapWidgetCommon.snap_to_update = False #print('test_select', mval) space = context.space_data - self.sctx.update_viewport_context(context.region, space) + self.sctx.update_viewport_context(context.depsgraph, context.region, space, True) shading = space.shading snap_face = not ((self.snap_vert or self.snap_edge) and @@ -692,33 +712,10 @@ class SnapWidgetCommon: increment=self.incremental ) - def __del__(self): - from .snap_context_l import global_snap_context_get - sctx = global_snap_context_get(None, None) - if sctx: - sctx.clear_snap_objects() - -class SnapPointWidget(SnapUtilities, SnapWidgetCommon, bpy.types.Gizmo): +class SnapPointWidget(SnapWidgetCommon, bpy.types.Gizmo): bl_idname = "VIEW3D_GT_snap_point" - __slots__ = ( - "bm", - "draw_cache", - "geom", - "incremental", - "preferences", - "last_operator", - "location", - "mode", - "snap_edge", - "snap_face", - "snap_vert", - "snap_obj", - "type", - "wm_operators", - ) - def test_select(self, context, mval): self.update_snap(context, mval) self.snap_to_grid() @@ -730,8 +727,7 @@ class SnapPointWidget(SnapUtilities, SnapWidgetCommon, bpy.types.Gizmo): self.draw_point_and_elem() def setup(self): - self.init_snap_widget(bpy.context) - SnapUtilities.snap_widget = self + self.init_snapwidget(bpy.context) def context_mode_check(context, widget_group): @@ -744,7 +740,8 @@ def context_mode_check(context, widget_group): return False return True -class SnapWidgetCommon: + +class SnapWidgetGroupCommon: bl_space_type = 'VIEW_3D' bl_region_type = 'WINDOW' bl_options = {'3D'} @@ -752,20 +749,16 @@ class SnapWidgetCommon: @classmethod def poll(cls, context): return context_mode_check(context, cls.bl_idname) -# return context_mode_change( -# context, SnapUtilities.snap_widget, cls.bl_idname) def init_tool(self, context, gizmo_name): - self.gizmos.new(gizmo_name) - SnapUtilities.snap_widget_refcnt += 1 + self.widget = self.gizmos.new(gizmo_name) def __del__(self): - SnapUtilities.snap_widget_refcnt -= 1 - if SnapUtilities.snap_widget_refcnt == 0: - SnapUtilities.snap_widget = None + if hasattr(self, "widget"): + super(bpy.types.bpy_struct, self.widget).__getattribute__("end_snapwidget")() -class SnapPointWidgetGroup(SnapWidgetCommon, bpy.types.GizmoGroup): +class SnapPointWidgetGroup(SnapWidgetGroupCommon, bpy.types.GizmoGroup): bl_idname = "MESH_GGT_snap_point" bl_label = "Draw Snap Point" diff --git a/mesh_snap_utilities_line/ops_line.py b/mesh_snap_utilities_line/ops_line.py index ba5b5a1a..891a6d29 100644 --- a/mesh_snap_utilities_line/ops_line.py +++ b/mesh_snap_utilities_line/ops_line.py @@ -407,6 +407,8 @@ class SnapUtilitiesLine(SnapUtilities, bpy.types.Operator): def invoke(self, context, event): if context.space_data.type == 'VIEW_3D': self.snap_context_init(context) + self.snap_context_update(context) + self.intersect = self.preferences.intersect self.create_face = self.preferences.create_face self.navigation_ops = SnapNavigation(context, True) diff --git a/mesh_snap_utilities_line/preferences.py b/mesh_snap_utilities_line/preferences.py index 98b89774..af2ca231 100644 --- a/mesh_snap_utilities_line/preferences.py +++ b/mesh_snap_utilities_line/preferences.py @@ -26,7 +26,7 @@ from bpy.props import ( ) -class SnapUtilitiesLinePreferences(bpy.types.AddonPreferences): +class SnapUtilitiesPreferences(bpy.types.AddonPreferences): # this must match the addon name, use '__package__' # when defining this in a submodule of a python package. bl_idname = __package__ diff --git a/mesh_snap_utilities_line/snap_context_l/__init__.py b/mesh_snap_utilities_line/snap_context_l/__init__.py index 17e8ff54..3f663434 100644 --- a/mesh_snap_utilities_line/snap_context_l/__init__.py +++ b/mesh_snap_utilities_line/snap_context_l/__init__.py @@ -192,7 +192,7 @@ class SnapContext(): :type space: :class:`bpy.types.SpaceView3D` """ - def __init__(self, region, space): + def __init__(self, depsgraph, region, space): #print('Render:', bgl.glGetString(bgl.GL_RENDERER)) #print('OpenGL Version:', bgl.glGetString(bgl.GL_VERSION)) @@ -202,6 +202,7 @@ class SnapContext(): self._offset_cur = 1 # Starts with index 1 self.region = region self.rv3d = space.region_3d + self.depsgraph = depsgraph if self.rv3d.is_perspective: self.depth_range = Vector((space.clip_start, space.clip_end)) @@ -337,12 +338,13 @@ class SnapContext(): ## PUBLIC ## - def update_viewport_context(self, region, space): + def update_viewport_context(self, depsgraph, region, space, resize = False): rv3d = space.region_3d - if region == self.region and rv3d == self.rv3d: + if not resize and self.rv3d == rv3d and self.region == region: return + self.depsgraph = depsgraph self.region = region self.rv3d = rv3d @@ -351,8 +353,11 @@ class SnapContext(): else: self.depth_range = Vector((-space.clip_end, space.clip_end)) - self.winsize = Vector((self.region.width, self.region.height)) - self._offscreen.resize(*self.winsize) + winsize = Vector((self.region.width, self.region.height)) + + if winsize != self.winsize: + self.winsize = winsize + self._offscreen.resize(*self.winsize) def clear_snap_objects(self): self.update_all() @@ -392,7 +397,7 @@ class SnapContext(): snap_obj.data[1].free() snap_obj.data.pop(1) - data = GPU_Indices_Mesh(snap_obj.data[0], snap_face, snap_edge, snap_vert) + data = GPU_Indices_Mesh(self.depsgraph, snap_obj.data[0], snap_face, snap_edge, snap_vert) snap_obj.data.append(data) _Internal.gpu_Indices_restore_state() @@ -479,7 +484,7 @@ class SnapContext(): draw_face = snap_face and not is_bound and obj.display_type != 'WIRE' draw_edge = snap_edge and not is_bound draw_vert = snap_vert and not is_bound - snap_obj.data.append(GPU_Indices_Mesh(obj, draw_face, draw_edge, draw_vert)) + snap_obj.data.append(GPU_Indices_Mesh(self.depsgraph, obj, draw_face, draw_edge, draw_vert)) snap_obj.data[1].set_draw_mode(snap_face, snap_edge, snap_vert) snap_obj.data[1].set_ModelViewMatrix(snap_obj.mat) @@ -520,25 +525,20 @@ class SnapContext(): self.__del__() self.freed = True -def global_snap_context_get(region, space): +def global_snap_context_get(depsgraph, region, space): if _Internal.global_snap_context == None: - if region is None or space is None: + if depsgraph is None or region is None or space is None: return import atexit - _Internal.global_snap_context = SnapContext(region, space) + _Internal.global_snap_context = SnapContext(depsgraph, region, space) # Make sure we only registered the callback once. atexit.unregister(_Internal.snap_context_free) atexit.register(_Internal.snap_context_free) - elif region is not None: - _Internal.global_snap_context.update_viewport_context(region, space) - - if ((region.width != _Internal.global_snap_context._offscreen.width) or - (region.height != _Internal.global_snap_context._offscreen.height)): - _Internal.global_snap_context.winsize[:] = region.width, region.height - _Internal.global_snap_context._offscreen.resize(region.width, region.height) + elif depsgraph is not None: + _Internal.global_snap_context.update_viewport_context(depsgraph, region, space, True) return _Internal.global_snap_context diff --git a/mesh_snap_utilities_line/snap_context_l/mesh_drawing.py b/mesh_snap_utilities_line/snap_context_l/mesh_drawing.py index da47fca7..cca4ca52 100644 --- a/mesh_snap_utilities_line/snap_context_l/mesh_drawing.py +++ b/mesh_snap_utilities_line/snap_context_l/mesh_drawing.py @@ -233,8 +233,8 @@ class GPU_Indices_Mesh(): gpu.matrix.load_matrix(MV) - def __init__(self, obj, draw_tris, draw_edges, draw_verts): - self.ob_data = obj.data + def __init__(self, depsgraph, obj, draw_tris, draw_edges, draw_verts): + self.ob_data = obj.data.original if self.ob_data in GPU_Indices_Mesh._Hash: src = GPU_Indices_Mesh._Hash[self.ob_data] @@ -270,7 +270,7 @@ class GPU_Indices_Mesh(): GPU_Indices_Mesh.init_opengl() ## Init Array ## - mesh_arrays = _Mesh_Arrays(obj, draw_tris, draw_edges, draw_verts) + mesh_arrays = _Mesh_Arrays(depsgraph.id_eval_get(obj), draw_tris, draw_edges, draw_verts) if mesh_arrays.verts_co is None: self.draw_tris = False |