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