Blender V5.0
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
8
9#include "DNA_space_types.h"
10#include "MEM_guardedalloc.h"
11
13
14#include "WM_types.hh"
15
16#include "BKE_context.hh"
17#include "BKE_screen.hh"
18
20
21#include "transform.hh"
22#include "transform_convert.hh"
23#include "transform_gizmo.hh"
24#include "transform_snap.hh"
25
26#include "transform_mode.hh"
27
28#define RESET_TRANSFORMATION
29#define REMOVE_GIZMO
30
31namespace blender::ed::transform {
32
33/* -------------------------------------------------------------------- */
36
43
46
47 struct {
48 void (*apply)(TransInfo *t, MouseInput *mi, const double mval[2], float output[3]);
49 void (*post)(TransInfo *t, float values[3]);
52};
53
55{
57
58 /* Restore. */
59 SnapSouceCustomData *customdata = static_cast<SnapSouceCustomData *>(t->custom.mode.data);
60 t->mode_info = customdata->mode_info_prev;
61 t->custom.mode.data = customdata->customdata_mode_prev;
62
64
65 t->mouse.apply = customdata->mouse_prev.apply;
66 t->mouse.post = customdata->mouse_prev.post;
68
69 MEM_freeN(customdata);
70
73}
74
76{
79 t->tsnap.snap_source_fn = nullptr;
82
83 SnapSouceCustomData *customdata = static_cast<SnapSouceCustomData *>(t->custom.mode.data);
84 t->tsnap.mode = customdata->snap_mode_confirm;
85
86 float2 mval;
87#ifndef RESET_TRANSFORMATION
88 if (true) {
89 if (t->transform_matrix) {
90 float mat_inv[4][4];
91 unit_m4(mat_inv);
92 t->transform_matrix(t, mat_inv);
93 invert_m4(mat_inv);
94 mul_m4_v3(mat_inv, t->tsnap.snap_source);
95 }
96 else {
97 float mat_inv[3][3];
98 invert_m3_m3(mat_inv, t->mat);
99
100 mul_m3_v3(mat_inv, t->tsnap.snap_source);
102 }
103
105 }
106 else
107#endif
108 {
109 mval = t->mval;
110 }
111
113 transform_input_reset(t, mval);
114
115 /* Remote individual snap projection since this mode does not use the new `snap_source`. */
117}
118
120{
121 if (t->redraw) {
122 /* Event already handled. */
123 return TREDRAW_NOTHING;
124 }
125
126 if (event->type == EVT_MODAL_MAP) {
127 switch (event->val) {
133
135 }
136 break;
137 case TFM_MODAL_CANCEL:
139 t->state = TRANS_CANCEL;
140 return TREDRAW_SOFT;
141 default:
142 break;
143 }
144 }
145 else if (event->val == KM_RELEASE && t->state == TRANS_CONFIRM) {
149 t->state = TRANS_RUNNING;
150 }
151 }
152 return TREDRAW_NOTHING;
153}
154
156{
158
159 t->tsnap.snap_target_fn(t, nullptr);
160 if (t->tsnap.status & SNAP_MULTI_POINTS) {
162 }
163 t->redraw |= TREDRAW_SOFT;
164}
165
167{
168 if (t->mode_info == &TransMode_snapsource) {
169 /* Already running. */
170 return;
171 }
172
173 if (!t->tsnap.snap_target_fn) {
174 /* A `snap_target_fn` is required for the operation to work.
175 * `snap_target_fn` can be `nullptr` when transforming camera in camera view. */
176 return;
177 }
178
179 if (ELEM(t->mode, TFM_INIT, TFM_DUMMY)) {
180 /* Fallback. */
182 }
183
184 SnapSouceCustomData *customdata = static_cast<SnapSouceCustomData *>(
185 MEM_callocN(sizeof(*customdata), __func__));
186 customdata->mode_info_prev = t->mode_info;
187
189
190 customdata->mouse_prev.apply = t->mouse.apply;
191 customdata->mouse_prev.post = t->mouse.post;
193
194 customdata->customdata_mode_prev = t->custom.mode.data;
195 t->custom.mode.data = customdata;
196
197 if (!(t->modifiers & MOD_SNAP) || !transformModeUseSnap(t)) {
199 }
200
204
205 if (t->spacetype == SPACE_VIEW3D) {
207 }
208
209 customdata->snap_mode_confirm = t->tsnap.mode;
212
213 if ((t->tsnap.mode & ~SCE_SNAP_TO_INCREMENT) == 0) {
214 /* Initialize snap modes for geometry. */
217
219 customdata->snap_mode_confirm = t->tsnap.mode;
220 }
221 }
222
223 if (t->data_type == &TransConvertType_Mesh) {
225 t->tsnap.object_context, nullptr, nullptr, nullptr, nullptr);
226 }
227
228#ifdef RESET_TRANSFORMATION
229 /* Temporarily disable snapping.
230 * We don't want #SCE_SNAP_PROJECT to affect `recalc_data` for example. */
231 t->tsnap.flag &= ~SCE_SNAP;
232
234
235 /* Restore snapping status. */
237
238 /* Reset initial values to restore gizmo position. */
240#endif
241
242#ifdef REMOVE_GIZMO
243 wmGizmo *gz = WM_gizmomap_get_modal(t->region->runtime->gizmo_map);
244 if (gz) {
245 const wmEvent *event = CTX_wm_window(t->context)->eventstate;
246# ifdef RESET_TRANSFORMATION
247 wmGizmoFnModal modal_fn = gz->custom_modal ? gz->custom_modal : gz->type->modal;
248 if (modal_fn) {
249 modal_fn(t->context, gz, event, eWM_GizmoFlagTweak(0));
250 }
251# endif
252
253 WM_gizmo_modal_set_while_modal(t->region->runtime->gizmo_map, t->context, nullptr, event);
254 }
255#endif
256
257 t->mouse.apply = nullptr;
258 t->mouse.post = nullptr;
259 t->mouse.use_virtual_mval = false;
261}
262
264
266 /*flags*/ 0,
268 /*transform_fn*/ snapsource_transform_fn,
269 /*transform_matrix_fn*/ nullptr,
270 /*handle_event_fn*/ snapsource_handle_event_fn,
271 /*snap_distance_fn*/ nullptr,
272 /*snap_apply_fn*/ nullptr,
273 /*draw_fn*/ nullptr,
274};
275
276} // namespace blender::ed::transform
wmWindow * CTX_wm_window(const bContext *C)
#define BLI_assert(a)
Definition BLI_assert.h:46
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 mul_m4_v3(const float M[4][4], float r[3])
bool invert_m4(float mat[4][4])
void unit_m4(float m[4][4])
MINLINE void sub_v3_v3(float r[3], const float a[3])
#define ELEM(...)
#define SCE_SNAP_TO_GEOM
@ SCE_SNAP
eSnapTargetOP
@ SCE_SNAP_TARGET_ALL
@ SCE_SNAP_INDIVIDUAL_NEAREST
@ SCE_SNAP_INDIVIDUAL_PROJECT
@ SCE_SNAP_TO_INCREMENT
@ SCE_SNAP_TO_EDGE_PERPENDICULAR
@ SPACE_VIEW3D
Read Guarded memory(de)allocation.
eWM_GizmoFlagTweak
Gizmo tweak flag. Bit-flag passed to gizmo while tweaking.
@ KM_RELEASE
Definition WM_types.hh:312
#define output
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
TransConvertTypeInfo TransConvertType_Mesh
void transform_snap_flag_from_modifiers_set(TransInfo *t)
void getSnapPoint(const TransInfo *t, float vec[3])
static void snapsource_confirm(TransInfo *t)
static eRedrawFlag snapsource_handle_event_fn(TransInfo *t, const wmEvent *event)
static void snapsource_transform_fn(TransInfo *t)
bool transformModeUseSnap(const TransInfo *t)
void tranform_snap_source_restore_context(TransInfo *t)
void projectFloatView(TransInfo *t, const float vec[3], float adr[2])
void transform_input_reset(TransInfo *t, const float2 &mval)
void restoreTransObjects(TransInfo *t)
void applyMouseInput(TransInfo *t, MouseInput *mi, const float2 &mval, float output[3])
void transform_gizmo_3d_model_from_constraint_and_mode_set(TransInfo *t)
void transform_mode_snap_source_init(TransInfo *t, wmOperator *op)
static void snapsource_end(TransInfo *t)
void 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)
void transform_mode_init(TransInfo *t, wmOperator *op, const int mode)
VecBase< float, 2 > float2
ARegionRuntimeHandle * runtime
void(* apply)(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
Definition transform.hh:603
void(* post)(TransInfo *t, float values[3])
Definition transform.hh:604
void(* post)(TransInfo *t, float values[3])
struct blender::ed::transform::SnapSouceCustomData::@221001315165003010163025242055306327270336076103 mouse_prev
void(* apply)(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
TransConvertTypeInfo * data_type
Definition transform.hh:810
TransCustomDataContainer custom
Definition transform.hh:974
SnapObjectContext * object_context
Definition transform.hh:565
void(* snap_source_fn)(TransInfo *)
Definition transform.hh:559
void(* snap_target_fn)(TransInfo *, float *)
Definition transform.hh:558
wmEventType type
Definition WM_types.hh:757
short val
Definition WM_types.hh:759
wmGizmoFnModal modal
const wmGizmoType * type
wmGizmoFnModal custom_modal
struct wmEvent * eventstate
conversion and adaptation of different datablocks to a common struct.
transform modes used by different operators.
@ EVT_MODAL_MAP
void WM_gizmo_modal_set_while_modal(wmGizmoMap *gzmap, bContext *C, wmGizmo *gz, const wmEvent *event)
Definition wm_gizmo.cc:434
wmOperatorStatus(*)(bContext *, wmGizmo *, const wmEvent *, eWM_GizmoFlagTweak) wmGizmoFnModal
wmGizmo * WM_gizmomap_get_modal(const wmGizmoMap *gzmap)