Blender  V3.3
transform_mode.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #include <stdlib.h>
9 
10 #include "DNA_anim_types.h"
11 #include "DNA_armature_types.h"
12 #include "DNA_constraint_types.h"
13 #include "DNA_gpencil_types.h"
15 
16 #include "BLI_listbase.h"
17 #include "BLI_math.h"
18 #include "BLI_string.h"
19 
20 #include "BKE_constraint.h"
21 #include "BKE_context.h"
22 #include "BKE_nla.h"
23 
24 #include "RNA_access.h"
25 
26 #include "UI_interface.h"
27 
28 #include "BLT_translation.h"
29 
30 #include "transform.h"
31 #include "transform_convert.h"
32 #include "transform_orientations.h"
33 #include "transform_snap.h"
34 
35 /* Own include. */
36 #include "transform_mode.h"
37 
39 {
40  if (mode == TFM_BONESIZE) {
42  BLI_assert(ob);
43  if (ob->type != OB_ARMATURE) {
44  return TFM_RESIZE;
45  }
46  bArmature *arm = ob->data;
47  if (arm->drawtype == ARM_ENVELOPE) {
49  }
50  }
51 
52  return mode;
53 }
54 
55 bool transdata_check_local_center(const TransInfo *t, short around)
56 {
57  return ((around == V3D_AROUND_LOCAL_ORIGINS) &&
58  ((t->options & (CTX_OBJECT | CTX_POSE_BONE)) ||
59  /* implicit: (t->flag & T_EDIT) */
61  (t->spacetype == SPACE_GRAPH) ||
63 }
64 
65 bool transform_mode_is_changeable(const int mode)
66 {
67  return ELEM(mode,
69  TFM_RESIZE,
74 }
75 
76 /* -------------------------------------------------------------------- */
80 void protectedTransBits(short protectflag, float vec[3])
81 {
82  if (protectflag & OB_LOCK_LOCX) {
83  vec[0] = 0.0f;
84  }
85  if (protectflag & OB_LOCK_LOCY) {
86  vec[1] = 0.0f;
87  }
88  if (protectflag & OB_LOCK_LOCZ) {
89  vec[2] = 0.0f;
90  }
91 }
92 
93 /* this function only does the delta rotation */
94 static void protectedQuaternionBits(short protectflag, float quat[4], const float oldquat[4])
95 {
96  /* check that protection flags are set */
97  if ((protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) == 0) {
98  return;
99  }
100 
101  if (protectflag & OB_LOCK_ROT4D) {
102  /* quaternions getting limited as 4D entities that they are... */
103  if (protectflag & OB_LOCK_ROTW) {
104  quat[0] = oldquat[0];
105  }
106  if (protectflag & OB_LOCK_ROTX) {
107  quat[1] = oldquat[1];
108  }
109  if (protectflag & OB_LOCK_ROTY) {
110  quat[2] = oldquat[2];
111  }
112  if (protectflag & OB_LOCK_ROTZ) {
113  quat[3] = oldquat[3];
114  }
115  }
116  else {
117  /* quaternions get limited with euler... (compatibility mode) */
118  float eul[3], oldeul[3], nquat[4], noldquat[4];
119  float qlen;
120 
121  qlen = normalize_qt_qt(nquat, quat);
122  normalize_qt_qt(noldquat, oldquat);
123 
124  quat_to_eul(eul, nquat);
125  quat_to_eul(oldeul, noldquat);
126 
127  if (protectflag & OB_LOCK_ROTX) {
128  eul[0] = oldeul[0];
129  }
130  if (protectflag & OB_LOCK_ROTY) {
131  eul[1] = oldeul[1];
132  }
133  if (protectflag & OB_LOCK_ROTZ) {
134  eul[2] = oldeul[2];
135  }
136 
137  eul_to_quat(quat, eul);
138 
139  /* restore original quat size */
140  mul_qt_fl(quat, qlen);
141 
142  /* quaternions flip w sign to accumulate rotations correctly */
143  if ((nquat[0] < 0.0f && quat[0] > 0.0f) || (nquat[0] > 0.0f && quat[0] < 0.0f)) {
144  mul_qt_fl(quat, -1.0f);
145  }
146  }
147 }
148 
149 static void protectedRotateBits(short protectflag, float eul[3], const float oldeul[3])
150 {
151  if (protectflag & OB_LOCK_ROTX) {
152  eul[0] = oldeul[0];
153  }
154  if (protectflag & OB_LOCK_ROTY) {
155  eul[1] = oldeul[1];
156  }
157  if (protectflag & OB_LOCK_ROTZ) {
158  eul[2] = oldeul[2];
159  }
160 }
161 
162 /* this function only does the delta rotation */
163 /* axis-angle is usually internally stored as quats... */
165  short protectflag, float axis[3], float *angle, const float oldAxis[3], float oldAngle)
166 {
167  /* check that protection flags are set */
168  if ((protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) == 0) {
169  return;
170  }
171 
172  if (protectflag & OB_LOCK_ROT4D) {
173  /* axis-angle getting limited as 4D entities that they are... */
174  if (protectflag & OB_LOCK_ROTW) {
175  *angle = oldAngle;
176  }
177  if (protectflag & OB_LOCK_ROTX) {
178  axis[0] = oldAxis[0];
179  }
180  if (protectflag & OB_LOCK_ROTY) {
181  axis[1] = oldAxis[1];
182  }
183  if (protectflag & OB_LOCK_ROTZ) {
184  axis[2] = oldAxis[2];
185  }
186  }
187  else {
188  /* axis-angle get limited with euler... */
189  float eul[3], oldeul[3];
190 
192  axis_angle_to_eulO(oldeul, EULER_ORDER_DEFAULT, oldAxis, oldAngle);
193 
194  if (protectflag & OB_LOCK_ROTX) {
195  eul[0] = oldeul[0];
196  }
197  if (protectflag & OB_LOCK_ROTY) {
198  eul[1] = oldeul[1];
199  }
200  if (protectflag & OB_LOCK_ROTZ) {
201  eul[2] = oldeul[2];
202  }
203 
205 
206  /* When converting to axis-angle,
207  * we need a special exception for the case when there is no axis. */
208  if (IS_EQF(axis[0], axis[1]) && IS_EQF(axis[1], axis[2])) {
209  /* for now, rotate around y-axis then (so that it simply becomes the roll) */
210  axis[1] = 1.0f;
211  }
212  }
213 }
214 
215 void protectedSizeBits(short protectflag, float size[3])
216 {
217  if (protectflag & OB_LOCK_SCALEX) {
218  size[0] = 1.0f;
219  }
220  if (protectflag & OB_LOCK_SCALEY) {
221  size[1] = 1.0f;
222  }
223  if (protectflag & OB_LOCK_SCALEZ) {
224  size[2] = 1.0f;
225  }
226 }
227 
230 /* -------------------------------------------------------------------- */
235 {
236  if (td->con) {
241 
242  bConstraintOb cob = {NULL};
243  bConstraint *con;
244  float ctime = (float)(t->scene->r.cfra);
245 
246  /* Make a temporary bConstraintOb for using these limit constraints
247  * - they only care that cob->matrix is correctly set ;-)
248  * - current space should be local
249  */
250  unit_m4(cob.matrix);
251  copy_v3_v3(cob.matrix[3], td->loc);
252 
253  /* Evaluate valid constraints */
254  for (con = td->con; con; con = con->next) {
255  const bConstraintTypeInfo *cti = NULL;
256  ListBase targets = {NULL, NULL};
257 
258  /* only consider constraint if enabled */
259  if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) {
260  continue;
261  }
262  if (con->enforce == 0.0f) {
263  continue;
264  }
265 
266  /* only use it if it's tagged for this purpose (and the right type) */
267  if (con->type == CONSTRAINT_TYPE_LOCLIMIT) {
269 
270  if ((data->flag2 & LIMIT_TRANSFORM) == 0) {
271  continue;
272  }
273  cti = ctiLoc;
274  }
275  else if (con->type == CONSTRAINT_TYPE_DISTLIMIT) {
277 
278  if ((data->flag & LIMITDIST_TRANSFORM) == 0) {
279  continue;
280  }
281  cti = ctiDist;
282  }
283 
284  if (cti) {
285  /* do space conversions */
286  if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
287  /* just multiply by td->mtx (this should be ok) */
288  mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
289  }
290  else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
291  /* skip... incompatible spacetype */
292  continue;
293  }
294 
295  /* Initialize the custom space for use in calculating the matrices. */
297 
298  /* get constraint targets if needed */
299  BKE_constraint_targets_for_solving_get(t->depsgraph, con, &cob, &targets, ctime);
300 
301  /* do constraint */
302  cti->evaluate_constraint(con, &cob, &targets);
303 
304  /* convert spaces again */
305  if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
306  /* just multiply by td->smtx (this should be ok) */
307  mul_m4_m3m4(cob.matrix, td->smtx, cob.matrix);
308  }
309 
310  /* free targets list */
311  BLI_freelistN(&targets);
312  }
313  }
314 
315  /* copy results from cob->matrix */
316  copy_v3_v3(td->loc, cob.matrix[3]);
317  }
318 }
319 
321 {
322  /* Make a temporary bConstraintOb for use by limit constraints
323  * - they only care that cob->matrix is correctly set ;-)
324  * - current space should be local
325  */
326  memset(cob, 0, sizeof(bConstraintOb));
327  if (td->ext) {
328  if (td->ext->rotOrder == ROT_MODE_QUAT) {
329  /* quats */
330  /* objects and bones do normalization first too, otherwise
331  * we don't necessarily end up with a rotation matrix, and
332  * then conversion back to quat gives a different result */
333  float quat[4];
334  normalize_qt_qt(quat, td->ext->quat);
335  quat_to_mat4(cob->matrix, quat);
336  }
337  else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
338  /* axis angle */
339  axis_angle_to_mat4(cob->matrix, td->ext->rotAxis, *td->ext->rotAngle);
340  }
341  else {
342  /* eulers */
343  eulO_to_mat4(cob->matrix, td->ext->rot, td->ext->rotOrder);
344  }
345  }
346 }
347 
348 static void constraintRotLim(const TransInfo *UNUSED(t), TransData *td)
349 {
350  if (td->con) {
352  bConstraintOb cob;
353  bConstraint *con;
354  bool do_limit = false;
355 
356  /* Evaluate valid constraints */
357  for (con = td->con; con; con = con->next) {
358  /* only consider constraint if enabled */
359  if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) {
360  continue;
361  }
362  if (con->enforce == 0.0f) {
363  continue;
364  }
365 
366  /* we're only interested in Limit-Rotation constraints */
367  if (con->type == CONSTRAINT_TYPE_ROTLIMIT) {
369 
370  /* only use it if it's tagged for this purpose */
371  if ((data->flag2 & LIMIT_TRANSFORM) == 0) {
372  continue;
373  }
374 
375  /* skip incompatible spacetypes */
377  continue;
378  }
379 
380  /* only do conversion if necessary, to preserve quats and eulers */
381  if (do_limit == false) {
382  constraintob_from_transdata(&cob, td);
383  do_limit = true;
384  }
385 
386  /* do space conversions */
387  if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
388  /* just multiply by td->mtx (this should be ok) */
389  mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
390  }
391 
392  /* do constraint */
393  cti->evaluate_constraint(con, &cob, NULL);
394 
395  /* convert spaces again */
396  if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
397  /* just multiply by td->smtx (this should be ok) */
398  mul_m4_m3m4(cob.matrix, td->smtx, cob.matrix);
399  }
400  }
401  }
402 
403  if (do_limit) {
404  /* copy results from cob->matrix */
405  if (td->ext->rotOrder == ROT_MODE_QUAT) {
406  /* quats */
407  mat4_to_quat(td->ext->quat, cob.matrix);
408  }
409  else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
410  /* axis angle */
411  mat4_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, cob.matrix);
412  }
413  else {
414  /* eulers */
415  mat4_to_eulO(td->ext->rot, td->ext->rotOrder, cob.matrix);
416  }
417  }
418  }
419 }
420 
422 {
423  if (td->con && td->ext) {
425  bConstraintOb cob = {NULL};
426  bConstraint *con;
427  float size_sign[3], size_abs[3];
428  int i;
429 
430  /* Make a temporary bConstraintOb for using these limit constraints
431  * - they only care that cob->matrix is correctly set ;-)
432  * - current space should be local
433  */
434  if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
435  /* scale val and reset size */
436  return; /* TODO: fix this case */
437  }
438 
439  /* Reset val if SINGLESIZE but using a constraint */
440  if (td->flag & TD_SINGLESIZE) {
441  return;
442  }
443 
444  /* separate out sign to apply back later */
445  for (i = 0; i < 3; i++) {
446  size_sign[i] = signf(td->ext->size[i]);
447  size_abs[i] = fabsf(td->ext->size[i]);
448  }
449 
450  size_to_mat4(cob.matrix, size_abs);
451 
452  /* Evaluate valid constraints */
453  for (con = td->con; con; con = con->next) {
454  /* only consider constraint if enabled */
455  if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) {
456  continue;
457  }
458  if (con->enforce == 0.0f) {
459  continue;
460  }
461 
462  /* we're only interested in Limit-Scale constraints */
463  if (con->type == CONSTRAINT_TYPE_SIZELIMIT) {
465 
466  /* only use it if it's tagged for this purpose */
467  if ((data->flag2 & LIMIT_TRANSFORM) == 0) {
468  continue;
469  }
470 
471  /* do space conversions */
472  if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
473  /* just multiply by td->mtx (this should be ok) */
474  mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
475  }
476  else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
477  /* skip... incompatible spacetype */
478  continue;
479  }
480 
481  /* do constraint */
482  cti->evaluate_constraint(con, &cob, NULL);
483 
484  /* convert spaces again */
485  if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
486  /* just multiply by td->smtx (this should be ok) */
487  mul_m4_m3m4(cob.matrix, td->smtx, cob.matrix);
488  }
489  }
490  }
491 
492  /* copy results from cob->matrix */
493  if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
494  /* scale val and reset size */
495  return; /* TODO: fix this case. */
496  }
497 
498  /* Reset val if SINGLESIZE but using a constraint */
499  if (td->flag & TD_SINGLESIZE) {
500  return;
501  }
502 
503  /* Extract scale from matrix and apply back sign. */
504  mat4_to_size(td->ext->size, cob.matrix);
505  mul_v3_v3(td->ext->size, size_sign);
506  }
507 }
508 
511 /* -------------------------------------------------------------------- */
515 void headerRotation(TransInfo *t, char *str, const int str_size, float final)
516 {
517  size_t ofs = 0;
518 
519  if (hasNumInput(&t->num)) {
520  char c[NUM_STR_REP_LEN];
521 
522  outputNumInput(&(t->num), c, &t->scene->unit);
523 
524  ofs += BLI_snprintf_rlen(
525  str + ofs, str_size - ofs, TIP_("Rotation: %s %s %s"), &c[0], t->con.text, t->proptext);
526  }
527  else {
528  ofs += BLI_snprintf_rlen(str + ofs,
529  str_size - ofs,
530  TIP_("Rotation: %.2f%s %s"),
531  RAD2DEGF(final),
532  t->con.text,
533  t->proptext);
534  }
535 
536  if (t->flag & T_PROP_EDIT_ALL) {
537  ofs += BLI_snprintf_rlen(
538  str + ofs, str_size - ofs, TIP_(" Proportional size: %.2f"), t->prop_size);
539  }
540 }
541 
543  const TransDataContainer *tc,
544  TransData *td,
545  const float mat[3][3],
546  const float *center)
547 {
548  float vec[3], totmat[3][3], smat[3][3];
549  float eul[3], fmat[3][3], quat[4];
550 
551  if (t->flag & T_POINTS) {
552  mul_m3_m3m3(totmat, mat, td->mtx);
553  mul_m3_m3m3(smat, td->smtx, totmat);
554 
555  /* Apply gpencil falloff. */
556  if (t->options & CTX_GPENCIL_STROKES) {
557  bGPDstroke *gps = (bGPDstroke *)td->extra;
558  if (gps->runtime.multi_frame_falloff != 1.0f) {
559  float ident_mat[3][3];
560  unit_m3(ident_mat);
561  interp_m3_m3m3(smat, ident_mat, smat, gps->runtime.multi_frame_falloff);
562  }
563  }
564 
565  sub_v3_v3v3(vec, td->iloc, center);
566  mul_m3_v3(smat, vec);
567 
568  add_v3_v3v3(td->loc, vec, center);
569 
570  sub_v3_v3v3(vec, td->loc, td->iloc);
572  add_v3_v3v3(td->loc, td->iloc, vec);
573 
574  if (td->flag & TD_USEQUAT) {
575  mul_m3_series(fmat, td->smtx, mat, td->mtx);
576  mat3_to_quat(quat, fmat); /* Actual transform */
577 
578  if (td->ext->quat) {
579  mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
580 
581  /* is there a reason not to have this here? -jahka */
583  }
584  }
585  }
598  else if (t->options & CTX_POSE_BONE) {
599  /* Extract and invert armature object matrix */
600 
601  if ((td->flag & TD_NO_LOC) == 0) {
602  sub_v3_v3v3(vec, td->center, center);
603 
604  mul_m3_v3(tc->mat3, vec); /* To Global space. */
605  mul_m3_v3(mat, vec); /* Applying rotation. */
606  mul_m3_v3(tc->imat3, vec); /* To Local space. */
607 
608  add_v3_v3(vec, center);
609  /* vec now is the location where the object has to be */
610 
611  sub_v3_v3v3(vec, vec, td->center); /* Translation needed from the initial location */
612 
613  /* special exception, see TD_PBONE_LOCAL_MTX definition comments */
614  if (td->flag & TD_PBONE_LOCAL_MTX_P) {
615  /* do nothing */
616  }
617  else if (td->flag & TD_PBONE_LOCAL_MTX_C) {
618  mul_m3_v3(tc->mat3, vec); /* To Global space. */
619  mul_m3_v3(td->ext->l_smtx, vec); /* To Pose space (Local Location). */
620  }
621  else {
622  mul_m3_v3(tc->mat3, vec); /* To Global space. */
623  mul_m3_v3(td->smtx, vec); /* To Pose space. */
624  }
625 
627 
628  add_v3_v3v3(td->loc, td->iloc, vec);
629 
630  constraintTransLim(t, td);
631  }
632 
633  /* rotation */
634  /* MORE HACK: as in some cases the matrix to apply location and rot/scale is not the same,
635  * and ElementRotation() might be called in Translation context (with align snapping),
636  * we need to be sure to actually use the *rotation* matrix here...
637  * So no other way than storing it in some dedicated members of td->ext! */
638  if ((t->flag & T_V3D_ALIGN) == 0) { /* align mode doesn't rotate objects itself */
639  /* euler or quaternion/axis-angle? */
640  if (td->ext->rotOrder == ROT_MODE_QUAT) {
641  mul_m3_series(fmat, td->ext->r_smtx, mat, td->ext->r_mtx);
642 
643  mat3_to_quat(quat, fmat); /* Actual transform */
644 
645  mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
646  /* this function works on end result */
648  }
649  else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
650  /* calculate effect based on quats */
651  float iquat[4], tquat[4];
652 
653  axis_angle_to_quat(iquat, td->ext->irotAxis, td->ext->irotAngle);
654 
655  mul_m3_series(fmat, td->ext->r_smtx, mat, td->ext->r_mtx);
656  mat3_to_quat(quat, fmat); /* Actual transform */
657  mul_qt_qtqt(tquat, quat, iquat);
658 
659  quat_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, tquat);
660 
661  /* this function works on end result */
663  td->ext->rotAxis,
664  td->ext->rotAngle,
665  td->ext->irotAxis,
666  td->ext->irotAngle);
667  }
668  else {
669  float eulmat[3][3];
670 
671  mul_m3_m3m3(totmat, mat, td->ext->r_mtx);
672  mul_m3_m3m3(smat, td->ext->r_smtx, totmat);
673 
674  /* Calculate the total rotation in eulers. */
675  copy_v3_v3(eul, td->ext->irot);
676  eulO_to_mat3(eulmat, eul, td->ext->rotOrder);
677 
678  /* mat = transform, obmat = bone rotation */
679  mul_m3_m3m3(fmat, smat, eulmat);
680 
681  mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat);
682 
683  /* and apply (to end result only) */
684  protectedRotateBits(td->protectflag, eul, td->ext->irot);
685  copy_v3_v3(td->ext->rot, eul);
686  }
687 
688  constraintRotLim(t, td);
689  }
690  }
691  else {
692  if ((td->flag & TD_NO_LOC) == 0) {
693  /* translation */
694  sub_v3_v3v3(vec, td->center, center);
695  mul_m3_v3(mat, vec);
696  add_v3_v3(vec, center);
697  /* vec now is the location where the object has to be */
698  sub_v3_v3(vec, td->center);
699  mul_m3_v3(td->smtx, vec);
700 
702 
703  add_v3_v3v3(td->loc, td->iloc, vec);
704  }
705 
706  constraintTransLim(t, td);
707 
708  /* rotation */
709  if ((t->flag & T_V3D_ALIGN) == 0) { /* Align mode doesn't rotate objects itself. */
710  /* euler or quaternion? */
711  if ((td->ext->rotOrder == ROT_MODE_QUAT) || (td->flag & TD_USEQUAT)) {
712  /* can be called for texture space translate for example, then opt out */
713  if (td->ext->quat) {
714  mul_m3_series(fmat, td->smtx, mat, td->mtx);
715 
716  if (!is_zero_v3(td->ext->dquat)) {
717  /* Correct for delta quat */
718  float tmp_mat[3][3];
719  quat_to_mat3(tmp_mat, td->ext->dquat);
720  mul_m3_m3m3(fmat, fmat, tmp_mat);
721  }
722 
723  mat3_to_quat(quat, fmat); /* Actual transform */
724 
725  if (!is_zero_v4(td->ext->dquat)) {
726  /* Correct back for delta quat. */
727  float idquat[4];
728  invert_qt_qt_normalized(idquat, td->ext->dquat);
729  mul_qt_qtqt(quat, idquat, quat);
730  }
731 
732  mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
733 
734  /* this function works on end result */
736  }
737  }
738  else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
739  /* calculate effect based on quats */
740  float iquat[4], tquat[4];
741 
742  axis_angle_to_quat(iquat, td->ext->irotAxis, td->ext->irotAngle);
743 
744  mul_m3_series(fmat, td->smtx, mat, td->mtx);
745  mat3_to_quat(quat, fmat); /* Actual transform */
746  mul_qt_qtqt(tquat, quat, iquat);
747 
748  quat_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, tquat);
749 
750  /* this function works on end result */
752  td->ext->rotAxis,
753  td->ext->rotAngle,
754  td->ext->irotAxis,
755  td->ext->irotAngle);
756  }
757  else {
758  /* Calculate the total rotation in eulers. */
759  float obmat[3][3];
760 
761  mul_m3_m3m3(totmat, mat, td->mtx);
762  mul_m3_m3m3(smat, td->smtx, totmat);
763 
764  if (!is_zero_v3(td->ext->drot)) {
765  /* Correct for delta rot */
766  add_eul_euleul(eul, td->ext->irot, td->ext->drot, td->ext->rotOrder);
767  }
768  else {
769  copy_v3_v3(eul, td->ext->irot);
770  }
771 
772  eulO_to_mat3(obmat, eul, td->ext->rotOrder);
773  mul_m3_m3m3(fmat, smat, obmat);
774  mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat);
775 
776  if (!is_zero_v3(td->ext->drot)) {
777  /* Correct back for delta rot. */
778  sub_eul_euleul(eul, eul, td->ext->drot, td->ext->rotOrder);
779  }
780 
781  /* and apply */
782  protectedRotateBits(td->protectflag, eul, td->ext->irot);
783  copy_v3_v3(td->ext->rot, eul);
784  }
785 
786  constraintRotLim(t, td);
787  }
788  }
789 }
790 
792  const TransDataContainer *tc,
793  TransData *td,
794  const float mat[3][3],
795  const short around)
796 {
797  const float *center;
798 
799  /* local constraint shouldn't alter center */
800  if (transdata_check_local_center(t, around)) {
801  center = td->center;
802  }
803  else {
804  center = tc->center_local;
805  }
806 
807  ElementRotation_ex(t, tc, td, mat, center);
808 }
809 
812 /* -------------------------------------------------------------------- */
816 void headerResize(TransInfo *t, const float vec[3], char *str, const int str_size)
817 {
818  char tvec[NUM_STR_REP_LEN * 3];
819  size_t ofs = 0;
820  if (hasNumInput(&t->num)) {
821  outputNumInput(&(t->num), tvec, &t->scene->unit);
822  }
823  else {
824  BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", vec[0]);
825  BLI_snprintf(&tvec[NUM_STR_REP_LEN], NUM_STR_REP_LEN, "%.4f", vec[1]);
826  BLI_snprintf(&tvec[NUM_STR_REP_LEN * 2], NUM_STR_REP_LEN, "%.4f", vec[2]);
827  }
828 
829  if (t->con.mode & CON_APPLY) {
830  switch (t->num.idx_max) {
831  case 0:
832  ofs += BLI_snprintf_rlen(
833  str + ofs, str_size - ofs, TIP_("Scale: %s%s %s"), &tvec[0], t->con.text, t->proptext);
834  break;
835  case 1:
836  ofs += BLI_snprintf_rlen(str + ofs,
837  str_size - ofs,
838  TIP_("Scale: %s : %s%s %s"),
839  &tvec[0],
840  &tvec[NUM_STR_REP_LEN],
841  t->con.text,
842  t->proptext);
843  break;
844  case 2:
845  ofs += BLI_snprintf_rlen(str + ofs,
846  str_size - ofs,
847  TIP_("Scale: %s : %s : %s%s %s"),
848  &tvec[0],
849  &tvec[NUM_STR_REP_LEN],
850  &tvec[NUM_STR_REP_LEN * 2],
851  t->con.text,
852  t->proptext);
853  break;
854  }
855  }
856  else {
857  if (t->flag & T_2D_EDIT) {
858  ofs += BLI_snprintf_rlen(str + ofs,
859  str_size - ofs,
860  TIP_("Scale X: %s Y: %s%s %s"),
861  &tvec[0],
862  &tvec[NUM_STR_REP_LEN],
863  t->con.text,
864  t->proptext);
865  }
866  else {
867  ofs += BLI_snprintf_rlen(str + ofs,
868  str_size - ofs,
869  TIP_("Scale X: %s Y: %s Z: %s%s %s"),
870  &tvec[0],
871  &tvec[NUM_STR_REP_LEN],
872  &tvec[NUM_STR_REP_LEN * 2],
873  t->con.text,
874  t->proptext);
875  }
876  }
877 
878  if (t->flag & T_PROP_EDIT_ALL) {
879  ofs += BLI_snprintf_rlen(
880  str + ofs, str_size - ofs, TIP_(" Proportional size: %.2f"), t->prop_size);
881  }
882 }
883 
889 static void TransMat3ToSize(const float mat[3][3], const float smat[3][3], float size[3])
890 {
891  float rmat[3][3];
892 
893  mat3_to_rot_size(rmat, size, mat);
894 
895  /* First tried with dot-product... but the sign flip is crucial. */
896  if (dot_v3v3(rmat[0], smat[0]) < 0.0f) {
897  size[0] = -size[0];
898  }
899  if (dot_v3v3(rmat[1], smat[1]) < 0.0f) {
900  size[1] = -size[1];
901  }
902  if (dot_v3v3(rmat[2], smat[2]) < 0.0f) {
903  size[2] = -size[2];
904  }
905 }
906 
908  const TransDataContainer *tc,
909  TransData *td,
910  const float mat[3][3])
911 {
912  float tmat[3][3], smat[3][3], center[3];
913  float vec[3];
914 
915  if (t->flag & T_EDIT) {
916  mul_m3_m3m3(smat, mat, td->mtx);
917  mul_m3_m3m3(tmat, td->smtx, smat);
918  }
919  else {
920  copy_m3_m3(tmat, mat);
921  }
922 
923  if (t->con.applySize) {
924  t->con.applySize(t, tc, td, tmat);
925  }
926 
927  /* local constraint shouldn't alter center */
928  if (transdata_check_local_center(t, t->around)) {
929  copy_v3_v3(center, td->center);
930  }
931  else if (t->options & CTX_MOVIECLIP) {
932  if (td->flag & TD_INDIVIDUAL_SCALE) {
933  copy_v3_v3(center, td->center);
934  }
935  else {
937  }
938  }
939  else {
941  }
942 
943  /* Size checked needed since the 3D cursor only uses rotation fields. */
944  if (td->ext && td->ext->size) {
945  float fsize[3];
946 
947  if (ELEM(t->data_type,
952  float obsizemat[3][3];
953  /* Reorient the size mat to fit the oriented object. */
954  mul_m3_m3m3(obsizemat, tmat, td->axismtx);
955  // print_m3("obsizemat", obsizemat);
956  TransMat3ToSize(obsizemat, td->axismtx, fsize);
957  // print_v3("fsize", fsize);
958  }
959  else {
960  mat3_to_size(fsize, tmat);
961  }
962 
963  protectedSizeBits(td->protectflag, fsize);
964 
965  if ((t->flag & T_V3D_ALIGN) == 0) { /* align mode doesn't resize objects itself */
966  if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
967  /* scale val and reset size */
968  *td->val = td->ival * (1 + (fsize[0] - 1) * td->factor);
969 
970  td->ext->size[0] = td->ext->isize[0];
971  td->ext->size[1] = td->ext->isize[1];
972  td->ext->size[2] = td->ext->isize[2];
973  }
974  else {
975  /* Reset val if SINGLESIZE but using a constraint */
976  if (td->flag & TD_SINGLESIZE) {
977  *td->val = td->ival;
978  }
979 
980  td->ext->size[0] = td->ext->isize[0] * (1 + (fsize[0] - 1) * td->factor);
981  td->ext->size[1] = td->ext->isize[1] * (1 + (fsize[1] - 1) * td->factor);
982  td->ext->size[2] = td->ext->isize[2] * (1 + (fsize[2] - 1) * td->factor);
983  }
984  }
985 
986  constraintSizeLim(t, td);
987  }
988 
989  /* For individual element center, Editmode need to use iloc */
990  if (t->flag & T_POINTS) {
991  sub_v3_v3v3(vec, td->iloc, center);
992  }
993  else {
994  sub_v3_v3v3(vec, td->center, center);
995  }
996 
997  mul_m3_v3(tmat, vec);
998 
999  add_v3_v3(vec, center);
1000  if (t->flag & T_POINTS) {
1001  sub_v3_v3(vec, td->iloc);
1002  }
1003  else {
1004  sub_v3_v3(vec, td->center);
1005  }
1006 
1007  /* Grease pencil falloff.
1008  *
1009  * FIXME: This is bad on multiple levels!
1010  *
1011  * - #applyNumInput is not intended to be run for every element,
1012  * this writes back into the number input in a way that doesn't make sense to run many times.
1013  *
1014  * - Writing into #TransInfo should be avoided since it means order of operations
1015  * may impact the result and isn't thread-safe.
1016  *
1017  * Operating on copies as a temporary solution.
1018  */
1019  if (t->options & CTX_GPENCIL_STROKES) {
1020  bGPDstroke *gps = (bGPDstroke *)td->extra;
1021  mul_v3_fl(vec, td->factor * gps->runtime.multi_frame_falloff);
1022 
1023  /* Scale stroke thickness. */
1024  if (td->val) {
1025  NumInput num_evil = t->num;
1026  float values_final_evil[4];
1027  copy_v4_v4(values_final_evil, t->values_final);
1028  transform_snap_increment(t, values_final_evil);
1029  applyNumInput(&num_evil, values_final_evil);
1030 
1031  float ratio = values_final_evil[0];
1032  float transformed_value = td->ival * fabs(ratio);
1033  *td->val = max_ff(interpf(transformed_value, td->ival, gps->runtime.multi_frame_falloff),
1034  0.001f);
1035  }
1036  }
1037  else {
1038  mul_v3_fl(vec, td->factor);
1039  }
1040 
1041  if (t->options & (CTX_OBJECT | CTX_POSE_BONE)) {
1042  if (t->options & CTX_POSE_BONE) {
1043  /* Without this, the resulting location of scaled bones aren't correct,
1044  * especially noticeable scaling root or disconnected bones around the cursor, see T92515. */
1045  mul_mat3_m4_v3(tc->poseobj->obmat, vec);
1046  }
1047  mul_m3_v3(td->smtx, vec);
1048  }
1049 
1050  protectedTransBits(td->protectflag, vec);
1051  if (td->loc) {
1052  add_v3_v3v3(td->loc, td->iloc, vec);
1053  }
1054 
1055  constraintTransLim(t, td);
1056 }
1057 
1060 /* -------------------------------------------------------------------- */
1064 void transform_mode_init(TransInfo *t, wmOperator *op, const int mode)
1065 {
1066  t->mode = mode;
1067 
1068  switch (mode) {
1069  case TFM_TRANSLATION:
1070  initTranslation(t);
1071  break;
1072  case TFM_ROTATION:
1073  initRotation(t);
1074  break;
1075  case TFM_RESIZE: {
1076  float mouse_dir_constraint[3];
1077  if (op) {
1078  PropertyRNA *prop = RNA_struct_find_property(op->ptr, "mouse_dir_constraint");
1079  if (prop) {
1080  RNA_property_float_get_array(op->ptr, prop, mouse_dir_constraint);
1081  }
1082  else {
1083  /* Resize is expected to have this property. */
1084  BLI_assert(!STREQ(op->idname, "TRANSFORM_OT_resize"));
1085  }
1086  }
1087  else {
1088  zero_v3(mouse_dir_constraint);
1089  }
1090  initResize(t, mouse_dir_constraint);
1091  break;
1092  }
1093  case TFM_SKIN_RESIZE:
1094  initSkinResize(t);
1095  break;
1096  case TFM_TOSPHERE:
1097  initToSphere(t);
1098  break;
1099  case TFM_SHEAR:
1100  initShear(t);
1101  break;
1102  case TFM_BEND:
1103  initBend(t);
1104  break;
1105  case TFM_SHRINKFATTEN:
1107  break;
1108  case TFM_TILT:
1109  initTilt(t);
1110  break;
1113  break;
1114  case TFM_MASK_SHRINKFATTEN:
1116  break;
1119  break;
1120  case TFM_TRACKBALL:
1121  initTrackball(t);
1122  break;
1123  case TFM_PUSHPULL:
1124  initPushPull(t);
1125  break;
1126  case TFM_EDGE_CREASE:
1127  initEgdeCrease(t);
1128  break;
1129  case TFM_VERT_CREASE:
1130  initVertCrease(t);
1131  break;
1132  case TFM_BONESIZE:
1133  initBoneSize(t);
1134  break;
1135  case TFM_BONE_ENVELOPE:
1138  break;
1139  case TFM_EDGE_SLIDE:
1140  case TFM_VERT_SLIDE: {
1141  const bool use_even = (op ? RNA_boolean_get(op->ptr, "use_even") : false);
1142  const bool flipped = (op ? RNA_boolean_get(op->ptr, "flipped") : false);
1143  const bool use_clamp = (op ? RNA_boolean_get(op->ptr, "use_clamp") : true);
1144  if (mode == TFM_EDGE_SLIDE) {
1145  const bool use_double_side = (op ? !RNA_boolean_get(op->ptr, "single_side") : true);
1146  initEdgeSlide_ex(t, use_double_side, use_even, flipped, use_clamp);
1147  }
1148  else {
1149  initVertSlide_ex(t, use_even, flipped, use_clamp);
1150  }
1151  break;
1152  }
1153  case TFM_BONE_ROLL:
1154  initBoneRoll(t);
1155  break;
1156  case TFM_TIME_TRANSLATE:
1158  break;
1159  case TFM_TIME_SLIDE:
1160  initTimeSlide(t);
1161  break;
1162  case TFM_TIME_SCALE:
1163  initTimeScale(t);
1164  break;
1165  case TFM_TIME_DUPLICATE:
1166  /* same as TFM_TIME_EXTEND, but we need the mode info for later
1167  * so that duplicate-culling will work properly
1168  */
1169  if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_NLA)) {
1170  initTranslation(t);
1171  }
1172  else {
1174  }
1175  break;
1176  case TFM_TIME_EXTEND:
1177  /* now that transdata has been made, do like for TFM_TIME_TRANSLATE (for most Animation
1178  * Editors because they have only 1D transforms for time values) or TFM_TRANSLATION
1179  * (for Graph/NLA Editors only since they uses 'standard' transforms to get 2D movement)
1180  * depending on which editor this was called from
1181  */
1182  if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_NLA)) {
1183  initTranslation(t);
1184  }
1185  else {
1187  }
1188  break;
1189  case TFM_BAKE_TIME:
1190  initBakeTime(t);
1191  break;
1192  case TFM_MIRROR:
1193  initMirror(t);
1194  break;
1195  case TFM_BWEIGHT:
1196  initBevelWeight(t);
1197  break;
1198  case TFM_ALIGN:
1199  initAlign(t);
1200  break;
1201  case TFM_SEQ_SLIDE:
1202  initSeqSlide(t);
1203  break;
1204  case TFM_NORMAL_ROTATION:
1206  break;
1207  case TFM_GPENCIL_OPACITY:
1208  initGPOpacity(t);
1209  break;
1210  }
1211 
1212  if (t->data_type == &TransConvertType_Mesh) {
1213  /* Init Custom Data correction.
1214  * Ideally this should be called when creating the TransData. */
1216  }
1217 
1218  /* TODO(germano): Some of these operations change the `t->mode`.
1219  * This can be bad for Redo. */
1220  // BLI_assert(t->mode == mode);
1221 }
1222 
1224 {
1225  /* Currently only these types are supported. */
1227 
1228  if (t->is_orient_default_overwrite) {
1229  return;
1230  }
1231 
1232  if (!(t->flag & T_MODAL)) {
1233  return;
1234  }
1235 
1236  if (t->orient[O_DEFAULT].type == type) {
1237  return;
1238  }
1239 
1240  View3D *v3d = NULL;
1241  RegionView3D *rv3d = NULL;
1242  if ((type == V3D_ORIENT_VIEW) && (t->spacetype == SPACE_VIEW3D) && t->region &&
1243  (t->region->regiontype == RGN_TYPE_WINDOW)) {
1244  v3d = t->view;
1245  rv3d = t->region->regiondata;
1246  }
1247 
1248  t->orient[O_DEFAULT].type = ED_transform_calc_orientation_from_type_ex(
1249  t->scene,
1250  t->view_layer,
1251  v3d,
1252  rv3d,
1253  NULL,
1254  NULL,
1255  type,
1257  t->orient[O_DEFAULT].matrix);
1258 
1259  if (t->orient_curr == O_DEFAULT) {
1260  /* Update Orientation. */
1262  }
1263 }
1264 
typedef float(TangentPoint)[2]
const bConstraintTypeInfo * BKE_constraint_typeinfo_from_type(int type)
Definition: constraint.c:5487
void BKE_constraint_custom_object_space_init(struct bConstraintOb *cob, struct bConstraint *con)
Definition: constraint.c:6331
void BKE_constraint_targets_for_solving_get(struct Depsgraph *depsgraph, struct bConstraint *con, struct bConstraintOb *ob, struct ListBase *targets, float ctime)
Definition: constraint.c:6293
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1353
#define BLI_assert(a)
Definition: BLI_assert.h:46
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
MINLINE float max_ff(float a, float b)
MINLINE float interpf(float a, float b, float t)
MINLINE float signf(float f)
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:926
void copy_m3_m3(float m1[3][3], const float m2[3][3])
Definition: math_matrix.c:71
void unit_m3(float m[3][3])
Definition: math_matrix.c:40
void mat3_to_rot_size(float rot[3][3], float size[3], const float mat3[3][3])
Definition: math_matrix.c:2202
void unit_m4(float m[4][4])
Definition: rct.c:1090
void mul_mat3_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:790
void size_to_mat4(float R[4][4], const float size[3])
Definition: math_matrix.c:2111
void interp_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3], float t)
Definition: math_matrix.c:2436
void mat4_to_size(float size[3], const float M[4][4])
Definition: math_matrix.c:2138
#define mul_m3_series(...)
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:388
void mat3_to_size(float size[3], const float M[3][3])
Definition: math_matrix.c:2131
void mul_m4_m3m4(float R[4][4], const float A[3][3], const float B[4][4])
Definition: math_matrix.c:500
void eulO_to_mat3(float mat[3][3], const float eul[3], short order)
void sub_eul_euleul(float r_eul[3], float a[3], float b[3], short order)
void mat4_to_axis_angle(float axis[3], float *angle, const float M[4][4])
void mat4_to_eulO(float eul[3], short order, const float mat[4][4])
void axis_angle_to_quat(float r[4], const float axis[3], float angle)
void mat3_to_compatible_eulO(float eul[3], const float old[3], short order, const float mat[3][3])
@ EULER_ORDER_DEFAULT
void mat3_to_quat(float q[4], const float mat[3][3])
void eulO_to_axis_angle(float axis[3], float *angle, const float eul[3], short order)
void mul_qt_fl(float q[4], float f)
void eul_to_quat(float quat[4], const float eul[3])
void axis_angle_to_mat4(float R[4][4], const float axis[3], float angle)
void quat_to_eul(float eul[3], const float quat[4])
float normalize_qt_qt(float r[4], const float q[4])
void invert_qt_qt_normalized(float q1[4], const float q2[4])
void mul_qt_qtqt(float q[4], const float a[4], const float b[4])
Definition: math_rotation.c:46
#define RAD2DEGF(_rad)
void quat_to_axis_angle(float axis[3], float *angle, const float q[4])
void axis_angle_to_eulO(float eul[3], short order, const float axis[3], float angle)
void mat4_to_quat(float q[4], const float mat[4][4])
void eulO_to_mat4(float mat[4][4], const float eul[3], short order)
void add_eul_euleul(float r_eul[3], float a[3], float b[3], short order)
void quat_to_mat3(float mat[3][3], const float q[4])
void quat_to_mat4(float mat[4][4], const float q[4])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void mul_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE bool is_zero_v4(const float a[4]) ATTR_WARN_UNUSED_RESULT
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
size_t BLI_snprintf_rlen(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define UNUSED(x)
#define ELEM(...)
#define IS_EQF(a, b)
#define STREQ(a, b)
#define TIP_(msgid)
@ ROT_MODE_QUAT
@ ROT_MODE_AXISANGLE
@ ARM_ENVELOPE
@ CONSTRAINT_OFF
@ CONSTRAINT_DISABLE
@ CONSTRAINT_TYPE_ROTLIMIT
@ CONSTRAINT_TYPE_DISTLIMIT
@ CONSTRAINT_TYPE_LOCLIMIT
@ CONSTRAINT_TYPE_SIZELIMIT
@ CONSTRAINT_SPACE_WORLD
@ CONSTRAINT_SPACE_LOCAL
@ LIMIT_TRANSFORM
@ LIMITDIST_TRANSFORM
@ OB_MBALL
@ OB_ARMATURE
@ OB_MESH
@ OB_CURVES_LEGACY
@ OB_GPENCIL
@ OB_LOCK_ROTZ
@ OB_LOCK_ROT4D
@ OB_LOCK_SCALEZ
@ OB_LOCK_ROTX
@ OB_LOCK_SCALEX
@ OB_LOCK_ROTW
@ OB_LOCK_LOCY
@ OB_LOCK_LOCZ
@ OB_LOCK_ROTY
@ OB_LOCK_SCALEY
@ OB_LOCK_LOCX
@ RGN_TYPE_WINDOW
@ SPACE_NLA
@ SPACE_GRAPH
@ SPACE_VIEW3D
@ V3D_AROUND_CENTER_BOUNDS
@ V3D_AROUND_LOCAL_ORIGINS
@ V3D_ORIENT_GLOBAL
@ V3D_ORIENT_VIEW
void outputNumInput(NumInput *n, char *str, struct UnitSettings *unit_settings)
Definition: numinput.c:87
#define NUM_STR_REP_LEN
Definition: ED_numinput.h:13
bool applyNumInput(NumInput *n, float *vec)
Definition: numinput.c:189
bool hasNumInput(const NumInput *n)
Definition: numinput.c:170
eTfmMode
Definition: ED_transform.h:27
@ TFM_RESIZE
Definition: ED_transform.h:32
@ TFM_EDGE_SLIDE
Definition: ED_transform.h:59
@ TFM_BONESIZE
Definition: ED_transform.h:44
@ TFM_SKIN_RESIZE
Definition: ED_transform.h:33
@ TFM_SHEAR
Definition: ED_transform.h:35
@ TFM_SHRINKFATTEN
Definition: ED_transform.h:37
@ TFM_TIME_TRANSLATE
Definition: ED_transform.h:50
@ TFM_TIME_SLIDE
Definition: ED_transform.h:51
@ TFM_BAKE_TIME
Definition: ED_transform.h:55
@ TFM_VERT_CREASE
Definition: ED_transform.h:42
@ TFM_VERT_SLIDE
Definition: ED_transform.h:60
@ TFM_BEND
Definition: ED_transform.h:36
@ TFM_ROTATION
Definition: ED_transform.h:31
@ TFM_BONE_ENVELOPE
Definition: ED_transform.h:45
@ TFM_BWEIGHT
Definition: ED_transform.h:57
@ TFM_ALIGN
Definition: ED_transform.h:58
@ TFM_TIME_SCALE
Definition: ED_transform.h:52
@ TFM_TIME_DUPLICATE
Definition: ED_transform.h:54
@ TFM_BONE_ROLL
Definition: ED_transform.h:49
@ TFM_TIME_EXTEND
Definition: ED_transform.h:53
@ TFM_GPENCIL_SHRINKFATTEN
Definition: ED_transform.h:48
@ TFM_CURVE_SHRINKFATTEN
Definition: ED_transform.h:46
@ TFM_TILT
Definition: ED_transform.h:38
@ TFM_SEQ_SLIDE
Definition: ED_transform.h:61
@ TFM_TOSPHERE
Definition: ED_transform.h:34
@ TFM_EDGE_CREASE
Definition: ED_transform.h:41
@ TFM_GPENCIL_OPACITY
Definition: ED_transform.h:64
@ TFM_MIRROR
Definition: ED_transform.h:43
@ TFM_TRANSLATION
Definition: ED_transform.h:30
@ TFM_MASK_SHRINKFATTEN
Definition: ED_transform.h:47
@ TFM_BONE_ENVELOPE_DIST
Definition: ED_transform.h:62
@ TFM_NORMAL_ROTATION
Definition: ED_transform.h:63
@ TFM_PUSHPULL
Definition: ED_transform.h:40
@ TFM_TRACKBALL
Definition: ED_transform.h:39
short ED_transform_calc_orientation_from_type_ex(const struct Scene *scene, struct ViewLayer *view_layer, const struct View3D *v3d, const struct RegionView3D *rv3d, struct Object *ob, struct Object *obedit, short orientation_index, int pivot_point, float r_mat[3][3])
NSNotificationCenter * center
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
#define C
Definition: RandGen.cpp:25
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
#define str(s)
ccl_device_inline float2 fabs(const float2 &a)
Definition: math_float2.h:222
#define fabsf(x)
Definition: metal/compat.h:219
static unsigned c
Definition: RandGen.cpp:83
void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
Definition: rna_access.c:2879
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
float obmat[4][4]
void * data
float r_smtx[3][3]
float l_smtx[3][3]
float smtx[3][3]
short protectflag
struct bConstraint * con
float axismtx[3][3]
float mtx[3][3]
TransDataExtension * ext
float * val
float matrix[4][4]
void(* evaluate_constraint)(struct bConstraint *con, struct bConstraintOb *cob, struct ListBase *targets)
struct bConstraint * next
bGPDstroke_Runtime runtime
struct PointerRNA * ptr
conversion and adaptation of different datablocks to a common struct.
void transform_convert_mesh_customdatacorrect_init(TransInfo *t)
TransConvertTypeInfo TransConvertType_Sculpt
TransConvertTypeInfo TransConvertType_ObjectTexSpace
TransConvertTypeInfo TransConvertType_Mesh
TransConvertTypeInfo TransConvertType_Pose
TransConvertTypeInfo TransConvertType_Object
@ TD_USEQUAT
@ TD_INDIVIDUAL_SCALE
@ TD_SINGLESIZE
@ TD_PBONE_LOCAL_MTX_P
@ TD_PBONE_LOCAL_MTX_C
@ TD_NO_LOC
static void constraintRotLim(const TransInfo *UNUSED(t), TransData *td)
void protectedTransBits(short protectflag, float vec[3])
bool transdata_check_local_center(const TransInfo *t, short around)
void constraintTransLim(const TransInfo *t, TransData *td)
void ElementRotation_ex(const TransInfo *t, const TransDataContainer *tc, TransData *td, const float mat[3][3], const float *center)
void transform_mode_init(TransInfo *t, wmOperator *op, const int mode)
static void TransMat3ToSize(const float mat[3][3], const float smat[3][3], float size[3])
void ElementResize(const TransInfo *t, const TransDataContainer *tc, TransData *td, const float mat[3][3])
void constraintSizeLim(const TransInfo *t, TransData *td)
static void constraintob_from_transdata(bConstraintOb *cob, TransData *td)
static void protectedQuaternionBits(short protectflag, float quat[4], const float oldquat[4])
static void protectedRotateBits(short protectflag, float eul[3], const float oldeul[3])
void transform_mode_default_modal_orientation_set(TransInfo *t, int type)
void protectedSizeBits(short protectflag, float size[3])
void headerResize(TransInfo *t, const float vec[3], char *str, const int str_size)
void ElementRotation(const TransInfo *t, const TransDataContainer *tc, TransData *td, const float mat[3][3], const short around)
bool transform_mode_is_changeable(const int mode)
void headerRotation(TransInfo *t, char *str, const int str_size, float final)
eTfmMode transform_mode_really_used(bContext *C, eTfmMode mode)
static void protectedAxisAngleBits(short protectflag, float axis[3], float *angle, const float oldAxis[3], float oldAngle)
transform modes used by different operators.
void initPushPull(TransInfo *t)
void initShear(TransInfo *t)
void initVertCrease(TransInfo *t)
void initAlign(TransInfo *t)
void initBoneSize(TransInfo *t)
void initTimeScale(TransInfo *t)
void initVertSlide_ex(TransInfo *t, bool use_even, bool flipped, bool use_clamp)
void initGPShrinkFatten(TransInfo *t)
void initBevelWeight(TransInfo *t)
void initTrackball(TransInfo *t)
void initTimeTranslate(TransInfo *t)
void initResize(TransInfo *t, float mouse_dir_constraint[3])
void initSkinResize(TransInfo *t)
void initSeqSlide(TransInfo *t)
void initTranslation(TransInfo *t)
void initCurveShrinkFatten(TransInfo *t)
void initBoneRoll(TransInfo *t)
void initGPOpacity(TransInfo *t)
void initEgdeCrease(TransInfo *t)
void initTimeSlide(TransInfo *t)
void initTilt(TransInfo *t)
void initMaskShrinkFatten(TransInfo *t)
void initMirror(TransInfo *t)
void initEdgeSlide_ex(TransInfo *t, bool use_double_side, bool use_even, bool flipped, bool use_clamp)
void initShrinkFatten(TransInfo *t)
void initNormalRotation(TransInfo *t)
void initBoneEnvelope(TransInfo *t)
void initToSphere(TransInfo *t)
void initRotation(TransInfo *t)
void initBend(TransInfo *t)
void initBakeTime(TransInfo *t)
void transform_orientations_current_set(TransInfo *t, const short orient_index)
bool transform_snap_increment(const TransInfo *t, float *r_val)