Blender V4.3
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
9#include <cstdlib>
10
11#include "MEM_guardedalloc.h"
12
14
15#include "BLI_math_matrix.h"
16#include "BLI_math_rotation.h"
17#include "BLI_math_vector.h"
18#include "BLI_string.h"
19#include "BLI_task.h"
20
21#include "BKE_image.hh"
22#include "BKE_report.hh"
23#include "BKE_unit.hh"
24
25#include "ED_node.hh"
26#include "ED_screen.hh"
27
28#include "UI_interface.hh"
29
30#include "BLT_translation.hh"
31
32#include "transform.hh"
33#include "transform_convert.hh"
34#include "transform_mode.hh"
35#include "transform_snap.hh"
36
37using namespace blender;
38
39/* -------------------------------------------------------------------- */
50
62
65/* -------------------------------------------------------------------- */
79
81 const TransDataContainer *tc,
82 TransData *td,
83 const float3 &snap_source_local,
84 const float3 &vec,
85 enum eTranslateRotateMode rotate_mode)
86{
87 float rotate_offset[3] = {0};
88 bool use_rotate_offset = false;
89
90 /* Handle snapping rotation before doing the translation. */
91 if (rotate_mode != TRANSLATE_ROTATE_OFF) {
92 float mat[3][3];
93
94 if (rotate_mode == TRANSLATE_ROTATE_RESET) {
95 unit_m3(mat);
96 }
97 else {
98 BLI_assert(rotate_mode == TRANSLATE_ROTATE_ON);
99
100 float3 original_normal;
101
102 /* In pose mode, we want to align normals with Y axis of bones. */
103 if (t->options & CTX_POSE_BONE) {
104 original_normal = td->axismtx[1];
105 }
106 else {
107 original_normal = td->axismtx[2];
108 }
109
110 if (t->flag & T_POINTS) {
111 /* Convert to Global Space since #ElementRotation_ex operates with the matrix in global
112 * space. */
113 original_normal = math::transform_direction(float3x3(td->mtx), original_normal);
114 }
115
116 rotation_between_vecs_to_mat3(mat, original_normal, t->tsnap.snapNormal);
117 }
118
119 ElementRotation_ex(t, tc, td, mat, snap_source_local);
120
121 if (td->loc) {
122 use_rotate_offset = true;
123 sub_v3_v3v3(rotate_offset, td->loc, td->iloc);
124 }
125 }
126
127 float tvec[3];
128
129 if (t->con.applyVec) {
130 t->con.applyVec(t, tc, td, vec, tvec);
131 }
132 else {
133 copy_v3_v3(tvec, vec);
134 }
135
136 mul_m3_v3(td->smtx, tvec);
137
138 if (use_rotate_offset) {
139 add_v3_v3(tvec, rotate_offset);
140 }
141
142 if (t->options & CTX_GPENCIL_STROKES) {
143 /* Grease pencil multi-frame falloff. */
144 bGPDstroke *gps = (bGPDstroke *)td->extra;
145 if (gps != nullptr) {
147 }
148 else {
149 mul_v3_fl(tvec, td->factor);
150 }
151 }
152 else {
153 /* Proportional editing falloff. */
154 mul_v3_fl(tvec, td->factor);
155 }
156
158
159 if (td->loc) {
160 add_v3_v3v3(td->loc, td->iloc, tvec);
161 }
162
163 constraintTransLim(t, tc, td);
164}
165
166static void transdata_elem_translate_fn(void *__restrict iter_data_v,
167 const int iter,
168 const TaskParallelTLS *__restrict /*tls*/)
169{
170 TransDataArgs_Translate *data = static_cast<TransDataArgs_Translate *>(iter_data_v);
171 TransData *td = &data->tc->data[iter];
172 if (td->flag & TD_SKIP) {
173 return;
174 }
176 data->t, data->tc, td, data->snap_source_local, data->vec, data->rotate_mode);
177}
178
181/* -------------------------------------------------------------------- */
185static void translate_dist_to_str(char *r_str,
186 const int r_str_maxncpy,
187 const float val,
188 const UnitSettings *unit)
189{
190 if (unit) {
192 r_str, r_str_maxncpy, val * unit->scale_length, 4, B_UNIT_LENGTH, unit, false);
193 }
194 else {
195 /* Check range to prevent string buffer overflow. */
196 BLI_snprintf(r_str, r_str_maxncpy, IN_RANGE_INCL(val, -1e10f, 1e10f) ? "%.4f" : "%.4e", val);
197 }
198}
199
200static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_STR])
201{
202 size_t ofs = 0;
203 char dvec_str[3][NUM_STR_REP_LEN];
204 char dist_str[NUM_STR_REP_LEN];
205 float dist;
206
207 const UnitSettings *unit = nullptr;
208 if (!(t->flag & T_2D_EDIT)) {
209 unit = &t->scene->unit;
210 }
211
212 if (hasNumInput(&t->num)) {
213 outputNumInput(&(t->num), dvec_str[0], &t->scene->unit);
214 dist = len_v3(t->num.val);
215 }
216 else {
217 float dvec[3];
218 copy_v3_v3(dvec, vec);
219 if (t->spacetype == SPACE_GRAPH) {
220 /* WORKAROUND:
221 * Special case where snapping is done in #recalData.
222 * Update the header based on the #center_local. */
223 eSnapMode autosnap = t->tsnap.mode;
224 float ival = TRANS_DATA_CONTAINER_FIRST_OK(t)->center_local[0];
225 float val = ival + dvec[0];
226 snapFrameTransform(t, autosnap, ival, val, &val);
227 dvec[0] = val - ival;
228 }
229
230 if (t->con.mode & CON_APPLY) {
231 int i = 0;
232 if (t->con.mode & CON_AXIS0) {
233 dvec[i++] = dvec[0];
234 }
235 if (t->con.mode & CON_AXIS1) {
236 dvec[i++] = dvec[1];
237 }
238 if (t->con.mode & CON_AXIS2) {
239 dvec[i++] = dvec[2];
240 }
241 while (i != 3) {
242 dvec[i++] = 0.0f;
243 }
244 }
245
246 if (t->flag & T_2D_EDIT) {
247 applyAspectRatio(t, dvec);
248 }
249
250 dist = len_v3(dvec);
251
252 for (int i = 0; i < 3; i++) {
253 translate_dist_to_str(dvec_str[i], sizeof(dvec_str[i]), dvec[i], unit);
254 }
255 }
256
257 translate_dist_to_str(dist_str, sizeof(dist_str), dist, unit);
258
259 if (t->flag & T_PROP_EDIT_ALL) {
260 char prop_str[NUM_STR_REP_LEN];
261 translate_dist_to_str(prop_str, sizeof(prop_str), t->prop_size, unit);
262
263 ofs += BLI_snprintf_rlen(str + ofs,
264 UI_MAX_DRAW_STR - ofs,
265 "%s %s: %s ",
266 IFACE_("Proportional Size"),
267 t->proptext,
268 prop_str);
269 }
270
271 if (t->flag & T_AUTOIK) {
272 short chainlen = t->settings->autoik_chainlen;
273 if (chainlen) {
274 ofs += BLI_snprintf_rlen(
275 str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_("Auto IK Length: %d"), chainlen);
276 ofs += BLI_strncpy_rlen(str + ofs, " ", UI_MAX_DRAW_STR - ofs);
277 }
278 }
279
280 if (t->con.mode & CON_APPLY) {
281 switch (t->num.idx_max) {
282 case 0:
283 ofs += BLI_snprintf_rlen(
284 str + ofs, UI_MAX_DRAW_STR - ofs, "D: %s (%s)%s", dvec_str[0], dist_str, t->con.text);
285 break;
286 case 1:
287 ofs += BLI_snprintf_rlen(str + ofs,
288 UI_MAX_DRAW_STR - ofs,
289 "D: %s D: %s (%s)%s",
290 dvec_str[0],
291 dvec_str[1],
292 dist_str,
293 t->con.text);
294 break;
295 case 2:
296 ofs += BLI_snprintf_rlen(str + ofs,
297 UI_MAX_DRAW_STR - ofs,
298 "D: %s D: %s D: %s (%s)%s",
299 dvec_str[0],
300 dvec_str[1],
301 dvec_str[2],
302 dist_str,
303 t->con.text);
304 break;
305 }
306 }
307 else {
308 if (t->spacetype == SPACE_NODE) {
309 SpaceNode *snode = (SpaceNode *)t->area->spacedata.first;
310 if (U.uiflag & USER_NODE_AUTO_OFFSET) {
311 const char *str_dir = (snode->insert_ofs_dir == SNODE_INSERTOFS_DIR_RIGHT) ?
312 IFACE_("right") :
313 IFACE_("left");
314 ofs += BLI_snprintf_rlen(
315 str, UI_MAX_DRAW_STR, IFACE_("Auto-offset direction: %s"), str_dir);
316 }
317 }
318 else {
319 if (t->flag & T_2D_EDIT) {
320 ofs += BLI_snprintf_rlen(str + ofs,
321 UI_MAX_DRAW_STR - ofs,
322 "Dx: %s Dy: %s (%s)%s",
323 dvec_str[0],
324 dvec_str[1],
325 dist_str,
326 t->con.text);
327 }
328 else {
329 ofs += BLI_snprintf_rlen(str + ofs,
330 UI_MAX_DRAW_STR - ofs,
331 "Dx: %s Dy: %s Dz: %s (%s)%s",
332 dvec_str[0],
333 dvec_str[1],
334 dvec_str[2],
335 dist_str,
336 t->con.text);
337 }
338 }
339 }
340}
341
344/* -------------------------------------------------------------------- */
348static void ApplySnapTranslation(TransInfo *t, float vec[3])
349{
350 float point[3];
351 getSnapPoint(t, point);
352
353 if (t->spacetype == SPACE_NODE) {
354 char border = t->tsnap.snapNodeBorder;
355 if (border & (NODE_LEFT | NODE_RIGHT)) {
356 vec[0] = point[0] - t->tsnap.snap_source[0];
357 }
358 if (border & (NODE_BOTTOM | NODE_TOP)) {
359 vec[1] = point[1] - t->tsnap.snap_source[1];
360 }
361 }
362 else if (t->spacetype == SPACE_SEQ) {
365 }
366 else {
368 }
369 }
370 else {
371 if (t->spacetype == SPACE_VIEW3D) {
372 if (t->options & CTX_PAINT_CURVE) {
375 {
376 zero_v3(point); /* No good answer here... */
377 }
378 }
379 }
380
381 sub_v3_v3v3(vec, point, t->tsnap.snap_source);
382 }
383}
385{
386 if (!(t->tsnap.flag & SCE_SNAP_ABS_GRID)) {
387 return;
388 }
389
390 TranslateCustomData *custom_data = static_cast<TranslateCustomData *>(t->custom.mode.data);
392 /* Use a fallback when transforming the cursor.
393 * In this case the center is _not_ derived from the cursor which is being transformed. */
394 custom_data->snap_target_grid = TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->data->iloc;
395 }
396 else if (t->around == V3D_AROUND_CURSOR) {
397 /* Use a fallback for cursor selection,
398 * this isn't useful as a global center for absolute grid snapping
399 * since its not based on the position of the selection. */
401 }
402 else {
403 custom_data->snap_target_grid = t->center_global;
404 }
405}
406
407static bool translate_snap_increment(const TransInfo *t, float *r_val)
408{
409 if (!transform_snap_increment_ex(t, (t->con.mode & CON_APPLY) != 0, r_val)) {
410 return false;
411 }
412
413 if (t->tsnap.flag & SCE_SNAP_ABS_GRID) {
414 TranslateCustomData *custom_data = static_cast<TranslateCustomData *>(t->custom.mode.data);
415
416 float3 absolute_grid_snap_offset = custom_data->snap_target_grid;
417 transform_snap_increment_ex(t, (t->con.mode & CON_APPLY) != 0, absolute_grid_snap_offset);
418 absolute_grid_snap_offset -= custom_data->snap_target_grid;
419 add_v3_v3(r_val, absolute_grid_snap_offset);
420
421 if (t->con.mode & CON_APPLY) {
422 t->con.applyVec(t, nullptr, nullptr, r_val, r_val);
423 }
424 }
425 return true;
426}
427
430/* -------------------------------------------------------------------- */
434static void applyTranslationValue(TransInfo *t, const float vec[3])
435{
436 TranslateCustomData *custom_data = static_cast<TranslateCustomData *>(t->custom.mode.data);
437
439
441 rotate_mode = TRANSLATE_ROTATE_ON;
442 }
443
444 /* Check to see if this needs to be re-enabled. */
445 if (rotate_mode == TRANSLATE_ROTATE_OFF) {
446 if (t->flag & T_POINTS) {
447 /* When transforming points, only use rotation when snapping is enabled
448 * since re-applying translation without rotation removes rotation. */
449 }
450 else {
451 /* When transforming data that itself stores rotation (objects, bones etc),
452 * apply rotation if it was applied (with the snap normal) previously.
453 * This is needed because failing to rotate will leave the rotation at the last
454 * value used before snapping was disabled. */
455 if (custom_data->prev.rotate_mode == TRANSLATE_ROTATE_ON) {
456 rotate_mode = TRANSLATE_ROTATE_RESET;
457 }
458 }
459 }
460
462 float3 snap_source_local(0);
463 if (rotate_mode != TRANSLATE_ROTATE_OFF) {
464 snap_source_local = t->tsnap.snap_source;
465 if (tc->use_local_mat) {
466 /* The pivot has to be in local-space (see #49494). */
467 snap_source_local = math::transform_point(float4x4(tc->imat), snap_source_local);
468 }
469 }
470
471 if (tc->data_len < TRANSDATA_THREAD_LIMIT) {
472 TransData *td = tc->data;
473 for (int i = 0; i < tc->data_len; i++, td++) {
474 if (td->flag & TD_SKIP) {
475 continue;
476 }
477 transdata_elem_translate(t, tc, td, snap_source_local, vec, rotate_mode);
478 }
479 }
480 else {
482 data.t = t;
483 data.tc = tc;
484 data.snap_source_local = snap_source_local;
485 data.vec = vec;
486 data.rotate_mode = rotate_mode;
487
488 TaskParallelSettings settings;
490 BLI_task_parallel_range(0, tc->data_len, &data, transdata_elem_translate_fn, &settings);
491 }
492 }
493
494 custom_data->prev.rotate_mode = rotate_mode;
495}
496
497static bool clip_uv_transform_translation(TransInfo *t, float vec[2])
498{
499 /* Stores the coordinates of the closest UDIM tile.
500 * Also acts as an offset to the tile from the origin of UV space. */
501 float base_offset[2] = {0.0f, 0.0f};
502
503 /* If tiled image then constrain to correct/closest UDIM tile, else 0-1 UV space. */
504 const SpaceImage *sima = static_cast<const SpaceImage *>(t->area->spacedata.first);
506
507 float min[2], max[2];
508 min[0] = min[1] = FLT_MAX;
509 max[0] = max[1] = -FLT_MAX;
510
512 for (TransData *td = tc->data; td < tc->data + tc->data_len; td++) {
513 minmax_v2v2_v2(min, max, td->loc);
514 }
515 }
516
517 bool result = false;
518 if (min[0] < base_offset[0]) {
519 vec[0] += base_offset[0] - min[0];
520 result = true;
521 }
522 else if (max[0] > base_offset[0] + t->aspect[0]) {
523 vec[0] -= max[0] - base_offset[0] - t->aspect[0];
524 result = true;
525 }
526
527 if (min[1] < base_offset[1]) {
528 vec[1] += base_offset[1] - min[1];
529 result = true;
530 }
531 else if (max[1] > base_offset[1] + t->aspect[1]) {
532 vec[1] -= max[1] - base_offset[1] - t->aspect[1];
533 result = true;
534 }
535
536 return result;
537}
538
540{
541 char str[UI_MAX_DRAW_STR] = "";
542 float global_dir[3] = {0.0f};
543
544 if (t->flag & T_INPUT_IS_VALUES_FINAL) {
545 mul_v3_m3v3(global_dir, t->spacemtx, t->values);
546 }
547 else if (applyNumInput(&t->num, global_dir)) {
548 if (t->con.mode & CON_APPLY) {
549 if (t->con.mode & CON_AXIS0) {
550 mul_v3_v3fl(global_dir, t->spacemtx[0], global_dir[0]);
551 }
552 else if (t->con.mode & CON_AXIS1) {
553 mul_v3_v3fl(global_dir, t->spacemtx[1], global_dir[0]);
554 }
555 else if (t->con.mode & CON_AXIS2) {
556 mul_v3_v3fl(global_dir, t->spacemtx[2], global_dir[0]);
557 }
558 }
559 else {
560 mul_v3_m3v3(global_dir, t->spacemtx, global_dir);
561 }
562 if (t->flag & T_2D_EDIT) {
563 removeAspectRatio(t, global_dir);
564 }
565 }
566 else {
567 copy_v3_v3(global_dir, t->values);
569 float values_ofs[3];
570 mul_v3_m3v3(values_ofs, t->spacemtx, t->values_modal_offset);
571 add_v3_v3(global_dir, values_ofs);
572 }
573
574 transform_snap_mixed_apply(t, global_dir);
575
576 if (t->con.mode & CON_APPLY) {
577 float in[3];
578 copy_v3_v3(in, global_dir);
579 t->con.applyVec(t, nullptr, nullptr, in, global_dir);
580 }
581
582 float incr_dir[3];
583 copy_v3_v3(incr_dir, global_dir);
584 if (!(transform_snap_is_active(t) && validSnap(t)) && translate_snap_increment(t, incr_dir)) {
585
586 /* Test for mixed snap with grid. */
587 float snap_dist_sq = FLT_MAX;
589 snap_dist_sq = len_squared_v3v3(t->values, global_dir);
590 }
591 if ((snap_dist_sq == FLT_MAX) || (len_squared_v3v3(global_dir, incr_dir) < snap_dist_sq)) {
592 copy_v3_v3(global_dir, incr_dir);
593 }
594 }
595 }
596
597 applyTranslationValue(t, global_dir);
598
599 /* Evil hack - redo translation if clipping needed. */
600 if (t->flag & T_CLIP_UV && clip_uv_transform_translation(t, global_dir)) {
601 applyTranslationValue(t, global_dir);
602
603 /* Not ideal, see #clipUVData code-comment. */
604 if (t->flag & T_PROP_EDIT) {
605 clipUVData(t);
606 }
607 }
608
609 /* Set the redo value. */
610 mul_v3_m3v3(t->values_final, t->spacemtx_inv, global_dir);
611 headerTranslation(t, (t->con.mode & CON_APPLY) ? t->values_final : global_dir, str);
612
613 recalc_data(t);
614 ED_area_status_text(t->area, (str[0] == '\0') ? nullptr : str);
615}
616
617static void applyTranslationMatrix(TransInfo *t, float mat_xform[4][4])
618{
619 float delta[3];
620 mul_v3_m3v3(delta, t->spacemtx, t->values_final);
621 add_v3_v3(mat_xform[3], delta);
622}
623
624static void initTranslation(TransInfo *t, wmOperator * /*op*/)
625{
626 if (t->spacetype == SPACE_ACTION) {
627 /* This space uses time translate. */
629 RPT_ERROR,
630 "Use 'Time_Translate' transform mode instead of 'Translation' mode "
631 "for translating keyframes in Dope Sheet Editor");
632 t->state = TRANS_CANCEL;
633 return;
634 }
635
636 initMouseInputMode(t, &t->mouse, INPUT_VECTOR);
637
638 t->idx_max = (t->flag & T_2D_EDIT) ? 1 : 2;
639 t->num.flag = 0;
640 t->num.idx_max = t->idx_max;
641
642 t->snap[0] = t->snap_spatial[0];
643 t->snap[1] = t->snap_spatial[0] * t->snap_spatial_precision;
644
645 copy_v3_fl(t->num.val_inc, t->snap[0]);
646 t->num.unit_sys = t->scene->unit.system;
647 if (t->spacetype == SPACE_VIEW3D) {
648 /* Handling units makes only sense in 3Dview... See #38877. */
652 }
653 else {
654 /* SPACE_GRAPH, SPACE_ACTION, etc. could use some time units, when we have them... */
655 t->num.unit_type[0] = B_UNIT_NONE;
656 t->num.unit_type[1] = B_UNIT_NONE;
657 t->num.unit_type[2] = B_UNIT_NONE;
658 }
659
662
663 TranslateCustomData *custom_data = static_cast<TranslateCustomData *>(
664 MEM_callocN(sizeof(*custom_data), __func__));
666 t->custom.mode.data = custom_data;
667 t->custom.mode.use_free = true;
668
670}
671
675 /*flags*/ 0,
676 /*init_fn*/ initTranslation,
677 /*transform_fn*/ applyTranslation,
678 /*transform_matrix_fn*/ applyTranslationMatrix,
679 /*handle_event_fn*/ nullptr,
680 /*snap_distance_fn*/ transform_snap_distance_len_squared_fn,
681 /*snap_apply_fn*/ ApplySnapTranslation,
682 /*draw_fn*/ nullptr,
683};
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:125
@ B_UNIT_LENGTH
Definition BKE_unit.hh:107
@ B_UNIT_NONE
Definition BKE_unit.hh:106
size_t BKE_unit_value_as_string(char *str, int str_maxncpy, double value, int prec, int type, const UnitSettings *settings, bool pad)
Definition unit.cc:1876
#define BLI_assert(a)
Definition BLI_assert.h:50
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
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition task_range.cc:99
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
Definition BLI_task.h:230
#define IN_RANGE_INCL(a, b, c)
#define IFACE_(msgid)
@ 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
@ NODE_LEFT
Definition ED_node_c.hh:30
@ NODE_RIGHT
Definition ED_node_c.hh:31
@ NODE_BOTTOM
Definition ED_node_c.hh:29
@ NODE_TOP
Definition ED_node_c.hh:28
#define NUM_STR_REP_LEN
void outputNumInput(NumInput *n, char *str, const UnitSettings *unit_settings)
Definition numinput.cc:88
bool applyNumInput(NumInput *n, float *vec)
Definition numinput.cc:190
bool hasNumInput(const NumInput *n)
Definition numinput.cc:171
void ED_area_status_text(ScrArea *area, const char *str)
Definition area.cc:803
@ V3D_PROJ_TEST_NOP
Definition ED_view3d.hh:266
@ V3D_PROJ_RET_OK
Definition ED_view3d.hh:243
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
unsigned int U
Definition btGjkEpa3.h:78
void removeAspectRatio(TransInfo *t, float vec[2])
void applyAspectRatio(TransInfo *t, float vec[2])
#define str(s)
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
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)
MatBase< float, 4, 4 > float4x4
MatBase< float, 3, 3 > float3x3
#define min(a, b)
Definition sort.c:32
#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
char text[50]
Definition transform.hh:347
void(* applyVec)(const TransInfo *t, const TransDataContainer *tc, const TransData *td, const float in[3], float r_out[3])
Definition transform.hh:360
eTConstraint mode
Definition transform.hh:351
TransCustomData mode
Definition transform.hh:423
unsigned int use_free
Definition transform.hh:410
const TransDataContainer * tc
enum eTranslateRotateMode rotate_mode
float smtx[3][3]
float axismtx[3][3]
float mtx[3][3]
float snap_spatial_precision
Definition transform.hh:568
short around
Definition transform.hh:580
char spacetype
Definition transform.hh:582
float snap[2]
Definition transform.hh:561
float spacemtx_inv[3][3]
Definition transform.hh:593
float snap_spatial[3]
Definition transform.hh:563
float prop_size
Definition transform.hh:546
ReportList * reports
Definition transform.hh:661
float values[4]
Definition transform.hh:624
char proptext[20]
Definition transform.hh:548
TransSnap tsnap
Definition transform.hh:537
short idx_max
Definition transform.hh:559
float values_modal_offset[4]
Definition transform.hh:627
eTState state
Definition transform.hh:527
ToolSettings * settings
Definition transform.hh:656
NumInput num
Definition transform.hh:540
TransCustomDataContainer custom
Definition transform.hh:676
float aspect[3]
Definition transform.hh:553
Scene * scene
Definition transform.hh:654
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
TransCon con
Definition transform.hh:534
float center_global[3]
Definition transform.hh:555
float spacemtx[3][3]
Definition transform.hh:592
TransConvertTypeInfo * data_type
Definition transform.hh:513
eTContext options
Definition transform.hh:521
ScrArea * area
Definition transform.hh:651
float snapNormal[3]
Definition transform.hh:328
eSnapFlag flag
Definition transform.hh:310
char snapNodeBorder
Definition transform.hh:329
float snap_source[3]
Definition transform.hh:325
eSnapMode mode
Definition transform.hh:312
eSnapMode target_type
Definition transform.hh:321
enum eTranslateRotateMode rotate_mode
struct TranslateCustomData::@585 prev
bGPDstroke_Runtime runtime
@ CON_APPLY
Definition transform.hh:193
@ CON_AXIS1
Definition transform.hh:196
@ CON_AXIS0
Definition transform.hh:195
@ CON_AXIS2
Definition transform.hh:197
@ CTX_PAINT_CURVE
Definition transform.hh:72
@ CTX_POSE_BONE
Definition transform.hh:73
@ CTX_GPENCIL_STROKES
Definition transform.hh:68
@ CTX_CAMERA
Definition transform.hh:65
#define TRANS_DATA_CONTAINER_FIRST_OK(t)
Definition transform.hh:849
@ T_AUTOIK
Definition transform.hh:108
@ T_PROP_EDIT
Definition transform.hh:98
@ T_INPUT_IS_VALUES_FINAL
Definition transform.hh:115
@ T_2D_EDIT
Definition transform.hh:104
@ T_POINTS
Definition transform.hh:93
@ T_CLIP_UV
Definition transform.hh:105
#define TRANS_DATA_CONTAINER_FIRST_SINGLE(t)
Definition transform.hh:851
@ TRANS_CANCEL
Definition transform.hh:210
#define T_PROP_EDIT_ALL
Definition transform.hh:157
void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode)
#define FOREACH_TRANS_DATA_CONTAINER(t, th)
Definition transform.hh:854
void clipUVData(TransInfo *t)
void recalc_data(TransInfo *t)
conversion and adaptation of different datablocks to a common struct.
TransConvertTypeInfo TransConvertType_Cursor3D
@ TD_SKIP
#define TRANSDATA_THREAD_LIMIT
void protectedTransBits(short protectflag, float vec[3])
void ElementRotation_ex(const TransInfo *t, const TransDataContainer *tc, TransData *td, const float mat[3][3], const float *center)
void transform_mode_default_modal_orientation_set(TransInfo *t, int type)
void constraintTransLim(const TransInfo *t, const TransDataContainer *tc, TransData *td)
transform modes used by different operators.
static void transdata_elem_translate_fn(void *__restrict iter_data_v, const int iter, const TaskParallelTLS *__restrict)
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)
static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_STR])
static void initTranslation(TransInfo *t, wmOperator *)
static void translate_dist_to_str(char *r_str, const int r_str_maxncpy, const float val, const UnitSettings *unit)
static void ApplySnapTranslation(TransInfo *t, float vec[3])
static void applyTranslation(TransInfo *t)
@ TRANSLATE_ROTATE_RESET
static void translate_snap_increment_init(const TransInfo *t)
static bool translate_snap_increment(const TransInfo *t, float *r_val)
static bool clip_uv_transform_translation(TransInfo *t, float vec[2])
TransModeInfo TransMode_translate
static void applyTranslationValue(TransInfo *t, const float vec[3])
static void applyTranslationMatrix(TransInfo *t, float mat_xform[4][4])
bool usingSnappingNormal(const TransInfo *t)
void transform_snap_mixed_apply(TransInfo *t, float *vec)
bool validSnap(const TransInfo *t)
bool transform_snap_is_active(const TransInfo *t)
float transform_snap_distance_len_squared_fn(TransInfo *, const float p1[3], const float p2[3])
void getSnapPoint(const TransInfo *t, float vec[3])
bool transform_snap_increment_ex(const TransInfo *t, bool use_local_space, float *r_val)
bool validSnappingNormal(const TransInfo *t)
void tranform_snap_target_median_calc(const TransInfo *t, float r_median[3])
void transform_snap_sequencer_image_apply_translate(TransInfo *t, float vec[2])
void transform_snap_sequencer_apply_seqslide(TransInfo *t, float *vec)
void snapFrameTransform(TransInfo *t, eSnapMode autosnap, float val_initial, float val_final, float *r_val_final)