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