Blender V4.3
transform_mode_snapsource.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "MEM_guardedalloc.h"
10
12
13#include "BKE_context.hh"
14
15#include "ED_screen.hh"
17
18#include "transform.hh"
19#include "transform_convert.hh"
20#include "transform_gizmo.hh"
21#include "transform_snap.hh"
22
23#include "transform_mode.hh"
24
25#define RESET_TRANSFORMATION
26#define REMOVE_GIZMO
27
28using namespace blender;
29
30/* -------------------------------------------------------------------- */
40
43
44 struct {
45 void (*apply)(TransInfo *t, MouseInput *mi, const double mval[2], float output[3]);
46 void (*post)(TransInfo *t, float values[3]);
49};
50
52{
53 t->modifiers &= ~MOD_EDIT_SNAP_SOURCE;
54
55 /* Restore. */
56 SnapSouceCustomData *customdata = static_cast<SnapSouceCustomData *>(t->custom.mode.data);
57 t->mode_info = customdata->mode_info_prev;
58 t->custom.mode.data = customdata->customdata_mode_prev;
59
61
62 t->mouse.apply = customdata->mouse_prev.apply;
63 t->mouse.post = customdata->mouse_prev.post;
65
66 MEM_freeN(customdata);
67
70}
71
73{
76 t->tsnap.snap_source_fn = nullptr;
79
80 SnapSouceCustomData *customdata = static_cast<SnapSouceCustomData *>(t->custom.mode.data);
81 t->tsnap.mode = customdata->snap_mode_confirm;
82
83 float2 mval;
84#ifndef RESET_TRANSFORMATION
85 if (true) {
86 if (t->transform_matrix) {
87 float mat_inv[4][4];
88 unit_m4(mat_inv);
89 t->transform_matrix(t, mat_inv);
90 invert_m4(mat_inv);
91 mul_m4_v3(mat_inv, t->tsnap.snap_source);
92 }
93 else {
94 float mat_inv[3][3];
95 invert_m3_m3(mat_inv, t->mat);
96
97 mul_m3_v3(mat_inv, t->tsnap.snap_source);
99 }
100
102 }
103 else
104#endif
105 {
106 mval = t->mval;
107 }
108
110 transform_input_reset(t, mval);
111
112 /* Remote individual snap projection since this mode does not use the new `snap_source`. */
114}
115
117{
118 if (event->type == EVT_MODAL_MAP) {
119 switch (event->val) {
125
127 }
128 else {
130 }
131 break;
132 case TFM_MODAL_CANCEL:
134 t->state = TRANS_CANCEL;
135 return TREDRAW_SOFT;
136 default:
137 break;
138 }
139 }
140 else if (event->val == KM_RELEASE && t->state == TRANS_CONFIRM) {
143 t->flag &= ~T_RELEASE_CONFIRM;
144 t->state = TRANS_RUNNING;
145 }
146 }
147 return TREDRAW_NOTHING;
148}
149
151{
153
154 t->tsnap.snap_target_fn(t, nullptr);
155 if (t->tsnap.status & SNAP_MULTI_POINTS) {
157 }
158 t->redraw |= TREDRAW_SOFT;
159}
160
162{
163 if (t->mode_info == &TransMode_snapsource) {
164 /* Already running. */
165 return;
166 }
167
168 if (!t->tsnap.snap_target_fn) {
169 /* A `snap_target_fn` is required for the operation to work.
170 * `snap_target_fn` can be `nullptr` when transforming camera in camera view. */
171 return;
172 }
173
174 if (ELEM(t->mode, TFM_INIT, TFM_DUMMY)) {
175 /* Fallback. */
177 }
178
179 SnapSouceCustomData *customdata = static_cast<SnapSouceCustomData *>(
180 MEM_callocN(sizeof(*customdata), __func__));
181 customdata->mode_info_prev = t->mode_info;
182
184
185 customdata->mouse_prev.apply = t->mouse.apply;
186 customdata->mouse_prev.post = t->mouse.post;
188
189 customdata->customdata_mode_prev = t->custom.mode.data;
190 t->custom.mode.data = customdata;
191
192 if (!(t->modifiers & MOD_SNAP) || !transformModeUseSnap(t)) {
194 }
195
198 t->tsnap.status &= ~SNAP_SOURCE_FOUND;
199
200 if (t->spacetype == SPACE_VIEW3D) {
202 }
203
204 customdata->snap_mode_confirm = t->tsnap.mode;
207
208 if ((t->tsnap.mode & ~SCE_SNAP_TO_INCREMENT) == 0) {
209 /* Initialize snap modes for geometry. */
210 t->tsnap.mode &= ~SCE_SNAP_TO_INCREMENT;
211 t->tsnap.mode |= SCE_SNAP_TO_GEOM & ~SCE_SNAP_TO_EDGE_PERPENDICULAR;
212
214 customdata->snap_mode_confirm = t->tsnap.mode;
215 }
216 }
217
218 if (t->data_type == &TransConvertType_Mesh) {
220 t->tsnap.object_context, nullptr, nullptr, nullptr, nullptr);
221 }
222
223#ifdef RESET_TRANSFORMATION
224 /* Temporarily disable snapping.
225 * We don't want #SCE_SNAP_PROJECT to affect `recalc_data` for example. */
226 t->tsnap.flag &= ~SCE_SNAP;
227
229
230 /* Restore snapping status. */
232
233 /* Reset initial values to restore gizmo position. */
235#endif
236
237#ifdef REMOVE_GIZMO
239 if (gz) {
240 const wmEvent *event = CTX_wm_window(t->context)->eventstate;
241# ifdef RESET_TRANSFORMATION
242 wmGizmoFnModal modal_fn = gz->custom_modal ? gz->custom_modal : gz->type->modal;
243 if (modal_fn) {
244 modal_fn(t->context, gz, event, eWM_GizmoFlagTweak(0));
245 }
246# endif
247
249 }
250#endif
251
252 t->mouse.apply = nullptr;
253 t->mouse.post = nullptr;
254 t->mouse.use_virtual_mval = false;
255}
256
260 /*flags*/ 0,
262 /*transform_fn*/ snapsource_transform_fn,
263 /*transform_matrix_fn*/ nullptr,
264 /*handle_event_fn*/ snapsource_handle_event_fn,
265 /*snap_distance_fn*/ nullptr,
266 /*snap_apply_fn*/ nullptr,
267 /*draw_fn*/ nullptr,
268};
wmWindow * CTX_wm_window(const bContext *C)
#define BLI_assert(a)
Definition BLI_assert.h:50
void mul_m3_v3(const float M[3][3], float r[3])
bool invert_m3_m3(float inverse[3][3], const float mat[3][3])
void unit_m4(float m[4][4])
Definition rct.c:1127
void mul_m4_v3(const float M[4][4], float r[3])
bool invert_m4(float mat[4][4])
MINLINE void sub_v3_v3(float r[3], const float a[3])
#define ELEM(...)
#define SCE_SNAP_TO_GEOM
eSnapTargetOP
@ SCE_SNAP_TARGET_ALL
@ SCE_SNAP_INDIVIDUAL_NEAREST
@ SCE_SNAP_INDIVIDUAL_PROJECT
@ SCE_SNAP_TO_INCREMENT
@ SCE_SNAP_TO_EDGE_PERPENDICULAR
@ SPACE_VIEW3D
@ TFM_INIT
@ TFM_TRANSLATION
@ TFM_DUMMY
void ED_transform_snap_object_context_set_editmesh_callbacks(SnapObjectContext *sctx, bool(*test_vert_fn)(BMVert *, void *user_data), bool(*test_edge_fn)(BMEdge *, void *user_data), bool(*test_face_fn)(BMFace *, void *user_data), void *user_data)
Read Guarded memory(de)allocation.
eWM_GizmoFlagTweak
Gizmo tweak flag. Bit-flag passed to gizmo while tweaking.
@ KM_RELEASE
Definition WM_types.hh:285
void projectFloatView(TransInfo *t, const float vec[3], float adr[2])
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
struct wmGizmoMap * gizmo_map
blender::float2 imval
Definition transform.hh:383
bool use_virtual_mval
Definition transform.hh:400
void(* post)(TransInfo *t, float values[3])
Definition transform.hh:380
void(* apply)(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
Definition transform.hh:379
void(* post)(TransInfo *t, float values[3])
struct SnapSouceCustomData::@584 mouse_prev
void(* apply)(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
TransCustomData mode
Definition transform.hh:423
eTfmMode mode
Definition transform.hh:517
TransModeInfo * mode_info
Definition transform.hh:518
char spacetype
Definition transform.hh:582
eRedrawFlag redraw
Definition transform.hh:529
TransSnap tsnap
Definition transform.hh:537
eTState state
Definition transform.hh:527
eTModifier modifiers
Definition transform.hh:525
TransCustomDataContainer custom
Definition transform.hh:676
float vec[3]
Definition transform.hh:587
eTFlag flag
Definition transform.hh:523
ARegion * region
Definition transform.hh:652
MouseInput mouse
Definition transform.hh:543
float values_final[4]
Definition transform.hh:632
float mat[3][3]
Definition transform.hh:589
bContext * context
Definition transform.hh:649
blender::float2 mval
Definition transform.hh:663
TransConvertTypeInfo * data_type
Definition transform.hh:513
void(* snap_target_fn)(TransInfo *, float *)
Definition transform.hh:333
eSnapFlag flag
Definition transform.hh:310
eTSnap status
Definition transform.hh:318
SnapObjectContext * object_context
Definition transform.hh:340
float snap_source[3]
Definition transform.hh:325
void(* snap_source_fn)(TransInfo *)
Definition transform.hh:334
eSnapMode mode
Definition transform.hh:312
eSnapMode target_type
Definition transform.hh:321
eSnapMode source_type
Definition transform.hh:320
eSnapTargetOP target_operation
Definition transform.hh:316
short val
Definition WM_types.hh:724
short type
Definition WM_types.hh:722
wmGizmoFnModal modal
const wmGizmoType * type
wmGizmoFnModal custom_modal
struct wmEvent * eventstate
@ SNAP_SOURCE_FOUND
Definition transform.hh:175
@ SNAP_MULTI_POINTS
Definition transform.hh:178
void applyMouseInput(TransInfo *t, MouseInput *mi, const blender::float2 &mval, float output[3])
@ MOD_EDIT_SNAP_SOURCE
Definition transform.hh:168
@ MOD_SNAP_FORCED
Definition transform.hh:167
@ MOD_SNAP
Definition transform.hh:163
eRedrawFlag
Definition transform.hh:214
@ TREDRAW_NOTHING
Definition transform.hh:215
@ TREDRAW_SOFT
Definition transform.hh:216
@ TFM_MODAL_EDIT_SNAP_SOURCE_OFF
Definition transform.hh:292
@ TFM_MODAL_CONFIRM
Definition transform.hh:248
@ TFM_MODAL_CANCEL
Definition transform.hh:247
@ TFM_MODAL_EDIT_SNAP_SOURCE_ON
Definition transform.hh:291
@ T_RELEASE_CONFIRM
Definition transform.hh:123
@ T_DRAW_SNAP_SOURCE
Definition transform.hh:149
void restoreTransObjects(TransInfo *t)
@ TRANS_CONFIRM
Definition transform.hh:209
@ TRANS_RUNNING
Definition transform.hh:208
@ TRANS_CANCEL
Definition transform.hh:210
void transform_input_reset(TransInfo *t, const blender::float2 &mval)
conversion and adaptation of different datablocks to a common struct.
TransConvertTypeInfo TransConvertType_Mesh
void transform_gizmo_3d_model_from_constraint_and_mode_set(TransInfo *t)
void transform_mode_init(TransInfo *t, wmOperator *op, const int mode)
transform modes used by different operators.
TransModeInfo TransMode_snapsource
static eRedrawFlag snapsource_handle_event_fn(TransInfo *t, const wmEvent *event)
void transform_mode_snap_source_init(TransInfo *t, wmOperator *)
static void snapsource_confirm(TransInfo *t)
static void snapsource_end(TransInfo *t)
static void snapsource_transform_fn(TransInfo *t)
bool transformModeUseSnap(const TransInfo *t)
void tranform_snap_source_restore_context(TransInfo *t)
void getSnapPoint(const TransInfo *t, float vec[3])
void transform_snap_flag_from_modifiers_set(TransInfo *t)
@ EVT_MODAL_MAP
void WM_gizmo_modal_set_while_modal(wmGizmoMap *gzmap, bContext *C, wmGizmo *gz, const wmEvent *event)
Definition wm_gizmo.cc:429
int(*)(bContext *, wmGizmo *, const wmEvent *, eWM_GizmoFlagTweak) wmGizmoFnModal
wmGizmo * WM_gizmomap_get_modal(const wmGizmoMap *gzmap)