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