Blender V5.0
snap3d_gizmo.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2020 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
14
15#include "BLI_math_vector.h"
16
17#include "BKE_context.hh"
18#include "BKE_screen.hh"
19
20#include "ED_gizmo_library.hh"
21#include "ED_screen.hh"
22#include "ED_view3d.hh"
23
24#include "RNA_access.hh"
25#include "RNA_define.hh"
26#include "RNA_prototypes.hh"
27
28#include "WM_api.hh"
29
30/* own includes */
32
38
39/* -------------------------------------------------------------------- */
42
48
50{
51 V3DSnapCursorState *snap_state = ((SnapGizmo3D *)gz)->snap_state;
52 snap_state->flag |= eV3DSnapCursor(flag);
53}
54
56{
58 return snap_data->is_enabled;
59}
60
62 wmGizmo *gz,
63 float r_loc[3],
64 float r_nor[3],
65 int r_elem_index[3],
66 eSnapMode *r_snap_elem)
67{
68 if (C) {
69 /* Snap values are updated too late at the cursor. Be sure to update ahead of time. */
70 const wmEvent *event = CTX_wm_window(C)->eventstate;
71 if (event) {
72 ARegion *region = CTX_wm_region(C);
73 const blender::int2 mval = {
74 event->xy[0] - region->winrct.xmin,
75 event->xy[1] - region->winrct.ymin,
76 };
77 SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
78 ED_view3d_cursor_snap_data_update(snap_gizmo->snap_state, C, region, mval);
79 }
80 }
81
83
84 if (r_loc) {
85 copy_v3_v3(r_loc, snap_data->loc);
86 }
87 if (r_nor) {
88 copy_v3_v3(r_nor, snap_data->nor);
89 }
90 if (r_elem_index) {
91 copy_v3_v3_int(r_elem_index, snap_data->elem_index);
92 }
93 if (r_snap_elem) {
94 *r_snap_elem = snap_data->type_target;
95 }
96}
97
99
100/* -------------------------------------------------------------------- */
103
109
111{
113 if (snap_gizmo) {
114 return snap_gizmo->snap_state;
115 }
116
118}
119
120static void gizmo_snap_rna_prevpoint_get_fn(PointerRNA *ptr, PropertyRNA * /*prop*/, float *values)
121{
123 if (snap_state->prevpoint) {
124 copy_v3_v3(values, snap_state->prevpoint);
125 }
126}
127
129 PropertyRNA * /*prop*/,
130 const float *values)
131{
134}
135
137 PropertyRNA * /*prop*/,
138 float *values)
139{
141 copy_v3_v3(values, snap_data->loc);
142}
143
145 PropertyRNA * /*prop*/,
146 const float *values)
147{
149 copy_v3_v3(snap_data->loc, values);
150}
151
153 PropertyRNA * /*prop*/,
154 float *values)
155{
157 copy_v3_v3(values, snap_data->nor);
158}
159
161 PropertyRNA * /*prop*/,
162 int *values)
163{
165 copy_v3_v3_int(values, snap_data->elem_index);
166}
167
169{
171 return int(snap_data->type_source);
172}
173
175 PropertyRNA * /*prop*/,
176 const int value)
177{
179 snap_data->type_source = (eSnapMode)value;
180}
181
183
184/* -------------------------------------------------------------------- */
187
188static void snap_cursor_free(SnapGizmo3D *snap_gizmo)
189{
190 if (snap_gizmo->snap_state) {
191 snap_gizmo->snap_state_stored = *snap_gizmo->snap_state;
193 snap_gizmo->snap_state = nullptr;
194 }
195}
196
197/* XXX: Delayed snap cursor removal. */
198static bool snap_cursor_poll(ARegion *region, void *data)
199{
200 SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)data;
201 if (!(snap_gizmo->gizmo.state & WM_GIZMO_STATE_HIGHLIGHT) &&
202 !(snap_gizmo->gizmo.flag & WM_GIZMO_DRAW_VALUE))
203 {
204 return false;
205 }
206
207 if (snap_gizmo->gizmo.flag & WM_GIZMO_HIDDEN) {
208 snap_cursor_free(snap_gizmo);
209 return false;
210 }
211
212 if (!WM_gizmomap_group_find_ptr(region->runtime->gizmo_map,
213 snap_gizmo->gizmo.parent_gzgroup->type))
214 {
215 /* Wrong viewport. */
216 snap_cursor_free(snap_gizmo);
217 return false;
218 }
219 return true;
220}
221
223
224/* -------------------------------------------------------------------- */
227
228static void snap_gizmo_setup(wmGizmo *gz)
229{
231
232 SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
234 snap_gizmo->snap_state->draw_point = true;
235 snap_gizmo->snap_state->draw_plane = false;
236 snap_gizmo->snap_state->poll = snap_cursor_poll;
237 snap_gizmo->snap_state->poll_data = snap_gizmo;
238
239 snap_gizmo->snap_state_stored = *snap_gizmo->snap_state;
240}
241
242static void snap_gizmo_draw(const bContext * /*C*/, wmGizmo *gz)
243{
244 SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
245 if (snap_gizmo->snap_state == nullptr) {
247 *snap_gizmo->snap_state = snap_gizmo->snap_state_stored;
248 }
249
250 /* All drawing is handled at the paint cursor.
251 * Therefore, make sure that the #V3DSnapCursorState is the one of the gizmo being drawn. */
253}
254
255static int snap_gizmo_test_select(bContext *C, wmGizmo *gz, const int mval[2])
256{
257 SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz;
258 const ARegion *region = CTX_wm_region(C);
259
260 /* Snap values are updated too late at the cursor. Be sure to update ahead of time. */
261 blender::int2 mval_copy;
262 {
263 const wmEvent *event = CTX_wm_window(C)->eventstate;
264 if (event) {
265 mval_copy = {
266 event->xy[0] - region->winrct.xmin,
267 event->xy[1] - region->winrct.ymin,
268 };
269 }
270 else {
271 mval_copy = mval;
272 }
273 }
274 ED_view3d_cursor_snap_data_update(snap_gizmo->snap_state, C, region, mval_copy);
276
277 if (snap_data->type_target != SCE_SNAP_TO_NONE) {
278 return 0;
279 }
280 return -1;
281}
282
284 wmGizmo * /*gz*/,
285 const wmEvent * /*event*/,
286 eWM_GizmoFlagTweak /*tweak_flag*/)
287{
289}
290
292 wmGizmo * /*gz*/,
293 const wmEvent * /*event*/)
294{
296}
297
298static void snap_gizmo_free(wmGizmo *gz)
299{
301}
302
304{
305 /* identifiers */
306 gzt->idname = "GIZMO_GT_snap_3d";
307
308 /* API callbacks. */
309 gzt->setup = snap_gizmo_setup;
310 gzt->draw = snap_gizmo_draw;
312 gzt->modal = snap_gizmo_modal;
314 gzt->free = snap_gizmo_free;
315
316 gzt->struct_size = sizeof(SnapGizmo3D);
317
319 {
320 /* Get Snap Element Items enum. */
321 bool free;
322 PointerRNA toolsettings_ptr = RNA_pointer_create_discrete(nullptr, &RNA_ToolSettings, nullptr);
323 PropertyRNA *prop = RNA_struct_find_property(&toolsettings_ptr, "snap_elements");
325 nullptr, &toolsettings_ptr, prop, &rna_enum_snap_element_items, nullptr, &free);
326
327 BLI_assert(free == false);
328 }
329
330 /* Setup. */
331 PropertyRNA *prop;
332 prop = RNA_def_float_array(gzt->srna,
333 "prev_point",
334 3,
335 nullptr,
336 FLT_MIN,
337 FLT_MAX,
338 "Previous Point",
339 "Point that defines the location of the perpendicular snap",
340 FLT_MIN,
341 FLT_MAX);
345 nullptr,
346 nullptr,
347 nullptr);
348
349 /* Returns. */
351 "location",
352 3,
353 nullptr,
354 FLT_MIN,
355 FLT_MAX,
356 "Location",
357 "Snap Point Location",
358 FLT_MIN,
359 FLT_MAX);
363 nullptr,
364 nullptr,
365 nullptr);
366
367 prop = RNA_def_float_vector_xyz(gzt->srna,
368 "normal",
369 3,
370 nullptr,
371 FLT_MIN,
372 FLT_MAX,
373 "Normal",
374 "Snap Point Normal",
375 FLT_MIN,
376 FLT_MAX);
378 prop, gizmo_snap_rna_normal_get_fn, nullptr, nullptr, nullptr, nullptr);
379
380 prop = RNA_def_int_vector(gzt->srna,
381 "snap_elem_index",
382 3,
383 nullptr,
384 INT_MIN,
385 INT_MAX,
386 "Snap Element",
387 "Array index of face, edge and vert snapped",
388 INT_MIN,
389 INT_MAX);
391 prop, gizmo_snap_rna_snap_elem_index_get_fn, nullptr, nullptr, nullptr, nullptr);
392
393 prop = RNA_def_enum(gzt->srna,
394 "snap_source_type",
397 "Snap Source Type",
398 "Snap Source type (influences drawing)");
402 nullptr,
403 nullptr,
404 nullptr);
405}
406
411
wmWindow * CTX_wm_window(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
#define BLI_assert(a)
Definition BLI_assert.h:46
void BLI_kdtree_nd_ free(KDTree *tree)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_v3_int(int r[3], const int a[3])
@ SCE_SNAP_TO_NONE
@ RGN_TYPE_WINDOW
@ SPACE_VIEW3D
@ OPERATOR_RUNNING_MODAL
V3DSnapCursorState * ED_view3d_cursor_snap_state_create()
V3DSnapCursorState * ED_view3d_cursor_snap_state_active_get()
void ED_view3d_cursor_snap_state_prevpoint_set(V3DSnapCursorState *state, const float prev_point[3])
eV3DSnapCursor
Definition ED_view3d.hh:329
void ED_view3d_cursor_snap_state_free(V3DSnapCursorState *state)
void ED_view3d_cursor_snap_state_active_set(V3DSnapCursorState *state)
V3DSnapCursorData * ED_view3d_cursor_snap_data_get()
void ED_view3d_cursor_snap_data_update(V3DSnapCursorState *state, const bContext *C, const ARegion *region, const blender::int2 &mval)
blender::ed::transform::SnapObjectContext * ED_view3d_cursor_snap_context_ensure(Scene *scene)
#define C
Definition RandGen.cpp:29
eWM_GizmoFlagTweak
Gizmo tweak flag. Bit-flag passed to gizmo while tweaking.
@ WM_GIZMO_HIDDEN
@ WM_GIZMO_DRAW_VALUE
@ WM_GIZMO_NO_TOOLTIP
@ WM_GIZMO_STATE_HIGHLIGHT
BMesh const char void * data
wmGizmo * gizmo_find_from_properties(const IDProperty *properties, const int spacetype, const int regionid)
VecBase< int32_t, 2 > int2
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
void RNA_def_property_int_array_funcs_runtime(PropertyRNA *prop, IntArrayPropertyGetFunc getfunc, IntArrayPropertySetFunc setfunc, IntPropertyRangeFunc rangefunc, IntArrayPropertyGetTransformFunc get_transform_fn, IntArrayPropertySetTransformFunc set_transform_fn)
PropertyRNA * RNA_def_float_translation(StructOrFunctionRNA *cont_, const char *identifier, const int len, const float *default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_int_vector(StructOrFunctionRNA *cont_, const char *identifier, const int len, const int *default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
PropertyRNA * RNA_def_float_vector_xyz(StructOrFunctionRNA *cont_, const char *identifier, const int len, const float *default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
void RNA_def_property_float_array_funcs_runtime(PropertyRNA *prop, FloatArrayPropertyGetFunc getfunc, FloatArrayPropertySetFunc setfunc, FloatPropertyRangeFunc rangefunc, FloatArrayPropertyGetTransformFunc get_transform_fn, FloatArrayPropertySetTransformFunc set_transform_fn)
void RNA_def_property_enum_funcs_runtime(PropertyRNA *prop, EnumPropertyGetFunc getfunc, EnumPropertySetFunc setfunc, EnumPropertyItemFunc itemfunc, EnumPropertyGetTransformFunc get_transform_fn, EnumPropertySetTransformFunc set_transform_fn)
PropertyRNA * RNA_def_float_array(StructOrFunctionRNA *cont_, const char *identifier, const int len, const float *default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
const EnumPropertyItem rna_enum_snap_element_items[]
Definition rna_scene.cc:150
static void gizmo_snap_rna_snap_srouce_type_set_fn(PointerRNA *, PropertyRNA *, const int value)
static void snap_cursor_free(SnapGizmo3D *snap_gizmo)
static void gizmo_snap_rna_prevpoint_set_fn(PointerRNA *ptr, PropertyRNA *, const float *values)
static int gizmo_snap_rna_snap_srouce_type_get_fn(PointerRNA *, PropertyRNA *)
static wmOperatorStatus snap_gizmo_modal(bContext *, wmGizmo *, const wmEvent *, eWM_GizmoFlagTweak)
static int snap_gizmo_test_select(bContext *C, wmGizmo *gz, const int mval[2])
void ED_gizmotypes_snap_3d_data_get(const bContext *C, wmGizmo *gz, float r_loc[3], float r_nor[3], int r_elem_index[3], eSnapMode *r_snap_elem)
blender::ed::transform::SnapObjectContext * ED_gizmotypes_snap_3d_context_ensure(Scene *scene, wmGizmo *)
static void gizmo_snap_rna_normal_get_fn(PointerRNA *, PropertyRNA *, float *values)
bool ED_gizmotypes_snap_3d_is_enabled(const wmGizmo *)
static void snap_gizmo_free(wmGizmo *gz)
void ED_gizmotypes_snap_3d()
static void snap_gizmo_draw(const bContext *, wmGizmo *gz)
static V3DSnapCursorState * gizmo_snap_state_from_rna_get(PointerRNA *ptr)
static void gizmo_snap_rna_location_get_fn(PointerRNA *, PropertyRNA *, float *values)
static void snap_gizmo_setup(wmGizmo *gz)
static bool snap_cursor_poll(ARegion *region, void *data)
static void gizmo_snap_rna_snap_elem_index_get_fn(PointerRNA *, PropertyRNA *, int *values)
static void gizmo_snap_rna_location_set_fn(PointerRNA *, PropertyRNA *, const float *values)
static wmOperatorStatus snap_gizmo_invoke(bContext *, wmGizmo *, const wmEvent *)
void ED_gizmotypes_snap_3d_flag_set(wmGizmo *gz, int flag)
static SnapGizmo3D * gizmo_snap_rna_find_operator(PointerRNA *ptr)
static void gizmo_snap_rna_prevpoint_get_fn(PointerRNA *ptr, PropertyRNA *, float *values)
static void GIZMO_GT_snap_3d(wmGizmoType *gzt)
#define FLT_MAX
Definition stdcycles.h:14
ARegionRuntimeHandle * runtime
V3DSnapCursorState snap_state_stored
wmGizmo gizmo
V3DSnapCursorState * snap_state
eSnapMode type_target
Definition ED_view3d.hh:340
eSnapMode type_source
Definition ED_view3d.hh:339
eV3DSnapCursor flag
Definition ED_view3d.hh:354
bool(* poll)(ARegion *region, void *custom_poll_data)
Definition ED_view3d.hh:364
int ymin
int xmin
wmGizmoGroupType * type
StructRNA * srna
wmGizmoFnDraw draw
wmGizmoFnModal modal
wmGizmoFnSetup setup
const char * idname
wmGizmoFnTestSelect test_select
wmGizmoFnInvoke invoke
wmGizmoFnFree free
wmGizmoGroup * parent_gzgroup
eWM_GizmoFlagState state
eWM_GizmoFlag flag
struct wmEvent * eventstate
PointerRNA * ptr
Definition wm_files.cc:4238
wmGizmoGroup * WM_gizmomap_group_find_ptr(wmGizmoMap *gzmap, const wmGizmoGroupType *gzgt)
void WM_gizmotype_append(void(*gtfunc)(wmGizmoType *))
uint8_t flag
Definition wm_window.cc:145