Fix T68723: GPencil - Split Select mode for Sculpt and Edit mode
[blender.git] / source / blender / editors / transform / transform_generics.c
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
20 /** \file
21  * \ingroup edtransform
22  */
23
24 #include <string.h>
25 #include <math.h>
26
27 #include "MEM_guardedalloc.h"
28
29 #include "BLI_sys_types.h" /* for intptr_t support */
30
31 #include "DNA_anim_types.h"
32 #include "DNA_armature_types.h"
33 #include "DNA_brush_types.h"
34 #include "DNA_gpencil_types.h"
35 #include "DNA_lattice_types.h"
36 #include "DNA_screen_types.h"
37 #include "DNA_sequence_types.h"
38 #include "DNA_space_types.h"
39 #include "DNA_scene_types.h"
40 #include "DNA_object_types.h"
41 #include "DNA_mesh_types.h"
42 #include "DNA_view3d_types.h"
43 #include "DNA_modifier_types.h"
44 #include "DNA_movieclip_types.h"
45 #include "DNA_mask_types.h"
46 #include "DNA_meta_types.h"
47
48 #include "BLI_math.h"
49 #include "BLI_blenlib.h"
50 #include "BLI_rand.h"
51 #include "BLI_utildefines.h"
52
53 #include "PIL_time.h"
54
55 #include "BLT_translation.h"
56
57 #include "RNA_access.h"
58
59 #include "GPU_immediate.h"
60 #include "GPU_matrix.h"
61
62 #include "BIK_api.h"
63
64 #include "BKE_action.h"
65 #include "BKE_animsys.h"
66 #include "BKE_armature.h"
67 #include "BKE_context.h"
68 #include "BKE_curve.h"
69 #include "BKE_editmesh.h"
70 #include "BKE_fcurve.h"
71 #include "BKE_gpencil.h"
72 #include "BKE_lattice.h"
73 #include "BKE_layer.h"
74 #include "BKE_library.h"
75 #include "BKE_mask.h"
76 #include "BKE_nla.h"
77 #include "BKE_paint.h"
78 #include "BKE_scene.h"
79 #include "BKE_sequencer.h"
80 #include "BKE_tracking.h"
81 #include "BKE_workspace.h"
82
83 #include "DEG_depsgraph.h"
84
85 #include "ED_anim_api.h"
86 #include "ED_armature.h"
87 #include "ED_image.h"
88 #include "ED_keyframing.h"
89 #include "ED_markers.h"
90 #include "ED_mesh.h"
91 #include "ED_object.h"
92 #include "ED_particle.h"
93 #include "ED_screen_types.h"
94 #include "ED_space_api.h"
95 #include "ED_uvedit.h"
96 #include "ED_view3d.h"
97 #include "ED_curve.h" /* for curve_editnurbs */
98 #include "ED_clip.h"
99 #include "ED_screen.h"
100 #include "ED_gpencil.h"
101
102 #include "WM_types.h"
103 #include "WM_api.h"
104
105 #include "RE_engine.h"
106
107 #include "UI_resources.h"
108 #include "UI_view2d.h"
109
110 #include "transform.h"
111
112 /* ************************** Functions *************************** */
113
114 void getViewVector(const TransInfo *t, const float coord[3], float vec[3])
115 {
116   if (t->persp != RV3D_ORTHO) {
117     sub_v3_v3v3(vec, coord, t->viewinv[3]);
118   }
119   else {
120     copy_v3_v3(vec, t->viewinv[2]);
121   }
122   normalize_v3(vec);
123 }
124
125 /* ************************** GENERICS **************************** */
126
127 static void clipMirrorModifier(TransInfo *t)
128 {
129   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
130     Object *ob = tc->obedit;
131     ModifierData *md = ob->modifiers.first;
132     float tolerance[3] = {0.0f, 0.0f, 0.0f};
133     int axis = 0;
134
135     for (; md; md = md->next) {
136       if ((md->type == eModifierType_Mirror) && (md->mode & eModifierMode_Realtime)) {
137         MirrorModifierData *mmd = (MirrorModifierData *)md;
138
139         if (mmd->flag & MOD_MIR_CLIPPING) {
140           axis = 0;
141           if (mmd->flag & MOD_MIR_AXIS_X) {
142             axis |= 1;
143             tolerance[0] = mmd->tolerance;
144           }
145           if (mmd->flag & MOD_MIR_AXIS_Y) {
146             axis |= 2;
147             tolerance[1] = mmd->tolerance;
148           }
149           if (mmd->flag & MOD_MIR_AXIS_Z) {
150             axis |= 4;
151             tolerance[2] = mmd->tolerance;
152           }
153           if (axis) {
154             float mtx[4][4], imtx[4][4];
155             int i;
156
157             if (mmd->mirror_ob) {
158               float obinv[4][4];
159
160               invert_m4_m4(obinv, mmd->mirror_ob->obmat);
161               mul_m4_m4m4(mtx, obinv, ob->obmat);
162               invert_m4_m4(imtx, mtx);
163             }
164
165             TransData *td = tc->data;
166             for (i = 0; i < tc->data_len; i++, td++) {
167               int clip;
168               float loc[3], iloc[3];
169
170               if (td->flag & TD_NOACTION) {
171                 break;
172               }
173               if (td->loc == NULL) {
174                 break;
175               }
176
177               if (td->flag & TD_SKIP) {
178                 continue;
179               }
180
181               copy_v3_v3(loc, td->loc);
182               copy_v3_v3(iloc, td->iloc);
183
184               if (mmd->mirror_ob) {
185                 mul_m4_v3(mtx, loc);
186                 mul_m4_v3(mtx, iloc);
187               }
188
189               clip = 0;
190               if (axis & 1) {
191                 if (fabsf(iloc[0]) <= tolerance[0] || loc[0] * iloc[0] < 0.0f) {
192                   loc[0] = 0.0f;
193                   clip = 1;
194                 }
195               }
196
197               if (axis & 2) {
198                 if (fabsf(iloc[1]) <= tolerance[1] || loc[1] * iloc[1] < 0.0f) {
199                   loc[1] = 0.0f;
200                   clip = 1;
201                 }
202               }
203               if (axis & 4) {
204                 if (fabsf(iloc[2]) <= tolerance[2] || loc[2] * iloc[2] < 0.0f) {
205                   loc[2] = 0.0f;
206                   clip = 1;
207                 }
208               }
209               if (clip) {
210                 if (mmd->mirror_ob) {
211                   mul_m4_v3(imtx, loc);
212                 }
213                 copy_v3_v3(td->loc, loc);
214               }
215             }
216           }
217         }
218       }
219     }
220   }
221 }
222
223 /* assumes obedit set to mesh object */
224 static void editbmesh_apply_to_mirror(TransInfo *t)
225 {
226   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
227     if (tc->mirror.axis_flag) {
228       TransData *td = tc->data;
229       BMVert *eve;
230       int i;
231
232       for (i = 0; i < tc->data_len; i++, td++) {
233         if (td->flag & TD_NOACTION) {
234           break;
235         }
236         if (td->loc == NULL) {
237           break;
238         }
239         if (td->flag & TD_SKIP) {
240           continue;
241         }
242
243         eve = td->extra;
244         if (eve) {
245           eve->co[0] = -td->loc[0];
246           eve->co[1] = td->loc[1];
247           eve->co[2] = td->loc[2];
248         }
249
250         if (td->flag & TD_MIRROR_EDGE) {
251           td->loc[0] = 0;
252         }
253       }
254     }
255   }
256 }
257
258 /* for the realtime animation recording feature, handle overlapping data */
259 static void animrecord_check_state(Scene *scene, ID *id, wmTimer *animtimer)
260 {
261   ScreenAnimData *sad = (animtimer) ? animtimer->customdata : NULL;
262
263   /* sanity checks */
264   if (ELEM(NULL, scene, id, sad)) {
265     return;
266   }
267
268   /* check if we need a new strip if:
269    * - if animtimer is running
270    * - we're not only keying for available channels
271    * - the option to add new actions for each round is not enabled
272    */
273   if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL) == 0 &&
274       (scene->toolsettings->autokey_flag & ANIMRECORD_FLAG_WITHNLA)) {
275     /* if playback has just looped around,
276      * we need to add a new NLA track+strip to allow a clean pass to occur */
277     if ((sad) && (sad->flag & ANIMPLAY_FLAG_JUMPED)) {
278       AnimData *adt = BKE_animdata_from_id(id);
279       const bool is_first = (adt) && (adt->nla_tracks.first == NULL);
280
281       /* perform push-down manually with some differences
282        * NOTE: BKE_nla_action_pushdown() sync warning...
283        */
284       if ((adt->action) && !(adt->flag & ADT_NLA_EDIT_ON)) {
285         float astart, aend;
286
287         /* only push down if action is more than 1-2 frames long */
288         calc_action_range(adt->action, &astart, &aend, 1);
289         if (aend > astart + 2.0f) {
290           NlaStrip *strip = BKE_nlastack_add_strip(adt, adt->action);
291
292           /* clear reference to action now that we've pushed it onto the stack */
293           id_us_min(&adt->action->id);
294           adt->action = NULL;
295
296           /* adjust blending + extend so that they will behave correctly */
297           strip->extendmode = NLASTRIP_EXTEND_NOTHING;
298           strip->flag &= ~(NLASTRIP_FLAG_AUTO_BLENDS | NLASTRIP_FLAG_SELECT |
299                            NLASTRIP_FLAG_ACTIVE);
300
301           /* copy current "action blending" settings from adt to the strip,
302            * as it was keyframed with these settings, so omitting them will
303            * change the effect  [T54766]
304            */
305           if (is_first == false) {
306             strip->blendmode = adt->act_blendmode;
307             strip->influence = adt->act_influence;
308
309             if (adt->act_influence < 1.0f) {
310               /* enable "user-controlled" influence (which will insert a default keyframe)
311                * so that the influence doesn't get lost on the new update
312                *
313                * NOTE: An alternative way would have been to instead hack the influence
314                * to not get always get reset to full strength if NLASTRIP_FLAG_USR_INFLUENCE
315                * is disabled but auto-blending isn't being used. However, that approach
316                * is a bit hacky/hard to discover, and may cause backwards compatibility issues,
317                * so it's better to just do it this way.
318                */
319               strip->flag |= NLASTRIP_FLAG_USR_INFLUENCE;
320               BKE_nlastrip_validate_fcurves(strip);
321             }
322           }
323
324           /* also, adjust the AnimData's action extend mode to be on
325            * 'nothing' so that previous result still play
326            */
327           adt->act_extendmode = NLASTRIP_EXTEND_NOTHING;
328         }
329       }
330     }
331   }
332 }
333
334 static bool fcu_test_selected(FCurve *fcu)
335 {
336   BezTriple *bezt = fcu->bezt;
337   unsigned int i;
338
339   if (bezt == NULL) { /* ignore baked */
340     return 0;
341   }
342
343   for (i = 0; i < fcu->totvert; i++, bezt++) {
344     if (BEZT_ISSEL_ANY(bezt)) {
345       return 1;
346     }
347   }
348
349   return 0;
350 }
351
352 /* helper for recalcData() - for Action Editor transforms */
353 static void recalcData_actedit(TransInfo *t)
354 {
355   ViewLayer *view_layer = t->view_layer;
356   SpaceAction *saction = (SpaceAction *)t->sa->spacedata.first;
357
358   bAnimContext ac = {NULL};
359   ListBase anim_data = {NULL, NULL};
360   bAnimListElem *ale;
361   int filter;
362
363   /* initialize relevant anim-context 'context' data from TransInfo data */
364   /* NOTE: sync this with the code in ANIM_animdata_get_context() */
365   ac.bmain = CTX_data_main(t->context);
366   ac.scene = t->scene;
367   ac.view_layer = t->view_layer;
368   ac.obact = OBACT(view_layer);
369   ac.sa = t->sa;
370   ac.ar = t->ar;
371   ac.sl = (t->sa) ? t->sa->spacedata.first : NULL;
372   ac.spacetype = (t->sa) ? t->sa->spacetype : 0;
373   ac.regiontype = (t->ar) ? t->ar->regiontype : 0;
374
375   ANIM_animdata_context_getdata(&ac);
376
377   /* perform flush */
378   if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
379     /* flush transform values back to actual coordinates */
380     flushTransIntFrameActionData(t);
381   }
382
383   if (ac.datatype != ANIMCONT_MASK) {
384     /* Get animdata blocks visible in editor,
385      * assuming that these will be the ones where things changed. */
386     filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ANIMDATA);
387     ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
388
389     /* just tag these animdata-blocks to recalc, assuming that some data there changed
390      * BUT only do this if realtime updates are enabled
391      */
392     if ((saction->flag & SACTION_NOREALTIMEUPDATES) == 0) {
393       for (ale = anim_data.first; ale; ale = ale->next) {
394         /* set refresh tags for objects using this animation */
395         ANIM_list_elem_update(CTX_data_main(t->context), t->scene, ale);
396       }
397     }
398
399     /* now free temp channels */
400     ANIM_animdata_freelist(&anim_data);
401   }
402 }
403 /* helper for recalcData() - for Graph Editor transforms */
404 static void recalcData_graphedit(TransInfo *t)
405 {
406   SpaceGraph *sipo = (SpaceGraph *)t->sa->spacedata.first;
407   ViewLayer *view_layer = t->view_layer;
408
409   ListBase anim_data = {NULL, NULL};
410   bAnimContext ac = {NULL};
411   int filter;
412
413   bAnimListElem *ale;
414   int dosort = 0;
415
416   /* initialize relevant anim-context 'context' data from TransInfo data */
417   /* NOTE: sync this with the code in ANIM_animdata_get_context() */
418   ac.bmain = CTX_data_main(t->context);
419   ac.scene = t->scene;
420   ac.view_layer = t->view_layer;
421   ac.obact = OBACT(view_layer);
422   ac.sa = t->sa;
423   ac.ar = t->ar;
424   ac.sl = (t->sa) ? t->sa->spacedata.first : NULL;
425   ac.spacetype = (t->sa) ? t->sa->spacetype : 0;
426   ac.regiontype = (t->ar) ? t->ar->regiontype : 0;
427
428   ANIM_animdata_context_getdata(&ac);
429
430   /* do the flush first */
431   flushTransGraphData(t);
432
433   /* get curves to check if a re-sort is needed */
434   filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE);
435   ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
436
437   /* now test if there is a need to re-sort */
438   for (ale = anim_data.first; ale; ale = ale->next) {
439     FCurve *fcu = (FCurve *)ale->key_data;
440
441     /* ignore FC-Curves without any selected verts */
442     if (!fcu_test_selected(fcu)) {
443       continue;
444     }
445
446     /* watch it: if the time is wrong: do not correct handles yet */
447     if (test_time_fcurve(fcu)) {
448       dosort++;
449     }
450     else {
451       calchandles_fcurve(fcu);
452     }
453
454     /* set refresh tags for objects using this animation,
455      * BUT only if realtime updates are enabled
456      */
457     if ((sipo->flag & SIPO_NOREALTIMEUPDATES) == 0) {
458       ANIM_list_elem_update(CTX_data_main(t->context), t->scene, ale);
459     }
460   }
461
462   /* do resort and other updates? */
463   if (dosort) {
464     remake_graph_transdata(t, &anim_data);
465   }
466
467   /* now free temp channels */
468   ANIM_animdata_freelist(&anim_data);
469 }
470
471 /* helper for recalcData() - for NLA Editor transforms */
472 static void recalcData_nla(TransInfo *t)
473 {
474   SpaceNla *snla = (SpaceNla *)t->sa->spacedata.first;
475   Scene *scene = t->scene;
476   double secf = FPS;
477   int i;
478
479   TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
480   TransDataNla *tdn = tc->custom.type.data;
481
482   /* For each strip we've got, perform some additional validation of the values
483    * that got set before using RNA to set the value (which does some special
484    * operations when setting these values to make sure that everything works ok).
485    */
486   for (i = 0; i < tc->data_len; i++, tdn++) {
487     NlaStrip *strip = tdn->strip;
488     PointerRNA strip_ptr;
489     short pExceeded, nExceeded, iter;
490     int delta_y1, delta_y2;
491
492     /* if this tdn has no handles, that means it is just a dummy that should be skipped */
493     if (tdn->handle == 0) {
494       continue;
495     }
496
497     /* set refresh tags for objects using this animation,
498      * BUT only if realtime updates are enabled
499      */
500     if ((snla->flag & SNLA_NOREALTIMEUPDATES) == 0) {
501       ANIM_id_update(CTX_data_main(t->context), tdn->id);
502     }
503
504     /* if canceling transform, just write the values without validating, then move on */
505     if (t->state == TRANS_CANCEL) {
506       /* clear the values by directly overwriting the originals, but also need to restore
507        * endpoints of neighboring transition-strips
508        */
509
510       /* start */
511       strip->start = tdn->h1[0];
512
513       if ((strip->prev) && (strip->prev->type == NLASTRIP_TYPE_TRANSITION)) {
514         strip->prev->end = tdn->h1[0];
515       }
516
517       /* end */
518       strip->end = tdn->h2[0];
519
520       if ((strip->next) && (strip->next->type == NLASTRIP_TYPE_TRANSITION)) {
521         strip->next->start = tdn->h2[0];
522       }
523
524       /* flush transforms to child strips (since this should be a meta) */
525       BKE_nlameta_flush_transforms(strip);
526
527       /* restore to original track (if needed) */
528       if (tdn->oldTrack != tdn->nlt) {
529         /* Just append to end of list for now,
530          * since strips get sorted in special_aftertrans_update(). */
531         BLI_remlink(&tdn->nlt->strips, strip);
532         BLI_addtail(&tdn->oldTrack->strips, strip);
533       }
534
535       continue;
536     }
537
538     /* firstly, check if the proposed transform locations would overlap with any neighboring strips
539      * (barring transitions) which are absolute barriers since they are not being moved
540      *
541      * this is done as a iterative procedure (done 5 times max for now)
542      */
543     for (iter = 0; iter < 5; iter++) {
544       pExceeded = ((strip->prev) && (strip->prev->type != NLASTRIP_TYPE_TRANSITION) &&
545                    (tdn->h1[0] < strip->prev->end));
546       nExceeded = ((strip->next) && (strip->next->type != NLASTRIP_TYPE_TRANSITION) &&
547                    (tdn->h2[0] > strip->next->start));
548
549       if ((pExceeded && nExceeded) || (iter == 4)) {
550         /* both endpoints exceeded (or iteration ping-pong'd meaning that we need a compromise)
551          * - Simply crop strip to fit within the bounds of the strips bounding it
552          * - If there were no neighbors, clear the transforms
553          *   (make it default to the strip's current values).
554          */
555         if (strip->prev && strip->next) {
556           tdn->h1[0] = strip->prev->end;
557           tdn->h2[0] = strip->next->start;
558         }
559         else {
560           tdn->h1[0] = strip->start;
561           tdn->h2[0] = strip->end;
562         }
563       }
564       else if (nExceeded) {
565         /* move backwards */
566         float offset = tdn->h2[0] - strip->next->start;
567
568         tdn->h1[0] -= offset;
569         tdn->h2[0] -= offset;
570       }
571       else if (pExceeded) {
572         /* more forwards */
573         float offset = strip->prev->end - tdn->h1[0];
574
575         tdn->h1[0] += offset;
576         tdn->h2[0] += offset;
577       }
578       else { /* all is fine and well */
579         break;
580       }
581     }
582
583     /* handle auto-snapping
584      * NOTE: only do this when transform is still running, or we can't restore
585      */
586     if (t->state != TRANS_CANCEL) {
587       switch (snla->autosnap) {
588         case SACTSNAP_FRAME: /* snap to nearest frame */
589         case SACTSNAP_STEP:  /* frame step - this is basically the same,
590                               * since we don't have any remapping going on */
591         {
592           tdn->h1[0] = floorf(tdn->h1[0] + 0.5f);
593           tdn->h2[0] = floorf(tdn->h2[0] + 0.5f);
594           break;
595         }
596
597         case SACTSNAP_SECOND: /* snap to nearest second */
598         case SACTSNAP_TSTEP:  /* second step - this is basically the same,
599                                * since we don't have any remapping going on */
600         {
601           /* This case behaves differently from the rest, since lengths of strips
602            * may not be multiples of a second. If we just naively resize adjust
603            * the handles, things may not work correctly. Instead, we only snap
604            * the first handle, and move the other to fit.
605            *
606            * FIXME: we do run into problems here when user attempts to negatively
607            *        scale the strip, as it then just compresses down and refuses
608            *        to expand out the other end.
609            */
610           float h1_new = (float)(floor(((double)tdn->h1[0] / secf) + 0.5) * secf);
611           float delta = h1_new - tdn->h1[0];
612
613           tdn->h1[0] = h1_new;
614           tdn->h2[0] += delta;
615           break;
616         }
617
618         case SACTSNAP_MARKER: /* snap to nearest marker */
619         {
620           tdn->h1[0] = (float)ED_markers_find_nearest_marker_time(&t->scene->markers, tdn->h1[0]);
621           tdn->h2[0] = (float)ED_markers_find_nearest_marker_time(&t->scene->markers, tdn->h2[0]);
622           break;
623         }
624       }
625     }
626
627     /* Use RNA to write the values to ensure that constraints on these are obeyed
628      * (e.g. for transition strips, the values are taken from the neighbors)
629      *
630      * NOTE: we write these twice to avoid truncation errors which can arise when
631      * moving the strips a large distance using numeric input [#33852]
632      */
633     RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
634
635     RNA_float_set(&strip_ptr, "frame_start", tdn->h1[0]);
636     RNA_float_set(&strip_ptr, "frame_end", tdn->h2[0]);
637
638     RNA_float_set(&strip_ptr, "frame_start", tdn->h1[0]);
639     RNA_float_set(&strip_ptr, "frame_end", tdn->h2[0]);
640
641     /* flush transforms to child strips (since this should be a meta) */
642     BKE_nlameta_flush_transforms(strip);
643
644     /* Now, check if we need to try and move track:
645      * - we need to calculate both,
646      *   as only one may have been altered by transform if only 1 handle moved.
647      */
648     delta_y1 = ((int)tdn->h1[1] / NLACHANNEL_STEP(snla) - tdn->trackIndex);
649     delta_y2 = ((int)tdn->h2[1] / NLACHANNEL_STEP(snla) - tdn->trackIndex);
650
651     if (delta_y1 || delta_y2) {
652       NlaTrack *track;
653       int delta = (delta_y2) ? delta_y2 : delta_y1;
654       int n;
655
656       /* Move in the requested direction,
657        * checking at each layer if there's space for strip to pass through,
658        * stopping on the last track available or that we're able to fit in.
659        */
660       if (delta > 0) {
661         for (track = tdn->nlt->next, n = 0; (track) && (n < delta); track = track->next, n++) {
662           /* check if space in this track for the strip */
663           if (BKE_nlatrack_has_space(track, strip->start, strip->end)) {
664             /* move strip to this track */
665             BLI_remlink(&tdn->nlt->strips, strip);
666             BKE_nlatrack_add_strip(track, strip);
667
668             tdn->nlt = track;
669             tdn->trackIndex++;
670           }
671           else { /* can't move any further */
672             break;
673           }
674         }
675       }
676       else {
677         /* make delta 'positive' before using it, since we now know to go backwards */
678         delta = -delta;
679
680         for (track = tdn->nlt->prev, n = 0; (track) && (n < delta); track = track->prev, n++) {
681           /* check if space in this track for the strip */
682           if (BKE_nlatrack_has_space(track, strip->start, strip->end)) {
683             /* move strip to this track */
684             BLI_remlink(&tdn->nlt->strips, strip);
685             BKE_nlatrack_add_strip(track, strip);
686
687             tdn->nlt = track;
688             tdn->trackIndex--;
689           }
690           else { /* can't move any further */
691             break;
692           }
693         }
694       }
695     }
696   }
697 }
698
699 static void recalcData_mask_common(TransInfo *t)
700 {
701   Mask *mask = CTX_data_edit_mask(t->context);
702
703   flushTransMasking(t);
704
705   DEG_id_tag_update(&mask->id, 0);
706 }
707
708 /* helper for recalcData() - for Image Editor transforms */
709 static void recalcData_image(TransInfo *t)
710 {
711   if (t->options & CTX_MASK) {
712     recalcData_mask_common(t);
713   }
714   else if (t->options & CTX_PAINT_CURVE) {
715     flushTransPaintCurve(t);
716   }
717   else if ((t->flag & T_EDIT) && t->obedit_type == OB_MESH) {
718     SpaceImage *sima = t->sa->spacedata.first;
719
720     flushTransUVs(t);
721     if (sima->flag & SI_LIVE_UNWRAP) {
722       ED_uvedit_live_unwrap_re_solve();
723     }
724
725     FOREACH_TRANS_DATA_CONTAINER (t, tc) {
726       if (tc->data_len) {
727         DEG_id_tag_update(tc->obedit->data, 0);
728       }
729     }
730   }
731 }
732
733 /* helper for recalcData() - for Movie Clip transforms */
734 static void recalcData_spaceclip(TransInfo *t)
735 {
736   SpaceClip *sc = t->sa->spacedata.first;
737
738   if (ED_space_clip_check_show_trackedit(sc)) {
739     MovieClip *clip = ED_space_clip_get_clip(sc);
740     ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
741     MovieTrackingTrack *track;
742     int framenr = ED_space_clip_get_clip_frame_number(sc);
743
744     flushTransTracking(t);
745
746     track = tracksbase->first;
747     while (track) {
748       if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
749         MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
750
751         if (t->mode == TFM_TRANSLATION) {
752           if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) {
753             BKE_tracking_marker_clamp(marker, CLAMP_PAT_POS);
754           }
755           if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) {
756             BKE_tracking_marker_clamp(marker, CLAMP_SEARCH_POS);
757           }
758         }
759         else if (t->mode == TFM_RESIZE) {
760           if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) {
761             BKE_tracking_marker_clamp(marker, CLAMP_PAT_DIM);
762           }
763           if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) {
764             BKE_tracking_marker_clamp(marker, CLAMP_SEARCH_DIM);
765           }
766         }
767         else if (t->mode == TFM_ROTATION) {
768           if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) {
769             BKE_tracking_marker_clamp(marker, CLAMP_PAT_POS);
770           }
771         }
772       }
773
774       track = track->next;
775     }
776
777     DEG_id_tag_update(&clip->id, 0);
778   }
779   else if (t->options & CTX_MASK) {
780     recalcData_mask_common(t);
781   }
782 }
783
784 /**
785  * if pose bone (partial) selected, copy data.
786  * context; posemode armature, with mirror editing enabled.
787  *
788  * \param pid: Optional, apply relative transform when set.
789  */
790 static void pose_transform_mirror_update(Object *ob, PoseInitData_Mirror *pid)
791 {
792   float flip_mtx[4][4];
793   unit_m4(flip_mtx);
794   flip_mtx[0][0] = -1;
795
796   for (bPoseChannel *pchan_orig = ob->pose->chanbase.first; pchan_orig;
797        pchan_orig = pchan_orig->next) {
798     /* no layer check, correct mirror is more important */
799     if (pchan_orig->bone->flag & BONE_TRANSFORM) {
800       bPoseChannel *pchan = BKE_pose_channel_get_mirrored(ob->pose, pchan_orig->name);
801
802       if (pchan) {
803         /* also do bbone scaling */
804         pchan->bone->xwidth = pchan_orig->bone->xwidth;
805         pchan->bone->zwidth = pchan_orig->bone->zwidth;
806
807         /* we assume X-axis flipping for now */
808         pchan->curve_in_x = pchan_orig->curve_in_x * -1;
809         pchan->curve_out_x = pchan_orig->curve_out_x * -1;
810         pchan->roll1 = pchan_orig->roll1 * -1;  // XXX?
811         pchan->roll2 = pchan_orig->roll2 * -1;  // XXX?
812
813         float pchan_mtx_final[4][4];
814         BKE_pchan_to_mat4(pchan_orig, pchan_mtx_final);
815         mul_m4_m4m4(pchan_mtx_final, pchan_mtx_final, flip_mtx);
816         mul_m4_m4m4(pchan_mtx_final, flip_mtx, pchan_mtx_final);
817         if (pid) {
818           mul_m4_m4m4(pchan_mtx_final, pid->offset_mtx, pchan_mtx_final);
819           pid++;
820         }
821         BKE_pchan_apply_mat4(pchan, pchan_mtx_final, false);
822
823         /* set flag to let autokeyframe know to keyframe the mirrred bone */
824         pchan->bone->flag |= BONE_TRANSFORM_MIRROR;
825       }
826     }
827   }
828 }
829
830 /* helper for recalcData() - for object transforms, typically in the 3D view */
831 static void recalcData_objects(TransInfo *t)
832 {
833   Base *base = t->view_layer->basact;
834
835   if (t->obedit_type != -1) {
836     if (ELEM(t->obedit_type, OB_CURVE, OB_SURF)) {
837
838       if (t->state != TRANS_CANCEL) {
839         clipMirrorModifier(t);
840         applyProject(t);
841       }
842
843       FOREACH_TRANS_DATA_CONTAINER (t, tc) {
844         Curve *cu = tc->obedit->data;
845         ListBase *nurbs = BKE_curve_editNurbs_get(cu);
846         Nurb *nu = nurbs->first;
847
848         DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
849
850         if (t->state == TRANS_CANCEL) {
851           while (nu) {
852             /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */
853             BKE_nurb_handles_calc(nu);
854             nu = nu->next;
855           }
856         }
857         else {
858           /* Normal updating */
859           while (nu) {
860             BKE_nurb_test_2d(nu);
861             BKE_nurb_handles_calc(nu);
862             nu = nu->next;
863           }
864         }
865       }
866     }
867     else if (t->obedit_type == OB_LATTICE) {
868
869       if (t->state != TRANS_CANCEL) {
870         applyProject(t);
871       }
872
873       FOREACH_TRANS_DATA_CONTAINER (t, tc) {
874         Lattice *la = tc->obedit->data;
875         DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
876         if (la->editlatt->latt->flag & LT_OUTSIDE) {
877           outside_lattice(la->editlatt->latt);
878         }
879       }
880     }
881     else if (t->obedit_type == OB_MESH) {
882       /* mirror modifier clipping? */
883       if (t->state != TRANS_CANCEL) {
884         /* apply clipping after so we never project past the clip plane [#25423] */
885         applyProject(t);
886         clipMirrorModifier(t);
887       }
888       if ((t->flag & T_NO_MIRROR) == 0 && (t->options & CTX_NO_MIRROR) == 0) {
889         editbmesh_apply_to_mirror(t);
890       }
891
892       if (t->mode == TFM_EDGE_SLIDE) {
893         projectEdgeSlideData(t, false);
894       }
895       else if (t->mode == TFM_VERT_SLIDE) {
896         projectVertSlideData(t, false);
897       }
898
899       FOREACH_TRANS_DATA_CONTAINER (t, tc) {
900         DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
901         BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
902         EDBM_mesh_normals_update(em);
903         BKE_editmesh_tessface_calc(em);
904       }
905     }
906     else if (t->obedit_type == OB_ARMATURE) { /* no recalc flag, does pose */
907
908       if (t->state != TRANS_CANCEL) {
909         applyProject(t);
910       }
911
912       FOREACH_TRANS_DATA_CONTAINER (t, tc) {
913         bArmature *arm = tc->obedit->data;
914         ListBase *edbo = arm->edbo;
915         EditBone *ebo, *ebo_parent;
916         TransData *td = tc->data;
917         int i;
918
919         /* Ensure all bones are correctly adjusted */
920         for (ebo = edbo->first; ebo; ebo = ebo->next) {
921           ebo_parent = (ebo->flag & BONE_CONNECTED) ? ebo->parent : NULL;
922
923           if (ebo_parent) {
924             /* If this bone has a parent tip that has been moved */
925             if (ebo_parent->flag & BONE_TIPSEL) {
926               copy_v3_v3(ebo->head, ebo_parent->tail);
927               if (t->mode == TFM_BONE_ENVELOPE) {
928                 ebo->rad_head = ebo_parent->rad_tail;
929               }
930             }
931             /* If this bone has a parent tip that has NOT been moved */
932             else {
933               copy_v3_v3(ebo_parent->tail, ebo->head);
934               if (t->mode == TFM_BONE_ENVELOPE) {
935                 ebo_parent->rad_tail = ebo->rad_head;
936               }
937             }
938           }
939
940           /* on extrude bones, oldlength==0.0f, so we scale radius of points */
941           ebo->length = len_v3v3(ebo->head, ebo->tail);
942           if (ebo->oldlength == 0.0f) {
943             ebo->rad_head = 0.25f * ebo->length;
944             ebo->rad_tail = 0.10f * ebo->length;
945             ebo->dist = 0.25f * ebo->length;
946             if (ebo->parent) {
947               if (ebo->rad_head > ebo->parent->rad_tail) {
948                 ebo->rad_head = ebo->parent->rad_tail;
949               }
950             }
951           }
952           else if (t->mode != TFM_BONE_ENVELOPE) {
953             /* if bones change length, lets do that for the deform distance as well */
954             ebo->dist *= ebo->length / ebo->oldlength;
955             ebo->rad_head *= ebo->length / ebo->oldlength;
956             ebo->rad_tail *= ebo->length / ebo->oldlength;
957             ebo->oldlength = ebo->length;
958
959             if (ebo_parent) {
960               ebo_parent->rad_tail = ebo->rad_head;
961             }
962           }
963         }
964
965         if (!ELEM(
966                 t->mode, TFM_BONE_ROLL, TFM_BONE_ENVELOPE, TFM_BONE_ENVELOPE_DIST, TFM_BONESIZE)) {
967           /* fix roll */
968           for (i = 0; i < tc->data_len; i++, td++) {
969             if (td->extra) {
970               float vec[3], up_axis[3];
971               float qrot[4];
972               float roll;
973
974               ebo = td->extra;
975
976               if (t->state == TRANS_CANCEL) {
977                 /* restore roll */
978                 ebo->roll = td->ival;
979               }
980               else {
981                 copy_v3_v3(up_axis, td->axismtx[2]);
982
983                 sub_v3_v3v3(vec, ebo->tail, ebo->head);
984                 normalize_v3(vec);
985                 rotation_between_vecs_to_quat(qrot, td->axismtx[1], vec);
986                 mul_qt_v3(qrot, up_axis);
987
988                 /* roll has a tendency to flip in certain orientations - [#34283], [#33974] */
989                 roll = ED_armature_ebone_roll_to_vector(ebo, up_axis, false);
990                 ebo->roll = angle_compat_rad(roll, td->ival);
991               }
992             }
993           }
994         }
995
996         if (arm->flag & ARM_MIRROR_EDIT) {
997           if (t->state != TRANS_CANCEL) {
998             ED_armature_edit_transform_mirror_update(tc->obedit);
999           }
1000           else {
1001             restoreBones(tc);
1002           }
1003         }
1004       }
1005     }
1006     else {
1007       if (t->state != TRANS_CANCEL) {
1008         applyProject(t);
1009       }
1010       FOREACH_TRANS_DATA_CONTAINER (t, tc) {
1011         if (tc->data_len) {
1012           DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
1013         }
1014       }
1015     }
1016   }
1017   else if (t->flag & T_POSE && (t->mode == TFM_BONESIZE)) {
1018     /* Handle the exception where for TFM_BONESIZE in edit mode we pretend to be
1019      * in pose mode (to use bone orientation matrix),
1020      * in that case we have to do mirroring as well. */
1021     FOREACH_TRANS_DATA_CONTAINER (t, tc) {
1022       Object *ob = tc->poseobj;
1023       bArmature *arm = ob->data;
1024       if (ob->mode == OB_MODE_EDIT) {
1025         if (arm->flag & ARM_MIRROR_EDIT) {
1026           if (t->state != TRANS_CANCEL) {
1027             ED_armature_edit_transform_mirror_update(ob);
1028           }
1029           else {
1030             restoreBones(tc);
1031           }
1032         }
1033       }
1034       else if (ob->mode == OB_MODE_POSE) {
1035         /* actually support TFM_BONESIZE in posemode as well */
1036         DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
1037         bPose *pose = ob->pose;
1038         if (arm->flag & ARM_MIRROR_EDIT || pose->flag & POSE_MIRROR_EDIT) {
1039           pose_transform_mirror_update(ob, NULL);
1040         }
1041       }
1042     }
1043   }
1044   else if (t->flag & T_POSE) {
1045     GSet *motionpath_updates = BLI_gset_ptr_new("motionpath updates");
1046
1047     FOREACH_TRANS_DATA_CONTAINER (t, tc) {
1048       Object *ob = tc->poseobj;
1049       bPose *pose = ob->pose;
1050
1051       if (pose->flag & POSE_MIRROR_EDIT) {
1052         if (t->state != TRANS_CANCEL) {
1053           PoseInitData_Mirror *pid = NULL;
1054           if (pose->flag & POSE_MIRROR_RELATIVE) {
1055             pid = tc->custom.type.data;
1056           }
1057           pose_transform_mirror_update(ob, pid);
1058         }
1059         else {
1060           restoreMirrorPoseBones(tc);
1061         }
1062       }
1063
1064       /* if animtimer is running, and the object already has animation data,
1065        * check if the auto-record feature means that we should record 'samples'
1066        * (i.e. un-editable animation values)
1067        *
1068        * context is needed for keying set poll() functions.
1069        */
1070
1071       /* TODO: autokeyframe calls need some setting to specify to add samples
1072        * (FPoints) instead of keyframes? */
1073       if ((t->animtimer) && (t->context) && IS_AUTOKEY_ON(t->scene)) {
1074         int targetless_ik =
1075             (t->flag & T_AUTOIK);  // XXX this currently doesn't work, since flags aren't set yet!
1076
1077         animrecord_check_state(t->scene, &ob->id, t->animtimer);
1078         autokeyframe_pose(t->context, t->scene, ob, t->mode, targetless_ik);
1079       }
1080
1081       if (motionpath_need_update_pose(t->scene, ob)) {
1082         BLI_gset_insert(motionpath_updates, ob);
1083       }
1084
1085       DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
1086     }
1087
1088     /* Update motion paths once for all transformed bones in an object. */
1089     GSetIterator gs_iter;
1090     GSET_ITER (gs_iter, motionpath_updates) {
1091       Object *ob = BLI_gsetIterator_getKey(&gs_iter);
1092       ED_pose_recalculate_paths(t->context, t->scene, ob, true);
1093     }
1094     BLI_gset_free(motionpath_updates, NULL);
1095   }
1096   else if (base && (base->object->mode & OB_MODE_PARTICLE_EDIT) &&
1097            PE_get_current(t->scene, base->object)) {
1098     if (t->state != TRANS_CANCEL) {
1099       applyProject(t);
1100     }
1101     flushTransParticles(t);
1102   }
1103   else {
1104     bool motionpath_update = false;
1105
1106     if (t->state != TRANS_CANCEL) {
1107       applyProject(t);
1108     }
1109
1110     FOREACH_TRANS_DATA_CONTAINER (t, tc) {
1111       TransData *td = tc->data;
1112
1113       for (int i = 0; i < tc->data_len; i++, td++) {
1114         Object *ob = td->ob;
1115
1116         if (td->flag & TD_NOACTION) {
1117           break;
1118         }
1119
1120         if (td->flag & TD_SKIP) {
1121           continue;
1122         }
1123
1124         /* if animtimer is running, and the object already has animation data,
1125          * check if the auto-record feature means that we should record 'samples'
1126          * (i.e. uneditable animation values)
1127          */
1128         /* TODO: autokeyframe calls need some setting to specify to add samples
1129          * (FPoints) instead of keyframes? */
1130         if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
1131           animrecord_check_state(t->scene, &ob->id, t->animtimer);
1132           autokeyframe_object(t->context, t->scene, t->view_layer, ob, t->mode);
1133         }
1134
1135         motionpath_update |= motionpath_need_update_object(t->scene, ob);
1136
1137         /* sets recalc flags fully, instead of flushing existing ones
1138          * otherwise proxies don't function correctly
1139          */
1140         DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
1141
1142         if (t->flag & T_TEXTURE) {
1143           DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
1144         }
1145       }
1146     }
1147
1148     if (motionpath_update) {
1149       /* Update motion paths once for all transformed objects. */
1150       ED_objects_recalculate_paths(t->context, t->scene, true);
1151     }
1152   }
1153 }
1154
1155 static void recalcData_cursor(TransInfo *t)
1156 {
1157   DEG_id_tag_update(&t->scene->id, ID_RECALC_COPY_ON_WRITE);
1158 }
1159
1160 /* helper for recalcData() - for sequencer transforms */
1161 static void recalcData_sequencer(TransInfo *t)
1162 {
1163   TransData *td;
1164   int a;
1165   Sequence *seq_prev = NULL;
1166
1167   TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
1168
1169   for (a = 0, td = tc->data; a < tc->data_len; a++, td++) {
1170     TransDataSeq *tdsq = (TransDataSeq *)td->extra;
1171     Sequence *seq = tdsq->seq;
1172
1173     if (seq != seq_prev) {
1174       BKE_sequence_invalidate_cache_composite(t->scene, seq);
1175     }
1176
1177     seq_prev = seq;
1178   }
1179
1180   DEG_id_tag_update(&t->scene->id, ID_RECALC_SEQUENCER_STRIPS);
1181
1182   flushTransSeq(t);
1183 }
1184
1185 /* force recalculation of triangles during transformation */
1186 static void recalcData_gpencil_strokes(TransInfo *t)
1187 {
1188   TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
1189
1190   TransData *td = tc->data;
1191   for (int i = 0; i < tc->data_len; i++, td++) {
1192     bGPDstroke *gps = td->extra;
1193     if (gps != NULL) {
1194       gps->flag |= GP_STROKE_RECALC_GEOMETRY;
1195     }
1196   }
1197 }
1198
1199 /* called for updating while transform acts, once per redraw */
1200 void recalcData(TransInfo *t)
1201 {
1202   /* if tests must match createTransData for correct updates */
1203   if (t->options & CTX_CURSOR) {
1204     recalcData_cursor(t);
1205   }
1206   else if (t->options & CTX_TEXTURE) {
1207     recalcData_objects(t);
1208   }
1209   else if (t->options & CTX_EDGE) {
1210     recalcData_objects(t);
1211   }
1212   else if (t->options & CTX_PAINT_CURVE) {
1213     flushTransPaintCurve(t);
1214   }
1215   else if (t->options & CTX_GPENCIL_STROKES) {
1216     /* set recalc triangle cache flag */
1217     recalcData_gpencil_strokes(t);
1218   }
1219   else if (t->spacetype == SPACE_IMAGE) {
1220     recalcData_image(t);
1221   }
1222   else if (t->spacetype == SPACE_ACTION) {
1223     recalcData_actedit(t);
1224   }
1225   else if (t->spacetype == SPACE_NLA) {
1226     recalcData_nla(t);
1227   }
1228   else if (t->spacetype == SPACE_SEQ) {
1229     recalcData_sequencer(t);
1230   }
1231   else if (t->spacetype == SPACE_GRAPH) {
1232     recalcData_graphedit(t);
1233   }
1234   else if (t->spacetype == SPACE_NODE) {
1235     flushTransNodes(t);
1236   }
1237   else if (t->spacetype == SPACE_CLIP) {
1238     recalcData_spaceclip(t);
1239   }
1240   else {
1241     recalcData_objects(t);
1242   }
1243 }
1244
1245 void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis, short options)
1246 {
1247   float v1[3], v2[3], v3[3];
1248   unsigned char col[3], col2[3];
1249
1250   if (t->spacetype == SPACE_VIEW3D) {
1251     View3D *v3d = t->view;
1252
1253     GPU_matrix_push();
1254
1255     copy_v3_v3(v3, dir);
1256     mul_v3_fl(v3, v3d->clip_end);
1257
1258     sub_v3_v3v3(v2, center, v3);
1259     add_v3_v3v3(v1, center, v3);
1260
1261     if (options & DRAWLIGHT) {
1262       col[0] = col[1] = col[2] = 220;
1263     }
1264     else {
1265       UI_GetThemeColor3ubv(TH_GRID, col);
1266     }
1267     UI_make_axis_color(col, col2, axis);
1268
1269     uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
1270
1271     immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
1272     immUniformColor3ubv(col2);
1273
1274     immBegin(GPU_PRIM_LINES, 2);
1275     immVertex3fv(pos, v1);
1276     immVertex3fv(pos, v2);
1277     immEnd();
1278
1279     immUnbindProgram();
1280
1281     GPU_matrix_pop();
1282   }
1283 }
1284
1285 /**
1286  * Free data before switching to another mode.
1287  */
1288 void resetTransModal(TransInfo *t)
1289 {
1290   freeTransCustomDataForMode(t);
1291 }
1292
1293 void resetTransRestrictions(TransInfo *t)
1294 {
1295   t->flag &= ~T_ALL_RESTRICTIONS;
1296 }
1297
1298 static int initTransInfo_edit_pet_to_flag(const int proportional)
1299 {
1300   int flag = 0;
1301   if (proportional & PROP_EDIT_USE) {
1302     flag |= T_PROP_EDIT;
1303   }
1304   if (proportional & PROP_EDIT_CONNECTED) {
1305     flag |= T_PROP_CONNECTED;
1306   }
1307   if (proportional & PROP_EDIT_PROJECTED) {
1308     flag |= T_PROP_PROJECTED;
1309   }
1310   return flag;
1311 }
1312
1313 void initTransDataContainers_FromObjectData(TransInfo *t,
1314                                             Object *obact,
1315                                             Object **objects,
1316                                             uint objects_len)
1317 {
1318   const eObjectMode object_mode = obact ? obact->mode : OB_MODE_OBJECT;
1319   const short object_type = obact ? obact->type : -1;
1320
1321   if ((object_mode & OB_MODE_EDIT) || (t->options & CTX_GPENCIL_STROKES) ||
1322       ((object_mode & OB_MODE_POSE) && (object_type == OB_ARMATURE))) {
1323     if (t->data_container) {
1324       MEM_freeN(t->data_container);
1325     }
1326
1327     bool free_objects = false;
1328     if (objects == NULL) {
1329       objects = BKE_view_layer_array_from_objects_in_mode(
1330           t->view_layer,
1331           (t->spacetype == SPACE_VIEW3D) ? t->view : NULL,
1332           &objects_len,
1333           {
1334               .object_mode = object_mode,
1335               .no_dup_data = true,
1336           });
1337       free_objects = true;
1338     }
1339
1340     t->data_container = MEM_callocN(sizeof(*t->data_container) * objects_len, __func__);
1341     t->data_container_len = objects_len;
1342
1343     for (int i = 0; i < objects_len; i++) {
1344       TransDataContainer *tc = &t->data_container[i];
1345       /* TODO, multiple axes. */
1346       tc->mirror.axis_flag = (((t->flag & T_NO_MIRROR) == 0) &&
1347                               ((t->options & CTX_NO_MIRROR) == 0) &&
1348                               (objects[i]->type == OB_MESH) &&
1349                               (((Mesh *)objects[i]->data)->editflag & ME_EDIT_MIRROR_X) != 0);
1350
1351       if (object_mode & OB_MODE_EDIT) {
1352         tc->obedit = objects[i];
1353         /* Check needed for UV's */
1354         if ((t->flag & T_2D_EDIT) == 0) {
1355           tc->use_local_mat = true;
1356         }
1357       }
1358       else if (object_mode & OB_MODE_POSE) {
1359         tc->poseobj = objects[i];
1360         tc->use_local_mat = true;
1361       }
1362       else if (t->options & CTX_GPENCIL_STROKES) {
1363         tc->use_local_mat = true;
1364       }
1365
1366       if (tc->use_local_mat) {
1367         BLI_assert((t->flag & T_2D_EDIT) == 0);
1368         copy_m4_m4(tc->mat, objects[i]->obmat);
1369         copy_m3_m4(tc->mat3, tc->mat);
1370         /* for non-invertible scale matrices, invert_m4_m4_fallback()
1371          * can still provide a valid pivot */
1372         invert_m4_m4_fallback(tc->imat, tc->mat);
1373         invert_m3_m3(tc->imat3, tc->mat3);
1374         normalize_m3_m3(tc->mat3_unit, tc->mat3);
1375       }
1376       /* Otherwise leave as zero. */
1377     }
1378
1379     if (free_objects) {
1380       MEM_freeN(objects);
1381     }
1382   }
1383 }
1384
1385 /**
1386  * Setup internal data, mouse, vectors
1387  *
1388  * \note \a op and \a event can be NULL
1389  *
1390  * \see #saveTransform does the reverse.
1391  */
1392 void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *event)
1393 {
1394   Scene *sce = CTX_data_scene(C);
1395   ViewLayer *view_layer = CTX_data_view_layer(C);
1396   const eObjectMode object_mode = OBACT(view_layer) ? OBACT(view_layer)->mode : OB_MODE_OBJECT;
1397   const short object_type = OBACT(view_layer) ? OBACT(view_layer)->type : -1;
1398   ToolSettings *ts = CTX_data_tool_settings(C);
1399   ARegion *ar = CTX_wm_region(C);
1400   ScrArea *sa = CTX_wm_area(C);
1401
1402   bGPdata *gpd = CTX_data_gpencil_data(C);
1403   PropertyRNA *prop;
1404
1405   t->depsgraph = CTX_data_depsgraph_pointer(C);
1406   t->scene = sce;
1407   t->view_layer = view_layer;
1408   t->sa = sa;
1409   t->ar = ar;
1410   t->settings = ts;
1411   t->reports = op ? op->reports : NULL;
1412
1413   t->helpline = HLP_NONE;
1414
1415   t->flag = 0;
1416
1417   t->obedit_type = ((object_mode == OB_MODE_EDIT) || (object_mode == OB_MODE_EDIT_GPENCIL)) ?
1418                        object_type :
1419                        -1;
1420
1421   /* Many kinds of transform only use a single handle. */
1422   if (t->data_container == NULL) {
1423     t->data_container = MEM_callocN(sizeof(*t->data_container), __func__);
1424     t->data_container_len = 1;
1425   }
1426
1427   t->redraw = TREDRAW_HARD; /* redraw first time */
1428
1429   if (event) {
1430     t->mouse.imval[0] = event->mval[0];
1431     t->mouse.imval[1] = event->mval[1];
1432   }
1433   else {
1434     t->mouse.imval[0] = 0;
1435     t->mouse.imval[1] = 0;
1436   }
1437
1438   t->con.imval[0] = t->mouse.imval[0];
1439   t->con.imval[1] = t->mouse.imval[1];
1440
1441   t->mval[0] = t->mouse.imval[0];
1442   t->mval[1] = t->mouse.imval[1];
1443
1444   t->transform = NULL;
1445   t->handleEvent = NULL;
1446
1447   t->data_len_all = 0;
1448
1449   t->val = 0.0f;
1450
1451   zero_v3(t->vec);
1452   zero_v3(t->center_global);
1453
1454   unit_m3(t->mat);
1455
1456   unit_m3(t->orient_matrix);
1457   negate_m3(t->orient_matrix);
1458   /* Leave 't->orient_matrix_is_set' to false,
1459    * so we overwrite it when we have a useful value. */
1460
1461   /* Default to rotate on the Z axis. */
1462   t->orient_axis = 2;
1463   t->orient_axis_ortho = 1;
1464
1465   /* if there's an event, we're modal */
1466   if (event) {
1467     t->flag |= T_MODAL;
1468   }
1469
1470   /* Crease needs edge flag */
1471   if (ELEM(t->mode, TFM_CREASE, TFM_BWEIGHT)) {
1472     t->options |= CTX_EDGE;
1473   }
1474
1475   t->remove_on_cancel = false;
1476
1477   if (op && (prop = RNA_struct_find_property(op->ptr, "remove_on_cancel")) &&
1478       RNA_property_is_set(op->ptr, prop)) {
1479     if (RNA_property_boolean_get(op->ptr, prop)) {
1480       t->remove_on_cancel = true;
1481     }
1482   }
1483
1484   /* GPencil editing context */
1485   if (GPENCIL_EDIT_MODE(gpd)) {
1486     t->options |= CTX_GPENCIL_STROKES;
1487   }
1488
1489   /* Assign the space type, some exceptions for running in different mode */
1490   if (sa == NULL) {
1491     /* background mode */
1492     t->spacetype = SPACE_EMPTY;
1493   }
1494   else if ((ar == NULL) && (sa->spacetype == SPACE_VIEW3D)) {
1495     /* running in the text editor */
1496     t->spacetype = SPACE_EMPTY;
1497   }
1498   else {
1499     /* normal operation */
1500     t->spacetype = sa->spacetype;
1501   }
1502
1503   /* handle T_ALT_TRANSFORM initialization, we may use for different operators */
1504   if (op) {
1505     const char *prop_id = NULL;
1506     if (t->mode == TFM_SHRINKFATTEN) {
1507       prop_id = "use_even_offset";
1508     }
1509
1510     if (prop_id && (prop = RNA_struct_find_property(op->ptr, prop_id))) {
1511       SET_FLAG_FROM_TEST(t->flag, RNA_property_boolean_get(op->ptr, prop), T_ALT_TRANSFORM);
1512     }
1513   }
1514
1515   if (t->spacetype == SPACE_VIEW3D) {
1516     View3D *v3d = sa->spacedata.first;
1517     bScreen *animscreen = ED_screen_animation_playing(CTX_wm_manager(C));
1518
1519     t->view = v3d;
1520     t->animtimer = (animscreen) ? animscreen->animtimer : NULL;
1521
1522     /* turn gizmo off during transform */
1523     if (t->flag & T_MODAL) {
1524       t->gizmo_flag = v3d->gizmo_flag;
1525       v3d->gizmo_flag = V3D_GIZMO_HIDE;
1526     }
1527
1528     if (t->scene->toolsettings->transform_flag & SCE_XFORM_AXIS_ALIGN) {
1529       t->flag |= T_V3D_ALIGN;
1530     }
1531     t->around = t->scene->toolsettings->transform_pivot_point;
1532
1533     /* bend always uses the cursor */
1534     if (t->mode == TFM_BEND) {
1535       t->around = V3D_AROUND_CURSOR;
1536     }
1537
1538     TransformOrientationSlot *orient_slot = &t->scene->orientation_slots[SCE_ORIENT_DEFAULT];
1539     t->orientation.unset = V3D_ORIENT_GLOBAL;
1540     t->orientation.user = orient_slot->type;
1541     t->orientation.custom = BKE_scene_transform_orientation_find(t->scene,
1542                                                                  orient_slot->index_custom);
1543
1544     t->orientation.index = 0;
1545     ARRAY_SET_ITEMS(t->orientation.types, &t->orientation.user, NULL);
1546
1547     /* Make second orientation local if both are global. */
1548     if (t->orientation.user == V3D_ORIENT_GLOBAL) {
1549       t->orientation.user_alt = V3D_ORIENT_LOCAL;
1550       t->orientation.types[0] = &t->orientation.user_alt;
1551       SWAP(short *, t->orientation.types[0], t->orientation.types[1]);
1552     }
1553
1554     /* exceptional case */
1555     if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
1556       if (ELEM(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL)) {
1557         const bool use_island = transdata_check_local_islands(t, t->around);
1558
1559         if ((t->obedit_type != -1) && !use_island) {
1560           t->options |= CTX_NO_PET;
1561         }
1562       }
1563     }
1564
1565     if (object_mode & OB_MODE_ALL_PAINT) {
1566       Paint *p = BKE_paint_get_active_from_context(C);
1567       if (p && p->brush && (p->brush->flag & BRUSH_CURVE)) {
1568         t->options |= CTX_PAINT_CURVE;
1569       }
1570     }
1571
1572     /* initialize UV transform from */
1573     if (op && ((prop = RNA_struct_find_property(op->ptr, "correct_uv")))) {
1574       if (RNA_property_is_set(op->ptr, prop)) {
1575         if (RNA_property_boolean_get(op->ptr, prop)) {
1576           t->settings->uvcalc_flag |= UVCALC_TRANSFORM_CORRECT;
1577         }
1578         else {
1579           t->settings->uvcalc_flag &= ~UVCALC_TRANSFORM_CORRECT;
1580         }
1581       }
1582       else {
1583         RNA_property_boolean_set(
1584             op->ptr, prop, (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) != 0);
1585       }
1586     }
1587   }
1588   else if (t->spacetype == SPACE_IMAGE) {
1589     SpaceImage *sima = sa->spacedata.first;
1590     // XXX for now, get View2D from the active region
1591     t->view = &ar->v2d;
1592     t->around = sima->around;
1593
1594     if (ED_space_image_show_uvedit(sima, OBACT(t->view_layer))) {
1595       /* UV transform */
1596     }
1597     else if (sima->mode == SI_MODE_MASK) {
1598       t->options |= CTX_MASK;
1599     }
1600     else if (sima->mode == SI_MODE_PAINT) {
1601       Paint *p = &sce->toolsettings->imapaint.paint;
1602       if (p->brush && (p->brush->flag & BRUSH_CURVE)) {
1603         t->options |= CTX_PAINT_CURVE;
1604       }
1605     }
1606     /* image not in uv edit, nor in mask mode, can happen for some tools */
1607   }
1608   else if (t->spacetype == SPACE_NODE) {
1609     // XXX for now, get View2D from the active region
1610     t->view = &ar->v2d;
1611     t->around = V3D_AROUND_CENTER_BOUNDS;
1612   }
1613   else if (t->spacetype == SPACE_GRAPH) {
1614     SpaceGraph *sipo = sa->spacedata.first;
1615     t->view = &ar->v2d;
1616     t->around = sipo->around;
1617   }
1618   else if (t->spacetype == SPACE_CLIP) {
1619     SpaceClip *sclip = sa->spacedata.first;
1620     t->view = &ar->v2d;
1621     t->around = sclip->around;
1622
1623     if (ED_space_clip_check_show_trackedit(sclip)) {
1624       t->options |= CTX_MOVIECLIP;
1625     }
1626     else if (ED_space_clip_check_show_maskedit(sclip)) {
1627       t->options |= CTX_MASK;
1628     }
1629   }
1630   else {
1631     if (ar) {
1632       // XXX for now, get View2D  from the active region
1633       t->view = &ar->v2d;
1634       // XXX for now, the center point is the midpoint of the data
1635     }
1636     else {
1637       t->view = NULL;
1638     }
1639     t->around = V3D_AROUND_CENTER_BOUNDS;
1640   }
1641
1642   if (op && (prop = RNA_struct_find_property(op->ptr, "orient_axis"))) {
1643     t->orient_axis = RNA_property_enum_get(op->ptr, prop);
1644   }
1645   if (op && (prop = RNA_struct_find_property(op->ptr, "orient_axis_ortho"))) {
1646     t->orient_axis_ortho = RNA_property_enum_get(op->ptr, prop);
1647   }
1648
1649   if (op &&
1650       ((prop = RNA_struct_find_property(op->ptr, "orient_matrix")) &&
1651        RNA_property_is_set(op->ptr, prop)) &&
1652       ((t->flag & T_MODAL) ||
1653        /* When using redo, don't use the the custom constraint matrix
1654         * if the user selects a different orientation. */
1655        (RNA_enum_get(op->ptr, "orient_type") == RNA_enum_get(op->ptr, "orient_matrix_type")))) {
1656     RNA_property_float_get_array(op->ptr, prop, &t->spacemtx[0][0]);
1657     /* Some transform modes use this to operate on an axis. */
1658     t->orient_matrix_is_set = true;
1659     copy_m3_m3(t->orient_matrix, t->spacemtx);
1660     t->orient_matrix_is_set = true;
1661     t->orientation.user = V3D_ORIENT_CUSTOM_MATRIX;
1662     t->orientation.custom = 0;
1663     if (t->flag & T_MODAL) {
1664       RNA_enum_set(op->ptr, "orient_matrix_type", RNA_enum_get(op->ptr, "orient_type"));
1665     }
1666   }
1667   else if (op && ((prop = RNA_struct_find_property(op->ptr, "orient_type")) &&
1668                   RNA_property_is_set(op->ptr, prop))) {
1669     short orientation = RNA_property_enum_get(op->ptr, prop);
1670     TransformOrientation *custom_orientation = NULL;
1671
1672     if (orientation >= V3D_ORIENT_CUSTOM) {
1673       if (orientation >= V3D_ORIENT_CUSTOM + BIF_countTransformOrientation(C)) {
1674         orientation = V3D_ORIENT_GLOBAL;
1675       }
1676       else {
1677         custom_orientation = BKE_scene_transform_orientation_find(t->scene,
1678                                                                   orientation - V3D_ORIENT_CUSTOM);
1679         orientation = V3D_ORIENT_CUSTOM;
1680       }
1681     }
1682
1683     t->orientation.user = orientation;
1684     t->orientation.custom = custom_orientation;
1685   }
1686
1687   if (op && ((prop = RNA_struct_find_property(op->ptr, "release_confirm")) &&
1688              RNA_property_is_set(op->ptr, prop))) {
1689     if (RNA_property_boolean_get(op->ptr, prop)) {
1690       t->flag |= T_RELEASE_CONFIRM;
1691     }
1692   }
1693   else {
1694     if (ISMOUSE(t->launch_event) && (U.flag & USER_RELEASECONFIRM)) {
1695       /* Global "release confirm" on mouse bindings */
1696       t->flag |= T_RELEASE_CONFIRM;
1697     }
1698   }
1699
1700   if (op && ((prop = RNA_struct_find_property(op->ptr, "mirror")) &&
1701              RNA_property_is_set(op->ptr, prop))) {
1702     if (!RNA_property_boolean_get(op->ptr, prop)) {
1703       t->flag |= T_NO_MIRROR;
1704     }
1705   }
1706   else if ((t->spacetype == SPACE_VIEW3D) && (t->obedit_type == OB_MESH)) {
1707     /* pass */
1708   }
1709   else {
1710     /* Avoid mirroring for unsupported contexts. */
1711     t->options |= CTX_NO_MIRROR;
1712   }
1713
1714   /* setting PET flag only if property exist in operator. Otherwise, assume it's not supported */
1715   if (op && (prop = RNA_struct_find_property(op->ptr, "use_proportional_edit"))) {
1716     if (RNA_property_is_set(op->ptr, prop)) {
1717       int proportional = 0;
1718       if (RNA_property_boolean_get(op->ptr, prop)) {
1719         proportional |= PROP_EDIT_USE;
1720         if (RNA_boolean_get(op->ptr, "use_proportional_connected")) {
1721           proportional |= PROP_EDIT_CONNECTED;
1722         }
1723         if (RNA_boolean_get(op->ptr, "use_proportional_projected")) {
1724           proportional |= PROP_EDIT_PROJECTED;
1725         }
1726       }
1727       t->flag |= initTransInfo_edit_pet_to_flag(proportional);
1728     }
1729     else {
1730       /* use settings from scene only if modal */
1731       if (t->flag & T_MODAL) {
1732         if ((t->options & CTX_NO_PET) == 0) {
1733           if (t->spacetype == SPACE_GRAPH) {
1734             t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional_fcurve);
1735           }
1736           else if (t->spacetype == SPACE_ACTION) {
1737             t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional_action);
1738           }
1739           else if (t->obedit_type != -1) {
1740             t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional_edit);
1741           }
1742           else if (t->options & CTX_GPENCIL_STROKES) {
1743             t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional_edit);
1744           }
1745           else if (t->options & CTX_MASK) {
1746             if (ts->proportional_mask) {
1747               t->flag |= T_PROP_EDIT;
1748
1749               if (ts->proportional_edit & PROP_EDIT_CONNECTED) {
1750                 t->flag |= T_PROP_CONNECTED;
1751               }
1752             }
1753           }
1754           else if ((t->obedit_type == -1) && ts->proportional_objects) {
1755             t->flag |= T_PROP_EDIT;
1756           }
1757         }
1758       }
1759     }
1760
1761     if (op && ((prop = RNA_struct_find_property(op->ptr, "proportional_size")) &&
1762                RNA_property_is_set(op->ptr, prop))) {
1763       t->prop_size = RNA_property_float_get(op->ptr, prop);
1764     }
1765     else {
1766       t->prop_size = ts->proportional_size;
1767     }
1768
1769     /* TRANSFORM_FIX_ME rna restrictions */
1770     if (t->prop_size <= 0.00001f) {
1771       printf("Proportional size (%f) under 0.00001, resetting to 1!\n", t->prop_size);
1772       t->prop_size = 1.0f;
1773     }
1774
1775     if (op && ((prop = RNA_struct_find_property(op->ptr, "proportional_edit_falloff")) &&
1776                RNA_property_is_set(op->ptr, prop))) {
1777       t->prop_mode = RNA_property_enum_get(op->ptr, prop);
1778     }
1779     else {
1780       t->prop_mode = ts->prop_mode;
1781     }
1782   }
1783   else { /* add not pet option to context when not available */
1784     t->options |= CTX_NO_PET;
1785   }
1786
1787   // Mirror is not supported with PET, turn it off.
1788 #if 0
1789   if (t->flag & T_PROP_EDIT) {
1790     t->flag &= ~T_MIRROR;
1791   }
1792 #endif
1793
1794   setTransformViewAspect(t, t->aspect);
1795
1796   if (op && (prop = RNA_struct_find_property(op->ptr, "center_override")) &&
1797       RNA_property_is_set(op->ptr, prop)) {
1798     RNA_property_float_get_array(op->ptr, prop, t->center_global);
1799     mul_v3_v3(t->center_global, t->aspect);
1800     t->flag |= T_OVERRIDE_CENTER;
1801   }
1802
1803   setTransformViewMatrices(t);
1804   initNumInput(&t->num);
1805 }
1806
1807 static void freeTransCustomData(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data)
1808 {
1809   if (custom_data->free_cb) {
1810     /* Can take over freeing t->data and data_2d etc... */
1811     custom_data->free_cb(t, tc, custom_data);
1812     BLI_assert(custom_data->data == NULL);
1813   }
1814   else if ((custom_data->data != NULL) && custom_data->use_free) {
1815     MEM_freeN(custom_data->data);
1816     custom_data->data = NULL;
1817   }
1818   /* In case modes are switched in the same transform session. */
1819   custom_data->free_cb = false;
1820   custom_data->use_free = false;
1821 }
1822
1823 static void freeTransCustomDataContainer(TransInfo *t,
1824                                          TransDataContainer *tc,
1825                                          TransCustomDataContainer *tcdc)
1826 {
1827   TransCustomData *custom_data = &tcdc->first_elem;
1828   for (int i = 0; i < TRANS_CUSTOM_DATA_ELEM_MAX; i++, custom_data++) {
1829     freeTransCustomData(t, tc, custom_data);
1830   }
1831 }
1832
1833 /**
1834  * Needed for mode switching.
1835  */
1836 void freeTransCustomDataForMode(TransInfo *t)
1837 {
1838   freeTransCustomData(t, NULL, &t->custom.mode);
1839   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
1840     freeTransCustomData(t, tc, &tc->custom.mode);
1841   }
1842 }
1843
1844 /* Here I would suggest only TransInfo related issues, like free data & reset vars. Not redraws */
1845 void postTrans(bContext *C, TransInfo *t)
1846 {
1847   if (t->draw_handle_view) {
1848     ED_region_draw_cb_exit(t->ar->type, t->draw_handle_view);
1849   }
1850   if (t->draw_handle_apply) {
1851     ED_region_draw_cb_exit(t->ar->type, t->draw_handle_apply);
1852   }
1853   if (t->draw_handle_pixel) {
1854     ED_region_draw_cb_exit(t->ar->type, t->draw_handle_pixel);
1855   }
1856   if (t->draw_handle_cursor) {
1857     WM_paint_cursor_end(CTX_wm_manager(C), t->draw_handle_cursor);
1858   }
1859
1860   if (t->flag & T_MODAL_CURSOR_SET) {
1861     WM_cursor_modal_restore(CTX_wm_window(C));
1862   }
1863
1864   /* Free all custom-data */
1865   freeTransCustomDataContainer(t, NULL, &t->custom);
1866   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
1867     freeTransCustomDataContainer(t, tc, &tc->custom);
1868   }
1869
1870   /* postTrans can be called when nothing is selected, so data is NULL already */
1871   if (t->data_len_all != 0) {
1872     FOREACH_TRANS_DATA_CONTAINER (t, tc) {
1873       /* free data malloced per trans-data */
1874       if (ELEM(t->obedit_type, OB_CURVE, OB_SURF) || (t->spacetype == SPACE_GRAPH)) {
1875         TransData *td = tc->data;
1876         for (int a = 0; a < tc->data_len; a++, td++) {
1877           if (td->flag & TD_BEZTRIPLE) {
1878             MEM_freeN(td->hdata);
1879           }
1880         }
1881       }
1882       MEM_freeN(tc->data);
1883
1884       MEM_SAFE_FREE(tc->data_ext);
1885       MEM_SAFE_FREE(tc->data_2d);
1886     }
1887   }
1888
1889   MEM_SAFE_FREE(t->data_container);
1890   t->data_container = NULL;
1891
1892   BLI_freelistN(&t->tsnap.points);
1893
1894   if (t->spacetype == SPACE_IMAGE) {
1895     if (t->options & (CTX_MASK | CTX_PAINT_CURVE)) {
1896       /* pass */
1897     }
1898     else {
1899       SpaceImage *sima = t->sa->spacedata.first;
1900       if (sima->flag & SI_LIVE_UNWRAP) {
1901         ED_uvedit_live_unwrap_end(t->state == TRANS_CANCEL);
1902       }
1903     }
1904   }
1905   else if (t->spacetype == SPACE_VIEW3D) {
1906     View3D *v3d = t->sa->spacedata.first;
1907     /* restore gizmo */
1908     if (t->flag & T_MODAL) {
1909       v3d->gizmo_flag = t->gizmo_flag;
1910     }
1911   }
1912
1913   if (t->mouse.data) {
1914     MEM_freeN(t->mouse.data);
1915   }
1916
1917   if (t->rng != NULL) {
1918     BLI_rng_free(t->rng);
1919   }
1920
1921   freeSnapping(t);
1922 }
1923
1924 void applyTransObjects(TransInfo *t)
1925 {
1926   TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
1927
1928   TransData *td;
1929
1930   for (td = tc->data; td < tc->data + tc->data_len; td++) {
1931     copy_v3_v3(td->iloc, td->loc);
1932     if (td->ext->rot) {
1933       copy_v3_v3(td->ext->irot, td->ext->rot);
1934     }
1935     if (td->ext->size) {
1936       copy_v3_v3(td->ext->isize, td->ext->size);
1937     }
1938   }
1939   recalcData(t);
1940 }
1941
1942 static void restoreElement(TransData *td)
1943 {
1944   /* TransData for crease has no loc */
1945   if (td->loc) {
1946     copy_v3_v3(td->loc, td->iloc);
1947   }
1948   if (td->val) {
1949     *td->val = td->ival;
1950   }
1951
1952   if (td->ext && (td->flag & TD_NO_EXT) == 0) {
1953     if (td->ext->rot) {
1954       copy_v3_v3(td->ext->rot, td->ext->irot);
1955     }
1956     if (td->ext->rotAngle) {
1957       *td->ext->rotAngle = td->ext->irotAngle;
1958     }
1959     if (td->ext->rotAxis) {
1960       copy_v3_v3(td->ext->rotAxis, td->ext->irotAxis);
1961     }
1962     /* XXX, drotAngle & drotAxis not used yet */
1963     if (td->ext->size) {
1964       copy_v3_v3(td->ext->size, td->ext->isize);
1965     }
1966     if (td->ext->quat) {
1967       copy_qt_qt(td->ext->quat, td->ext->iquat);
1968     }
1969   }
1970
1971   if (td->flag & TD_BEZTRIPLE) {
1972     *(td->hdata->h1) = td->hdata->ih1;
1973     *(td->hdata->h2) = td->hdata->ih2;
1974   }
1975 }
1976
1977 void restoreTransObjects(TransInfo *t)
1978 {
1979   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
1980
1981     TransData *td;
1982     TransData2D *td2d;
1983
1984     for (td = tc->data; td < tc->data + tc->data_len; td++) {
1985       restoreElement(td);
1986     }
1987
1988     for (td2d = tc->data_2d; tc->data_2d && td2d < tc->data_2d + tc->data_len; td2d++) {
1989       if (td2d->h1) {
1990         td2d->h1[0] = td2d->ih1[0];
1991         td2d->h1[1] = td2d->ih1[1];
1992       }
1993       if (td2d->h2) {
1994         td2d->h2[0] = td2d->ih2[0];
1995         td2d->h2[1] = td2d->ih2[1];
1996       }
1997     }
1998
1999     unit_m3(t->mat);
2000   }
2001
2002   recalcData(t);
2003 }
2004
2005 void calculateCenter2D(TransInfo *t)
2006 {
2007   BLI_assert(!is_zero_v3(t->aspect));
2008   projectFloatView(t, t->center_global, t->center2d);
2009 }
2010
2011 void calculateCenterLocal(TransInfo *t, const float center_global[3])
2012 {
2013   /* setting constraint center */
2014   /* note, init functions may over-ride t->center */
2015   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
2016     if (tc->use_local_mat) {
2017       mul_v3_m4v3(tc->center_local, tc->imat, center_global);
2018     }
2019     else {
2020       copy_v3_v3(tc->center_local, center_global);
2021     }
2022   }
2023 }
2024
2025 void calculateCenterCursor(TransInfo *t, float r_center[3])
2026 {
2027   const float *cursor = t->scene->cursor.location;
2028   copy_v3_v3(r_center, cursor);
2029
2030   /* If edit or pose mode, move cursor in local space */
2031   if (t->options & CTX_PAINT_CURVE) {
2032     if (ED_view3d_project_float_global(t->ar, cursor, r_center, V3D_PROJ_TEST_NOP) !=
2033         V3D_PROJ_RET_OK) {
2034       r_center[0] = t->ar->winx / 2.0f;
2035       r_center[1] = t->ar->winy / 2.0f;
2036     }
2037     r_center[2] = 0.0f;
2038   }
2039 }
2040
2041 void calculateCenterCursor2D(TransInfo *t, float r_center[2])
2042 {
2043   const float *cursor = NULL;
2044
2045   if (t->spacetype == SPACE_IMAGE) {
2046     SpaceImage *sima = (SpaceImage *)t->sa->spacedata.first;
2047     cursor = sima->cursor;
2048   }
2049   else if (t->spacetype == SPACE_CLIP) {
2050     SpaceClip *space_clip = (SpaceClip *)t->sa->spacedata.first;
2051     cursor = space_clip->cursor;
2052   }
2053
2054   if (cursor) {
2055     if (t->options & CTX_MASK) {
2056       float co[2];
2057
2058       if (t->spacetype == SPACE_IMAGE) {
2059         SpaceImage *sima = (SpaceImage *)t->sa->spacedata.first;
2060         BKE_mask_coord_from_image(sima->image, &sima->iuser, co, cursor);
2061       }
2062       else if (t->spacetype == SPACE_CLIP) {
2063         SpaceClip *space_clip = (SpaceClip *)t->sa->spacedata.first;
2064         BKE_mask_coord_from_movieclip(space_clip->clip, &space_clip->user, co, cursor);
2065       }
2066       else {
2067         BLI_assert(!"Shall not happen");
2068       }
2069
2070       r_center[0] = co[0] * t->aspect[0];
2071       r_center[1] = co[1] * t->aspect[1];
2072     }
2073     else if (t->options & CTX_PAINT_CURVE) {
2074       if (t->spacetype == SPACE_IMAGE) {
2075         r_center[0] = UI_view2d_view_to_region_x(&t->ar->v2d, cursor[0]);
2076         r_center[1] = UI_view2d_view_to_region_y(&t->ar->v2d, cursor[1]);
2077       }
2078     }
2079     else {
2080       r_center[0] = cursor[0] * t->aspect[0];
2081       r_center[1] = cursor[1] * t->aspect[1];
2082     }
2083   }
2084 }
2085
2086 void calculateCenterCursorGraph2D(TransInfo *t, float r_center[2])
2087 {
2088   SpaceGraph *sipo = (SpaceGraph *)t->sa->spacedata.first;
2089   Scene *scene = t->scene;
2090
2091   /* cursor is combination of current frame, and graph-editor cursor value */
2092   if (sipo->mode == SIPO_MODE_DRIVERS) {
2093     r_center[0] = sipo->cursorTime;
2094     r_center[1] = sipo->cursorVal;
2095   }
2096   else {
2097     r_center[0] = (float)(scene->r.cfra);
2098     r_center[1] = sipo->cursorVal;
2099   }
2100 }
2101
2102 void calculateCenterMedian(TransInfo *t, float r_center[3])
2103 {
2104   float partial[3] = {0.0f, 0.0f, 0.0f};
2105   int total = 0;
2106
2107   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
2108     for (int i = 0; i < tc->data_len; i++) {
2109       if (tc->data[i].flag & TD_SELECTED) {
2110         if (!(tc->data[i].flag & TD_NOCENTER)) {
2111           if (tc->use_local_mat) {
2112             float v[3];
2113             mul_v3_m4v3(v, tc->mat, tc->data[i].center);
2114             add_v3_v3(partial, v);
2115           }
2116           else {
2117             add_v3_v3(partial, tc->data[i].center);
2118           }
2119           total++;
2120         }
2121       }
2122     }
2123   }
2124   if (total) {
2125     mul_v3_fl(partial, 1.0f / (float)total);
2126   }
2127   copy_v3_v3(r_center, partial);
2128 }
2129
2130 void calculateCenterBound(TransInfo *t, float r_center[3])
2131 {
2132   float max[3], min[3];
2133   bool changed = false;
2134   INIT_MINMAX(min, max);
2135   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
2136     for (int i = 0; i < tc->data_len; i++) {
2137       if (tc->data[i].flag & TD_SELECTED) {
2138         if (!(tc->data[i].flag & TD_NOCENTER)) {
2139           if (tc->use_local_mat) {
2140             float v[3];
2141             mul_v3_m4v3(v, tc->mat, tc->data[i].center);
2142             minmax_v3v3_v3(min, max, v);
2143           }
2144           else {
2145             minmax_v3v3_v3(min, max, tc->data[i].center);
2146           }
2147           changed = true;
2148         }
2149       }
2150     }
2151   }
2152   if (changed) {
2153     mid_v3_v3v3(r_center, min, max);
2154   }
2155 }
2156
2157 /**
2158  * \param select_only: only get active center from data being transformed.
2159  */
2160 bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3])
2161 {
2162   TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_OK(t);
2163
2164   if (t->spacetype != SPACE_VIEW3D) {
2165     return false;
2166   }
2167   else if (tc->obedit) {
2168     if (ED_object_calc_active_center_for_editmode(tc->obedit, select_only, r_center)) {
2169       mul_m4_v3(tc->obedit->obmat, r_center);
2170       return true;
2171     }
2172   }
2173   else if (t->flag & T_POSE) {
2174     ViewLayer *view_layer = t->view_layer;
2175     Object *ob = OBACT(view_layer);
2176     if (ED_object_calc_active_center_for_posemode(ob, select_only, r_center)) {
2177       mul_m4_v3(ob->obmat, r_center);
2178       return true;
2179     }
2180   }
2181   else if (t->options & CTX_PAINT_CURVE) {
2182     Paint *p = BKE_paint_get_active(t->scene, t->view_layer);
2183     Brush *br = p->brush;
2184     PaintCurve *pc = br->paint_curve;
2185     copy_v3_v3(r_center, pc->points[pc->add_index - 1].bez.vec[1]);
2186     r_center[2] = 0.0f;
2187     return true;
2188   }
2189   else {
2190     /* object mode */
2191     ViewLayer *view_layer = t->view_layer;
2192     Object *ob = OBACT(view_layer);
2193     Base *base = BASACT(view_layer);
2194     if (ob && ((!select_only) || ((base->flag & BASE_SELECTED) != 0))) {
2195       copy_v3_v3(r_center, ob->obmat[3]);
2196       return true;
2197     }
2198   }
2199
2200   return false;
2201 }
2202
2203 static void calculateCenter_FromAround(TransInfo *t, int around, float r_center[3])
2204 {
2205   switch (around) {
2206     case V3D_AROUND_CENTER_BOUNDS:
2207       calculateCenterBound(t, r_center);
2208       break;
2209     case V3D_AROUND_CENTER_MEDIAN:
2210       calculateCenterMedian(t, r_center);
2211       break;
2212     case V3D_AROUND_CURSOR:
2213       if (ELEM(t->spacetype, SPACE_IMAGE, SPACE_CLIP)) {
2214         calculateCenterCursor2D(t, r_center);
2215       }
2216       else if (t->spacetype == SPACE_GRAPH) {
2217         calculateCenterCursorGraph2D(t, r_center);
2218       }
2219       else {
2220         calculateCenterCursor(t, r_center);
2221       }
2222       break;
2223     case V3D_AROUND_LOCAL_ORIGINS:
2224       /* Individual element center uses median center for helpline and such */
2225       calculateCenterMedian(t, r_center);
2226       break;
2227     case V3D_AROUND_ACTIVE: {
2228       if (calculateCenterActive(t, false, r_center)) {
2229         /* pass */
2230       }
2231       else {
2232         /* fallback */
2233         calculateCenterMedian(t, r_center);
2234       }
2235       break;
2236     }
2237   }
2238 }
2239
2240 void calculateCenter(TransInfo *t)
2241 {
2242   if ((t->flag & T_OVERRIDE_CENTER) == 0) {
2243     calculateCenter_FromAround(t, t->around, t->center_global);
2244   }
2245   calculateCenterLocal(t, t->center_global);
2246
2247   /* avoid calculating again */
2248   {
2249     TransCenterData *cd = &t->center_cache[t->around];
2250     copy_v3_v3(cd->global, t->center_global);
2251     cd->is_set = true;
2252   }
2253
2254   calculateCenter2D(t);
2255
2256   /* for panning from cameraview */
2257   if ((t->flag & T_OBJECT) && (t->flag & T_OVERRIDE_CENTER) == 0) {
2258     if (t->spacetype == SPACE_VIEW3D && t->ar && t->ar->regiontype == RGN_TYPE_WINDOW) {
2259
2260       if (t->flag & T_CAMERA) {
2261         float axis[3];
2262         /* persinv is nasty, use viewinv instead, always right */
2263         copy_v3_v3(axis, t->viewinv[2]);
2264         normalize_v3(axis);
2265
2266         /* 6.0 = 6 grid units */
2267         axis[0] = t->center_global[0] - 6.0f * axis[0];
2268         axis[1] = t->center_global[1] - 6.0f * axis[1];
2269         axis[2] = t->center_global[2] - 6.0f * axis[2];
2270
2271         projectFloatView(t, axis, t->center2d);
2272
2273         /* rotate only needs correct 2d center, grab needs ED_view3d_calc_zfac() value */
2274         if (t->mode == TFM_TRANSLATION) {
2275           copy_v3_v3(t->center_global, axis);
2276         }
2277       }
2278     }
2279   }
2280
2281   if (t->spacetype == SPACE_VIEW3D) {
2282     /* ED_view3d_calc_zfac() defines a factor for perspective depth correction,
2283      * used in ED_view3d_win_to_delta() */
2284
2285     /* zfac is only used convertViewVec only in cases operator was invoked in RGN_TYPE_WINDOW
2286      * and never used in other cases.
2287      *
2288      * We need special case here as well, since ED_view3d_calc_zfac will crash when called
2289      * for a region different from RGN_TYPE_WINDOW.
2290      */
2291     if (t->ar->regiontype == RGN_TYPE_WINDOW) {
2292       t->zfac = ED_view3d_calc_zfac(t->ar->regiondata, t->center_global, NULL);
2293     }
2294     else {
2295       t->zfac = 0.0f;
2296     }
2297   }
2298 }
2299
2300 BLI_STATIC_ASSERT(ARRAY_SIZE(((TransInfo *)NULL)->center_cache) == (V3D_AROUND_ACTIVE + 1),
2301                   "test size");
2302
2303 /**
2304  * Lazy initialize transform center data, when we need to access center values from other types.
2305  */
2306 const TransCenterData *transformCenter_from_type(TransInfo *t, int around)
2307 {
2308   BLI_assert(around <= V3D_AROUND_ACTIVE);
2309   TransCenterData *cd = &t->center_cache[around];
2310   if (cd->is_set == false) {
2311     calculateCenter_FromAround(t, around, cd->global);
2312     cd->is_set = true;
2313   }
2314   return cd;
2315 }
2316
2317 void calculatePropRatio(TransInfo *t)
2318 {
2319   int i;
2320   float dist;
2321   const bool connected = (t->flag & T_PROP_CONNECTED) != 0;
2322
2323   t->proptext[0] = '\0';
2324
2325   if (t->flag & T_PROP_EDIT) {
2326     const char *pet_id = NULL;
2327     FOREACH_TRANS_DATA_CONTAINER (t, tc) {
2328       TransData *td = tc->data;
2329       for (i = 0; i < tc->data_len; i++, td++) {
2330         if (td->flag & TD_SELECTED) {
2331           td->factor = 1.0f;
2332         }
2333         else if (tc->mirror.axis_flag && (td->loc[0] * tc->mirror.sign) < -0.00001f) {
2334           td->flag |= TD_SKIP;
2335           td->factor = 0.0f;
2336           restoreElement(td);
2337         }
2338         else if ((connected && (td->flag & TD_NOTCONNECTED || td->dist > t->prop_size)) ||
2339                  (connected == 0 && td->rdist > t->prop_size)) {
2340           /*
2341            * The elements are sorted according to their dist member in the array,
2342            * that means we can stop when it finds one element outside of the propsize.
2343            * do not set 'td->flag |= TD_NOACTION', the prop circle is being changed.
2344            */
2345
2346           td->factor = 0.0f;
2347           restoreElement(td);
2348         }
2349         else {
2350           /* Use rdist for falloff calculations, it is the real distance */
2351           td->flag &= ~TD_NOACTION;
2352
2353           if (connected) {
2354             dist = (t->prop_size - td->dist) / t->prop_size;
2355           }
2356           else {
2357             dist = (t->prop_size - td->rdist) / t->prop_size;
2358           }
2359
2360           /*
2361            * Clamp to positive numbers.
2362            * Certain corner cases with connectivity and individual centers
2363            * can give values of rdist larger than propsize.
2364            */
2365           if (dist < 0.0f) {
2366             dist = 0.0f;
2367           }
2368
2369           switch (t->prop_mode) {
2370             case PROP_SHARP:
2371               td->factor = dist * dist;
2372               break;
2373             case PROP_SMOOTH:
2374               td->factor = 3.0f * dist * dist - 2.0f * dist * dist * dist;
2375               break;
2376             case PROP_ROOT:
2377               td->factor = sqrtf(dist);
2378               break;
2379             case PROP_LIN:
2380               td->factor = dist;
2381               break;
2382             case PROP_CONST:
2383               td->factor = 1.0f;
2384               break;
2385             case PROP_SPHERE:
2386               td->factor = sqrtf(2 * dist - dist * dist);
2387               break;
2388             case PROP_RANDOM:
2389               if (t->rng == NULL) {
2390                 /* Lazy initialization. */
2391                 uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX);
2392                 t->rng = BLI_rng_new(rng_seed);
2393               }
2394               td->factor = BLI_rng_get_float(t->rng) * dist;
2395               break;
2396             case PROP_INVSQUARE:
2397               td->factor = dist * (2.0f - dist);
2398               break;
2399             default:
2400               td->factor = 1;
2401               break;
2402           }
2403         }
2404       }
2405     }
2406
2407     switch (t->prop_mode) {
2408       case PROP_SHARP:
2409         pet_id = N_("(Sharp)");
2410         break;
2411       case PROP_SMOOTH:
2412         pet_id = N_("(Smooth)");
2413         break;
2414       case PROP_ROOT:
2415         pet_id = N_("(Root)");
2416         break;
2417       case PROP_LIN:
2418         pet_id = N_("(Linear)");
2419         break;
2420       case PROP_CONST:
2421         pet_id = N_("(Constant)");
2422         break;
2423       case PROP_SPHERE:
2424         pet_id = N_("(Sphere)");
2425         break;
2426       case PROP_RANDOM:
2427         pet_id = N_("(Random)");
2428         break;
2429       case PROP_INVSQUARE:
2430         pet_id = N_("(InvSquare)");
2431         break;
2432       default:
2433         break;
2434     }
2435
2436     if (pet_id) {
2437       BLI_strncpy(t->proptext, IFACE_(pet_id), sizeof(t->proptext));
2438     }
2439   }
2440   else {
2441     FOREACH_TRANS_DATA_CONTAINER (t, tc) {
2442       TransData *td = tc->data;
2443       for (i = 0; i < tc->data_len; i++, td++) {
2444         td->factor = 1.0;
2445       }
2446     }
2447   }
2448 }
2449
2450 /**
2451  * Rotate an element, low level code, ignore protected channels.
2452  * (use for objects or pose-bones)
2453  * Similar to #ElementRotation.
2454  */
2455 void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot)
2456 {
2457   float totmat[3][3];
2458   float smat[3][3];
2459   float fmat[3][3];
2460   float obmat[3][3];
2461
2462   float dmat[3][3]; /* delta rotation */
2463   float dmat_inv[3][3];
2464
2465   mul_m3_m3m3(totmat, mat, td->mtx);
2466   mul_m3_m3m3(smat, td->smtx, mat);
2467
2468   /* logic from BKE_object_rot_to_mat3 */
2469   if (use_drot) {
2470     if (td->ext->rotOrder > 0) {
2471       eulO_to_mat3(dmat, td->ext->drot, td->ext->rotOrder);
2472     }
2473     else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
2474 #if 0
2475       axis_angle_to_mat3(dmat, td->ext->drotAxis, td->ext->drotAngle);
2476 #else
2477       unit_m3(dmat);
2478 #endif
2479     }
2480     else {
2481       float tquat[4];
2482       normalize_qt_qt(tquat, td->ext->dquat);
2483       quat_to_mat3(dmat, tquat);
2484     }
2485
2486     invert_m3_m3(dmat_inv, dmat);
2487   }
2488
2489   if (td->ext->rotOrder == ROT_MODE_QUAT) {
2490     float quat[4];
2491
2492     /* calculate the total rotatation */
2493     quat_to_mat3(obmat, td->ext->iquat);
2494     if (use_drot) {
2495       mul_m3_m3m3(obmat, dmat, obmat);
2496     }
2497
2498     /* mat = transform, obmat = object rotation */
2499     mul_m3_m3m3(fmat, smat, obmat);
2500
2501     if (use_drot) {
2502       mul_m3_m3m3(fmat, dmat_inv, fmat);
2503     }
2504
2505     mat3_to_quat(quat, fmat);
2506
2507     /* apply */
2508     copy_qt_qt(td->ext->quat, quat);
2509   }
2510   else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
2511     float axis[3], angle;
2512
2513     /* calculate the total rotatation */
2514     axis_angle_to_mat3(obmat, td->ext->irotAxis, td->ext->irotAngle);
2515     if (use_drot) {
2516       mul_m3_m3m3(obmat, dmat, obmat);
2517     }
2518
2519     /* mat = transform, obmat = object rotation */
2520     mul_m3_m3m3(fmat, smat, obmat);
2521
2522     if (use_drot) {
2523       mul_m3_m3m3(fmat, dmat_inv, fmat);
2524     }
2525
2526     mat3_to_axis_angle(axis, &angle, fmat);
2527
2528     /* apply */
2529     copy_v3_v3(td->ext->rotAxis, axis);
2530     *td->ext->rotAngle = angle;
2531   }
2532   else {
2533     float eul[3];
2534
2535     /* calculate the total rotatation */
2536     eulO_to_mat3(obmat, td->ext->irot, td->ext->rotOrder);
2537     if (use_drot) {
2538       mul_m3_m3m3(obmat, dmat, obmat);
2539     }
2540
2541     /* mat = transform, obmat = object rotation */
2542     mul_m3_m3m3(fmat, smat, obmat);
2543
2544     if (use_drot) {
2545       mul_m3_m3m3(fmat, dmat_inv, fmat);
2546     }
2547
2548     mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat);
2549
2550     /* apply */
2551     copy_v3_v3(td->ext->rot, eul);
2552   }
2553 }