Blender  V2.93
transform_mode.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
24 #include <stdlib.h>
25 
26 #include "DNA_anim_types.h"
27 #include "DNA_armature_types.h"
28 #include "DNA_constraint_types.h"
29 #include "DNA_gpencil_types.h"
31 
32 #include "BLI_listbase.h"
33 #include "BLI_math.h"
34 #include "BLI_string.h"
35 
36 #include "BKE_constraint.h"
37 #include "BKE_context.h"
38 #include "BKE_nla.h"
39 
40 #include "RNA_access.h"
41 
42 #include "UI_interface.h"
43 
44 #include "BLT_translation.h"
45 
46 #include "transform.h"
47 #include "transform_convert.h"
48 #include "transform_orientations.h"
49 #include "transform_snap.h"
50 
51 /* Own include. */
52 #include "transform_mode.h"
53 
55 {
56  if (mode == TFM_BONESIZE) {
58  BLI_assert(ob);
59  if (ob->type != OB_ARMATURE) {
60  return TFM_RESIZE;
61  }
62  bArmature *arm = ob->data;
63  if (arm->drawtype == ARM_ENVELOPE) {
65  }
66  }
67 
68  return mode;
69 }
70 
72 {
73  return ((around == V3D_AROUND_LOCAL_ORIGINS) &&
74  ((t->options & (CTX_OBJECT | CTX_POSE_BONE)) ||
75  /* implicit: (t->flag & T_EDIT) */
76  (ELEM(t->obedit_type, OB_MESH, OB_CURVE, OB_MBALL, OB_ARMATURE, OB_GPENCIL)) ||
77  (t->spacetype == SPACE_GRAPH) ||
78  (t->options & (CTX_MOVIECLIP | CTX_MASK | CTX_PAINT_CURVE))));
79 }
80 
81 /* Informs if the mode can be switched during modal. */
82 bool transform_mode_is_changeable(const int mode)
83 {
84  return ELEM(mode,
86  TFM_RESIZE,
91 }
92 
93 /* -------------------------------------------------------------------- */
97 void protectedTransBits(short protectflag, float vec[3])
98 {
99  if (protectflag & OB_LOCK_LOCX) {
100  vec[0] = 0.0f;
101  }
102  if (protectflag & OB_LOCK_LOCY) {
103  vec[1] = 0.0f;
104  }
105  if (protectflag & OB_LOCK_LOCZ) {
106  vec[2] = 0.0f;
107  }
108 }
109 
110 /* this function only does the delta rotation */
111 static void protectedQuaternionBits(short protectflag, float quat[4], const float oldquat[4])
112 {
113  /* check that protection flags are set */
114  if ((protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) == 0) {
115  return;
116  }
117 
118  if (protectflag & OB_LOCK_ROT4D) {
119  /* quaternions getting limited as 4D entities that they are... */
120  if (protectflag & OB_LOCK_ROTW) {
121  quat[0] = oldquat[0];
122  }
123  if (protectflag & OB_LOCK_ROTX) {
124  quat[1] = oldquat[1];
125  }
126  if (protectflag & OB_LOCK_ROTY) {
127  quat[2] = oldquat[2];
128  }
129  if (protectflag & OB_LOCK_ROTZ) {
130  quat[3] = oldquat[3];
131  }
132  }
133  else {
134  /* quaternions get limited with euler... (compatibility mode) */
135  float eul[3], oldeul[3], nquat[4], noldquat[4];
136  float qlen;
137 
138  qlen = normalize_qt_qt(nquat, quat);
139  normalize_qt_qt(noldquat, oldquat);
140 
141  quat_to_eul(eul, nquat);
142  quat_to_eul(oldeul, noldquat);
143 
144  if (protectflag & OB_LOCK_ROTX) {
145  eul[0] = oldeul[0];
146  }
147  if (protectflag & OB_LOCK_ROTY) {
148  eul[1] = oldeul[1];
149  }
150  if (protectflag & OB_LOCK_ROTZ) {
151  eul[2] = oldeul[2];
152  }
153 
154  eul_to_quat(quat, eul);
155 
156  /* restore original quat size */
157  mul_qt_fl(quat, qlen);
158 
159  /* quaternions flip w sign to accumulate rotations correctly */
160  if ((nquat[0] < 0.0f && quat[0] > 0.0f) || (nquat[0] > 0.0f && quat[0] < 0.0f)) {
161  mul_qt_fl(quat, -1.0f);
162  }
163  }
164 }
165 
166 static void protectedRotateBits(short protectflag, float eul[3], const float oldeul[3])
167 {
168  if (protectflag & OB_LOCK_ROTX) {
169  eul[0] = oldeul[0];
170  }
171  if (protectflag & OB_LOCK_ROTY) {
172  eul[1] = oldeul[1];
173  }
174  if (protectflag & OB_LOCK_ROTZ) {
175  eul[2] = oldeul[2];
176  }
177 }
178 
179 /* this function only does the delta rotation */
180 /* axis-angle is usually internally stored as quats... */
182  short protectflag, float axis[3], float *angle, const float oldAxis[3], float oldAngle)
183 {
184  /* check that protection flags are set */
185  if ((protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) == 0) {
186  return;
187  }
188 
189  if (protectflag & OB_LOCK_ROT4D) {
190  /* axis-angle getting limited as 4D entities that they are... */
191  if (protectflag & OB_LOCK_ROTW) {
192  *angle = oldAngle;
193  }
194  if (protectflag & OB_LOCK_ROTX) {
195  axis[0] = oldAxis[0];
196  }
197  if (protectflag & OB_LOCK_ROTY) {
198  axis[1] = oldAxis[1];
199  }
200  if (protectflag & OB_LOCK_ROTZ) {
201  axis[2] = oldAxis[2];
202  }
203  }
204  else {
205  /* axis-angle get limited with euler... */
206  float eul[3], oldeul[3];
207 
209  axis_angle_to_eulO(oldeul, EULER_ORDER_DEFAULT, oldAxis, oldAngle);
210 
211  if (protectflag & OB_LOCK_ROTX) {
212  eul[0] = oldeul[0];
213  }
214  if (protectflag & OB_LOCK_ROTY) {
215  eul[1] = oldeul[1];
216  }
217  if (protectflag & OB_LOCK_ROTZ) {
218  eul[2] = oldeul[2];
219  }
220 
222 
223  /* When converting to axis-angle,
224  * we need a special exception for the case when there is no axis. */
225  if (IS_EQF(axis[0], axis[1]) && IS_EQF(axis[1], axis[2])) {
226  /* for now, rotate around y-axis then (so that it simply becomes the roll) */
227  axis[1] = 1.0f;
228  }
229  }
230 }
231 
232 void protectedSizeBits(short protectflag, float size[3])
233 {
234  if (protectflag & OB_LOCK_SCALEX) {
235  size[0] = 1.0f;
236  }
237  if (protectflag & OB_LOCK_SCALEY) {
238  size[1] = 1.0f;
239  }
240  if (protectflag & OB_LOCK_SCALEZ) {
241  size[2] = 1.0f;
242  }
243 }
244 
247 /* -------------------------------------------------------------------- */
252 {
253  if (td->con) {
258 
259  bConstraintOb cob = {NULL};
260  bConstraint *con;
261  float ctime = (float)(t->scene->r.cfra);
262 
263  /* Make a temporary bConstraintOb for using these limit constraints
264  * - they only care that cob->matrix is correctly set ;-)
265  * - current space should be local
266  */
267  unit_m4(cob.matrix);
268  copy_v3_v3(cob.matrix[3], td->loc);
269 
270  /* Evaluate valid constraints */
271  for (con = td->con; con; con = con->next) {
272  const bConstraintTypeInfo *cti = NULL;
273  ListBase targets = {NULL, NULL};
274 
275  /* only consider constraint if enabled */
276  if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) {
277  continue;
278  }
279  if (con->enforce == 0.0f) {
280  continue;
281  }
282 
283  /* only use it if it's tagged for this purpose (and the right type) */
284  if (con->type == CONSTRAINT_TYPE_LOCLIMIT) {
286 
287  if ((data->flag2 & LIMIT_TRANSFORM) == 0) {
288  continue;
289  }
290  cti = ctiLoc;
291  }
292  else if (con->type == CONSTRAINT_TYPE_DISTLIMIT) {
294 
295  if ((data->flag & LIMITDIST_TRANSFORM) == 0) {
296  continue;
297  }
298  cti = ctiDist;
299  }
300 
301  if (cti) {
302  /* do space conversions */
303  if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
304  /* just multiply by td->mtx (this should be ok) */
305  mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
306  }
307  else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
308  /* skip... incompatible spacetype */
309  continue;
310  }
311 
312  /* get constraint targets if needed */
313  BKE_constraint_targets_for_solving_get(t->depsgraph, con, &cob, &targets, ctime);
314 
315  /* do constraint */
316  cti->evaluate_constraint(con, &cob, &targets);
317 
318  /* convert spaces again */
319  if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
320  /* just multiply by td->smtx (this should be ok) */
321  mul_m4_m3m4(cob.matrix, td->smtx, cob.matrix);
322  }
323 
324  /* free targets list */
325  BLI_freelistN(&targets);
326  }
327  }
328 
329  /* copy results from cob->matrix */
330  copy_v3_v3(td->loc, cob.matrix[3]);
331  }
332 }
333 
335 {
336  /* Make a temporary bConstraintOb for use by limit constraints
337  * - they only care that cob->matrix is correctly set ;-)
338  * - current space should be local
339  */
340  memset(cob, 0, sizeof(bConstraintOb));
341  if (td->ext) {
342  if (td->ext->rotOrder == ROT_MODE_QUAT) {
343  /* quats */
344  /* objects and bones do normalization first too, otherwise
345  * we don't necessarily end up with a rotation matrix, and
346  * then conversion back to quat gives a different result */
347  float quat[4];
348  normalize_qt_qt(quat, td->ext->quat);
349  quat_to_mat4(cob->matrix, quat);
350  }
351  else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
352  /* axis angle */
353  axis_angle_to_mat4(cob->matrix, td->ext->rotAxis, *td->ext->rotAngle);
354  }
355  else {
356  /* eulers */
357  eulO_to_mat4(cob->matrix, td->ext->rot, td->ext->rotOrder);
358  }
359  }
360 }
361 
363 {
364  if (td->con) {
366  bConstraintOb cob;
367  bConstraint *con;
368  bool do_limit = false;
369 
370  /* Evaluate valid constraints */
371  for (con = td->con; con; con = con->next) {
372  /* only consider constraint if enabled */
373  if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) {
374  continue;
375  }
376  if (con->enforce == 0.0f) {
377  continue;
378  }
379 
380  /* we're only interested in Limit-Rotation constraints */
381  if (con->type == CONSTRAINT_TYPE_ROTLIMIT) {
383 
384  /* only use it if it's tagged for this purpose */
385  if ((data->flag2 & LIMIT_TRANSFORM) == 0) {
386  continue;
387  }
388 
389  /* skip incompatible spacetypes */
391  continue;
392  }
393 
394  /* only do conversion if necessary, to preserve quats and eulers */
395  if (do_limit == false) {
396  constraintob_from_transdata(&cob, td);
397  do_limit = true;
398  }
399 
400  /* do space conversions */
401  if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
402  /* just multiply by td->mtx (this should be ok) */
403  mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
404  }
405 
406  /* do constraint */
407  cti->evaluate_constraint(con, &cob, NULL);
408 
409  /* convert spaces again */
410  if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
411  /* just multiply by td->smtx (this should be ok) */
412  mul_m4_m3m4(cob.matrix, td->smtx, cob.matrix);
413  }
414  }
415  }
416 
417  if (do_limit) {
418  /* copy results from cob->matrix */
419  if (td->ext->rotOrder == ROT_MODE_QUAT) {
420  /* quats */
421  mat4_to_quat(td->ext->quat, cob.matrix);
422  }
423  else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
424  /* axis angle */
425  mat4_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, cob.matrix);
426  }
427  else {
428  /* eulers */
429  mat4_to_eulO(td->ext->rot, td->ext->rotOrder, cob.matrix);
430  }
431  }
432  }
433 }
434 
436 {
437  if (td->con && td->ext) {
439  bConstraintOb cob = {NULL};
440  bConstraint *con;
441  float size_sign[3], size_abs[3];
442  int i;
443 
444  /* Make a temporary bConstraintOb for using these limit constraints
445  * - they only care that cob->matrix is correctly set ;-)
446  * - current space should be local
447  */
448  if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
449  /* scale val and reset size */
450  return; /* TODO: fix this case */
451  }
452 
453  /* Reset val if SINGLESIZE but using a constraint */
454  if (td->flag & TD_SINGLESIZE) {
455  return;
456  }
457 
458  /* separate out sign to apply back later */
459  for (i = 0; i < 3; i++) {
460  size_sign[i] = signf(td->ext->size[i]);
461  size_abs[i] = fabsf(td->ext->size[i]);
462  }
463 
464  size_to_mat4(cob.matrix, size_abs);
465 
466  /* Evaluate valid constraints */
467  for (con = td->con; con; con = con->next) {
468  /* only consider constraint if enabled */
469  if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) {
470  continue;
471  }
472  if (con->enforce == 0.0f) {
473  continue;
474  }
475 
476  /* we're only interested in Limit-Scale constraints */
477  if (con->type == CONSTRAINT_TYPE_SIZELIMIT) {
479 
480  /* only use it if it's tagged for this purpose */
481  if ((data->flag2 & LIMIT_TRANSFORM) == 0) {
482  continue;
483  }
484 
485  /* do space conversions */
486  if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
487  /* just multiply by td->mtx (this should be ok) */
488  mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
489  }
490  else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
491  /* skip... incompatible spacetype */
492  continue;
493  }
494 
495  /* do constraint */
496  cti->evaluate_constraint(con, &cob, NULL);
497 
498  /* convert spaces again */
499  if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
500  /* just multiply by td->smtx (this should be ok) */
501  mul_m4_m3m4(cob.matrix, td->smtx, cob.matrix);
502  }
503  }
504  }
505 
506  /* copy results from cob->matrix */
507  if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
508  /* scale val and reset size */
509  return; /* TODO: fix this case. */
510  }
511 
512  /* Reset val if SINGLESIZE but using a constraint */
513  if (td->flag & TD_SINGLESIZE) {
514  return;
515  }
516 
517  /* Extract scale from matrix and apply back sign. */
518  mat4_to_size(td->ext->size, cob.matrix);
519  mul_v3_v3(td->ext->size, size_sign);
520  }
521 }
522 
523 /* -------------------------------------------------------------------- */
526 /* Used by Transform Rotation and Transform Normal Rotation */
527 void headerRotation(TransInfo *t, char str[UI_MAX_DRAW_STR], float final)
528 {
529  size_t ofs = 0;
530 
531  if (hasNumInput(&t->num)) {
532  char c[NUM_STR_REP_LEN];
533 
534  outputNumInput(&(t->num), c, &t->scene->unit);
535 
536  ofs += BLI_snprintf(str + ofs,
537  UI_MAX_DRAW_STR - ofs,
538  TIP_("Rotation: %s %s %s"),
539  &c[0],
540  t->con.text,
541  t->proptext);
542  }
543  else {
544  ofs += BLI_snprintf(str + ofs,
545  UI_MAX_DRAW_STR - ofs,
546  TIP_("Rotation: %.2f%s %s"),
547  RAD2DEGF(final),
548  t->con.text,
549  t->proptext);
550  }
551 
552  if (t->flag & T_PROP_EDIT_ALL) {
553  ofs += BLI_snprintf(
554  str + ofs, UI_MAX_DRAW_STR - ofs, TIP_(" Proportional size: %.2f"), t->prop_size);
555  }
556 }
557 
565  TransDataContainer *tc,
566  TransData *td,
567  const float mat[3][3],
568  const float *center)
569 {
570  float vec[3], totmat[3][3], smat[3][3];
571  float eul[3], fmat[3][3], quat[4];
572 
573  if (t->flag & T_POINTS) {
574  mul_m3_m3m3(totmat, mat, td->mtx);
575  mul_m3_m3m3(smat, td->smtx, totmat);
576 
577  /* apply gpencil falloff */
578  if (t->options & CTX_GPENCIL_STROKES) {
579  bGPDstroke *gps = (bGPDstroke *)td->extra;
580  float sx = smat[0][0];
581  float sy = smat[1][1];
582  float sz = smat[2][2];
583 
585  /* fix scale */
586  smat[0][0] = sx;
587  smat[1][1] = sy;
588  smat[2][2] = sz;
589  }
590 
591  sub_v3_v3v3(vec, td->iloc, center);
592  mul_m3_v3(smat, vec);
593 
594  add_v3_v3v3(td->loc, vec, center);
595 
596  sub_v3_v3v3(vec, td->loc, td->iloc);
598  add_v3_v3v3(td->loc, td->iloc, vec);
599 
600  if (td->flag & TD_USEQUAT) {
601  mul_m3_series(fmat, td->smtx, mat, td->mtx);
602  mat3_to_quat(quat, fmat); /* Actual transform */
603 
604  if (td->ext->quat) {
605  mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
606 
607  /* is there a reason not to have this here? -jahka */
609  }
610  }
611  }
624  else if (t->options & CTX_POSE_BONE) {
625  /* Extract and invert armature object matrix */
626 
627  if ((td->flag & TD_NO_LOC) == 0) {
628  sub_v3_v3v3(vec, td->center, center);
629 
630  mul_m3_v3(tc->mat3, vec); /* To Global space. */
631  mul_m3_v3(mat, vec); /* Applying rotation. */
632  mul_m3_v3(tc->imat3, vec); /* To Local space. */
633 
634  add_v3_v3(vec, center);
635  /* vec now is the location where the object has to be */
636 
637  sub_v3_v3v3(vec, vec, td->center); /* Translation needed from the initial location */
638 
639  /* special exception, see TD_PBONE_LOCAL_MTX definition comments */
640  if (td->flag & TD_PBONE_LOCAL_MTX_P) {
641  /* do nothing */
642  }
643  else if (td->flag & TD_PBONE_LOCAL_MTX_C) {
644  mul_m3_v3(tc->mat3, vec); /* To Global space. */
645  mul_m3_v3(td->ext->l_smtx, vec); /* To Pose space (Local Location). */
646  }
647  else {
648  mul_m3_v3(tc->mat3, vec); /* To Global space. */
649  mul_m3_v3(td->smtx, vec); /* To Pose space. */
650  }
651 
653 
654  add_v3_v3v3(td->loc, td->iloc, vec);
655 
656  constraintTransLim(t, td);
657  }
658 
659  /* rotation */
660  /* MORE HACK: as in some cases the matrix to apply location and rot/scale is not the same,
661  * and ElementRotation() might be called in Translation context (with align snapping),
662  * we need to be sure to actually use the *rotation* matrix here...
663  * So no other way than storing it in some dedicated members of td->ext! */
664  if ((t->flag & T_V3D_ALIGN) == 0) { /* align mode doesn't rotate objects itself */
665  /* euler or quaternion/axis-angle? */
666  if (td->ext->rotOrder == ROT_MODE_QUAT) {
667  mul_m3_series(fmat, td->ext->r_smtx, mat, td->ext->r_mtx);
668 
669  mat3_to_quat(quat, fmat); /* Actual transform */
670 
671  mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
672  /* this function works on end result */
674  }
675  else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
676  /* calculate effect based on quats */
677  float iquat[4], tquat[4];
678 
679  axis_angle_to_quat(iquat, td->ext->irotAxis, td->ext->irotAngle);
680 
681  mul_m3_series(fmat, td->ext->r_smtx, mat, td->ext->r_mtx);
682  mat3_to_quat(quat, fmat); /* Actual transform */
683  mul_qt_qtqt(tquat, quat, iquat);
684 
685  quat_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, tquat);
686 
687  /* this function works on end result */
689  td->ext->rotAxis,
690  td->ext->rotAngle,
691  td->ext->irotAxis,
692  td->ext->irotAngle);
693  }
694  else {
695  float eulmat[3][3];
696 
697  mul_m3_m3m3(totmat, mat, td->ext->r_mtx);
698  mul_m3_m3m3(smat, td->ext->r_smtx, totmat);
699 
700  /* Calculate the total rotation in eulers. */
701  copy_v3_v3(eul, td->ext->irot);
702  eulO_to_mat3(eulmat, eul, td->ext->rotOrder);
703 
704  /* mat = transform, obmat = bone rotation */
705  mul_m3_m3m3(fmat, smat, eulmat);
706 
707  mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat);
708 
709  /* and apply (to end result only) */
710  protectedRotateBits(td->protectflag, eul, td->ext->irot);
711  copy_v3_v3(td->ext->rot, eul);
712  }
713 
714  constraintRotLim(t, td);
715  }
716  }
717  else {
718  if ((td->flag & TD_NO_LOC) == 0) {
719  /* translation */
720  sub_v3_v3v3(vec, td->center, center);
721  mul_m3_v3(mat, vec);
722  add_v3_v3(vec, center);
723  /* vec now is the location where the object has to be */
724  sub_v3_v3(vec, td->center);
725  mul_m3_v3(td->smtx, vec);
726 
728 
729  add_v3_v3v3(td->loc, td->iloc, vec);
730  }
731 
732  constraintTransLim(t, td);
733 
734  /* rotation */
735  if ((t->flag & T_V3D_ALIGN) == 0) { /* Align mode doesn't rotate objects itself. */
736  /* euler or quaternion? */
737  if ((td->ext->rotOrder == ROT_MODE_QUAT) || (td->flag & TD_USEQUAT)) {
738  /* can be called for texture space translate for example, then opt out */
739  if (td->ext->quat) {
740  mul_m3_series(fmat, td->smtx, mat, td->mtx);
741  mat3_to_quat(quat, fmat); /* Actual transform */
742 
743  mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
744  /* this function works on end result */
746  }
747  }
748  else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
749  /* calculate effect based on quats */
750  float iquat[4], tquat[4];
751 
752  axis_angle_to_quat(iquat, td->ext->irotAxis, td->ext->irotAngle);
753 
754  mul_m3_series(fmat, td->smtx, mat, td->mtx);
755  mat3_to_quat(quat, fmat); /* Actual transform */
756  mul_qt_qtqt(tquat, quat, iquat);
757 
758  quat_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, tquat);
759 
760  /* this function works on end result */
762  td->ext->rotAxis,
763  td->ext->rotAngle,
764  td->ext->irotAxis,
765  td->ext->irotAngle);
766  }
767  else {
768  float obmat[3][3];
769 
770  mul_m3_m3m3(totmat, mat, td->mtx);
771  mul_m3_m3m3(smat, td->smtx, totmat);
772 
773  /* Calculate the total rotation in eulers. */
774  add_v3_v3v3(eul, td->ext->irot, td->ext->drot); /* correct for delta rot */
775  eulO_to_mat3(obmat, eul, td->ext->rotOrder);
776  /* mat = transform, obmat = object rotation */
777  mul_m3_m3m3(fmat, smat, obmat);
778 
779  mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat);
780 
781  /* correct back for delta rot */
782  sub_v3_v3v3(eul, eul, td->ext->drot);
783 
784  /* and apply */
785  protectedRotateBits(td->protectflag, eul, td->ext->irot);
786  copy_v3_v3(td->ext->rot, eul);
787  }
788 
789  constraintRotLim(t, td);
790  }
791  }
792 }
793 
795  TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3], 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 }
811 /* -------------------------------------------------------------------- */
814 void headerResize(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_STR])
815 {
816  char tvec[NUM_STR_REP_LEN * 3];
817  size_t ofs = 0;
818  if (hasNumInput(&t->num)) {
819  outputNumInput(&(t->num), tvec, &t->scene->unit);
820  }
821  else {
822  BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", vec[0]);
823  BLI_snprintf(&tvec[NUM_STR_REP_LEN], NUM_STR_REP_LEN, "%.4f", vec[1]);
824  BLI_snprintf(&tvec[NUM_STR_REP_LEN * 2], NUM_STR_REP_LEN, "%.4f", vec[2]);
825  }
826 
827  if (t->con.mode & CON_APPLY) {
828  switch (t->num.idx_max) {
829  case 0:
830  ofs += BLI_snprintf(str + ofs,
831  UI_MAX_DRAW_STR - ofs,
832  TIP_("Scale: %s%s %s"),
833  &tvec[0],
834  t->con.text,
835  t->proptext);
836  break;
837  case 1:
838  ofs += BLI_snprintf(str + ofs,
839  UI_MAX_DRAW_STR - ofs,
840  TIP_("Scale: %s : %s%s %s"),
841  &tvec[0],
842  &tvec[NUM_STR_REP_LEN],
843  t->con.text,
844  t->proptext);
845  break;
846  case 2:
847  ofs += BLI_snprintf(str + ofs,
848  UI_MAX_DRAW_STR - ofs,
849  TIP_("Scale: %s : %s : %s%s %s"),
850  &tvec[0],
851  &tvec[NUM_STR_REP_LEN],
852  &tvec[NUM_STR_REP_LEN * 2],
853  t->con.text,
854  t->proptext);
855  break;
856  }
857  }
858  else {
859  if (t->flag & T_2D_EDIT) {
860  ofs += BLI_snprintf(str + ofs,
861  UI_MAX_DRAW_STR - ofs,
862  TIP_("Scale X: %s Y: %s%s %s"),
863  &tvec[0],
864  &tvec[NUM_STR_REP_LEN],
865  t->con.text,
866  t->proptext);
867  }
868  else {
869  ofs += BLI_snprintf(str + ofs,
870  UI_MAX_DRAW_STR - ofs,
871  TIP_("Scale X: %s Y: %s Z: %s%s %s"),
872  &tvec[0],
873  &tvec[NUM_STR_REP_LEN],
874  &tvec[NUM_STR_REP_LEN * 2],
875  t->con.text,
876  t->proptext);
877  }
878  }
879 
880  if (t->flag & T_PROP_EDIT_ALL) {
881  ofs += BLI_snprintf(
882  str + ofs, UI_MAX_DRAW_STR - ofs, TIP_(" Proportional size: %.2f"), t->prop_size);
883  }
884 }
885 
891 static void TransMat3ToSize(const float mat[3][3], const float smat[3][3], float size[3])
892 {
893  float rmat[3][3];
894 
895  mat3_to_rot_size(rmat, size, mat);
896 
897  /* First tried with dot-product... but the sign flip is crucial. */
898  if (dot_v3v3(rmat[0], smat[0]) < 0.0f) {
899  size[0] = -size[0];
900  }
901  if (dot_v3v3(rmat[1], smat[1]) < 0.0f) {
902  size[1] = -size[1];
903  }
904  if (dot_v3v3(rmat[2], smat[2]) < 0.0f) {
905  size[2] = -size[2];
906  }
907 }
908 
909 void ElementResize(TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3])
910 {
911  float tmat[3][3], smat[3][3], center[3];
912  float vec[3];
913 
914  if (t->flag & T_EDIT) {
915  mul_m3_m3m3(smat, mat, td->mtx);
916  mul_m3_m3m3(tmat, td->smtx, smat);
917  }
918  else {
919  copy_m3_m3(tmat, mat);
920  }
921 
922  if (t->con.applySize) {
923  t->con.applySize(t, tc, td, tmat);
924  }
925 
926  /* local constraint shouldn't alter center */
927  if (transdata_check_local_center(t, t->around)) {
928  copy_v3_v3(center, td->center);
929  }
930  else if (t->options & CTX_MOVIECLIP) {
931  if (td->flag & TD_INDIVIDUAL_SCALE) {
932  copy_v3_v3(center, td->center);
933  }
934  else {
936  }
937  }
938  else {
940  }
941 
942  /* Size checked needed since the 3D cursor only uses rotation fields. */
943  if (td->ext && td->ext->size) {
944  float fsize[3];
945 
946  if (ELEM(t->data_type, TC_SCULPT, TC_OBJECT, TC_OBJECT_TEXSPACE, TC_POSE)) {
947  float obsizemat[3][3];
948  /* Reorient the size mat to fit the oriented object. */
949  mul_m3_m3m3(obsizemat, tmat, td->axismtx);
950  /* print_m3("obsizemat", obsizemat); */
951  TransMat3ToSize(obsizemat, td->axismtx, fsize);
952  /* print_v3("fsize", fsize); */
953  }
954  else {
955  mat3_to_size(fsize, tmat);
956  }
957 
958  protectedSizeBits(td->protectflag, fsize);
959 
960  if ((t->flag & T_V3D_ALIGN) == 0) { /* align mode doesn't resize objects itself */
961  if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
962  /* scale val and reset size */
963  *td->val = td->ival * (1 + (fsize[0] - 1) * td->factor);
964 
965  td->ext->size[0] = td->ext->isize[0];
966  td->ext->size[1] = td->ext->isize[1];
967  td->ext->size[2] = td->ext->isize[2];
968  }
969  else {
970  /* Reset val if SINGLESIZE but using a constraint */
971  if (td->flag & TD_SINGLESIZE) {
972  *td->val = td->ival;
973  }
974 
975  td->ext->size[0] = td->ext->isize[0] * (1 + (fsize[0] - 1) * td->factor);
976  td->ext->size[1] = td->ext->isize[1] * (1 + (fsize[1] - 1) * td->factor);
977  td->ext->size[2] = td->ext->isize[2] * (1 + (fsize[2] - 1) * td->factor);
978  }
979  }
980 
981  constraintSizeLim(t, td);
982  }
983 
984  /* For individual element center, Editmode need to use iloc */
985  if (t->flag & T_POINTS) {
986  sub_v3_v3v3(vec, td->iloc, center);
987  }
988  else {
989  sub_v3_v3v3(vec, td->center, center);
990  }
991 
992  mul_m3_v3(tmat, vec);
993 
994  add_v3_v3(vec, center);
995  if (t->flag & T_POINTS) {
996  sub_v3_v3(vec, td->iloc);
997  }
998  else {
999  sub_v3_v3(vec, td->center);
1000  }
1001 
1002  /* grease pencil falloff */
1003  if (t->options & CTX_GPENCIL_STROKES) {
1004  bGPDstroke *gps = (bGPDstroke *)td->extra;
1005  mul_v3_fl(vec, td->factor * gps->runtime.multi_frame_falloff);
1006 
1007  /* scale stroke thickness */
1008  if (td->val) {
1009  transform_snap_increment(t, t->values_final);
1010  applyNumInput(&t->num, t->values_final);
1011 
1012  float ratio = t->values_final[0];
1013  *td->val = td->ival * ratio * gps->runtime.multi_frame_falloff;
1014  CLAMP_MIN(*td->val, 0.001f);
1015  }
1016  }
1017  else {
1018  mul_v3_fl(vec, td->factor);
1019  }
1020 
1021  if (t->options & (CTX_OBJECT | CTX_POSE_BONE)) {
1022  if (t->options & CTX_POSE_BONE) {
1023  /* Without this, the resulting location of scaled bones aren't correct,
1024  * especially noticeable scaling root or disconnected bones around the cursor, see T92515. */
1025  mul_mat3_m4_v3(tc->poseobj->obmat, vec);
1026  }
1027  mul_m3_v3(td->smtx, vec);
1028  }
1029 
1030  protectedTransBits(td->protectflag, vec);
1031  if (td->loc) {
1032  add_v3_v3v3(td->loc, td->iloc, vec);
1033  }
1034 
1035  constraintTransLim(t, td);
1036 }
1039 /* -------------------------------------------------------------------- */
1050 {
1051  short autosnap = SACTSNAP_OFF;
1052 
1053  if (t->spacetype == SPACE_ACTION) {
1054  SpaceAction *saction = (SpaceAction *)t->area->spacedata.first;
1055 
1056  if (saction) {
1057  autosnap = saction->autosnap;
1058  }
1059  }
1060  else if (t->spacetype == SPACE_GRAPH) {
1061  SpaceGraph *sipo = (SpaceGraph *)t->area->spacedata.first;
1062 
1063  if (sipo) {
1064  autosnap = sipo->autosnap;
1065  }
1066  }
1067  else if (t->spacetype == SPACE_NLA) {
1068  SpaceNla *snla = (SpaceNla *)t->area->spacedata.first;
1069 
1070  if (snla) {
1071  autosnap = snla->autosnap;
1072  }
1073  }
1074  else {
1075  autosnap = SACTSNAP_OFF;
1076  }
1077 
1078  /* toggle autosnap on/off
1079  * - when toggling on, prefer nearest frame over 1.0 frame increments
1080  */
1081  if (t->modifiers & MOD_SNAP_INVERT) {
1082  if (autosnap) {
1083  autosnap = SACTSNAP_OFF;
1084  }
1085  else {
1086  autosnap = SACTSNAP_FRAME;
1087  }
1088  }
1089 
1090  return autosnap;
1091 }
1092 
1093 /* This function is used by Animation Editor specific transform functions to do
1094  * the Snap Keyframe to Nearest Frame/Marker
1095  */
1097  TransInfo *t, TransData *td, TransData2D *td2d, AnimData *adt, short autosnap)
1098 {
1099  if (autosnap != SACTSNAP_OFF) {
1100  float val;
1101 
1102  /* convert frame to nla-action time (if needed) */
1103  if (adt && (t->spacetype != SPACE_SEQ)) {
1104  val = BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_MAP);
1105  }
1106  else {
1107  val = *(td->val);
1108  }
1109 
1110  snapFrameTransform(t, autosnap, true, val, &val);
1111 
1112  /* convert frame out of nla-action time */
1113  if (adt && (t->spacetype != SPACE_SEQ)) {
1115  }
1116  else {
1117  *(td->val) = val;
1118  }
1119  }
1120 
1121  /* If the handles are to be moved too
1122  * (as side-effect of keyframes moving, to keep the general effect)
1123  * offset them by the same amount so that the general angles are maintained
1124  * (i.e. won't change while handles are free-to-roam and keyframes are snap-locked).
1125  */
1126  if ((td->flag & TD_MOVEHANDLE1) && td2d->h1) {
1127  td2d->h1[0] = td2d->ih1[0] + *td->val - td->ival;
1128  }
1129  if ((td->flag & TD_MOVEHANDLE2) && td2d->h2) {
1130  td2d->h2[0] = td2d->ih2[0] + *td->val - td->ival;
1131  }
1132 }
1135 /* -------------------------------------------------------------------- */
1139 void transform_mode_init(TransInfo *t, wmOperator *op, const int mode)
1140 {
1141  t->mode = mode;
1142 
1143  switch (mode) {
1144  case TFM_TRANSLATION:
1145  initTranslation(t);
1146  break;
1147  case TFM_ROTATION:
1148  initRotation(t);
1149  break;
1150  case TFM_RESIZE:
1151  initResize(t);
1152  break;
1153  case TFM_SKIN_RESIZE:
1154  initSkinResize(t);
1155  break;
1156  case TFM_TOSPHERE:
1157  initToSphere(t);
1158  break;
1159  case TFM_SHEAR:
1160  initShear(t);
1161  break;
1162  case TFM_BEND:
1163  initBend(t);
1164  break;
1165  case TFM_SHRINKFATTEN:
1167  break;
1168  case TFM_TILT:
1169  initTilt(t);
1170  break;
1173  break;
1174  case TFM_MASK_SHRINKFATTEN:
1176  break;
1179  break;
1180  case TFM_TRACKBALL:
1181  initTrackball(t);
1182  break;
1183  case TFM_PUSHPULL:
1184  initPushPull(t);
1185  break;
1186  case TFM_CREASE:
1187  initCrease(t);
1188  break;
1189  case TFM_BONESIZE:
1190  initBoneSize(t);
1191  break;
1192  case TFM_BONE_ENVELOPE:
1195  break;
1196  case TFM_EDGE_SLIDE:
1197  case TFM_VERT_SLIDE: {
1198  const bool use_even = (op ? RNA_boolean_get(op->ptr, "use_even") : false);
1199  const bool flipped = (op ? RNA_boolean_get(op->ptr, "flipped") : false);
1200  const bool use_clamp = (op ? RNA_boolean_get(op->ptr, "use_clamp") : true);
1201  if (mode == TFM_EDGE_SLIDE) {
1202  const bool use_double_side = (op ? !RNA_boolean_get(op->ptr, "single_side") : true);
1203  initEdgeSlide_ex(t, use_double_side, use_even, flipped, use_clamp);
1204  }
1205  else {
1206  initVertSlide_ex(t, use_even, flipped, use_clamp);
1207  }
1208  break;
1209  }
1210  case TFM_BONE_ROLL:
1211  initBoneRoll(t);
1212  break;
1213  case TFM_TIME_TRANSLATE:
1215  break;
1216  case TFM_TIME_SLIDE:
1217  initTimeSlide(t);
1218  break;
1219  case TFM_TIME_SCALE:
1220  initTimeScale(t);
1221  break;
1222  case TFM_TIME_DUPLICATE:
1223  /* same as TFM_TIME_EXTEND, but we need the mode info for later
1224  * so that duplicate-culling will work properly
1225  */
1226  if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_NLA)) {
1227  initTranslation(t);
1228  }
1229  else {
1231  }
1232  break;
1233  case TFM_TIME_EXTEND:
1234  /* now that transdata has been made, do like for TFM_TIME_TRANSLATE (for most Animation
1235  * Editors because they have only 1D transforms for time values) or TFM_TRANSLATION
1236  * (for Graph/NLA Editors only since they uses 'standard' transforms to get 2D movement)
1237  * depending on which editor this was called from
1238  */
1239  if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_NLA)) {
1240  initTranslation(t);
1241  }
1242  else {
1244  }
1245  break;
1246  case TFM_BAKE_TIME:
1247  initBakeTime(t);
1248  break;
1249  case TFM_MIRROR:
1250  initMirror(t);
1251  break;
1252  case TFM_BWEIGHT:
1253  initBevelWeight(t);
1254  break;
1255  case TFM_ALIGN:
1256  initAlign(t);
1257  break;
1258  case TFM_SEQ_SLIDE:
1259  initSeqSlide(t);
1260  break;
1261  case TFM_NORMAL_ROTATION:
1263  break;
1264  case TFM_GPENCIL_OPACITY:
1265  initGPOpacity(t);
1266  break;
1267  }
1268 
1269  if (t->data_type == TC_MESH_VERTS) {
1270  /* Init Custom Data correction.
1271  * Ideally this should be called when creating the TransData. */
1273  }
1274 
1275  /* TODO(germano): Some of these operations change the `t->mode`.
1276  * This can be bad for Redo.
1277  * BLI_assert(t->mode == mode); */
1278 }
1279 
1284 {
1285  /* Currently only these types are supported. */
1287 
1288  if (t->is_orient_default_overwrite) {
1289  return;
1290  }
1291 
1292  if (!(t->flag & T_MODAL)) {
1293  return;
1294  }
1295 
1296  if (t->orient[O_DEFAULT].type == type) {
1297  return;
1298  }
1299 
1300  RegionView3D *rv3d = NULL;
1301  if ((type == V3D_ORIENT_VIEW) && (t->spacetype == SPACE_VIEW3D) && t->region &&
1302  (t->region->regiontype == RGN_TYPE_WINDOW)) {
1303  rv3d = t->region->regiondata;
1304  }
1305 
1306  t->orient[O_DEFAULT].type = ED_transform_calc_orientation_from_type_ex(
1307  NULL, t->orient[O_DEFAULT].matrix, NULL, rv3d, NULL, NULL, type, 0);
1308 
1309  if (t->orient_curr == O_DEFAULT) {
1310  /* Update Orientation. */
1312  }
1313 }
typedef float(TangentPoint)[2]
const bConstraintTypeInfo * BKE_constraint_typeinfo_from_type(int type)
Definition: constraint.c:5413
void BKE_constraint_targets_for_solving_get(struct Depsgraph *depsgraph, struct bConstraint *con, struct bConstraintOb *ob, struct ListBase *targets, float ctime)
Definition: constraint.c:6102
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1279
@ NLATIME_CONVERT_MAP
Definition: BKE_nla.h:156
@ NLATIME_CONVERT_UNMAP
Definition: BKE_nla.h:153
float BKE_nla_tweakedit_remap(struct AnimData *adt, float cframe, short mode)
Definition: nla.c:582
#define BLI_assert(a)
Definition: BLI_assert.h:58
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
MINLINE float signf(float f)
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:930
void copy_m3_m3(float m1[3][3], const float m2[3][3])
Definition: math_matrix.c:89
void mat3_to_rot_size(float rot[3][3], float size[3], const float mat3[3][3])
Definition: math_matrix.c:2214
void mul_m3_fl(float R[3][3], float f)
Definition: math_matrix.c:960
void unit_m4(float m[4][4])
Definition: rct.c:1140
void mul_mat3_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:794
void size_to_mat4(float R[4][4], const float size[3])
Definition: math_matrix.c:2118
void mat4_to_size(float size[3], const float M[4][4])
Definition: math_matrix.c:2145
#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:391
void mat3_to_size(float size[3], const float M[3][3])
Definition: math_matrix.c:2138
void mul_m4_m3m4(float R[4][4], const float A[3][3], const float B[4][4])
Definition: math_matrix.c:505
void mat4_to_axis_angle(float axis[3], float *angle, const float M[4][4])
void eulO_to_axis_angle(float axis[3], float *angle, const float eul[3], const short order)
void mul_qt_fl(float q[4], const float f)
@ EULER_ORDER_DEFAULT
void mat3_to_quat(float q[4], const float mat[3][3])
void axis_angle_to_quat(float r[4], const float axis[3], const float angle)
void eul_to_quat(float quat[4], const float eul[3])
void quat_to_eul(float eul[3], const float quat[4])
float normalize_qt_qt(float r[4], const float q[4])
void mul_qt_qtqt(float q[4], const float a[4], const float b[4])
Definition: math_rotation.c:65
#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], const short order, const float axis[3], const float angle)
void mat4_to_quat(float q[4], const float mat[4][4])
void eulO_to_mat3(float mat[3][3], const float eul[3], const short order)
void axis_angle_to_mat4(float R[4][4], const float axis[3], const float angle)
void mat3_to_compatible_eulO(float eul[3], const float old[3], const short order, const float mat[3][3])
void eulO_to_mat4(float mat[4][4], const float eul[3], const short order)
void mat4_to_eulO(float eul[3], const short order, const float mat[4][4])
void quat_to_mat4(float mat[4][4], const float q[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 void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
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 add_v3_v3(float r[3], const float a[3])
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 CLAMP_MIN(a, b)
#define TIP_(msgid)
@ SACTSNAP_OFF
@ SACTSNAP_FRAME
@ 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_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
@ OB_MBALL
@ OB_ARMATURE
@ OB_MESH
@ OB_CURVE
@ OB_GPENCIL
@ RGN_TYPE_WINDOW
@ SPACE_ACTION
@ SPACE_NLA
@ SPACE_SEQ
@ SPACE_GRAPH
@ SPACE_VIEW3D
@ V3D_ORIENT_GLOBAL
@ V3D_ORIENT_VIEW
@ V3D_AROUND_LOCAL_ORIGINS
void outputNumInput(NumInput *n, char *str, struct UnitSettings *unit_settings)
Definition: numinput.c:102
#define NUM_STR_REP_LEN
Definition: ED_numinput.h:27
bool applyNumInput(NumInput *n, float *vec)
Definition: numinput.c:207
bool hasNumInput(const NumInput *n)
Definition: numinput.c:185
@ TFM_RESIZE
Definition: ED_transform.h:48
@ TFM_EDGE_SLIDE
Definition: ED_transform.h:74
@ TFM_BONESIZE
Definition: ED_transform.h:59
@ TFM_SKIN_RESIZE
Definition: ED_transform.h:49
@ TFM_SHEAR
Definition: ED_transform.h:51
@ TFM_SHRINKFATTEN
Definition: ED_transform.h:53
@ TFM_TIME_TRANSLATE
Definition: ED_transform.h:65
@ TFM_TIME_SLIDE
Definition: ED_transform.h:66
@ TFM_BAKE_TIME
Definition: ED_transform.h:70
@ TFM_VERT_SLIDE
Definition: ED_transform.h:75
@ TFM_CREASE
Definition: ED_transform.h:57
@ TFM_BEND
Definition: ED_transform.h:52
@ TFM_ROTATION
Definition: ED_transform.h:47
@ TFM_BONE_ENVELOPE
Definition: ED_transform.h:60
@ TFM_BWEIGHT
Definition: ED_transform.h:72
@ TFM_ALIGN
Definition: ED_transform.h:73
@ TFM_TIME_SCALE
Definition: ED_transform.h:67
@ TFM_TIME_DUPLICATE
Definition: ED_transform.h:69
@ TFM_BONE_ROLL
Definition: ED_transform.h:64
@ TFM_TIME_EXTEND
Definition: ED_transform.h:68
@ TFM_GPENCIL_SHRINKFATTEN
Definition: ED_transform.h:63
@ TFM_CURVE_SHRINKFATTEN
Definition: ED_transform.h:61
@ TFM_TILT
Definition: ED_transform.h:54
@ TFM_SEQ_SLIDE
Definition: ED_transform.h:76
@ TFM_TOSPHERE
Definition: ED_transform.h:50
@ TFM_GPENCIL_OPACITY
Definition: ED_transform.h:79
@ TFM_MIRROR
Definition: ED_transform.h:58
@ TFM_TRANSLATION
Definition: ED_transform.h:46
@ TFM_MASK_SHRINKFATTEN
Definition: ED_transform.h:62
@ TFM_BONE_ENVELOPE_DIST
Definition: ED_transform.h:77
@ TFM_NORMAL_ROTATION
Definition: ED_transform.h:78
@ TFM_PUSHPULL
Definition: ED_transform.h:56
@ TFM_TRACKBALL
Definition: ED_transform.h:55
short ED_transform_calc_orientation_from_type_ex(const struct bContext *C, float r_mat[3][3], struct Scene *scene, struct RegionView3D *rv3d, struct Object *ob, struct Object *obedit, const short orientation_index, const int pivot_point)
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:39
#define UI_MAX_DRAW_STR
Definition: UI_interface.h:90
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)
#define fabsf(x)
static unsigned c
Definition: RandGen.cpp:97
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
float obmat[4][4]
void * data
short autosnap
float ih2[2]
float ih1[2]
float mat3[3][3]
Definition: transform.h:466
float center_local[3]
Definition: transform.h:476
float imat3[3][3]
Definition: transform.h:467
struct Object * poseobj
Definition: transform.h:473
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
@ CON_APPLY
Definition: transform.h:177
@ CTX_MOVIECLIP
Definition: transform.h:84
@ CTX_PAINT_CURVE
Definition: transform.h:86
@ CTX_POSE_BONE
Definition: transform.h:87
@ CTX_OBJECT
Definition: transform.h:85
@ CTX_GPENCIL_STROKES
Definition: transform.h:82
@ CTX_MASK
Definition: transform.h:83
@ MOD_SNAP_INVERT
Definition: transform.h:160
@ T_PROP_EDIT_ALL
Definition: transform.h:114
@ T_MODAL
Definition: transform.h:132
@ T_V3D_ALIGN
Definition: transform.h:116
@ T_2D_EDIT
Definition: transform.h:118
@ T_POINTS
Definition: transform.h:104
@ T_EDIT
Definition: transform.h:102
@ TC_POSE
Definition: transform.h:217
@ TC_MESH_VERTS
Definition: transform.h:227
@ TC_OBJECT_TEXSPACE
Definition: transform.h:234
@ TC_SCULPT
Definition: transform.h:237
@ TC_OBJECT
Definition: transform.h:233
conversion and adaptation of different datablocks to a common struct.
void mesh_customdatacorrect_init(TransInfo *t)
@ TD_USEQUAT
@ TD_INDIVIDUAL_SCALE
@ TD_SINGLESIZE
@ TD_PBONE_LOCAL_MTX_P
@ TD_PBONE_LOCAL_MTX_C
@ TD_MOVEHANDLE1
@ TD_NO_LOC
@ TD_MOVEHANDLE2
void protectedTransBits(short protectflag, float vec[3])
void headerResize(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_STR])
void constraintTransLim(TransInfo *t, TransData *td)
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])
short getAnimEdit_SnapMode(TransInfo *t)
void ElementRotation_ex(TransInfo *t, TransDataContainer *tc, TransData *td, const float mat[3][3], const float *center)
static void constraintob_from_transdata(bConstraintOb *cob, TransData *td)
void headerRotation(TransInfo *t, char str[UI_MAX_DRAW_STR], float final)
bool transdata_check_local_center(TransInfo *t, short around)
void ElementRotation(TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3], const short around)
void ElementResize(TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3])
static void protectedQuaternionBits(short protectflag, float quat[4], const float oldquat[4])
void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, TransData2D *td2d, AnimData *adt, short autosnap)
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])
int transform_mode_really_used(bContext *C, int mode)
static void constraintRotLim(TransInfo *UNUSED(t), TransData *td)
void constraintSizeLim(TransInfo *t, TransData *td)
bool transform_mode_is_changeable(const int 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 initResize(TransInfo *t)
void initShear(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 initSkinResize(TransInfo *t)
void initSeqSlide(TransInfo *t)
void initTranslation(TransInfo *t)
void initCurveShrinkFatten(TransInfo *t)
void initBoneRoll(TransInfo *t)
void initGPOpacity(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 initCrease(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(TransInfo *t, float *r_val)
void snapFrameTransform(TransInfo *t, const eAnimEdit_AutoSnap autosnap, const bool is_frame_value, const float delta, float *r_val)