mesh_snap_utilities_line: Use depsgraph API to evaluate updates
And cleanup.
This commit is contained in:
parent
dd594a9d72
commit
7cdfb60f78
|
@ -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,
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue