Blender V5.0
transform_mode_translate.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 <cstdlib>
10
11#include "MEM_guardedalloc.h"
12
13#include "BLI_math_matrix.h"
14#include "BLI_math_matrix.hh"
15#include "BLI_math_rotation.h"
16#include "BLI_math_vector.h"
17#include "BLI_string_utf8.h"
18#include "BLI_task.hh"
19
20#include "BKE_image.hh"
21#include "BKE_report.hh"
22#include "BKE_unit.hh"
23
24#include "ED_screen.hh"
25
26#include "BLT_translation.hh"
27
28#include "UI_interface_types.hh"
29#include "UI_view2d.hh"
30
31#include "transform.hh"
32#include "transform_convert.hh"
33#include "transform_mode.hh"
34#include "transform_snap.hh"
35
36namespace blender::ed::transform {
37
38/* -------------------------------------------------------------------- */
41
49
61
63
64/* -------------------------------------------------------------------- */
67
69 const TransDataContainer *tc,
70 TransData *td,
71 TransDataExtension *td_ext,
72 const float3 &snap_source_local,
73 const float3 &vec,
74 enum eTranslateRotateMode rotate_mode)
75{
76 float rotate_offset[3] = {0};
77 bool use_rotate_offset = false;
78
79 /* Handle snapping rotation before doing the translation. */
80 if (rotate_mode != TRANSLATE_ROTATE_OFF) {
81 float mat[3][3];
82
83 if (rotate_mode == TRANSLATE_ROTATE_RESET) {
84 unit_m3(mat);
85 }
86 else {
87 BLI_assert(rotate_mode == TRANSLATE_ROTATE_ON);
88
89 float3 original_normal;
90
91 /* In pose mode, we want to align normals with Y axis of bones. */
92 if (t->options & CTX_POSE_BONE) {
93 original_normal = td->axismtx[1];
94 }
95 else {
96 original_normal = td->axismtx[2];
97 }
98
99 if (t->flag & T_POINTS) {
100 /* Convert to Global Space since #ElementRotation_ex operates with the matrix in global
101 * space. */
102 original_normal = math::transform_direction(float3x3(td->mtx), original_normal);
103 }
104
105 rotation_between_vecs_to_mat3(mat, original_normal, t->tsnap.snapNormal);
106 }
107
108 ElementRotation_ex(t, tc, td, td_ext, mat, snap_source_local);
109
110 if (td->loc) {
111 use_rotate_offset = true;
112 sub_v3_v3v3(rotate_offset, td->loc, td->iloc);
113 }
114 }
115
116 float tvec[3];
117
118 if (t->con.applyVec) {
119 t->con.applyVec(t, tc, td, vec, tvec);
120 }
121 else {
122 copy_v3_v3(tvec, vec);
123 }
124
125 mul_m3_v3(td->smtx, tvec);
126
127 if (use_rotate_offset) {
128 add_v3_v3(tvec, rotate_offset);
129 }
130
131 if (t->options & CTX_GPENCIL_STROKES) {
132 /* Grease pencil multi-frame falloff. */
133 float *gp_falloff = static_cast<float *>(td->extra);
134 if (gp_falloff != nullptr) {
135 mul_v3_fl(tvec, td->factor * *gp_falloff);
136 }
137 else {
138 mul_v3_fl(tvec, td->factor);
139 }
140 }
141 else {
142 /* Proportional editing falloff. */
143 mul_v3_fl(tvec, td->factor);
144 }
145
147
148 if (td->loc) {
149 add_v3_v3v3(td->loc, td->iloc, tvec);
150 }
151
152 constraintTransLim(t, tc, td);
153}
154
156
157/* -------------------------------------------------------------------- */
160
161static void translate_dist_to_str(char *r_str,
162 const int r_str_maxncpy,
163 const float val,
164 const UnitSettings *unit)
165{
166 if (unit && (unit->system != USER_UNIT_NONE)) {
167 BKE_unit_value_as_string_scaled(r_str, r_str_maxncpy, val, -4, B_UNIT_LENGTH, *unit, false);
168 }
169 else {
170 /* Check range to prevent string buffer overflow. */
172 r_str, r_str_maxncpy, IN_RANGE_INCL(val, -1e10f, 1e10f) ? "%.4f" : "%.4e", val);
173 }
174}
175
176static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_STR])
177{
178 size_t ofs = 0;
179 char dvec_str[3][NUM_STR_REP_LEN];
180 char dist_str[NUM_STR_REP_LEN];
181 float dist;
182
183 const UnitSettings *unit = nullptr;
184 if (!(t->flag & T_2D_EDIT)) {
185 unit = &t->scene->unit;
186 }
187
188 if (hasNumInput(&t->num)) {
189 outputNumInput(&(t->num), dvec_str[0], t->scene->unit);
190 dist = len_v3(t->num.val);
191 }
192 else {
193 float dvec[3];
194 copy_v3_v3(dvec, vec);
195 if (t->spacetype == SPACE_GRAPH) {
196 /* WORKAROUND:
197 * Special case where snapping is done in #recalData.
198 * Update the header based on the #center_local. */
199 eSnapMode autosnap = t->tsnap.mode;
200 float ival = TRANS_DATA_CONTAINER_FIRST_OK(t)->center_local[0];
201 float val = ival + dvec[0];
202 snapFrameTransform(t, autosnap, ival, val, &val);
203 dvec[0] = val - ival;
204 }
205
206 if (t->flag & T_2D_EDIT) {
207 applyAspectRatio(t, dvec);
208 }
209
210 if (t->con.mode & CON_APPLY) {
211 int i = 0;
212 if (t->con.mode & CON_AXIS0) {
213 dvec[i++] = dvec[0];
214 }
215 if (t->con.mode & CON_AXIS1) {
216 dvec[i++] = dvec[1];
217 }
218 if (t->con.mode & CON_AXIS2) {
219 dvec[i++] = dvec[2];
220 }
221 while (i != 3) {
222 dvec[i++] = 0.0f;
223 }
224 }
225
226 dist = len_v3(dvec);
227
228 for (int i = 0; i < 3; i++) {
229 translate_dist_to_str(dvec_str[i], sizeof(dvec_str[i]), dvec[i], unit);
230 }
231 }
232
233 translate_dist_to_str(dist_str, sizeof(dist_str), dist, unit);
234
235 if (t->flag & T_PROP_EDIT_ALL) {
236 char prop_str[NUM_STR_REP_LEN];
237 translate_dist_to_str(prop_str, sizeof(prop_str), t->prop_size, unit);
238
239 ofs += BLI_snprintf_utf8_rlen(str + ofs,
240 UI_MAX_DRAW_STR - ofs,
241 "%s %s: %s ",
242 IFACE_("Proportional Size"),
243 t->proptext,
244 prop_str);
245 }
246
247 if (t->flag & T_AUTOIK) {
248 short chainlen = t->settings->autoik_chainlen;
249 if (chainlen) {
251 str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_("Auto IK Length: %d"), chainlen);
252 ofs += BLI_strncpy_utf8_rlen(str + ofs, " ", UI_MAX_DRAW_STR - ofs);
253 }
254 }
255
256 if (t->con.mode & CON_APPLY) {
257 switch (t->num.idx_max) {
258 case 0:
260 str + ofs, UI_MAX_DRAW_STR - ofs, "D: %s (%s)%s", dvec_str[0], dist_str, t->con.text);
261 break;
262 case 1:
263 ofs += BLI_snprintf_utf8_rlen(str + ofs,
264 UI_MAX_DRAW_STR - ofs,
265 "D: %s D: %s (%s)%s",
266 dvec_str[0],
267 dvec_str[1],
268 dist_str,
269 t->con.text);
270 break;
271 case 2:
272 ofs += BLI_snprintf_utf8_rlen(str + ofs,
273 UI_MAX_DRAW_STR - ofs,
274 "D: %s D: %s D: %s (%s)%s",
275 dvec_str[0],
276 dvec_str[1],
277 dvec_str[2],
278 dist_str,
279 t->con.text);
280 break;
281 }
282 }
283 else {
284 if (t->spacetype == SPACE_NODE) {
285 SpaceNode *snode = (SpaceNode *)t->area->spacedata.first;
286 if (U.uiflag & USER_NODE_AUTO_OFFSET) {
287 const char *str_dir = (snode->insert_ofs_dir == SNODE_INSERTOFS_DIR_RIGHT) ?
288 IFACE_("right") :
289 IFACE_("left");
291 str, UI_MAX_DRAW_STR, IFACE_("Auto-offset direction: %s"), str_dir);
292 }
293 }
294 else {
295 if (t->flag & T_2D_EDIT) {
296 ofs += BLI_snprintf_utf8_rlen(str + ofs,
297 UI_MAX_DRAW_STR - ofs,
298 "Dx: %s Dy: %s (%s)%s",
299 dvec_str[0],
300 dvec_str[1],
301 dist_str,
302 t->con.text);
303 }
304 else {
305 ofs += BLI_snprintf_utf8_rlen(str + ofs,
306 UI_MAX_DRAW_STR - ofs,
307 "Dx: %s Dy: %s Dz: %s (%s)%s",
308 dvec_str[0],
309 dvec_str[1],
310 dvec_str[2],
311 dist_str,
312 t->con.text);
313 }
314 }
315 }
316}
317
319
320/* -------------------------------------------------------------------- */
323
324static void ApplySnapTranslation(TransInfo *t, float vec[3])
325{
326 float point[3];
327 getSnapPoint(t, point);
328
329 if (t->spacetype == SPACE_SEQ) {
332 }
333 else {
335 }
336 }
337 else {
338 if (t->spacetype == SPACE_VIEW3D) {
339 if (t->options & CTX_PAINT_CURVE) {
342 {
343 zero_v3(point); /* No good answer here... */
344 }
345 }
346 }
347
348 sub_v3_v3v3(vec, point, t->tsnap.snap_source);
349 }
350}
352{
353 if (!(t->tsnap.flag & SCE_SNAP_ABS_GRID)) {
354 return;
355 }
356
357 TranslateCustomData *custom_data = static_cast<TranslateCustomData *>(t->custom.mode.data);
359 /* Use a fallback when transforming the cursor.
360 * In this case the center is _not_ derived from the cursor which is being transformed. */
361 custom_data->snap_target_grid = TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->data->iloc;
362 }
363 else if (t->around == V3D_AROUND_CURSOR) {
364 /* Use a fallback for cursor selection,
365 * this isn't useful as a global center for absolute grid snapping
366 * since its not based on the position of the selection. */
368 }
369 else {
370 custom_data->snap_target_grid = t->center_global;
371 }
372}
373
374static bool translate_snap_increment(const TransInfo *t, float *r_val)
375{
376 if (!transform_snap_increment_ex(t, (t->con.mode & CON_APPLY) != 0, r_val)) {
377 return false;
378 }
379
380 if (t->tsnap.flag & SCE_SNAP_ABS_GRID) {
381 TranslateCustomData *custom_data = static_cast<TranslateCustomData *>(t->custom.mode.data);
382
383 float3 absolute_grid_snap_offset = custom_data->snap_target_grid;
384 transform_snap_increment_ex(t, (t->con.mode & CON_APPLY) != 0, absolute_grid_snap_offset);
385 absolute_grid_snap_offset -= custom_data->snap_target_grid;
386 add_v3_v3(r_val, absolute_grid_snap_offset);
387
388 if (t->con.mode & CON_APPLY) {
389 t->con.applyVec(t, nullptr, nullptr, r_val, r_val);
390 }
391 }
392 return true;
393}
394
396
397/* -------------------------------------------------------------------- */
400
401static void applyTranslationValue(TransInfo *t, const float vec[3])
402{
403 TranslateCustomData *custom_data = static_cast<TranslateCustomData *>(t->custom.mode.data);
404
406
408 rotate_mode = TRANSLATE_ROTATE_ON;
409 }
410
411 /* Check to see if this needs to be re-enabled. */
412 if (rotate_mode == TRANSLATE_ROTATE_OFF) {
413 if (t->flag & T_POINTS) {
414 /* When transforming points, only use rotation when snapping is enabled
415 * since re-applying translation without rotation removes rotation. */
416 }
417 else {
418 /* When transforming data that itself stores rotation (objects, bones etc),
419 * apply rotation if it was applied (with the snap normal) previously.
420 * This is needed because failing to rotate will leave the rotation at the last
421 * value used before snapping was disabled. */
422 if (custom_data->prev.rotate_mode == TRANSLATE_ROTATE_ON) {
423 rotate_mode = TRANSLATE_ROTATE_RESET;
424 }
425 }
426 }
427
429 float3 snap_source_local(0);
430 if (rotate_mode != TRANSLATE_ROTATE_OFF) {
431 snap_source_local = t->tsnap.snap_source;
432 if (tc->use_local_mat) {
433 /* The pivot has to be in local-space (see #49494). */
434 snap_source_local = math::transform_point(float4x4(tc->imat), snap_source_local);
435 }
436 }
437
438 threading::parallel_for(IndexRange(tc->data_len), 1024, [&](const IndexRange range) {
439 for (const int i : range) {
440 TransData *td = &tc->data[i];
441 TransDataExtension *td_ext = tc->data_ext ? &tc->data_ext[i] : nullptr;
442 if (td->flag & TD_SKIP) {
443 continue;
444 }
445 transdata_elem_translate(t, tc, td, td_ext, snap_source_local, vec, rotate_mode);
446 }
447 });
448 }
449
450 custom_data->prev.rotate_mode = rotate_mode;
451}
452
453static bool clip_uv_transform_translation(TransInfo *t, float vec[2])
454{
455 /* Stores the coordinates of the closest UDIM tile.
456 * Also acts as an offset to the tile from the origin of UV space. */
457 float base_offset[2] = {0.0f, 0.0f};
458
459 /* If tiled image then constrain to correct/closest UDIM tile, else 0-1 UV space. */
460 const SpaceImage *sima = static_cast<const SpaceImage *>(t->area->spacedata.first);
462
463 float min[2], max[2];
464 min[0] = min[1] = FLT_MAX;
465 max[0] = max[1] = -FLT_MAX;
466
468 for (TransData *td = tc->data; td < tc->data + tc->data_len; td++) {
469 minmax_v2v2_v2(min, max, td->loc);
470 }
471 }
472
473 bool result = false;
474 if (min[0] < base_offset[0]) {
475 vec[0] += base_offset[0] - min[0];
476 result = true;
477 }
478 else if (max[0] > base_offset[0] + t->aspect[0]) {
479 vec[0] -= max[0] - base_offset[0] - t->aspect[0];
480 result = true;
481 }
482
483 if (min[1] < base_offset[1]) {
484 vec[1] += base_offset[1] - min[1];
485 result = true;
486 }
487 else if (max[1] > base_offset[1] + t->aspect[1]) {
488 vec[1] -= max[1] - base_offset[1] - t->aspect[1];
489 result = true;
490 }
491
492 return result;
493}
494
496{
497 char str[UI_MAX_DRAW_STR] = "";
498 float global_dir[3] = {0.0f};
499
500 if (t->flag & T_INPUT_IS_VALUES_FINAL) {
501 mul_v3_m3v3(global_dir, t->spacemtx, t->values);
502 }
503 else if (applyNumInput(&t->num, global_dir)) {
504 if (t->con.mode & CON_APPLY) {
505 if (t->con.mode & CON_AXIS0) {
506 mul_v3_v3fl(global_dir, t->spacemtx[0], global_dir[0]);
507 }
508 else if (t->con.mode & CON_AXIS1) {
509 mul_v3_v3fl(global_dir, t->spacemtx[1], global_dir[0]);
510 }
511 else if (t->con.mode & CON_AXIS2) {
512 mul_v3_v3fl(global_dir, t->spacemtx[2], global_dir[0]);
513 }
514 }
515 else {
516 mul_v3_m3v3(global_dir, t->spacemtx, global_dir);
517 }
518 if (t->flag & T_2D_EDIT) {
519 removeAspectRatio(t, global_dir);
520 }
521 }
522 else {
523 copy_v3_v3(global_dir, t->values);
525 float values_ofs[3];
526 mul_v3_m3v3(values_ofs, t->spacemtx, t->values_modal_offset);
527 add_v3_v3(global_dir, values_ofs);
528 }
529
530 transform_snap_mixed_apply(t, global_dir);
531
532 if (t->con.mode & CON_APPLY) {
533 float in[3];
534 copy_v3_v3(in, global_dir);
535 t->con.applyVec(t, nullptr, nullptr, in, global_dir);
536 }
537
538 float incr_dir[3];
539 copy_v3_v3(incr_dir, global_dir);
540 if (!(transform_snap_is_active(t) && validSnap(t)) && translate_snap_increment(t, incr_dir)) {
541
542 /* Test for mixed snap with grid. */
543 float snap_dist_sq = FLT_MAX;
545 snap_dist_sq = len_squared_v3v3(t->values, global_dir);
546 }
547 if ((snap_dist_sq == FLT_MAX) || (len_squared_v3v3(global_dir, incr_dir) < snap_dist_sq)) {
548 copy_v3_v3(global_dir, incr_dir);
549 }
550 }
551 }
552
553 applyTranslationValue(t, global_dir);
554
555 /* Evil hack - redo translation if clipping needed. */
556 if (t->flag & T_CLIP_UV && clip_uv_transform_translation(t, global_dir)) {
557 applyTranslationValue(t, global_dir);
558
559 /* Not ideal, see #clipUVData code-comment. */
560 if (t->flag & T_PROP_EDIT) {
561 clipUVData(t);
562 }
563 }
564
565 /* Set the redo value. */
566 mul_v3_m3v3(t->values_final, t->spacemtx_inv, global_dir);
567 headerTranslation(t, (t->con.mode & CON_APPLY) ? t->values_final : global_dir, str);
568
569 recalc_data(t);
570 ED_area_status_text(t->area, (str[0] == '\0') ? nullptr : str);
571}
572
573static void applyTranslationMatrix(TransInfo *t, float mat_xform[4][4])
574{
575 float delta[3];
576 mul_v3_m3v3(delta, t->spacemtx, t->values_final);
577 add_v3_v3(mat_xform[3], delta);
578}
579
580static void initTranslation(TransInfo *t, wmOperator * /*op*/)
581{
582 if (t->spacetype == SPACE_ACTION) {
583 /* This space uses time translate. */
585 RPT_ERROR,
586 "Use 'Time_Translate' transform mode instead of 'Translation' mode "
587 "for translating keyframes in Dope Sheet Editor");
588 t->state = TRANS_CANCEL;
589 return;
590 }
591
593
594 t->idx_max = (t->flag & T_2D_EDIT) ? 1 : 2;
595 t->num.flag = 0;
596 t->num.idx_max = t->idx_max;
597
598 float3 aspect = t->aspect;
599 /* Custom aspect for fcurve. */
600 if (t->spacetype == SPACE_GRAPH) {
601 View2D *v2d = &t->region->v2d;
602 Scene *scene = t->scene;
604 aspect[1] = UI_view2d_grid_resolution_y__values(v2d, 10);
605 }
606
607 t->increment = t->snap_spatial * aspect;
609
610 copy_v3_fl(t->num.val_inc, t->increment[0]);
611 t->num.unit_sys = t->scene->unit.system;
612 if (t->spacetype == SPACE_VIEW3D) {
613 /* Handling units makes only sense in 3Dview... See #38877. */
617 }
618 else {
619 /* SPACE_GRAPH, SPACE_ACTION, etc. could use some time units, when we have them... */
620 t->num.unit_type[0] = B_UNIT_NONE;
621 t->num.unit_type[1] = B_UNIT_NONE;
622 t->num.unit_type[2] = B_UNIT_NONE;
623 }
624
627
628 TranslateCustomData *custom_data = static_cast<TranslateCustomData *>(
629 MEM_callocN(sizeof(*custom_data), __func__));
631 t->custom.mode.data = custom_data;
632 t->custom.mode.use_free = true;
633
635}
636
638
640 /*flags*/ 0,
641 /*init_fn*/ initTranslation,
642 /*transform_fn*/ applyTranslation,
643 /*transform_matrix_fn*/ applyTranslationMatrix,
644 /*handle_event_fn*/ nullptr,
645 /*snap_distance_fn*/ transform_snap_distance_len_squared_fn,
646 /*snap_apply_fn*/ ApplySnapTranslation,
647 /*draw_fn*/ nullptr,
648};
649
650} // namespace blender::ed::transform
int BKE_image_find_nearest_tile_with_offset(const Image *image, const float co[2], float r_uv_offset[2]) ATTR_NONNULL(2
@ RPT_ERROR
Definition BKE_report.hh:39
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:153
@ B_UNIT_LENGTH
Definition BKE_unit.hh:137
@ B_UNIT_NONE
Definition BKE_unit.hh:136
size_t BKE_unit_value_as_string_scaled(char *str, int str_maxncpy, double value, int prec, int type, const UnitSettings &settings, bool pad)
Definition unit.cc:1895
#define BLI_assert(a)
Definition BLI_assert.h:46
void mul_m3_v3(const float M[3][3], float r[3])
void unit_m3(float m[3][3])
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
void rotation_between_vecs_to_mat3(float m[3][3], const float v1[3], const float v2[3])
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
void minmax_v2v2_v2(float min[2], float max[2], const float vec[2])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE bool is_zero_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void zero_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
size_t size_t size_t BLI_snprintf_utf8(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char size_t BLI_strncpy_utf8_rlen(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
size_t BLI_snprintf_utf8_rlen(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define IN_RANGE_INCL(a, b, c)
#define IFACE_(msgid)
@ SCE_SNAP_ABS_GRID
@ USER_UNIT_NONE
@ SCE_SNAP_TO_NONE
@ RGN_TYPE_PREVIEW
@ SPACE_ACTION
@ SPACE_NODE
@ SPACE_SEQ
@ SPACE_GRAPH
@ SPACE_VIEW3D
@ SNODE_INSERTOFS_DIR_RIGHT
@ USER_NODE_AUTO_OFFSET
@ V3D_AROUND_CURSOR
@ V3D_ORIENT_GLOBAL
@ V3D_ORIENT_VIEW
#define NUM_STR_REP_LEN
bool applyNumInput(NumInput *n, float *vec)
Definition numinput.cc:190
void outputNumInput(NumInput *n, char *str, const UnitSettings &unit_settings)
Definition numinput.cc:88
bool hasNumInput(const NumInput *n)
Definition numinput.cc:171
void ED_area_status_text(ScrArea *area, const char *str)
Definition area.cc:851
@ V3D_PROJ_TEST_NOP
Definition ED_view3d.hh:279
@ V3D_PROJ_RET_OK
Definition ED_view3d.hh:256
eV3DProjStatus ED_view3d_project_float_global(const ARegion *region, const float co[3], float r_co[2], eV3DProjTest flag)
Read Guarded memory(de)allocation.
#define UI_MAX_DRAW_STR
float UI_view2d_grid_resolution_x__frames_or_seconds(const View2D *v2d, const Scene *scene)
float UI_view2d_grid_resolution_y__values(const View2D *v2d, int base)
#define U
BMesh const char void * data
#define str(s)
#define in
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode)
static void transdata_elem_translate(const TransInfo *t, const TransDataContainer *tc, TransData *td, TransDataExtension *td_ext, const float3 &snap_source_local, const float3 &vec, enum eTranslateRotateMode rotate_mode)
void recalc_data(TransInfo *t)
void clipUVData(TransInfo *t)
void getSnapPoint(const TransInfo *t, float vec[3])
static void applyTranslation(TransInfo *t)
bool validSnappingNormal(const TransInfo *t)
bool usingSnappingNormal(const TransInfo *t)
void transform_snap_mixed_apply(TransInfo *t, float *vec)
static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_STR])
static void translate_snap_increment_init(const TransInfo *t)
bool validSnap(const TransInfo *t)
void protectedTransBits(short protectflag, float vec[3])
void snap_sequencer_apply_seqslide(TransInfo *t, float *vec)
float transform_snap_distance_len_squared_fn(TransInfo *, const float p1[3], const float p2[3])
void snap_sequencer_image_apply_translate(TransInfo *t, float vec[2])
void ElementRotation_ex(const TransInfo *t, const TransDataContainer *tc, TransData *td, TransDataExtension *td_ext, const float mat[3][3], const float *center)
void transform_mode_default_modal_orientation_set(TransInfo *t, int type)
bool transform_snap_is_active(const TransInfo *t)
void tranform_snap_target_median_calc(const TransInfo *t, float r_median[3])
void snapFrameTransform(TransInfo *t, eSnapMode snap_mode, float val_initial, float val_final, float *r_val_final)
void removeAspectRatio(TransInfo *t, float vec[2])
static void applyTranslationMatrix(TransInfo *t, float mat_xform[4][4])
static bool translate_snap_increment(const TransInfo *t, float *r_val)
void constraintTransLim(const TransInfo *t, const TransDataContainer *tc, TransData *td)
bool transform_snap_increment_ex(const TransInfo *t, bool use_local_space, float *r_val)
void applyAspectRatio(TransInfo *t, float vec[2])
static void applyTranslationValue(TransInfo *t, const float vec[3])
static void ApplySnapTranslation(TransInfo *t, float vec[3])
static void initTranslation(TransInfo *t, wmOperator *)
TransConvertTypeInfo TransConvertType_Cursor3D
static void translate_dist_to_str(char *r_str, const int r_str_maxncpy, const float val, const UnitSettings *unit)
static bool clip_uv_transform_translation(TransInfo *t, float vec[2])
VecBase< T, 3 > transform_direction(const MatBase< T, 3, 3 > &mat, const VecBase< T, 3 > &direction)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Definition BLI_task.hh:93
MatBase< float, 4, 4 > float4x4
MatBase< float, 3, 3 > float3x3
VecBase< float, 3 > float3
#define FLT_MAX
Definition stdcycles.h:14
void * first
short idx_max
float val[NUM_MAX_ELEMENTS]
float val_inc[NUM_MAX_ELEMENTS]
int unit_type[NUM_MAX_ELEMENTS]
short flag
struct UnitSettings unit
ListBase spacedata
struct Image * image
void(* applyVec)(const TransInfo *t, const TransDataContainer *tc, const TransData *td, const float in[3], float r_out[3])
Definition transform.hh:585
TransConvertTypeInfo * data_type
Definition transform.hh:810
TransCustomDataContainer custom
Definition transform.hh:974
struct blender::ed::transform::TranslateCustomData::@116007100214127073151012312036336264274205242232 prev
i
Definition text_draw.cc:230
#define TRANS_DATA_CONTAINER_FIRST_OK(t)
Definition transform.hh:37
#define TRANS_DATA_CONTAINER_FIRST_SINGLE(t)
Definition transform.hh:39
#define T_PROP_EDIT_ALL
Definition transform.hh:28
#define FOREACH_TRANS_DATA_CONTAINER(t, th)
Definition transform.hh:42
conversion and adaptation of different datablocks to a common struct.
transform modes used by different operators.