1 # SPDX-FileCopyrightText: 2019-2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
7 from .common_classes
import SnapUtilities
8 from .common_utilities
import snap_utilities
11 # def mesh_runtime_batchcache_isdirty(me):
13 # batch_cache = ctypes.c_void_p.from_address(me.as_pointer() + 1440)
15 # return ctypes.c_bool.from_address(batch_cache.value + 549).value
19 class SnapWidgetCommon(SnapUtilities
, bpy
.types
.Gizmo
):
20 # __slots__ = ('inited', 'mode', 'last_mval')
22 snap_to_update
= False
24 def handler(self
, scene
, depsgraph
):
25 cls
= SnapWidgetCommon
26 if cls
.snap_to_update
is False:
27 last_operator
= self
.wm_operators
[-1] if self
.wm_operators
else None
28 if not last_operator
or last_operator
.name
not in {'Select', 'Loop Select', '(De)select All'}:
29 cls
.snap_to_update
= depsgraph
.id_type_updated('MESH') or depsgraph
.id_type_updated('OBJECT')
31 def draw_point_and_elem(self
):
32 if self
.bm
and self
.geom
:
33 if self
.bm
.is_valid
and self
.geom
.is_valid
:
34 self
.draw_cache
.draw_elem(self
.snap_obj
, self
.bm
, self
.geom
)
39 self
.draw_cache
.draw(self
.type, self
.location
, None, None, None)
41 def init_delayed(self
):
44 def init_snapwidget(self
, context
, snap_edge_and_vert
=True):
47 self
.snap_context_init(context
, snap_edge_and_vert
)
48 self
.snap_context_update(context
)
49 self
.mode
= context
.mode
52 self
.wm_operators
= context
.window_manager
.operators
53 bpy
.app
.handlers
.depsgraph_update_post
.append(self
.handler
)
54 SnapWidgetCommon
.snap_to_update
= False
56 SnapUtilities
.snapwidgets
.append(self
)
58 def end_snapwidget(self
):
59 if self
in SnapUtilities
.snapwidgets
:
60 SnapUtilities
.snapwidgets
.remove(self
)
62 # from .snap_context_l import global_snap_context_get
63 # sctx = global_snap_context_get(None, None, None)
65 sctx
= object.__getattribute
__(self
, 'sctx')
66 if sctx
and not SnapUtilities
.snapwidgets
:
67 sctx
.clear_snap_objects()
69 handler
= object.__getattribute
__(self
, 'handler')
70 bpy
.app
.handlers
.depsgraph_update_post
.remove(handler
)
72 def update_snap(self
, context
, mval
):
73 if self
.last_mval
== mval
:
78 if SnapWidgetCommon
.snap_to_update
:
79 # Something has changed since the last time.
80 # Has the mesh been changed?
81 # In the doubt lets clear the snap context.
82 self
.snap_context_update(context
)
83 SnapWidgetCommon
.snap_to_update
= False
85 # print('test_select', mval)
86 space
= context
.space_data
87 self
.sctx
.update_viewport_context(
88 context
.evaluated_depsgraph_get(), context
.region
, space
, True)
90 shading
= space
.shading
91 snap_face
= not ((self
.snap_vert
or self
.snap_edge
) and
92 (shading
.show_xray
or shading
.type == 'WIREFRAME'))
94 if snap_face
!= self
.snap_face
:
95 self
.snap_face
= snap_face
96 self
.sctx
.set_snap_mode(
97 self
.snap_vert
, self
.snap_edge
, self
.snap_face
)
99 snap_utilities
.cache
.clear()
100 self
.snap_obj
, prev_loc
, self
.location
, self
.type, self
.bm
, self
.geom
, len = snap_utilities(
104 increment
=self
.incremental
108 class SnapPointWidget(SnapWidgetCommon
):
109 bl_idname
= "VIEW3D_GT_snap_point"
113 def test_select(self
, context
, mval
):
115 self
.init_snapwidget(context
)
117 self
.update_snap(context
, mval
)
120 context
.area
.tag_redraw()
123 def draw(self
, context
):
125 self
.draw_point_and_elem()
131 def context_mode_check(context
, widget_group
):
132 tools
= context
.workspace
.tools
135 if (tool
.widget
== widget_group
) and (tool
.mode
== mode
):
138 context
.window_manager
.gizmo_group_type_unlink_delayed(widget_group
)
143 class SnapWidgetGroupCommon(bpy
.types
.GizmoGroup
):
144 bl_space_type
= 'VIEW_3D'
145 bl_region_type
= 'WINDOW'
149 def poll(cls
, context
):
150 return context_mode_check(context
, cls
.bl_idname
)
152 def init_tool(self
, context
, gizmo_name
):
153 self
._widget
= self
.gizmos
.new(gizmo_name
)
156 if hasattr(self
, "_widget"):
157 object.__getattribute
__(self
._widget
, 'end_snapwidget')()
160 class SnapPointWidgetGroup(SnapWidgetGroupCommon
):
161 bl_idname
= "MESH_GGT_snap_point"
162 bl_label
= "Draw Snap Point"
164 def setup(self
, context
):
165 self
.init_tool(context
, SnapPointWidget
.bl_idname
)