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