Blender  V2.93
transform_convert.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 "DNA_anim_types.h"
25 #include "DNA_constraint_types.h"
26 #include "DNA_mesh_types.h"
27 
28 #include "MEM_guardedalloc.h"
29 
30 #include "BLI_kdtree.h"
31 #include "BLI_linklist_stack.h"
32 #include "BLI_listbase.h"
33 #include "BLI_math.h"
34 
35 #include "BKE_action.h"
36 #include "BKE_anim_data.h"
37 #include "BKE_context.h"
38 #include "BKE_fcurve.h"
39 #include "BKE_global.h"
40 #include "BKE_image.h"
41 #include "BKE_layer.h"
42 #include "BKE_lib_id.h"
43 #include "BKE_main.h"
44 #include "BKE_modifier.h"
45 #include "BKE_nla.h"
46 #include "BKE_scene.h"
47 
48 #include "ED_keyframes_edit.h"
49 #include "ED_keyframing.h"
50 #include "ED_particle.h"
51 #include "ED_screen.h"
52 #include "ED_screen_types.h"
53 
54 #include "UI_view2d.h"
55 
56 #include "WM_types.h"
57 
58 #include "DEG_depsgraph_build.h"
59 
60 #include "transform.h"
61 #include "transform_snap.h"
62 
63 /* Own include. */
64 #include "transform_convert.h"
65 
67 {
68  return ELEM(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL);
69 }
70 
76 {
77  if (data_len_all != 1) {
78  return;
79  }
81  return;
82  }
84  return;
85  }
86  if (t->flag & T_OVERRIDE_CENTER) {
87  return;
88  }
89 
90  t->around = V3D_AROUND_LOCAL_ORIGINS;
91 }
92 
94 {
95  transform_around_single_fallback_ex(t, t->data_len_all);
96 }
97 
98 /* -------------------------------------------------------------------- */
102 static int trans_data_compare_dist(const void *a, const void *b)
103 {
104  const TransData *td_a = (const TransData *)a;
105  const TransData *td_b = (const TransData *)b;
106 
107  if (td_a->dist < td_b->dist) {
108  return -1;
109  }
110  if (td_a->dist > td_b->dist) {
111  return 1;
112  }
113  return 0;
114 }
115 
116 static int trans_data_compare_rdist(const void *a, const void *b)
117 {
118  const TransData *td_a = (const TransData *)a;
119  const TransData *td_b = (const TransData *)b;
120 
121  if (td_a->rdist < td_b->rdist) {
122  return -1;
123  }
124  if (td_a->rdist > td_b->rdist) {
125  return 1;
126  }
127  return 0;
128 }
129 
131 {
132  TransData *start = tc->data;
133  int i;
134 
135  for (i = 0; i < tc->data_len && start->flag & TD_SELECTED; i++) {
136  start++;
137  }
138 
139  if (i < tc->data_len) {
140  if (t->flag & T_PROP_CONNECTED) {
141  qsort(start, (size_t)tc->data_len - i, sizeof(TransData), trans_data_compare_dist);
142  }
143  else {
144  qsort(start, (size_t)tc->data_len - i, sizeof(TransData), trans_data_compare_rdist);
145  }
146  }
147 }
149 {
152  }
153 }
154 
159 {
160  TransData *sel, *unsel;
161  TransData temp;
162  unsel = tc->data;
163  sel = &tc->data[tc->data_len - 1];
164  while (sel > unsel) {
165  while (unsel->flag & TD_SELECTED) {
166  unsel++;
167  if (unsel == sel) {
168  return;
169  }
170  }
171  while (!(sel->flag & TD_SELECTED)) {
172  sel--;
173  if (unsel == sel) {
174  return;
175  }
176  }
177  temp = *unsel;
178  *unsel = *sel;
179  *sel = temp;
180  sel--;
181  unsel++;
182  }
183 }
185 {
188  }
189 }
190 
194 static void set_prop_dist(TransInfo *t, const bool with_dist)
195 {
196  int a;
197 
198  float _proj_vec[3];
199  const float *proj_vec = NULL;
200 
201  /* support for face-islands */
202  const bool use_island = transdata_check_local_islands(t, t->around);
203 
204  if (t->flag & T_PROP_PROJECTED) {
205  if (t->spacetype == SPACE_VIEW3D && t->region && t->region->regiontype == RGN_TYPE_WINDOW) {
206  RegionView3D *rv3d = t->region->regiondata;
207  normalize_v3_v3(_proj_vec, rv3d->viewinv[2]);
208  proj_vec = _proj_vec;
209  }
210  }
211 
212  /* Count number of selected. */
213  int td_table_len = 0;
215  TransData *td = tc->data;
216  for (a = 0; a < tc->data_len; a++, td++) {
217  if (td->flag & TD_SELECTED) {
218  td_table_len++;
219  }
220  else {
221  /* By definition transform-data has selected items in beginning. */
222  break;
223  }
224  }
225  }
226 
227  /* Pointers to selected's #TransData.
228  * Used to find #TransData from the index returned by #BLI_kdtree_find_nearest. */
229  TransData **td_table = MEM_mallocN(sizeof(*td_table) * td_table_len, __func__);
230 
231  /* Create and fill kd-tree of selected's positions - in global or proj_vec space. */
232  KDTree_3d *td_tree = BLI_kdtree_3d_new(td_table_len);
233 
234  int td_table_index = 0;
236  TransData *td = tc->data;
237  for (a = 0; a < tc->data_len; a++, td++) {
238  if (td->flag & TD_SELECTED) {
239  /* Initialize, it was mallocced. */
240  float vec[3];
241  td->rdist = 0.0f;
242 
243  if (use_island) {
244  if (tc->use_local_mat) {
245  mul_v3_m4v3(vec, tc->mat, td->iloc);
246  }
247  else {
248  mul_v3_m3v3(vec, td->mtx, td->iloc);
249  }
250  }
251  else {
252  if (tc->use_local_mat) {
253  mul_v3_m4v3(vec, tc->mat, td->center);
254  }
255  else {
256  mul_v3_m3v3(vec, td->mtx, td->center);
257  }
258  }
259 
260  if (proj_vec) {
261  float vec_p[3];
262  project_v3_v3v3(vec_p, vec, proj_vec);
263  sub_v3_v3(vec, vec_p);
264  }
265 
266  BLI_kdtree_3d_insert(td_tree, td_table_index, vec);
267  td_table[td_table_index++] = td;
268  }
269  else {
270  /* By definition transform-data has selected items in beginning. */
271  break;
272  }
273  }
274  }
275  BLI_assert(td_table_index == td_table_len);
276 
277  BLI_kdtree_3d_balance(td_tree);
278 
279  /* For each non-selected vertex, find distance to the nearest selected vertex. */
281  TransData *td = tc->data;
282  for (a = 0; a < tc->data_len; a++, td++) {
283  if ((td->flag & TD_SELECTED) == 0) {
284  float vec[3];
285 
286  if (use_island) {
287  if (tc->use_local_mat) {
288  mul_v3_m4v3(vec, tc->mat, td->iloc);
289  }
290  else {
291  mul_v3_m3v3(vec, td->mtx, td->iloc);
292  }
293  }
294  else {
295  if (tc->use_local_mat) {
296  mul_v3_m4v3(vec, tc->mat, td->center);
297  }
298  else {
299  mul_v3_m3v3(vec, td->mtx, td->center);
300  }
301  }
302 
303  if (proj_vec) {
304  float vec_p[3];
305  project_v3_v3v3(vec_p, vec, proj_vec);
306  sub_v3_v3(vec, vec_p);
307  }
308 
309  KDTreeNearest_3d nearest;
310  const int td_index = BLI_kdtree_3d_find_nearest(td_tree, vec, &nearest);
311 
312  td->rdist = -1.0f;
313  if (td_index != -1) {
314  td->rdist = nearest.dist;
315  if (use_island) {
316  copy_v3_v3(td->center, td_table[td_index]->center);
317  copy_m3_m3(td->axismtx, td_table[td_index]->axismtx);
318  }
319  }
320 
321  if (with_dist) {
322  td->dist = td->rdist;
323  }
324  }
325  }
326  }
327 
328  BLI_kdtree_3d_free(td_tree);
329  MEM_freeN(td_table);
330 }
331 
334 /* -------------------------------------------------------------------- */
338 /* adjust pose-channel's auto-ik chainlen */
339 static bool pchan_autoik_adjust(bPoseChannel *pchan, short chainlen)
340 {
341  bConstraint *con;
342  bool changed = false;
343 
344  /* don't bother to search if no valid constraints */
345  if ((pchan->constflag & (PCHAN_HAS_IK | PCHAN_HAS_TARGET)) == 0) {
346  return changed;
347  }
348 
349  /* check if pchan has ik-constraint */
350  for (con = pchan->constraints.first; con; con = con->next) {
351  if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce != 0.0f)) {
353 
354  /* only accept if a temporary one (for auto-ik) */
355  if (data->flag & CONSTRAINT_IK_TEMP) {
356  /* chainlen is new chainlen, but is limited by maximum chainlen */
357  const int old_rootbone = data->rootbone;
358  if ((chainlen == 0) || (chainlen > data->max_rootbone)) {
359  data->rootbone = data->max_rootbone;
360  }
361  else {
362  data->rootbone = chainlen;
363  }
364  changed |= (data->rootbone != old_rootbone);
365  }
366  }
367  }
368 
369  return changed;
370 }
371 
372 /* change the chain-length of auto-ik */
374 {
375  Main *bmain = CTX_data_main(t->context);
376 
377  short *chainlen = &t->settings->autoik_chainlen;
378  bPoseChannel *pchan;
379 
380  /* mode determines what change to apply to chainlen */
381  if (mode == 1) {
382  /* mode=1 is from WHEELMOUSEDOWN... increases len */
383  (*chainlen)++;
384  }
385  else if (mode == -1) {
386  /* mode==-1 is from WHEELMOUSEUP... decreases len */
387  if (*chainlen > 0) {
388  (*chainlen)--;
389  }
390  else {
391  /* IK length did not change, skip updates. */
392  return;
393  }
394  }
395 
396  /* apply to all pose-channels */
397  bool changed = false;
398 
400 
401  /* sanity checks (don't assume t->poseobj is set, or that it is an armature) */
402  if (ELEM(NULL, tc->poseobj, tc->poseobj->pose)) {
403  continue;
404  }
405 
406  for (pchan = tc->poseobj->pose->chanbase.first; pchan; pchan = pchan->next) {
407  changed |= pchan_autoik_adjust(pchan, *chainlen);
408  }
409  }
410 
411  if (changed) {
412  /* TODO(sergey): Consider doing partial update only. */
414  }
415 }
416 
419 /* -------------------------------------------------------------------- */
423 void calc_distanceCurveVerts(TransData *head, TransData *tail, bool cyclic)
424 {
425  TransData *td;
428  for (td = head; td <= tail; td++) {
429  if (td->flag & TD_SELECTED) {
430  td->dist = 0.0f;
432  }
433  else {
434  td->dist = FLT_MAX;
435  }
436  }
437 
438  while ((td = BLI_LINKSTACK_POP(queue))) {
439  float dist;
440  float vec[3];
441 
442  TransData *next_td = NULL;
443 
444  if (td + 1 <= tail) {
445  next_td = td + 1;
446  }
447  else if (cyclic) {
448  next_td = head;
449  }
450 
451  if (next_td != NULL && !(next_td->flag & TD_NOTCONNECTED)) {
452  sub_v3_v3v3(vec, next_td->center, td->center);
453  mul_m3_v3(head->mtx, vec);
454  dist = len_v3(vec) + td->dist;
455 
456  if (dist < next_td->dist) {
457  next_td->dist = dist;
458  BLI_LINKSTACK_PUSH(queue, next_td);
459  }
460  }
461 
462  next_td = NULL;
463 
464  if (td - 1 >= head) {
465  next_td = td - 1;
466  }
467  else if (cyclic) {
468  next_td = tail;
469  }
470 
471  if (next_td != NULL && !(next_td->flag & TD_NOTCONNECTED)) {
472  sub_v3_v3v3(vec, next_td->center, td->center);
473  mul_m3_v3(head->mtx, vec);
474  dist = len_v3(vec) + td->dist;
475 
476  if (dist < next_td->dist) {
477  next_td->dist = dist;
478  BLI_LINKSTACK_PUSH(queue, next_td);
479  }
480  }
481  }
483 }
484 
485 /* Utility function for getting the handle data from bezier's */
487 {
489  td->flag |= TD_BEZTRIPLE;
490  hdata = td->hdata = MEM_mallocN(sizeof(TransDataCurveHandleFlags), "CuHandle Data");
491  hdata->ih1 = bezt->h1;
492  hdata->h1 = &bezt->h1;
493  hdata->ih2 = bezt->h2; /* in case the second is not selected */
494  hdata->h2 = &bezt->h2;
495  return hdata;
496 }
497 
500 /* -------------------------------------------------------------------- */
504 bool clipUVTransform(TransInfo *t, float vec[2], const bool resize)
505 {
506  bool clipx = true, clipy = true;
507  float min[2], max[2];
508 
509  /* Check if the current image in UV editor is a tiled image or not. */
510  const SpaceImage *sima = t->area->spacedata.first;
511  const Image *image = sima->image;
512  const bool is_tiled_image = image && (image->source == IMA_SRC_TILED);
513  /* Stores the coordinates of the closest UDIM tile.
514  * Also acts as an offset to the tile from the origin of UV space. */
515  float base_offset[2] = {0.0f, 0.0f};
516 
517  /* If tiled image then constrain to correct/closest UDIM tile, else 0-1 UV space. */
518  if (is_tiled_image) {
519  int nearest_tile_index = BKE_image_find_nearest_tile(image, t->center_global);
520  if (nearest_tile_index != -1) {
521  nearest_tile_index -= 1001;
522  /* Getting coordinates of nearest tile from the tile index. */
523  base_offset[0] = nearest_tile_index % 10;
524  base_offset[1] = nearest_tile_index / 10;
525  }
526  }
527 
528  min[0] = min[1] = FLT_MAX;
529  max[0] = max[1] = FLT_MIN;
530 
532 
533  TransData *td;
534  int a;
535 
536  for (a = 0, td = tc->data; a < tc->data_len; a++, td++) {
537  minmax_v2v2_v2(min, max, td->loc);
538  }
539  }
540 
541  if (resize) {
542  if (min[0] < base_offset[0] && t->center_global[0] > base_offset[0] &&
543  t->center_global[0] < base_offset[0] + (t->aspect[0] * 0.5f)) {
544  vec[0] *= (t->center_global[0] - base_offset[0]) / (t->center_global[0] - min[0]);
545  }
546  else if (max[0] > (base_offset[0] + t->aspect[0]) &&
547  t->center_global[0] < (base_offset[0] + t->aspect[0])) {
548  vec[0] *= (t->center_global[0] - (base_offset[0] + t->aspect[0])) /
549  (t->center_global[0] - max[0]);
550  }
551  else {
552  clipx = 0;
553  }
554 
555  if (min[1] < base_offset[1] && t->center_global[1] > base_offset[1] &&
556  t->center_global[1] < base_offset[1] + (t->aspect[1] * 0.5f)) {
557  vec[1] *= (t->center_global[1] - base_offset[1]) / (t->center_global[1] - min[1]);
558  }
559  else if (max[1] > (base_offset[1] + t->aspect[1]) &&
560  t->center_global[1] < (base_offset[1] + t->aspect[1])) {
561  vec[1] *= (t->center_global[1] - (base_offset[1] + t->aspect[1])) /
562  (t->center_global[1] - max[1]);
563  }
564  else {
565  clipy = 0;
566  }
567  }
568  else {
569  if (min[0] < base_offset[0]) {
570  vec[0] += base_offset[0] - min[0];
571  }
572  else if (max[0] > base_offset[0] + t->aspect[0]) {
573  vec[0] -= max[0] - base_offset[0] - t->aspect[0];
574  }
575  else {
576  clipx = 0;
577  }
578 
579  if (min[1] < base_offset[1]) {
580  vec[1] += base_offset[1] - min[1];
581  }
582  else if (max[1] > base_offset[1] + t->aspect[1]) {
583  vec[1] -= max[1] - base_offset[1] - t->aspect[1];
584  }
585  else {
586  clipy = 0;
587  }
588  }
589 
590  return (clipx || clipy);
591 }
592 
594 {
596  TransData *td = tc->data;
597  for (int a = 0; a < tc->data_len; a++, td++) {
598  if ((td->flag & TD_SKIP) || (!td->loc)) {
599  continue;
600  }
601 
602  td->loc[0] = min_ff(max_ff(0.0f, td->loc[0]), t->aspect[0]);
603  td->loc[1] = min_ff(max_ff(0.0f, td->loc[1]), t->aspect[1]);
604  }
605  }
606 }
607 
610 /* -------------------------------------------------------------------- */
618 {
619  char r_dir;
620  float center[2];
621  if (t->flag & T_MODAL) {
623  (View2D *)t->view, t->mouse.imval[0], t->mouse.imval[1], &center[0], &center[1]);
624  r_dir = (center[0] > cframe) ? 'R' : 'L';
625  {
626  /* XXX: This saves the direction in the "mirror" property to be used for redo! */
627  if (r_dir == 'R') {
628  t->flag |= T_NO_MIRROR;
629  }
630  }
631  }
632  else {
633  r_dir = (t->flag & T_NO_MIRROR) ? 'R' : 'L';
634  }
635 
636  return r_dir;
637 }
638 
639 /* This function tests if a point is on the "mouse" side of the cursor/frame-marking */
640 bool FrameOnMouseSide(char side, float frame, float cframe)
641 {
642  /* both sides, so it doesn't matter */
643  if (side == 'B') {
644  return true;
645  }
646 
647  /* only on the named side */
648  if (side == 'R') {
649  return (frame >= cframe);
650  }
651  return (frame <= cframe);
652 }
653 
656 /* -------------------------------------------------------------------- */
660 /* Time + Average value */
661 typedef struct tRetainedKeyframe {
663  float frame; /* frame to cluster around */
664  float val; /* average value */
665 
666  size_t tot_count; /* number of keyframes that have been averaged */
667  size_t del_count; /* number of keyframes of this sort that have been deleted so far */
669 
678 void posttrans_fcurve_clean(FCurve *fcu, const int sel_flag, const bool use_handle)
679 {
680  /* NOTE: We assume that all keys are sorted */
681  ListBase retained_keys = {NULL, NULL};
682  const bool can_average_points = ((fcu->flag & (FCURVE_INT_VALUES | FCURVE_DISCRETE_VALUES)) ==
683  0);
684 
685  /* sanity checks */
686  if ((fcu->totvert == 0) || (fcu->bezt == NULL)) {
687  return;
688  }
689 
690  /* 1) Identify selected keyframes, and average the values on those
691  * in case there are collisions due to multiple keys getting scaled
692  * to all end up on the same frame
693  */
694  for (int i = 0; i < fcu->totvert; i++) {
695  BezTriple *bezt = &fcu->bezt[i];
696 
697  if (BEZT_ISSEL_ANY(bezt)) {
698  bool found = false;
699 
700  /* If there's another selected frame here, merge it */
701  for (tRetainedKeyframe *rk = retained_keys.last; rk; rk = rk->prev) {
702  if (IS_EQT(rk->frame, bezt->vec[1][0], BEZT_BINARYSEARCH_THRESH)) {
703  rk->val += bezt->vec[1][1];
704  rk->tot_count++;
705 
706  found = true;
707  break;
708  }
709  if (rk->frame < bezt->vec[1][0]) {
710  /* Terminate early if have passed the supposed insertion point? */
711  break;
712  }
713  }
714 
715  /* If nothing found yet, create a new one */
716  if (found == false) {
717  tRetainedKeyframe *rk = MEM_callocN(sizeof(tRetainedKeyframe), "tRetainedKeyframe");
718 
719  rk->frame = bezt->vec[1][0];
720  rk->val = bezt->vec[1][1];
721  rk->tot_count = 1;
722 
723  BLI_addtail(&retained_keys, rk);
724  }
725  }
726  }
727 
728  if (BLI_listbase_is_empty(&retained_keys)) {
729  /* This may happen if none of the points were selected... */
730  if (G.debug & G_DEBUG) {
731  printf("%s: nothing to do for FCurve %p (rna_path = '%s')\n", __func__, fcu, fcu->rna_path);
732  }
733  return;
734  }
735 
736  /* Compute the average values for each retained keyframe */
737  LISTBASE_FOREACH (tRetainedKeyframe *, rk, &retained_keys) {
738  rk->val = rk->val / (float)rk->tot_count;
739  }
740 
741  /* 2) Delete all keyframes duplicating the "retained keys" found above
742  * - Most of these will be unselected keyframes
743  * - Some will be selected keyframes though. For those, we only keep the last one
744  * (or else everything is gone), and replace its value with the averaged value.
745  */
746  for (int i = fcu->totvert - 1; i >= 0; i--) {
747  BezTriple *bezt = &fcu->bezt[i];
748 
749  /* Is this keyframe a candidate for deletion? */
750  /* TODO: Replace loop with an O(1) lookup instead */
751  for (tRetainedKeyframe *rk = retained_keys.last; rk; rk = rk->prev) {
752  if (IS_EQT(bezt->vec[1][0], rk->frame, BEZT_BINARYSEARCH_THRESH)) {
753  /* Selected keys are treated with greater care than unselected ones... */
754  if (BEZT_ISSEL_ANY(bezt)) {
755  /* - If this is the last selected key left (based on rk->del_count) ==> UPDATE IT
756  * (or else we wouldn't have any keyframe left here)
757  * - Otherwise, there are still other selected keyframes on this frame
758  * to be merged down still ==> DELETE IT
759  */
760  if (rk->del_count == rk->tot_count - 1) {
761  /* Update keyframe... */
762  if (can_average_points) {
763  /* TODO: update handles too? */
764  bezt->vec[1][1] = rk->val;
765  }
766  }
767  else {
768  /* Delete Keyframe */
769  delete_fcurve_key(fcu, i, 0);
770  }
771 
772  /* Update count of how many we've deleted
773  * - It should only matter that we're doing this for all but the last one
774  */
775  rk->del_count++;
776  }
777  else {
778  /* Always delete - Unselected keys don't matter */
779  delete_fcurve_key(fcu, i, 0);
780  }
781 
782  /* Stop the RK search... we've found our match now */
783  break;
784  }
785  }
786  }
787 
788  /* 3) Recalculate handles */
789  testhandles_fcurve(fcu, sel_flag, use_handle);
790 
791  /* cleanup */
792  BLI_freelistN(&retained_keys);
793 }
794 
797 /* -------------------------------------------------------------------- */
801 /* Little helper function for ObjectToTransData used to give certain
802  * constraints (ChildOf, FollowPath, and others that may be added)
803  * inverse corrections for transform, so that they aren't in CrazySpace.
804  * These particular constraints benefit from this, but others don't, hence
805  * this semi-hack ;-) - Aligorith
806  */
808 {
809  bConstraint *con;
810 
811  /* loop through constraints, checking if there's one of the mentioned
812  * constraints needing special crazy-space corrections
813  */
814  if (list) {
815  for (con = list->first; con; con = con->next) {
816  /* only consider constraint if it is enabled, and has influence on result */
817  if ((con->flag & CONSTRAINT_DISABLE) == 0 && (con->enforce != 0.0f)) {
818  /* (affirmative) returns for specific constraints here... */
819  /* constraints that require this regardless */
820  if (ELEM(con->type,
826  return true;
827  }
828 
829  /* constraints that require this only under special conditions */
830  if (con->type == CONSTRAINT_TYPE_CHILDOF) {
831  /* ChildOf constraint only works when using all location components, see T42256. */
833 
834  if ((data->flag & CHILDOF_LOCX) && (data->flag & CHILDOF_LOCY) &&
835  (data->flag & CHILDOF_LOCZ)) {
836  return true;
837  }
838  }
839  else if (con->type == CONSTRAINT_TYPE_ROTLIKE) {
840  /* CopyRot constraint only does this when rotating, and offset is on */
842 
844  ELEM(t->mode, TFM_ROTATION)) {
845  return true;
846  }
847  }
848  else if (con->type == CONSTRAINT_TYPE_TRANSLIKE) {
849  /* Copy Transforms constraint only does this in the Before mode. */
851 
852  if (ELEM(data->mix_mode, TRANSLIKE_MIX_BEFORE) &&
853  ELEM(t->mode, TFM_ROTATION, TFM_TRANSLATION)) {
854  return true;
855  }
856  }
857  else if (con->type == CONSTRAINT_TYPE_ACTION) {
858  /* The Action constraint only does this in the Before mode. */
860 
861  if (ELEM(data->mix_mode, ACTCON_MIX_BEFORE) &&
862  ELEM(t->mode, TFM_ROTATION, TFM_TRANSLATION)) {
863  return true;
864  }
865  }
866  else if (con->type == CONSTRAINT_TYPE_TRANSFORM) {
867  /* Transform constraint needs it for rotation at least (r.57309),
868  * but doing so when translating may also mess things up, see: T36203. */
870 
871  if (data->to == TRANS_ROTATION) {
872  if (t->mode == TFM_ROTATION && data->mix_mode_rot == TRANS_MIXROT_BEFORE) {
873  return true;
874  }
875  }
876  }
877  }
878  }
879  }
880 
881  /* no appropriate candidates found */
882  return false;
883 }
884 
887 /* -------------------------------------------------------------------- */
891 /* inserting keys, pointcache, redraw events... */
898 {
899  /* early out when nothing happened */
900  if (t->data_len_all == 0 || t->mode == TFM_DUMMY) {
901  return;
902  }
903 
904  BLI_assert(CTX_data_main(t->context) == CTX_data_main(C));
905  switch (t->data_type) {
906  case TC_ACTION_DATA:
908  break;
909  case TC_POSE:
911  break;
912  case TC_GRAPH_EDIT_DATA:
914  break;
915  case TC_MASKING_DATA:
917  break;
918  case TC_MESH_VERTS:
919  case TC_MESH_EDGES:
921  break;
922  case TC_NLA_DATA:
924  break;
925  case TC_NODE_DATA:
927  break;
928  case TC_OBJECT:
930  break;
931  case TC_SCULPT:
933  break;
934  case TC_SEQ_DATA:
936  break;
937  case TC_TRACKING_DATA:
939  break;
940  case TC_ARMATURE_VERTS:
941  case TC_CURSOR_IMAGE:
942  case TC_CURSOR_VIEW3D:
943  case TC_CURVE_VERTS:
944  case TC_GPENCIL:
945  case TC_LATTICE_VERTS:
946  case TC_MBALL_VERTS:
947  case TC_MESH_UV:
948  case TC_MESH_SKIN:
949  case TC_OBJECT_TEXSPACE:
951  case TC_PARTICLE_VERTS:
952  case TC_NONE:
953  default:
954  break;
955  }
956 }
957 
959 {
960  if (t->spacetype == SPACE_SEQ) {
961  return G_TRANSFORM_SEQ;
962  }
963  if (t->spacetype == SPACE_GRAPH) {
964  return G_TRANSFORM_FCURVES;
965  }
966  if ((t->flag & T_EDIT) || (t->options & CTX_POSE_BONE)) {
967  return G_TRANSFORM_EDIT;
968  }
969  if (t->options & (CTX_OBJECT | CTX_TEXTURE_SPACE)) {
970  return G_TRANSFORM_OBJ;
971  }
972 
973  return 0;
974 }
975 
978 /* -------------------------------------------------------------------- */
983 {
984  BLI_assert(ELEM(t->data_len_all, 0, -1));
985  t->data_len_all = 0;
986  int data_container_len_orig = t->data_container_len;
987  for (TransDataContainer *th_end = t->data_container - 1,
988  *tc = &t->data_container[t->data_container_len - 1];
989  tc != th_end;
990  tc--) {
991  if (tc->data_len == 0) {
992  uint index = tc - t->data_container;
993  if (index + 1 != t->data_container_len) {
995  t->data_container[index],
996  t->data_container[t->data_container_len - 1]);
997  }
998  t->data_container_len -= 1;
999  }
1000  else {
1001  t->data_len_all += tc->data_len;
1002  }
1003  }
1004  if (data_container_len_orig != t->data_container_len) {
1005  t->data_container = MEM_reallocN(t->data_container,
1006  sizeof(*t->data_container) * t->data_container_len);
1007  }
1008  return t->data_len_all;
1009 }
1010 
1012 {
1013  eTConvertType convert_type = t->data_type;
1014  switch (convert_type) {
1015  case TC_ACTION_DATA:
1016  case TC_CURVE_VERTS:
1017  case TC_GRAPH_EDIT_DATA:
1018  case TC_GPENCIL:
1019  case TC_LATTICE_VERTS:
1020  case TC_MASKING_DATA:
1021  case TC_MBALL_VERTS:
1022  case TC_MESH_VERTS:
1023  case TC_MESH_EDGES:
1024  case TC_MESH_SKIN:
1025  case TC_MESH_UV:
1026  case TC_NODE_DATA:
1027  case TC_OBJECT:
1028  case TC_PARTICLE_VERTS:
1029  break;
1030  case TC_POSE: /* Disable PET, its not usable in pose mode yet T32444. */
1031  case TC_ARMATURE_VERTS:
1032  case TC_CURSOR_IMAGE:
1033  case TC_CURSOR_VIEW3D:
1034  case TC_NLA_DATA:
1035  case TC_OBJECT_TEXSPACE:
1036  case TC_PAINT_CURVE_VERTS:
1037  case TC_SCULPT:
1038  case TC_SEQ_DATA:
1039  case TC_TRACKING_DATA:
1040  case TC_NONE:
1041  default:
1042  t->options |= CTX_NO_PET;
1043  t->flag &= ~T_PROP_EDIT_ALL;
1044  return;
1045  }
1046 
1047  if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
1048  if (convert_type == TC_OBJECT) {
1049  /* Selected objects are already first, no need to presort. */
1050  }
1051  else {
1053  }
1054 
1055  if (ELEM(convert_type, TC_ACTION_DATA, TC_GRAPH_EDIT_DATA)) {
1056  /* Distance has already been set. */
1057  }
1058  else if (ELEM(convert_type, TC_MESH_VERTS, TC_MESH_SKIN)) {
1059  if (t->flag & T_PROP_CONNECTED) {
1060  /* Already calculated by transform_convert_mesh_connectivity_distance. */
1061  }
1062  else {
1063  set_prop_dist(t, false);
1064  }
1065  }
1066  else if (convert_type == TC_MESH_UV && t->flag & T_PROP_CONNECTED) {
1067  /* Already calculated by uv_set_connectivity_distance. */
1068  }
1069  else if (convert_type == TC_CURVE_VERTS) {
1070  BLI_assert(t->obedit_type == OB_CURVE);
1071  set_prop_dist(t, false);
1072  }
1073  else {
1074  set_prop_dist(t, true);
1075  }
1076 
1078  }
1079  else if (ELEM(t->obedit_type, OB_CURVE)) {
1080  /* Needed because bezier handles can be partially selected
1081  * and are still added into transform data. */
1083  }
1084 }
1085 
1086 /* For multi object editing. */
1088  Object *obact,
1089  Object **objects,
1090  uint objects_len)
1091 {
1092  switch (t->data_type) {
1093  case TC_POSE:
1094  case TC_ARMATURE_VERTS:
1095  case TC_CURVE_VERTS:
1096  case TC_GPENCIL:
1097  case TC_LATTICE_VERTS:
1098  case TC_MBALL_VERTS:
1099  case TC_MESH_VERTS:
1100  case TC_MESH_EDGES:
1101  case TC_MESH_SKIN:
1102  case TC_MESH_UV:
1103  break;
1104  case TC_ACTION_DATA:
1105  case TC_GRAPH_EDIT_DATA:
1106  case TC_CURSOR_IMAGE:
1107  case TC_CURSOR_VIEW3D:
1108  case TC_MASKING_DATA:
1109  case TC_NLA_DATA:
1110  case TC_NODE_DATA:
1111  case TC_OBJECT:
1112  case TC_OBJECT_TEXSPACE:
1113  case TC_PAINT_CURVE_VERTS:
1114  case TC_PARTICLE_VERTS:
1115  case TC_SCULPT:
1116  case TC_SEQ_DATA:
1117  case TC_TRACKING_DATA:
1118  case TC_NONE:
1119  default:
1120  /* Does not support Multi object editing. */
1121  return;
1122  }
1123 
1124  const eObjectMode object_mode = obact ? obact->mode : OB_MODE_OBJECT;
1125  const short object_type = obact ? obact->type : -1;
1126 
1127  if ((object_mode & OB_MODE_EDIT) || (t->data_type == TC_GPENCIL) ||
1128  ((object_mode & OB_MODE_POSE) && (object_type == OB_ARMATURE))) {
1129  if (t->data_container) {
1130  MEM_freeN(t->data_container);
1131  }
1132 
1133  bool free_objects = false;
1134  if (objects == NULL) {
1136  t->view_layer,
1137  (t->spacetype == SPACE_VIEW3D) ? t->view : NULL,
1138  &objects_len,
1139  {
1140  .object_mode = object_mode,
1141  .no_dup_data = true,
1142  });
1143  free_objects = true;
1144  }
1145 
1146  t->data_container = MEM_callocN(sizeof(*t->data_container) * objects_len, __func__);
1147  t->data_container_len = objects_len;
1148 
1149  for (int i = 0; i < objects_len; i++) {
1150  TransDataContainer *tc = &t->data_container[i];
1151  if (((t->flag & T_NO_MIRROR) == 0) && ((t->options & CTX_NO_MIRROR) == 0) &&
1152  (objects[i]->type == OB_MESH)) {
1153  tc->use_mirror_axis_x = (((Mesh *)objects[i]->data)->symmetry & ME_SYMMETRY_X) != 0;
1154  tc->use_mirror_axis_y = (((Mesh *)objects[i]->data)->symmetry & ME_SYMMETRY_Y) != 0;
1155  tc->use_mirror_axis_z = (((Mesh *)objects[i]->data)->symmetry & ME_SYMMETRY_Z) != 0;
1156  }
1157 
1158  if (object_mode & OB_MODE_EDIT) {
1159  tc->obedit = objects[i];
1160  /* Check needed for UV's */
1161  if ((t->flag & T_2D_EDIT) == 0) {
1162  tc->use_local_mat = true;
1163  }
1164  }
1165  else if (object_mode & OB_MODE_POSE) {
1166  tc->poseobj = objects[i];
1167  tc->use_local_mat = true;
1168  }
1169  else if (t->data_type == TC_GPENCIL) {
1170  tc->use_local_mat = true;
1171  }
1172 
1173  if (tc->use_local_mat) {
1174  BLI_assert((t->flag & T_2D_EDIT) == 0);
1175  copy_m4_m4(tc->mat, objects[i]->obmat);
1176  copy_m3_m4(tc->mat3, tc->mat);
1177  /* for non-invertible scale matrices, invert_m4_m4_fallback()
1178  * can still provide a valid pivot */
1179  invert_m4_m4_fallback(tc->imat, tc->mat);
1180  invert_m3_m3(tc->imat3, tc->mat3);
1181  normalize_m3_m3(tc->mat3_unit, tc->mat3);
1182  }
1183  /* Otherwise leave as zero. */
1184  }
1185 
1186  if (free_objects) {
1187  MEM_freeN(objects);
1188  }
1189  }
1190 }
1191 
1193 {
1194  switch (data_type) {
1195  case TC_ACTION_DATA:
1196  case TC_GRAPH_EDIT_DATA:
1197  case TC_MASKING_DATA:
1198  case TC_NLA_DATA:
1199  case TC_NODE_DATA:
1200  case TC_PAINT_CURVE_VERTS:
1201  case TC_SEQ_DATA:
1202  case TC_TRACKING_DATA:
1203  return T_POINTS | T_2D_EDIT;
1204  case TC_ARMATURE_VERTS:
1205  case TC_CURVE_VERTS:
1206  case TC_GPENCIL:
1207  case TC_LATTICE_VERTS:
1208  case TC_MBALL_VERTS:
1209  case TC_MESH_VERTS:
1210  case TC_MESH_SKIN:
1211  return T_EDIT | T_POINTS;
1212  case TC_MESH_EDGES:
1213  return T_EDIT;
1214  case TC_MESH_UV:
1215  return T_EDIT | T_POINTS | T_2D_EDIT;
1216  case TC_CURSOR_IMAGE:
1217  return T_2D_EDIT;
1218  case TC_PARTICLE_VERTS:
1219  return T_POINTS;
1220  case TC_POSE:
1221  case TC_CURSOR_VIEW3D:
1222  case TC_OBJECT:
1223  case TC_OBJECT_TEXSPACE:
1224  case TC_SCULPT:
1225  case TC_NONE:
1226  default:
1227  break;
1228  }
1229  return 0;
1230 }
1231 
1232 static eTConvertType convert_type_get(const TransInfo *t, Object **r_obj_armature)
1233 {
1234  ViewLayer *view_layer = t->view_layer;
1235  Object *ob = OBACT(view_layer);
1236  eTConvertType convert_type = TC_NONE;
1237 
1238  /* if tests must match recalcData for correct updates */
1239  if (t->options & CTX_CURSOR) {
1240  if (t->spacetype == SPACE_IMAGE) {
1241  convert_type = TC_CURSOR_IMAGE;
1242  }
1243  else {
1244  convert_type = TC_CURSOR_VIEW3D;
1245  }
1246  }
1247  else if (!(t->options & CTX_PAINT_CURVE) && (t->spacetype == SPACE_VIEW3D) && ob &&
1248  (ob->mode == OB_MODE_SCULPT) && ob->sculpt) {
1249  convert_type = TC_SCULPT;
1250  }
1251  else if (t->options & CTX_TEXTURE_SPACE) {
1252  convert_type = TC_OBJECT_TEXSPACE;
1253  }
1254  else if (t->options & CTX_EDGE_DATA) {
1255  convert_type = TC_MESH_EDGES;
1256  }
1257  else if (t->options & CTX_GPENCIL_STROKES) {
1258  convert_type = TC_GPENCIL;
1259  }
1260  else if (t->spacetype == SPACE_IMAGE) {
1261  if (t->options & CTX_MASK) {
1262  convert_type = TC_MASKING_DATA;
1263  }
1264  else if (t->options & CTX_PAINT_CURVE) {
1265  if (!ELEM(t->mode, TFM_SHEAR, TFM_SHRINKFATTEN)) {
1266  convert_type = TC_PAINT_CURVE_VERTS;
1267  }
1268  }
1269  else if (t->obedit_type == OB_MESH) {
1270  convert_type = TC_MESH_UV;
1271  }
1272  }
1273  else if (t->spacetype == SPACE_ACTION) {
1274  convert_type = TC_ACTION_DATA;
1275  }
1276  else if (t->spacetype == SPACE_NLA) {
1277  convert_type = TC_NLA_DATA;
1278  }
1279  else if (t->spacetype == SPACE_SEQ) {
1280  convert_type = TC_SEQ_DATA;
1281  }
1282  else if (t->spacetype == SPACE_GRAPH) {
1283  convert_type = TC_GRAPH_EDIT_DATA;
1284  }
1285  else if (t->spacetype == SPACE_NODE) {
1286  convert_type = TC_NODE_DATA;
1287  }
1288  else if (t->spacetype == SPACE_CLIP) {
1289  if (t->options & CTX_MOVIECLIP) {
1290  convert_type = TC_TRACKING_DATA;
1291  }
1292  else if (t->options & CTX_MASK) {
1293  convert_type = TC_MASKING_DATA;
1294  }
1295  }
1296  else if (t->obedit_type != -1) {
1297  if (t->obedit_type == OB_MESH) {
1298  if (t->mode == TFM_SKIN_RESIZE) {
1299  convert_type = TC_MESH_SKIN;
1300  }
1301  else {
1302  convert_type = TC_MESH_VERTS;
1303  }
1304  }
1305  else if (ELEM(t->obedit_type, OB_CURVE, OB_SURF)) {
1306  convert_type = TC_CURVE_VERTS;
1307  }
1308  else if (t->obedit_type == OB_LATTICE) {
1309  convert_type = TC_LATTICE_VERTS;
1310  }
1311  else if (t->obedit_type == OB_MBALL) {
1312  convert_type = TC_MBALL_VERTS;
1313  }
1314  else if (t->obedit_type == OB_ARMATURE) {
1315  convert_type = TC_ARMATURE_VERTS;
1316  }
1317  }
1318  else if (ob && (ob->mode & OB_MODE_POSE)) {
1319  convert_type = TC_POSE;
1320  }
1321  else if (ob && (ob->mode & OB_MODE_ALL_WEIGHT_PAINT) && !(t->options & CTX_PAINT_CURVE)) {
1323  if (ob_armature) {
1324  *r_obj_armature = ob_armature;
1325  convert_type = TC_POSE;
1326  }
1327  }
1328  else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT) &&
1329  PE_start_edit(PE_get_current(t->depsgraph, t->scene, ob))) {
1330  convert_type = TC_PARTICLE_VERTS;
1331  }
1332  else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) {
1333  if ((t->options & CTX_PAINT_CURVE) && !ELEM(t->mode, TFM_SHEAR, TFM_SHRINKFATTEN)) {
1334  convert_type = TC_PAINT_CURVE_VERTS;
1335  }
1336  }
1337  else if ((ob) && (ELEM(ob->mode,
1342  /* In grease pencil all transformations must be canceled if not Object or Edit. */
1343  }
1344  else {
1345  convert_type = TC_OBJECT;
1346  }
1347 
1348  return convert_type;
1349 }
1350 
1352 {
1353  t->data_len_all = -1;
1354 
1355  Object *ob_armature = NULL;
1356  t->data_type = convert_type_get(t, &ob_armature);
1357  t->flag |= flags_from_data_type(t->data_type);
1358 
1359  if (ob_armature) {
1360  init_TransDataContainers(t, ob_armature, &ob_armature, 1);
1361  }
1362  else {
1363  ViewLayer *view_layer = t->view_layer;
1364  Object *ob = OBACT(view_layer);
1365  init_TransDataContainers(t, ob, NULL, 0);
1366  }
1367 
1368  switch (t->data_type) {
1369  case TC_ACTION_DATA:
1371  break;
1372  case TC_POSE:
1373  t->options |= CTX_POSE_BONE;
1374 
1375  /* XXX active-layer checking isn't done
1376  * as that should probably be checked through context instead. */
1377  createTransPose(t);
1378  break;
1379  case TC_ARMATURE_VERTS:
1381  break;
1382  case TC_CURSOR_IMAGE:
1384  break;
1385  case TC_CURSOR_VIEW3D:
1387  break;
1388  case TC_CURVE_VERTS:
1390  break;
1391  case TC_GRAPH_EDIT_DATA:
1393  break;
1394  case TC_GPENCIL:
1396  break;
1397  case TC_LATTICE_VERTS:
1399  break;
1400  case TC_MASKING_DATA:
1402  break;
1403  case TC_MBALL_VERTS:
1405  break;
1406  case TC_MESH_VERTS:
1408  break;
1409  case TC_MESH_EDGES:
1410  createTransEdge(t);
1411  break;
1412  case TC_MESH_SKIN:
1414  break;
1415  case TC_MESH_UV:
1416  createTransUVs(C, t);
1417  break;
1418  case TC_NLA_DATA:
1420  break;
1421  case TC_NODE_DATA:
1423  break;
1424  case TC_OBJECT:
1425  t->options |= CTX_OBJECT;
1426 
1427  /* Needed for correct Object.obmat after duplication, see: T62135. */
1428  BKE_scene_graph_evaluated_ensure(t->depsgraph, CTX_data_main(t->context));
1429 
1430  if ((t->settings->transform_flag & SCE_XFORM_DATA_ORIGIN) != 0) {
1431  t->options |= CTX_OBMODE_XFORM_OBDATA;
1432  }
1433  if ((t->settings->transform_flag & SCE_XFORM_SKIP_CHILDREN) != 0) {
1434  t->options |= CTX_OBMODE_XFORM_SKIP_CHILDREN;
1435  }
1436  createTransObject(C, t);
1437  /* Check if we're transforming the camera from the camera */
1438  if ((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW)) {
1439  View3D *v3d = t->view;
1440  RegionView3D *rv3d = t->region->regiondata;
1441  if ((rv3d->persp == RV3D_CAMOB) && v3d->camera) {
1442  /* we could have a flag to easily check an object is being transformed */
1443  if (v3d->camera->id.tag & LIB_TAG_DOIT) {
1444  t->options |= CTX_CAMERA;
1445  }
1446  }
1447  else if (v3d->ob_center && v3d->ob_center->id.tag & LIB_TAG_DOIT) {
1448  t->options |= CTX_CAMERA;
1449  }
1450  }
1451  break;
1452  case TC_OBJECT_TEXSPACE:
1454  break;
1455  case TC_PAINT_CURVE_VERTS:
1457  break;
1458  case TC_PARTICLE_VERTS:
1460  break;
1461  case TC_SCULPT:
1462  createTransSculpt(C, t);
1463  break;
1464  case TC_SEQ_DATA:
1465  t->num.flag |= NUM_NO_FRACTION; /* sequencer has no use for floating point transform. */
1467  break;
1468  case TC_TRACKING_DATA:
1470  break;
1471  case TC_NONE:
1472  default:
1473  printf("edit type not implemented!\n");
1474  BLI_assert(t->data_len_all == -1);
1475  t->data_len_all = 0;
1476  return;
1477  }
1478 
1480 
1482 }
1483 
1486 /* -------------------------------------------------------------------- */
1491 {
1493  Object *ob = tc->obedit;
1494  ModifierData *md = ob->modifiers.first;
1495  float tolerance[3] = {0.0f, 0.0f, 0.0f};
1496  int axis = 0;
1497 
1498  for (; md; md = md->next) {
1499  if ((md->type == eModifierType_Mirror) && (md->mode & eModifierMode_Realtime)) {
1501 
1502  if (mmd->flag & MOD_MIR_CLIPPING) {
1503  axis = 0;
1504  if (mmd->flag & MOD_MIR_AXIS_X) {
1505  axis |= 1;
1506  tolerance[0] = mmd->tolerance;
1507  }
1508  if (mmd->flag & MOD_MIR_AXIS_Y) {
1509  axis |= 2;
1510  tolerance[1] = mmd->tolerance;
1511  }
1512  if (mmd->flag & MOD_MIR_AXIS_Z) {
1513  axis |= 4;
1514  tolerance[2] = mmd->tolerance;
1515  }
1516  if (axis) {
1517  float mtx[4][4], imtx[4][4];
1518  int i;
1519 
1520  if (mmd->mirror_ob) {
1521  float obinv[4][4];
1522 
1523  invert_m4_m4(obinv, mmd->mirror_ob->obmat);
1524  mul_m4_m4m4(mtx, obinv, ob->obmat);
1525  invert_m4_m4(imtx, mtx);
1526  }
1527 
1528  TransData *td = tc->data;
1529  for (i = 0; i < tc->data_len; i++, td++) {
1530  int clip;
1531  float loc[3], iloc[3];
1532 
1533  if (td->loc == NULL) {
1534  break;
1535  }
1536 
1537  if (td->flag & TD_SKIP) {
1538  continue;
1539  }
1540 
1541  copy_v3_v3(loc, td->loc);
1542  copy_v3_v3(iloc, td->iloc);
1543 
1544  if (mmd->mirror_ob) {
1545  mul_m4_v3(mtx, loc);
1546  mul_m4_v3(mtx, iloc);
1547  }
1548 
1549  clip = 0;
1550  if (axis & 1) {
1551  if (fabsf(iloc[0]) <= tolerance[0] || loc[0] * iloc[0] < 0.0f) {
1552  loc[0] = 0.0f;
1553  clip = 1;
1554  }
1555  }
1556 
1557  if (axis & 2) {
1558  if (fabsf(iloc[1]) <= tolerance[1] || loc[1] * iloc[1] < 0.0f) {
1559  loc[1] = 0.0f;
1560  clip = 1;
1561  }
1562  }
1563  if (axis & 4) {
1564  if (fabsf(iloc[2]) <= tolerance[2] || loc[2] * iloc[2] < 0.0f) {
1565  loc[2] = 0.0f;
1566  clip = 1;
1567  }
1568  }
1569  if (clip) {
1570  if (mmd->mirror_ob) {
1571  mul_m4_v3(imtx, loc);
1572  }
1573  copy_v3_v3(td->loc, loc);
1574  }
1575  }
1576  }
1577  }
1578  }
1579  }
1580  }
1581 }
1582 
1583 /* for the realtime animation recording feature, handle overlapping data */
1585 {
1586  Scene *scene = t->scene;
1587  ID *id = &ob->id;
1588  wmTimer *animtimer = t->animtimer;
1589  ScreenAnimData *sad = (animtimer) ? animtimer->customdata : NULL;
1590 
1591  /* sanity checks */
1592  if (ELEM(NULL, scene, id, sad)) {
1593  return;
1594  }
1595 
1596  /* check if we need a new strip if:
1597  * - if animtimer is running
1598  * - we're not only keying for available channels
1599  * - the option to add new actions for each round is not enabled
1600  */
1601  if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL) == 0 &&
1603  /* if playback has just looped around,
1604  * we need to add a new NLA track+strip to allow a clean pass to occur */
1605  if ((sad) && (sad->flag & ANIMPLAY_FLAG_JUMPED)) {
1606  AnimData *adt = BKE_animdata_from_id(id);
1607  const bool is_first = (adt) && (adt->nla_tracks.first == NULL);
1608 
1609  /* perform push-down manually with some differences
1610  * NOTE: BKE_nla_action_pushdown() sync warning...
1611  */
1612  if ((adt->action) && !(adt->flag & ADT_NLA_EDIT_ON)) {
1613  float astart, aend;
1614 
1615  /* only push down if action is more than 1-2 frames long */
1616  calc_action_range(adt->action, &astart, &aend, 1);
1617  if (aend > astart + 2.0f) {
1619 
1620  /* clear reference to action now that we've pushed it onto the stack */
1621  id_us_min(&adt->action->id);
1622  adt->action = NULL;
1623 
1624  /* adjust blending + extend so that they will behave correctly */
1628 
1629  /* copy current "action blending" settings from adt to the strip,
1630  * as it was keyframed with these settings, so omitting them will
1631  * change the effect [T54766]
1632  */
1633  if (is_first == false) {
1634  strip->blendmode = adt->act_blendmode;
1635  strip->influence = adt->act_influence;
1636 
1637  if (adt->act_influence < 1.0f) {
1638  /* enable "user-controlled" influence (which will insert a default keyframe)
1639  * so that the influence doesn't get lost on the new update
1640  *
1641  * NOTE: An alternative way would have been to instead hack the influence
1642  * to not get always get reset to full strength if NLASTRIP_FLAG_USR_INFLUENCE
1643  * is disabled but auto-blending isn't being used. However, that approach
1644  * is a bit hacky/hard to discover, and may cause backwards compatibility issues,
1645  * so it's better to just do it this way.
1646  */
1649  }
1650  }
1651 
1652  /* also, adjust the AnimData's action extend mode to be on
1653  * 'nothing' so that previous result still play
1654  */
1656  }
1657  }
1658  }
1659  }
1660 }
1661 
1663 {
1664  TransDataContainer *tc = t->data_container;
1665  TransData *td = tc->data;
1666  float aspect_inv[2];
1667 
1668  aspect_inv[0] = 1.0f / t->aspect[0];
1669  aspect_inv[1] = 1.0f / t->aspect[1];
1670 
1671  td->loc[0] = td->loc[0] * aspect_inv[0];
1672  td->loc[1] = td->loc[1] * aspect_inv[1];
1673 
1675 }
1676 
1678 {
1680 }
1681 
1683 {
1684  if (t->state != TRANS_CANCEL) {
1685  applyProject(t);
1686  }
1688  if (tc->data_len) {
1689  DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
1690  }
1691  }
1692 }
1693 
1694 /* called for updating while transform acts, once per redraw */
1696 {
1697  switch (t->data_type) {
1698  case TC_ACTION_DATA:
1700  break;
1701  case TC_POSE:
1702  recalcData_pose(t);
1703  break;
1704  case TC_ARMATURE_VERTS:
1706  break;
1707  case TC_CURVE_VERTS:
1709  break;
1710  case TC_CURSOR_IMAGE:
1712  break;
1713  case TC_CURSOR_VIEW3D:
1715  break;
1716  case TC_GRAPH_EDIT_DATA:
1718  break;
1719  case TC_GPENCIL:
1721  break;
1722  case TC_MASKING_DATA:
1724  break;
1725  case TC_MESH_VERTS:
1726  case TC_MESH_EDGES:
1727  recalcData_mesh(t);
1728  break;
1729  case TC_MESH_SKIN:
1731  break;
1732  case TC_MESH_UV:
1733  recalcData_uv(t);
1734  break;
1735  case TC_NLA_DATA:
1736  recalcData_nla(t);
1737  break;
1738  case TC_NODE_DATA:
1739  flushTransNodes(t);
1740  break;
1741  case TC_OBJECT:
1743  break;
1744  case TC_OBJECT_TEXSPACE:
1746  break;
1747  case TC_PAINT_CURVE_VERTS:
1749  break;
1750  case TC_SCULPT:
1752  break;
1753  case TC_SEQ_DATA:
1755  break;
1756  case TC_TRACKING_DATA:
1758  break;
1759  case TC_MBALL_VERTS:
1761  break;
1762  case TC_LATTICE_VERTS:
1764  break;
1765  case TC_PARTICLE_VERTS:
1767  break;
1768  case TC_NONE:
1769  default:
1770  break;
1771  }
1772 }
1773 
typedef float(TangentPoint)[2]
Blender kernel action and pose functionality.
void calc_action_range(const struct bAction *act, float *start, float *end, short incl_modifiers)
struct AnimData * BKE_animdata_from_id(struct ID *id)
Definition: anim_data.c:96
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
void testhandles_fcurve(struct FCurve *fcu, eBezTriple_Flag sel_flag, const bool use_handle)
Definition: fcurve.c:1407
#define BEZT_BINARYSEARCH_THRESH
Definition: BKE_fcurve.h:181
@ G_DEBUG
Definition: BKE_global.h:133
@ G_TRANSFORM_OBJ
Definition: BKE_global.h:218
@ G_TRANSFORM_SEQ
Definition: BKE_global.h:220
@ G_TRANSFORM_EDIT
Definition: BKE_global.h:219
@ G_TRANSFORM_FCURVES
Definition: BKE_global.h:221
int BKE_image_find_nearest_tile(const struct Image *image, const float co[2])
#define BKE_view_layer_array_from_objects_in_mode(view_layer, v3d, r_len,...)
Definition: BKE_layer.h:407
void id_us_min(struct ID *id)
Definition: lib_id.c:297
void BKE_nlastrip_validate_fcurves(struct NlaStrip *strip)
Definition: nla.c:1516
struct NlaStrip * BKE_nlastack_add_strip(struct AnimData *adt, struct bAction *act, const bool is_liboverride)
Definition: nla.c:368
void BKE_scene_graph_evaluated_ensure(struct Depsgraph *depsgraph, struct Main *bmain)
Definition: scene.c:2718
#define BLI_assert(a)
Definition: BLI_assert.h:58
A kd-tree for nearest neighbor search.
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:930
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:262
bool invert_m4_m4_fallback(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1206
void normalize_m3_m3(float R[3][3], const float M[3][3]) ATTR_NONNULL()
Definition: math_matrix.c:1934
void copy_m3_m3(float m1[3][3], const float m2[3][3])
Definition: math_matrix.c:89
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:105
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
bool invert_m3_m3(float R[3][3], const float A[3][3])
Definition: math_matrix.c:1161
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:95
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:742
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
Definition: math_matrix.c:901
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 copy_v3_v3(float r[3], const float a[3])
void project_v3_v3v3(float out[3], const float p[3], const float v_proj[3])
Definition: math_vector.c:674
void minmax_v2v2_v2(float min[2], float max[2], const float vec[2])
Definition: math_vector.c:1043
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
unsigned int uint
Definition: BLI_sys_types.h:83
#define SWAP(type, a, b)
#define ELEM(...)
#define IS_EQT(a, b, c)
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_relations_tag_update(struct Main *bmain)
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:654
@ LIB_TAG_DOIT
Definition: DNA_ID.h:554
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition: DNA_ID.h:445
@ PCHAN_HAS_IK
@ PCHAN_HAS_TARGET
@ NLASTRIP_FLAG_ACTIVE
@ NLASTRIP_FLAG_USR_INFLUENCE
@ NLASTRIP_FLAG_AUTO_BLENDS
@ NLASTRIP_FLAG_SELECT
@ ADT_NLA_EDIT_ON
@ NLASTRIP_EXTEND_NOTHING
@ FCURVE_INT_VALUES
@ FCURVE_DISCRETE_VALUES
@ CONSTRAINT_DISABLE
@ CONSTRAINT_IK_TEMP
@ ROTLIKE_MIX_OFFSET
@ ROTLIKE_MIX_BEFORE
@ CONSTRAINT_TYPE_CHILDOF
@ CONSTRAINT_TYPE_TRANSFORM
@ CONSTRAINT_TYPE_FOLLOWTRACK
@ CONSTRAINT_TYPE_OBJECTSOLVER
@ CONSTRAINT_TYPE_ARMATURE
@ CONSTRAINT_TYPE_ROTLIKE
@ CONSTRAINT_TYPE_KINEMATIC
@ CONSTRAINT_TYPE_TRANSLIKE
@ CONSTRAINT_TYPE_CLAMPTO
@ CONSTRAINT_TYPE_ACTION
@ CONSTRAINT_TYPE_FOLLOWPATH
@ ACTCON_MIX_BEFORE
@ TRANSLIKE_MIX_BEFORE
@ CHILDOF_LOCZ
@ CHILDOF_LOCX
@ CHILDOF_LOCY
@ TRANS_ROTATION
@ TRANS_MIXROT_BEFORE
#define BEZT_ISSEL_ANY(bezt)
@ IMA_SRC_TILED
@ ME_SYMMETRY_X
@ ME_SYMMETRY_Y
@ ME_SYMMETRY_Z
@ eModifierMode_Realtime
@ eModifierType_Mirror
@ MOD_MIR_AXIS_Z
@ MOD_MIR_CLIPPING
@ MOD_MIR_AXIS_X
@ MOD_MIR_AXIS_Y
#define OB_MODE_ALL_PAINT
#define OB_MODE_ALL_WEIGHT_PAINT
eObjectMode
@ OB_MODE_VERTEX_GPENCIL
@ OB_MODE_PARTICLE_EDIT
@ OB_MODE_EDIT
@ OB_MODE_WEIGHT_GPENCIL
@ OB_MODE_SCULPT
@ OB_MODE_SCULPT_GPENCIL
@ OB_MODE_POSE
@ OB_MODE_OBJECT
@ OB_MODE_PAINT_GPENCIL
@ OB_LATTICE
@ OB_MBALL
@ OB_SURF
@ OB_ARMATURE
@ OB_MESH
@ OB_CURVE
@ SCE_XFORM_SKIP_CHILDREN
@ SCE_XFORM_DATA_ORIGIN
#define OBACT(_view_layer)
@ RGN_TYPE_WINDOW
@ SPACE_CLIP
@ SPACE_ACTION
@ SPACE_NODE
@ SPACE_NLA
@ SPACE_SEQ
@ SPACE_IMAGE
@ SPACE_GRAPH
@ SPACE_VIEW3D
@ ANIMRECORD_FLAG_WITHNLA
@ V3D_AROUND_ACTIVE
@ V3D_AROUND_CENTER_BOUNDS
@ V3D_AROUND_CENTER_MEDIAN
@ V3D_AROUND_LOCAL_ORIGINS
#define RV3D_CAMOB
#define IS_AUTOKEY_FLAG(scene, flag)
@ NUM_NO_FRACTION
Definition: ED_numinput.h:72
int PE_start_edit(struct PTCacheEdit *edit)
struct PTCacheEdit * PE_get_current(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob)
@ ANIMPLAY_FLAG_JUMPED
@ TFM_RESIZE
Definition: ED_transform.h:48
@ TFM_SKIN_RESIZE
Definition: ED_transform.h:49
@ TFM_SHEAR
Definition: ED_transform.h:51
@ TFM_SHRINKFATTEN
Definition: ED_transform.h:53
@ TFM_ROTATION
Definition: ED_transform.h:47
@ TFM_TRANSLATION
Definition: ED_transform.h:46
@ TFM_DUMMY
Definition: ED_transform.h:45
@ TFM_TRACKBALL
Definition: ED_transform.h:55
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 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
Read Guarded memory(de)allocation.
#define MEM_reallocN(vmemh, len)
#define C
Definition: RandGen.cpp:39
void UI_view2d_region_to_view(const struct View2D *v2d, float x, float y, float *r_view_x, float *r_view_y) ATTR_NONNULL()
short source
Scene scene
#define fabsf(x)
void delete_fcurve_key(FCurve *fcu, int index, bool do_recalc)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static unsigned a[3]
Definition: RandGen.cpp:92
ThreadQueue * queue
all scheduled work for the cpu
#define min(a, b)
Definition: sort.c:51
bAction * action
short act_blendmode
float act_influence
short act_extendmode
ListBase nla_tracks
float vec[3][3]
char * rna_path
BezTriple * bezt
short flag
unsigned int totvert
Definition: DNA_ID.h:273
int tag
Definition: DNA_ID.h:292
void * last
Definition: DNA_listBase.h:47
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
struct Object * mirror_ob
struct ModifierData * next
short blendmode
float influence
short extendmode
ListBase modifiers
float obmat[4][4]
struct SculptSession * sculpt
float viewinv[4][4]
struct ToolSettings * toolsettings
struct Image * image
float mat3_unit[3][3]
Definition: transform.h:470
float mat3[3][3]
Definition: transform.h:466
struct Object * obedit
Definition: transform.h:461
float mat[4][4]
Definition: transform.h:463
TransData * data
Definition: transform.h:448
float imat3[3][3]
Definition: transform.h:467
float imat[4][4]
Definition: transform.h:464
struct Object * poseobj
Definition: transform.h:473
TransDataCurveHandleFlags * hdata
float axismtx[3][3]
float mtx[3][3]
struct Object * camera
struct Object * ob_center
struct bConstraint * next
ListBase constraints
struct bPoseChannel * next
struct tRetainedKeyframe * prev
struct tRetainedKeyframe * next
void * customdata
Definition: WM_types.h:702
bool transdata_check_local_islands(TransInfo *t, short around)
Definition: transform.c:79
@ CTX_MOVIECLIP
Definition: transform.h:84
@ CTX_PAINT_CURVE
Definition: transform.h:86
@ CTX_CURSOR
Definition: transform.h:80
@ CTX_OBMODE_XFORM_OBDATA
Definition: transform.h:94
@ CTX_POSE_BONE
Definition: transform.h:87
@ CTX_OBMODE_XFORM_SKIP_CHILDREN
Definition: transform.h:96
@ CTX_OBJECT
Definition: transform.h:85
@ CTX_EDGE_DATA
Definition: transform.h:81
@ CTX_GPENCIL_STROKES
Definition: transform.h:82
@ CTX_MASK
Definition: transform.h:83
@ CTX_TEXTURE_SPACE
Definition: transform.h:88
@ CTX_NO_MIRROR
Definition: transform.h:91
@ CTX_NO_PET
Definition: transform.h:90
@ CTX_CAMERA
Definition: transform.h:79
struct Object * transform_object_deform_pose_armature_get(const TransInfo *t, struct Object *ob)
eTFlag
Definition: transform.h:100
@ T_OVERRIDE_CENTER
Definition: transform.h:143
@ T_PROP_EDIT_ALL
Definition: transform.h:114
@ T_MODAL
Definition: transform.h:132
@ T_PROP_CONNECTED
Definition: transform.h:112
@ T_NO_MIRROR
Definition: transform.h:125
@ T_PROP_EDIT
Definition: transform.h:111
@ T_2D_EDIT
Definition: transform.h:118
@ T_POINTS
Definition: transform.h:104
@ T_EDIT
Definition: transform.h:102
@ T_PROP_PROJECTED
Definition: transform.h:113
@ TRANS_CANCEL
Definition: transform.h:193
#define FOREACH_TRANS_DATA_CONTAINER(t, th)
Definition: transform.h:813
eTConvertType
Definition: transform.h:214
@ TC_NONE
Definition: transform.h:215
@ TC_PARTICLE_VERTS
Definition: transform.h:236
@ TC_ACTION_DATA
Definition: transform.h:216
@ TC_GRAPH_EDIT_DATA
Definition: transform.h:222
@ TC_POSE
Definition: transform.h:217
@ TC_LATTICE_VERTS
Definition: transform.h:224
@ TC_MASKING_DATA
Definition: transform.h:225
@ TC_CURSOR_IMAGE
Definition: transform.h:219
@ TC_CURVE_VERTS
Definition: transform.h:221
@ TC_PAINT_CURVE_VERTS
Definition: transform.h:235
@ TC_CURSOR_VIEW3D
Definition: transform.h:220
@ TC_MBALL_VERTS
Definition: transform.h:226
@ TC_MESH_EDGES
Definition: transform.h:228
@ TC_NLA_DATA
Definition: transform.h:231
@ TC_MESH_VERTS
Definition: transform.h:227
@ TC_OBJECT_TEXSPACE
Definition: transform.h:234
@ TC_SCULPT
Definition: transform.h:237
@ TC_NODE_DATA
Definition: transform.h:232
@ TC_MESH_SKIN
Definition: transform.h:229
@ TC_TRACKING_DATA
Definition: transform.h:239
@ TC_MESH_UV
Definition: transform.h:230
@ TC_SEQ_DATA
Definition: transform.h:238
@ TC_GPENCIL
Definition: transform.h:223
@ TC_OBJECT
Definition: transform.h:233
@ TC_ARMATURE_VERTS
Definition: transform.h:218
void calc_distanceCurveVerts(TransData *head, TransData *tail, bool cyclic)
void transform_autoik_update(TransInfo *t, short mode)
static eTFlag flags_from_data_type(eTConvertType data_type)
void special_aftertrans_update(bContext *C, TransInfo *t)
static eTConvertType convert_type_get(const TransInfo *t, Object **r_obj_armature)
void recalcData(TransInfo *t)
void animrecord_check_state(TransInfo *t, struct Object *ob)
void sort_trans_data_dist(TransInfo *t)
bool FrameOnMouseSide(char side, float frame, float cframe)
void transform_around_single_fallback(TransInfo *t)
static void sort_trans_data_dist_container(const TransInfo *t, TransDataContainer *tc)
static bool pchan_autoik_adjust(bPoseChannel *pchan, short chainlen)
void clipUVData(TransInfo *t)
static void init_proportional_edit(TransInfo *t)
static int countAndCleanTransDataContainer(TransInfo *t)
struct tRetainedKeyframe tRetainedKeyframe
static void recalcData_obedit(TransInfo *t)
bool clipUVTransform(TransInfo *t, float vec[2], const bool resize)
static void recalcData_cursor_image(TransInfo *t)
void transform_around_single_fallback_ex(TransInfo *t, int data_len_all)
static void init_TransDataContainers(TransInfo *t, Object *obact, Object **objects, uint objects_len)
static void sort_trans_data_selected_first(TransInfo *t)
void createTransData(bContext *C, TransInfo *t)
bool transform_mode_use_local_origins(const TransInfo *t)
int special_transform_moving(TransInfo *t)
bool constraints_list_needinv(TransInfo *t, ListBase *list)
void posttrans_fcurve_clean(FCurve *fcu, const int sel_flag, const bool use_handle)
void clipMirrorModifier(TransInfo *t)
static void sort_trans_data_selected_first_container(TransDataContainer *tc)
TransDataCurveHandleFlags * initTransDataCurveHandles(TransData *td, struct BezTriple *bezt)
static int trans_data_compare_rdist(const void *a, const void *b)
static void set_prop_dist(TransInfo *t, const bool with_dist)
char transform_convert_frame_side_dir_get(TransInfo *t, float cframe)
static int trans_data_compare_dist(const void *a, const void *b)
static void recalcData_cursor(TransInfo *t)
conversion and adaptation of different datablocks to a common struct.
void createTransSculpt(bContext *C, TransInfo *t)
void special_aftertrans_update__mesh(bContext *C, TransInfo *t)
void flushTransPaintCurve(TransInfo *t)
void recalcData_mesh_skin(TransInfo *t)
void recalcData_graphedit(TransInfo *t)
void special_aftertrans_update__pose(bContext *C, TransInfo *t)
void recalcData_pose(TransInfo *t)
void createTransCursor_image(TransInfo *t)
void special_aftertrans_update__movieclip(bContext *C, TransInfo *t)
void recalcData_particles(TransInfo *t)
void createTransSeqData(TransInfo *t)
void createTransNodeData(TransInfo *t)
void special_aftertrans_update__sequencer(bContext *C, TransInfo *t)
void recalcData_sculpt(TransInfo *t)
void special_aftertrans_update__object(bContext *C, TransInfo *t)
void recalcData_lattice(TransInfo *t)
void recalcData_nla(TransInfo *t)
void createTransPaintCurveVerts(bContext *C, TransInfo *t)
void special_aftertrans_update__sculpt(bContext *C, TransInfo *t)
void special_aftertrans_update__nla(bContext *C, TransInfo *t)
void createTransMaskingData(bContext *C, TransInfo *t)
void createTransCurveVerts(TransInfo *t)
void createTransActionData(bContext *C, TransInfo *t)
void flushTransNodes(TransInfo *t)
void createTransPose(TransInfo *t)
void recalcData_gpencil_strokes(TransInfo *t)
void recalcData_actedit(TransInfo *t)
void recalcData_mesh(TransInfo *t)
void createTransEdge(TransInfo *t)
void createTransCursor_view3d(TransInfo *t)
void special_aftertrans_update__graph(bContext *C, TransInfo *t)
void recalcData_edit_armature(TransInfo *t)
void createTransParticleVerts(TransInfo *t)
void recalcData_objects(TransInfo *t)
void recalcData_tracking(TransInfo *t)
void createTransGraphEditData(bContext *C, TransInfo *t)
void createTransArmatureVerts(TransInfo *t)
void createTransLatticeVerts(TransInfo *t)
void createTransObject(bContext *C, TransInfo *t)
void createTransMBallVerts(TransInfo *t)
void recalcData_texspace(TransInfo *t)
void special_aftertrans_update__mask(bContext *C, TransInfo *t)
void special_aftertrans_update__node(bContext *C, TransInfo *t)
void recalcData_sequencer(TransInfo *t)
void createTransMeshSkin(TransInfo *t)
void createTransEditVerts(TransInfo *t)
void recalcData_uv(TransInfo *t)
void createTransNlaData(bContext *C, TransInfo *t)
void recalcData_mask_common(TransInfo *t)
void createTransGPencil(bContext *C, TransInfo *t)
void createTransTexspace(TransInfo *t)
void createTransTrackingData(bContext *C, TransInfo *t)
void recalcData_curve(TransInfo *t)
void special_aftertrans_update__actedit(bContext *C, TransInfo *t)
void createTransUVs(bContext *C, TransInfo *t)
@ TD_BEZTRIPLE
@ TD_NOTCONNECTED
@ TD_SELECTED
@ TD_SKIP
float max
void applyProject(TransInfo *t)
#define G(x, y, z)