Fix T65632: Connected Proportional Editing is affected by Curve Object's Local Scale
[blender.git] / source / blender / editors / transform / transform_conversions.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 #include <limits.h>
27
28 #include "DNA_anim_types.h"
29 #include "DNA_brush_types.h"
30 #include "DNA_armature_types.h"
31 #include "DNA_lattice_types.h"
32 #include "DNA_mesh_types.h"
33 #include "DNA_meta_types.h"
34 #include "DNA_node_types.h"
35 #include "DNA_screen_types.h"
36 #include "DNA_space_types.h"
37 #include "DNA_sequence_types.h"
38 #include "DNA_view3d_types.h"
39 #include "DNA_constraint_types.h"
40 #include "DNA_scene_types.h"
41 #include "DNA_meshdata_types.h"
42 #include "DNA_gpencil_types.h"
43 #include "DNA_movieclip_types.h"
44 #include "DNA_mask_types.h"
45
46 #include "MEM_guardedalloc.h"
47
48 #include "BLI_math.h"
49 #include "BLI_utildefines.h"
50 #include "BLI_listbase.h"
51 #include "BLI_linklist_stack.h"
52 #include "BLI_string.h"
53 #include "BLI_bitmap.h"
54 #include "BLI_rect.h"
55
56 #include "BKE_action.h"
57 #include "BKE_animsys.h"
58 #include "BKE_armature.h"
59 #include "BKE_constraint.h"
60 #include "BKE_context.h"
61 #include "BKE_crazyspace.h"
62 #include "BKE_curve.h"
63 #include "BKE_fcurve.h"
64 #include "BKE_global.h"
65 #include "BKE_gpencil.h"
66 #include "BKE_layer.h"
67 #include "BKE_key.h"
68 #include "BKE_main.h"
69 #include "BKE_mesh.h"
70 #include "BKE_mesh_mapping.h"
71 #include "BKE_modifier.h"
72 #include "BKE_movieclip.h"
73 #include "BKE_nla.h"
74 #include "BKE_node.h"
75 #include "BKE_object.h"
76 #include "BKE_particle.h"
77 #include "BKE_paint.h"
78 #include "BKE_pointcache.h"
79 #include "BKE_report.h"
80 #include "BKE_rigidbody.h"
81 #include "BKE_scene.h"
82 #include "BKE_sequencer.h"
83 #include "BKE_editmesh.h"
84 #include "BKE_tracking.h"
85 #include "BKE_mask.h"
86 #include "BKE_colortools.h"
87
88 #include "BIK_api.h"
89
90 #include "ED_anim_api.h"
91 #include "ED_armature.h"
92 #include "ED_particle.h"
93 #include "ED_image.h"
94 #include "ED_keyframing.h"
95 #include "ED_keyframes_edit.h"
96 #include "ED_object.h"
97 #include "ED_markers.h"
98 #include "ED_mesh.h"
99 #include "ED_node.h"
100 #include "ED_uvedit.h"
101 #include "ED_clip.h"
102 #include "ED_mask.h"
103 #include "ED_gpencil.h"
104
105 #include "WM_api.h" /* for WM_event_add_notifier to deal with stabilization nodes */
106 #include "WM_types.h"
107
108 #include "UI_view2d.h"
109 #include "UI_interface.h"
110
111 #include "RNA_access.h"
112
113 #include "DEG_depsgraph.h"
114 #include "DEG_depsgraph_build.h"
115 #include "DEG_depsgraph_query.h"
116
117 #include "transform.h"
118 #include "bmesh.h"
119
120 /**
121  * Transforming around ourselves is no use, fallback to individual origins,
122  * useful for curve/armatures.
123  */
124 static void transform_around_single_fallback(TransInfo *t)
125 {
126   if ((t->data_len_all == 1) &&
127       (ELEM(t->around, V3D_AROUND_CENTER_BOUNDS, V3D_AROUND_CENTER_MEDIAN, V3D_AROUND_ACTIVE)) &&
128       (ELEM(t->mode, TFM_RESIZE, TFM_ROTATION, TFM_TRACKBALL))) {
129     t->around = V3D_AROUND_LOCAL_ORIGINS;
130   }
131 }
132
133 /* when transforming islands */
134 struct TransIslandData {
135   float co[3];
136   float axismtx[3][3];
137 };
138
139 /* local function prototype - for Object/Bone Constraints */
140 static bool constraints_list_needinv(TransInfo *t, ListBase *list);
141
142 /* ************************** Functions *************************** */
143
144 static int trans_data_compare_dist(const void *a, const void *b)
145 {
146   const TransData *td_a = (const TransData *)a;
147   const TransData *td_b = (const TransData *)b;
148
149   if (td_a->dist < td_b->dist) {
150     return -1;
151   }
152   else if (td_a->dist > td_b->dist) {
153     return 1;
154   }
155   else {
156     return 0;
157   }
158 }
159
160 static int trans_data_compare_rdist(const void *a, const void *b)
161 {
162   const TransData *td_a = (const TransData *)a;
163   const TransData *td_b = (const TransData *)b;
164
165   if (td_a->rdist < td_b->rdist) {
166     return -1;
167   }
168   else if (td_a->rdist > td_b->rdist) {
169     return 1;
170   }
171   else {
172     return 0;
173   }
174 }
175
176 static void sort_trans_data_dist_container(const TransInfo *t, TransDataContainer *tc)
177 {
178   TransData *start = tc->data;
179   int i;
180
181   for (i = 0; i < tc->data_len && start->flag & TD_SELECTED; i++) {
182     start++;
183   }
184
185   if (i < tc->data_len) {
186     if (t->flag & T_PROP_CONNECTED) {
187       qsort(start, tc->data_len - i, sizeof(TransData), trans_data_compare_dist);
188     }
189     else {
190       qsort(start, tc->data_len - i, sizeof(TransData), trans_data_compare_rdist);
191     }
192   }
193 }
194 void sort_trans_data_dist(TransInfo *t)
195 {
196   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
197     sort_trans_data_dist_container(t, tc);
198   }
199 }
200
201 /**
202  * Make #TD_SELECTED first in the array.
203  */
204 static void sort_trans_data_selected_first_container(TransDataContainer *tc)
205 {
206   TransData *sel, *unsel;
207   TransData temp;
208   unsel = tc->data;
209   sel = tc->data;
210   sel += tc->data_len - 1;
211   while (sel > unsel) {
212     while (unsel->flag & TD_SELECTED) {
213       unsel++;
214       if (unsel == sel) {
215         return;
216       }
217     }
218     while (!(sel->flag & TD_SELECTED)) {
219       sel--;
220       if (unsel == sel) {
221         return;
222       }
223     }
224     temp = *unsel;
225     *unsel = *sel;
226     *sel = temp;
227     sel--;
228     unsel++;
229   }
230 }
231 static void sort_trans_data_selected_first(TransInfo *t)
232 {
233   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
234     sort_trans_data_selected_first_container(tc);
235   }
236 }
237
238 /* distance calculated from not-selected vertex to nearest selected vertex
239  * warning; this is loops inside loop, has minor N^2 issues, but by sorting list it is OK */
240 static void set_prop_dist(TransInfo *t, const bool with_dist)
241 {
242   int a;
243
244   float _proj_vec[3];
245   const float *proj_vec = NULL;
246
247   /* support for face-islands */
248   const bool use_island = transdata_check_local_islands(t, t->around);
249
250   if (t->flag & T_PROP_PROJECTED) {
251     if (t->spacetype == SPACE_VIEW3D && t->ar && t->ar->regiontype == RGN_TYPE_WINDOW) {
252       RegionView3D *rv3d = t->ar->regiondata;
253       normalize_v3_v3(_proj_vec, rv3d->viewinv[2]);
254       proj_vec = _proj_vec;
255     }
256   }
257
258   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
259     TransData *tob = tc->data;
260     for (a = 0; a < tc->data_len; a++, tob++) {
261
262       tob->rdist = 0.0f;  // init, it was mallocced
263
264       if ((tob->flag & TD_SELECTED) == 0) {
265         TransData *td;
266         int i;
267         float dist_sq, vec[3];
268
269         tob->rdist = -1.0f;  // signal for next loop
270
271         for (i = 0, td = tc->data; i < tc->data_len; i++, td++) {
272           if (td->flag & TD_SELECTED) {
273             if (use_island) {
274               sub_v3_v3v3(vec, tob->iloc, td->iloc);
275             }
276             else {
277               sub_v3_v3v3(vec, tob->center, td->center);
278             }
279             mul_m3_v3(tob->mtx, vec);
280
281             if (proj_vec) {
282               float vec_p[3];
283               project_v3_v3v3(vec_p, vec, proj_vec);
284               sub_v3_v3(vec, vec_p);
285             }
286
287             dist_sq = len_squared_v3(vec);
288             if ((tob->rdist == -1.0f) || (dist_sq < SQUARE(tob->rdist))) {
289               tob->rdist = sqrtf(dist_sq);
290               if (use_island) {
291                 copy_v3_v3(tob->center, td->center);
292                 copy_m3_m3(tob->axismtx, td->axismtx);
293               }
294             }
295           }
296           else {
297             break; /* by definition transdata has selected items in beginning */
298           }
299         }
300         if (with_dist) {
301           tob->dist = tob->rdist;
302         }
303       }
304     }
305   }
306 }
307
308 /* ************************** CONVERSIONS ************************* */
309
310 /* ********************* texture space ********* */
311
312 static void createTransTexspace(TransInfo *t)
313 {
314   ViewLayer *view_layer = t->view_layer;
315   TransData *td;
316   Object *ob;
317   ID *id;
318   short *texflag;
319
320   ob = OBACT(view_layer);
321
322   if (ob == NULL) {  // Shouldn't logically happen, but still...
323     return;
324   }
325
326   id = ob->data;
327   if (id == NULL || !ELEM(GS(id->name), ID_ME, ID_CU, ID_MB)) {
328     BKE_report(t->reports, RPT_ERROR, "Unsupported object type for text-space transform");
329     return;
330   }
331
332   if (BKE_object_obdata_is_libdata(ob)) {
333     BKE_report(t->reports, RPT_ERROR, "Linked data can't text-space transform");
334     return;
335   }
336
337   {
338     BLI_assert(t->data_container_len == 1);
339     TransDataContainer *tc = t->data_container;
340     tc->data_len = 1;
341     td = tc->data = MEM_callocN(sizeof(TransData), "TransTexspace");
342     td->ext = tc->data_ext = MEM_callocN(sizeof(TransDataExtension), "TransTexspace");
343   }
344
345   td->flag = TD_SELECTED;
346   copy_v3_v3(td->center, ob->obmat[3]);
347   td->ob = ob;
348
349   copy_m3_m4(td->mtx, ob->obmat);
350   copy_m3_m4(td->axismtx, ob->obmat);
351   normalize_m3(td->axismtx);
352   pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
353
354   if (BKE_object_obdata_texspace_get(ob, &texflag, &td->loc, &td->ext->size, &td->ext->rot)) {
355     ob->dtx |= OB_TEXSPACE;
356     *texflag &= ~ME_AUTOSPACE;
357   }
358
359   copy_v3_v3(td->iloc, td->loc);
360   copy_v3_v3(td->ext->irot, td->ext->rot);
361   copy_v3_v3(td->ext->isize, td->ext->size);
362 }
363
364 /* -------------------------------------------------------------------- */
365 /** \name Cursor Transform Creation
366  *
367  * Instead of transforming the selection, move the 2D/3D cursor.
368  *
369  * \{ */
370
371 static void createTransCursor_image(TransInfo *t)
372 {
373   TransData *td;
374   SpaceImage *sima = t->sa->spacedata.first;
375   float *cursor_location = sima->cursor;
376
377   {
378     BLI_assert(t->data_container_len == 1);
379     TransDataContainer *tc = t->data_container;
380     tc->data_len = 1;
381     td = tc->data = MEM_callocN(sizeof(TransData), "TransTexspace");
382     td->ext = tc->data_ext = MEM_callocN(sizeof(TransDataExtension), "TransTexspace");
383   }
384
385   td->flag = TD_SELECTED;
386   copy_v3_v3(td->center, cursor_location);
387   td->ob = NULL;
388
389   unit_m3(td->mtx);
390   unit_m3(td->axismtx);
391   pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
392
393   td->loc = cursor_location;
394   copy_v3_v3(td->iloc, cursor_location);
395 }
396
397 static void createTransCursor_view3d(TransInfo *t)
398 {
399   TransData *td;
400
401   Scene *scene = t->scene;
402   if (ID_IS_LINKED(scene)) {
403     BKE_report(t->reports, RPT_ERROR, "Linked data can't text-space transform");
404     return;
405   }
406
407   View3DCursor *cursor = &scene->cursor;
408   {
409     BLI_assert(t->data_container_len == 1);
410     TransDataContainer *tc = t->data_container;
411     tc->data_len = 1;
412     td = tc->data = MEM_callocN(sizeof(TransData), "TransTexspace");
413     td->ext = tc->data_ext = MEM_callocN(sizeof(TransDataExtension), "TransTexspace");
414   }
415
416   td->flag = TD_SELECTED;
417   copy_v3_v3(td->center, cursor->location);
418   td->ob = NULL;
419
420   unit_m3(td->mtx);
421   BKE_scene_cursor_rot_to_mat3(cursor, td->axismtx);
422   normalize_m3(td->axismtx);
423   pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
424
425   td->loc = cursor->location;
426   copy_v3_v3(td->iloc, cursor->location);
427
428   if (cursor->rotation_mode > 0) {
429     td->ext->rot = cursor->rotation_euler;
430     td->ext->rotAxis = NULL;
431     td->ext->rotAngle = NULL;
432     td->ext->quat = NULL;
433
434     copy_v3_v3(td->ext->irot, cursor->rotation_euler);
435   }
436   else if (cursor->rotation_mode == ROT_MODE_AXISANGLE) {
437     td->ext->rot = NULL;
438     td->ext->rotAxis = cursor->rotation_axis;
439     td->ext->rotAngle = &cursor->rotation_angle;
440     td->ext->quat = NULL;
441
442     td->ext->irotAngle = cursor->rotation_angle;
443     copy_v3_v3(td->ext->irotAxis, cursor->rotation_axis);
444   }
445   else {
446     td->ext->rot = NULL;
447     td->ext->rotAxis = NULL;
448     td->ext->rotAngle = NULL;
449     td->ext->quat = cursor->rotation_quaternion;
450
451     copy_qt_qt(td->ext->iquat, cursor->rotation_quaternion);
452   }
453   td->ext->rotOrder = cursor->rotation_mode;
454 }
455
456 /** \} */
457
458 /* ********************* edge (for crease) ***** */
459
460 static void createTransEdge(TransInfo *t)
461 {
462   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
463
464     BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
465     TransData *td = NULL;
466     BMEdge *eed;
467     BMIter iter;
468     float mtx[3][3], smtx[3][3];
469     int count = 0, countsel = 0;
470     const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
471     int cd_edge_float_offset;
472
473     BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
474       if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
475         if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
476           countsel++;
477         }
478         if (is_prop_edit) {
479           count++;
480         }
481       }
482     }
483
484     if (countsel == 0) {
485       tc->data_len = 0;
486       continue;
487     }
488
489     if (is_prop_edit) {
490       tc->data_len = count;
491     }
492     else {
493       tc->data_len = countsel;
494     }
495
496     td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransCrease");
497
498     copy_m3_m4(mtx, tc->obedit->obmat);
499     pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
500
501     /* create data we need */
502     if (t->mode == TFM_BWEIGHT) {
503       BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_EDGE_BWEIGHT);
504       cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT);
505     }
506     else {  // if (t->mode == TFM_CREASE) {
507       BLI_assert(t->mode == TFM_CREASE);
508       BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_EDGE_CREASE);
509       cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE);
510     }
511
512     BLI_assert(cd_edge_float_offset != -1);
513
514     BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
515       if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) &&
516           (BM_elem_flag_test(eed, BM_ELEM_SELECT) || is_prop_edit)) {
517         float *fl_ptr;
518         /* need to set center for center calculations */
519         mid_v3_v3v3(td->center, eed->v1->co, eed->v2->co);
520
521         td->loc = NULL;
522         if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
523           td->flag = TD_SELECTED;
524         }
525         else {
526           td->flag = 0;
527         }
528
529         copy_m3_m3(td->smtx, smtx);
530         copy_m3_m3(td->mtx, mtx);
531
532         td->ext = NULL;
533
534         fl_ptr = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_float_offset);
535         td->val = fl_ptr;
536         td->ival = *fl_ptr;
537
538         td++;
539       }
540     }
541   }
542 }
543
544 /* ********************* pose mode ************* */
545
546 static bKinematicConstraint *has_targetless_ik(bPoseChannel *pchan)
547 {
548   bConstraint *con = pchan->constraints.first;
549
550   for (; con; con = con->next) {
551     if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce != 0.0f)) {
552       bKinematicConstraint *data = con->data;
553
554       if (data->tar == NULL) {
555         return data;
556       }
557       if (data->tar->type == OB_ARMATURE && data->subtarget[0] == 0) {
558         return data;
559       }
560     }
561   }
562   return NULL;
563 }
564
565 static short apply_targetless_ik(Object *ob)
566 {
567   bPoseChannel *pchan, *parchan, *chanlist[256];
568   bKinematicConstraint *data;
569   int segcount, apply = 0;
570
571   /* now we got a difficult situation... we have to find the
572    * target-less IK pchans, and apply transformation to the all
573    * pchans that were in the chain */
574
575   for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
576     data = has_targetless_ik(pchan);
577     if (data && (data->flag & CONSTRAINT_IK_AUTO)) {
578
579       /* fill the array with the bones of the chain (armature.c does same, keep it synced) */
580       segcount = 0;
581
582       /* exclude tip from chain? */
583       if (!(data->flag & CONSTRAINT_IK_TIP)) {
584         parchan = pchan->parent;
585       }
586       else {
587         parchan = pchan;
588       }
589
590       /* Find the chain's root & count the segments needed */
591       for (; parchan; parchan = parchan->parent) {
592         chanlist[segcount] = parchan;
593         segcount++;
594
595         if (segcount == data->rootbone || segcount > 255) {
596           break;  // 255 is weak
597         }
598       }
599       for (; segcount; segcount--) {
600         Bone *bone;
601         float rmat[4][4] /*, tmat[4][4], imat[4][4]*/;
602
603         /* pose_mat(b) = pose_mat(b-1) * offs_bone * channel * constraint * IK  */
604         /* we put in channel the entire result of rmat = (channel * constraint * IK) */
605         /* pose_mat(b) = pose_mat(b-1) * offs_bone * rmat  */
606         /* rmat = pose_mat(b) * inv(pose_mat(b-1) * offs_bone ) */
607
608         parchan = chanlist[segcount - 1];
609         bone = parchan->bone;
610         bone->flag |= BONE_TRANSFORM; /* ensures it gets an auto key inserted */
611
612         BKE_armature_mat_pose_to_bone(parchan, parchan->pose_mat, rmat);
613
614         /* apply and decompose, doesn't work for constraints or non-uniform scale well */
615         {
616           float rmat3[3][3], qrmat[3][3], imat3[3][3], smat[3][3];
617           copy_m3_m4(rmat3, rmat);
618
619           /* rotation */
620           /* [#22409] is partially caused by this, as slight numeric error introduced during
621            * the solving process leads to locked-axis values changing. However, we cannot modify
622            * the values here, or else there are huge discrepancies between IK-solver (interactive)
623            * and applied poses. */
624           BKE_pchan_mat3_to_rot(parchan, rmat3, false);
625
626           /* for size, remove rotation */
627           /* causes problems with some constraints (so apply only if needed) */
628           if (data->flag & CONSTRAINT_IK_STRETCH) {
629             BKE_pchan_rot_to_mat3(parchan, qrmat);
630             invert_m3_m3(imat3, qrmat);
631             mul_m3_m3m3(smat, rmat3, imat3);
632             mat3_to_size(parchan->size, smat);
633           }
634
635           /* causes problems with some constraints (e.g. childof), so disable this */
636           /* as it is IK shouldn't affect location directly */
637           /* copy_v3_v3(parchan->loc, rmat[3]); */
638         }
639       }
640
641       apply = 1;
642       data->flag &= ~CONSTRAINT_IK_AUTO;
643     }
644   }
645
646   return apply;
647 }
648
649 static void add_pose_transdata(
650     TransInfo *t, bPoseChannel *pchan, Object *ob, TransDataContainer *tc, TransData *td)
651 {
652   Bone *bone = pchan->bone;
653   float pmat[3][3], omat[3][3];
654   float cmat[3][3], tmat[3][3];
655   float vec[3];
656
657   copy_v3_v3(vec, pchan->pose_mat[3]);
658   copy_v3_v3(td->center, vec);
659
660   td->ob = ob;
661   td->flag = TD_SELECTED;
662   if (bone->flag & BONE_HINGE_CHILD_TRANSFORM) {
663     td->flag |= TD_NOCENTER;
664   }
665
666   if (bone->flag & BONE_TRANSFORM_CHILD) {
667     td->flag |= TD_NOCENTER;
668     td->flag |= TD_NO_LOC;
669   }
670
671   td->protectflag = pchan->protectflag;
672
673   td->loc = pchan->loc;
674   copy_v3_v3(td->iloc, pchan->loc);
675
676   td->ext->size = pchan->size;
677   copy_v3_v3(td->ext->isize, pchan->size);
678
679   if (pchan->rotmode > 0) {
680     td->ext->rot = pchan->eul;
681     td->ext->rotAxis = NULL;
682     td->ext->rotAngle = NULL;
683     td->ext->quat = NULL;
684
685     copy_v3_v3(td->ext->irot, pchan->eul);
686   }
687   else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
688     td->ext->rot = NULL;
689     td->ext->rotAxis = pchan->rotAxis;
690     td->ext->rotAngle = &pchan->rotAngle;
691     td->ext->quat = NULL;
692
693     td->ext->irotAngle = pchan->rotAngle;
694     copy_v3_v3(td->ext->irotAxis, pchan->rotAxis);
695   }
696   else {
697     td->ext->rot = NULL;
698     td->ext->rotAxis = NULL;
699     td->ext->rotAngle = NULL;
700     td->ext->quat = pchan->quat;
701
702     copy_qt_qt(td->ext->iquat, pchan->quat);
703   }
704   td->ext->rotOrder = pchan->rotmode;
705
706   /* proper way to get parent transform + own transform + constraints transform */
707   copy_m3_m4(omat, ob->obmat);
708
709   /* New code, using "generic" BKE_bone_parent_transform_calc_from_pchan(). */
710   {
711     BoneParentTransform bpt;
712     float rpmat[3][3];
713
714     BKE_bone_parent_transform_calc_from_pchan(pchan, &bpt);
715     if (t->mode == TFM_TRANSLATION) {
716       copy_m3_m4(pmat, bpt.loc_mat);
717     }
718     else {
719       copy_m3_m4(pmat, bpt.rotscale_mat);
720     }
721
722     /* Grrr! Exceptional case: When translating pose bones that are either Hinge or NoLocal,
723      * and want align snapping, we just need both loc_mat and rotscale_mat.
724      * So simply always store rotscale mat in td->ext, and always use it to apply rotations...
725      * Ugly to need such hacks! :/ */
726     copy_m3_m4(rpmat, bpt.rotscale_mat);
727
728     if (constraints_list_needinv(t, &pchan->constraints)) {
729       copy_m3_m4(tmat, pchan->constinv);
730       invert_m3_m3(cmat, tmat);
731       mul_m3_series(td->mtx, cmat, omat, pmat);
732       mul_m3_series(td->ext->r_mtx, cmat, omat, rpmat);
733     }
734     else {
735       mul_m3_series(td->mtx, omat, pmat);
736       mul_m3_series(td->ext->r_mtx, omat, rpmat);
737     }
738     invert_m3_m3(td->ext->r_smtx, td->ext->r_mtx);
739   }
740
741   pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
742
743   /* exceptional case: rotate the pose bone which also applies transformation
744    * when a parentless bone has BONE_NO_LOCAL_LOCATION [] */
745   if (!ELEM(t->mode, TFM_TRANSLATION, TFM_RESIZE) &&
746       (pchan->bone->flag & BONE_NO_LOCAL_LOCATION)) {
747     if (pchan->parent) {
748       /* same as td->smtx but without pchan->bone->bone_mat */
749       td->flag |= TD_PBONE_LOCAL_MTX_C;
750       mul_m3_m3m3(td->ext->l_smtx, pchan->bone->bone_mat, td->smtx);
751     }
752     else {
753       td->flag |= TD_PBONE_LOCAL_MTX_P;
754     }
755   }
756
757   /* for axismat we use bone's own transform */
758   copy_m3_m4(pmat, pchan->pose_mat);
759   mul_m3_m3m3(td->axismtx, omat, pmat);
760   normalize_m3(td->axismtx);
761
762   if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
763     bArmature *arm = tc->poseobj->data;
764
765     if ((t->mode == TFM_BONE_ENVELOPE_DIST) || (arm->drawtype == ARM_ENVELOPE)) {
766       td->loc = NULL;
767       td->val = &bone->dist;
768       td->ival = bone->dist;
769     }
770     else {
771       // abusive storage of scale in the loc pointer :)
772       td->loc = &bone->xwidth;
773       copy_v3_v3(td->iloc, td->loc);
774       td->val = NULL;
775     }
776   }
777
778   /* in this case we can do target-less IK grabbing */
779   if (t->mode == TFM_TRANSLATION) {
780     bKinematicConstraint *data = has_targetless_ik(pchan);
781     if (data) {
782       if (data->flag & CONSTRAINT_IK_TIP) {
783         copy_v3_v3(data->grabtarget, pchan->pose_tail);
784       }
785       else {
786         copy_v3_v3(data->grabtarget, pchan->pose_head);
787       }
788       td->loc = data->grabtarget;
789       copy_v3_v3(td->iloc, td->loc);
790       data->flag |= CONSTRAINT_IK_AUTO;
791
792       /* only object matrix correction */
793       copy_m3_m3(td->mtx, omat);
794       pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
795     }
796   }
797
798   /* store reference to first constraint */
799   td->con = pchan->constraints.first;
800 }
801
802 static void bone_children_clear_transflag(int mode, short around, ListBase *lb)
803 {
804   Bone *bone = lb->first;
805
806   for (; bone; bone = bone->next) {
807     if ((bone->flag & BONE_HINGE) && (bone->flag & BONE_CONNECTED)) {
808       bone->flag |= BONE_HINGE_CHILD_TRANSFORM;
809     }
810     else if ((bone->flag & BONE_TRANSFORM) && (mode == TFM_ROTATION || mode == TFM_TRACKBALL) &&
811              (around == V3D_AROUND_LOCAL_ORIGINS)) {
812       bone->flag |= BONE_TRANSFORM_CHILD;
813     }
814     else {
815       bone->flag &= ~(BONE_TRANSFORM | BONE_TRANSFORM_MIRROR);
816     }
817
818     bone_children_clear_transflag(mode, around, &bone->childbase);
819   }
820 }
821
822 /* sets transform flags in the bones
823  * returns total number of bones with BONE_TRANSFORM */
824 int count_set_pose_transflags(Object *ob,
825                               const int mode,
826                               const short around,
827                               bool has_translate_rotate[2])
828 {
829   bArmature *arm = ob->data;
830   bPoseChannel *pchan;
831   Bone *bone;
832   int total = 0;
833
834   for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
835     bone = pchan->bone;
836     if (PBONE_VISIBLE(arm, bone)) {
837       if ((bone->flag & BONE_SELECTED)) {
838         bone->flag |= BONE_TRANSFORM;
839       }
840       else {
841         bone->flag &= ~(BONE_TRANSFORM | BONE_TRANSFORM_MIRROR);
842       }
843
844       bone->flag &= ~BONE_HINGE_CHILD_TRANSFORM;
845       bone->flag &= ~BONE_TRANSFORM_CHILD;
846     }
847     else {
848       bone->flag &= ~(BONE_TRANSFORM | BONE_TRANSFORM_MIRROR);
849     }
850   }
851
852   /* make sure no bone can be transformed when a parent is transformed */
853   /* since pchans are depsgraph sorted, the parents are in beginning of list */
854   if (!ELEM(mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
855     for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
856       bone = pchan->bone;
857       if (bone->flag & BONE_TRANSFORM) {
858         bone_children_clear_transflag(mode, around, &bone->childbase);
859       }
860     }
861   }
862   /* now count, and check if we have autoIK or have to switch from translate to rotate */
863   for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
864     bone = pchan->bone;
865     if (bone->flag & BONE_TRANSFORM) {
866       total++;
867
868       if (has_translate_rotate != NULL) {
869         if (has_targetless_ik(pchan) == NULL) {
870           if (pchan->parent && (pchan->bone->flag & BONE_CONNECTED)) {
871             if (pchan->bone->flag & BONE_HINGE_CHILD_TRANSFORM) {
872               has_translate_rotate[0] = true;
873             }
874           }
875           else {
876             if ((pchan->protectflag & OB_LOCK_LOC) != OB_LOCK_LOC) {
877               has_translate_rotate[0] = true;
878             }
879           }
880           if ((pchan->protectflag & OB_LOCK_ROT) != OB_LOCK_ROT) {
881             has_translate_rotate[1] = true;
882           }
883         }
884         else {
885           has_translate_rotate[0] = true;
886         }
887       }
888     }
889   }
890
891   return total;
892 }
893
894 /* -------- Auto-IK ---------- */
895
896 /* adjust pose-channel's auto-ik chainlen */
897 static bool pchan_autoik_adjust(bPoseChannel *pchan, short chainlen)
898 {
899   bConstraint *con;
900   bool changed = false;
901
902   /* don't bother to search if no valid constraints */
903   if ((pchan->constflag & (PCHAN_HAS_IK | PCHAN_HAS_TARGET)) == 0) {
904     return changed;
905   }
906
907   /* check if pchan has ik-constraint */
908   for (con = pchan->constraints.first; con; con = con->next) {
909     if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce != 0.0f)) {
910       bKinematicConstraint *data = con->data;
911
912       /* only accept if a temporary one (for auto-ik) */
913       if (data->flag & CONSTRAINT_IK_TEMP) {
914         /* chainlen is new chainlen, but is limited by maximum chainlen */
915         const int old_rootbone = data->rootbone;
916         if ((chainlen == 0) || (chainlen > data->max_rootbone)) {
917           data->rootbone = data->max_rootbone;
918         }
919         else {
920           data->rootbone = chainlen;
921         }
922         changed |= (data->rootbone != old_rootbone);
923       }
924     }
925   }
926
927   return changed;
928 }
929
930 /* change the chain-length of auto-ik */
931 void transform_autoik_update(TransInfo *t, short mode)
932 {
933   Main *bmain = CTX_data_main(t->context);
934
935   short *chainlen = &t->settings->autoik_chainlen;
936   bPoseChannel *pchan;
937
938   /* mode determines what change to apply to chainlen */
939   if (mode == 1) {
940     /* mode=1 is from WHEELMOUSEDOWN... increases len */
941     (*chainlen)++;
942   }
943   else if (mode == -1) {
944     /* mode==-1 is from WHEELMOUSEUP... decreases len */
945     if (*chainlen > 0) {
946       (*chainlen)--;
947     }
948     else {
949       /* IK length did not change, skip updates. */
950       return;
951     }
952   }
953
954   /* apply to all pose-channels */
955   bool changed = false;
956
957   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
958
959     /* sanity checks (don't assume t->poseobj is set, or that it is an armature) */
960     if (ELEM(NULL, tc->poseobj, tc->poseobj->pose)) {
961       continue;
962     }
963
964     for (pchan = tc->poseobj->pose->chanbase.first; pchan; pchan = pchan->next) {
965       changed |= pchan_autoik_adjust(pchan, *chainlen);
966     }
967   }
968
969   if (changed) {
970     /* TODO(sergey): Consider doing partial update only. */
971     DEG_relations_tag_update(bmain);
972   }
973 }
974
975 /* frees temporal IKs */
976 static void pose_grab_with_ik_clear(Main *bmain, Object *ob)
977 {
978   bKinematicConstraint *data;
979   bPoseChannel *pchan;
980   bConstraint *con, *next;
981   bool relations_changed = false;
982
983   for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
984     /* clear all temporary lock flags */
985     pchan->ikflag &= ~(BONE_IK_NO_XDOF_TEMP | BONE_IK_NO_YDOF_TEMP | BONE_IK_NO_ZDOF_TEMP);
986
987     pchan->constflag &= ~(PCHAN_HAS_IK | PCHAN_HAS_TARGET);
988
989     /* remove all temporary IK-constraints added */
990     for (con = pchan->constraints.first; con; con = next) {
991       next = con->next;
992       if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
993         data = con->data;
994         if (data->flag & CONSTRAINT_IK_TEMP) {
995           relations_changed = true;
996
997           /* iTaSC needs clear for removed constraints */
998           BIK_clear_data(ob->pose);
999
1000           BLI_remlink(&pchan->constraints, con);
1001           MEM_freeN(con->data);
1002           MEM_freeN(con);
1003           continue;
1004         }
1005         pchan->constflag |= PCHAN_HAS_IK;
1006         if (data->tar == NULL || (data->tar->type == OB_ARMATURE && data->subtarget[0] == 0)) {
1007           pchan->constflag |= PCHAN_HAS_TARGET;
1008         }
1009       }
1010     }
1011   }
1012
1013   if (relations_changed) {
1014     /* TODO(sergey): Consider doing partial update only. */
1015     DEG_relations_tag_update(bmain);
1016   }
1017 }
1018
1019 /* adds the IK to pchan - returns if added */
1020 static short pose_grab_with_ik_add(bPoseChannel *pchan)
1021 {
1022   bKinematicConstraint *targetless = NULL;
1023   bKinematicConstraint *data;
1024   bConstraint *con;
1025
1026   /* Sanity check */
1027   if (pchan == NULL) {
1028     return 0;
1029   }
1030
1031   /* Rule: not if there's already an IK on this channel */
1032   for (con = pchan->constraints.first; con; con = con->next) {
1033     if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
1034       data = con->data;
1035
1036       if (data->tar == NULL || (data->tar->type == OB_ARMATURE && data->subtarget[0] == '\0')) {
1037         /* make reference to constraint to base things off later
1038          * (if it's the last targetless constraint encountered) */
1039         targetless = (bKinematicConstraint *)con->data;
1040
1041         /* but, if this is a targetless IK, we make it auto anyway (for the children loop) */
1042         if (con->enforce != 0.0f) {
1043           data->flag |= CONSTRAINT_IK_AUTO;
1044
1045           /* if no chain length has been specified,
1046            * just make things obey standard rotation locks too */
1047           if (data->rootbone == 0) {
1048             for (; pchan; pchan = pchan->parent) {
1049               /* here, we set ik-settings for bone from pchan->protectflag */
1050               // XXX: careful with quats/axis-angle rotations where we're locking 4d components
1051               if (pchan->protectflag & OB_LOCK_ROTX) {
1052                 pchan->ikflag |= BONE_IK_NO_XDOF_TEMP;
1053               }
1054               if (pchan->protectflag & OB_LOCK_ROTY) {
1055                 pchan->ikflag |= BONE_IK_NO_YDOF_TEMP;
1056               }
1057               if (pchan->protectflag & OB_LOCK_ROTZ) {
1058                 pchan->ikflag |= BONE_IK_NO_ZDOF_TEMP;
1059               }
1060             }
1061           }
1062
1063           return 0;
1064         }
1065       }
1066
1067       if ((con->flag & CONSTRAINT_DISABLE) == 0 && (con->enforce != 0.0f)) {
1068         return 0;
1069       }
1070     }
1071   }
1072
1073   con = BKE_constraint_add_for_pose(NULL, pchan, "TempConstraint", CONSTRAINT_TYPE_KINEMATIC);
1074
1075   /* for draw, but also for detecting while pose solving */
1076   pchan->constflag |= (PCHAN_HAS_IK | PCHAN_HAS_TARGET);
1077
1078   data = con->data;
1079   if (targetless) {
1080     /* if exists, use values from last targetless (but disabled) IK-constraint as base */
1081     *data = *targetless;
1082   }
1083   else {
1084     data->flag = CONSTRAINT_IK_TIP;
1085   }
1086   data->flag |= CONSTRAINT_IK_TEMP | CONSTRAINT_IK_AUTO | CONSTRAINT_IK_POS;
1087   copy_v3_v3(data->grabtarget, pchan->pose_tail);
1088
1089   /* watch-it! has to be 0 here, since we're still on the
1090    * same bone for the first time through the loop T25885. */
1091   data->rootbone = 0;
1092
1093   /* we only include bones that are part of a continual connected chain */
1094   do {
1095     /* here, we set ik-settings for bone from pchan->protectflag */
1096     // XXX: careful with quats/axis-angle rotations where we're locking 4d components
1097     if (pchan->protectflag & OB_LOCK_ROTX) {
1098       pchan->ikflag |= BONE_IK_NO_XDOF_TEMP;
1099     }
1100     if (pchan->protectflag & OB_LOCK_ROTY) {
1101       pchan->ikflag |= BONE_IK_NO_YDOF_TEMP;
1102     }
1103     if (pchan->protectflag & OB_LOCK_ROTZ) {
1104       pchan->ikflag |= BONE_IK_NO_ZDOF_TEMP;
1105     }
1106
1107     /* now we count this pchan as being included */
1108     data->rootbone++;
1109
1110     /* continue to parent, but only if we're connected to it */
1111     if (pchan->bone->flag & BONE_CONNECTED) {
1112       pchan = pchan->parent;
1113     }
1114     else {
1115       pchan = NULL;
1116     }
1117   } while (pchan);
1118
1119   /* make a copy of maximum chain-length */
1120   data->max_rootbone = data->rootbone;
1121
1122   return 1;
1123 }
1124
1125 /* bone is a candidate to get IK, but we don't do it if it has children connected */
1126 static short pose_grab_with_ik_children(bPose *pose, Bone *bone)
1127 {
1128   Bone *bonec;
1129   short wentdeeper = 0, added = 0;
1130
1131   /* go deeper if children & children are connected */
1132   for (bonec = bone->childbase.first; bonec; bonec = bonec->next) {
1133     if (bonec->flag & BONE_CONNECTED) {
1134       wentdeeper = 1;
1135       added += pose_grab_with_ik_children(pose, bonec);
1136     }
1137   }
1138   if (wentdeeper == 0) {
1139     bPoseChannel *pchan = BKE_pose_channel_find_name(pose, bone->name);
1140     if (pchan) {
1141       added += pose_grab_with_ik_add(pchan);
1142     }
1143   }
1144
1145   return added;
1146 }
1147
1148 /* main call which adds temporal IK chains */
1149 static short pose_grab_with_ik(Main *bmain, Object *ob)
1150 {
1151   bArmature *arm;
1152   bPoseChannel *pchan, *parent;
1153   Bone *bonec;
1154   short tot_ik = 0;
1155
1156   if ((ob == NULL) || (ob->pose == NULL) || (ob->mode & OB_MODE_POSE) == 0) {
1157     return 0;
1158   }
1159
1160   arm = ob->data;
1161
1162   /* Rule: allow multiple Bones
1163    * (but they must be selected, and only one ik-solver per chain should get added) */
1164   for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
1165     if (pchan->bone->layer & arm->layer) {
1166       if (pchan->bone->flag & BONE_SELECTED) {
1167         /* Rule: no IK for solitatry (unconnected) bones */
1168         for (bonec = pchan->bone->childbase.first; bonec; bonec = bonec->next) {
1169           if (bonec->flag & BONE_CONNECTED) {
1170             break;
1171           }
1172         }
1173         if ((pchan->bone->flag & BONE_CONNECTED) == 0 && (bonec == NULL)) {
1174           continue;
1175         }
1176
1177         /* rule: if selected Bone is not a root bone, it gets a temporal IK */
1178         if (pchan->parent) {
1179           /* only adds if there's no IK yet (and no parent bone was selected) */
1180           for (parent = pchan->parent; parent; parent = parent->parent) {
1181             if (parent->bone->flag & BONE_SELECTED) {
1182               break;
1183             }
1184           }
1185           if (parent == NULL) {
1186             tot_ik += pose_grab_with_ik_add(pchan);
1187           }
1188         }
1189         else {
1190           /* rule: go over the children and add IK to the tips */
1191           tot_ik += pose_grab_with_ik_children(ob->pose, pchan->bone);
1192         }
1193       }
1194     }
1195   }
1196
1197   /* iTaSC needs clear for new IK constraints */
1198   if (tot_ik) {
1199     BIK_clear_data(ob->pose);
1200     /* TODO(sergey): Consider doing partial update only. */
1201     DEG_relations_tag_update(bmain);
1202   }
1203
1204   return (tot_ik) ? 1 : 0;
1205 }
1206
1207 static void pose_mirror_info_init(PoseInitData_Mirror *pid,
1208                                   bPoseChannel *pchan,
1209                                   bPoseChannel *pchan_orig,
1210                                   bool is_mirror_relative)
1211 {
1212   pid->pchan = pchan;
1213   copy_v3_v3(pid->orig.loc, pchan->loc);
1214   copy_v3_v3(pid->orig.size, pchan->size);
1215   pid->orig.curve_in_x = pchan->curve_in_x;
1216   pid->orig.curve_out_x = pchan->curve_out_x;
1217   pid->orig.roll1 = pchan->roll1;
1218   pid->orig.roll2 = pchan->roll2;
1219
1220   if (pchan->rotmode > 0) {
1221     copy_v3_v3(pid->orig.eul, pchan->eul);
1222   }
1223   else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
1224     copy_v3_v3(pid->orig.axis_angle, pchan->rotAxis);
1225     pid->orig.axis_angle[3] = pchan->rotAngle;
1226   }
1227   else {
1228     copy_qt_qt(pid->orig.quat, pchan->quat);
1229   }
1230
1231   if (is_mirror_relative) {
1232     float pchan_mtx[4][4];
1233     float pchan_mtx_mirror[4][4];
1234
1235     float flip_mtx[4][4];
1236     unit_m4(flip_mtx);
1237     flip_mtx[0][0] = -1;
1238
1239     BKE_pchan_to_mat4(pchan_orig, pchan_mtx_mirror);
1240     BKE_pchan_to_mat4(pchan, pchan_mtx);
1241
1242     mul_m4_m4m4(pchan_mtx_mirror, pchan_mtx_mirror, flip_mtx);
1243     mul_m4_m4m4(pchan_mtx_mirror, flip_mtx, pchan_mtx_mirror);
1244
1245     invert_m4(pchan_mtx_mirror);
1246     mul_m4_m4m4(pid->offset_mtx, pchan_mtx, pchan_mtx_mirror);
1247   }
1248   else {
1249     unit_m4(pid->offset_mtx);
1250   }
1251 }
1252
1253 static void pose_mirror_info_restore(const PoseInitData_Mirror *pid)
1254 {
1255   bPoseChannel *pchan = pid->pchan;
1256   copy_v3_v3(pchan->loc, pid->orig.loc);
1257   copy_v3_v3(pchan->size, pid->orig.size);
1258   pchan->curve_in_x = pid->orig.curve_in_x;
1259   pchan->curve_out_x = pid->orig.curve_out_x;
1260   pchan->roll1 = pid->orig.roll1;
1261   pchan->roll2 = pid->orig.roll2;
1262
1263   if (pchan->rotmode > 0) {
1264     copy_v3_v3(pchan->eul, pid->orig.eul);
1265   }
1266   else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
1267     copy_v3_v3(pchan->rotAxis, pid->orig.axis_angle);
1268     pchan->rotAngle = pid->orig.axis_angle[3];
1269   }
1270   else {
1271     copy_qt_qt(pchan->quat, pid->orig.quat);
1272   }
1273 }
1274
1275 /**
1276  * When objects array is NULL, use 't->data_container' as is.
1277  */
1278 static void createTransPose(TransInfo *t)
1279 {
1280   Main *bmain = CTX_data_main(t->context);
1281
1282   t->data_len_all = 0;
1283
1284   bool has_translate_rotate_buf[2] = {false, false};
1285   bool *has_translate_rotate = (t->mode == TFM_TRANSLATION) ? has_translate_rotate_buf : NULL;
1286
1287   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
1288     Object *ob = tc->poseobj;
1289     bPose *pose = ob->pose;
1290
1291     bArmature *arm;
1292     short ik_on = 0;
1293
1294     /* check validity of state */
1295     arm = BKE_armature_from_object(tc->poseobj);
1296     if ((arm == NULL) || (pose == NULL)) {
1297       continue;
1298     }
1299
1300     const bool mirror = ((pose->flag & POSE_MIRROR_EDIT) != 0);
1301
1302     /* set flags and count total */
1303     tc->data_len = count_set_pose_transflags(ob, t->mode, t->around, has_translate_rotate);
1304     if (tc->data_len == 0) {
1305       continue;
1306     }
1307
1308     if (arm->flag & ARM_RESTPOS) {
1309       if (ELEM(t->mode, TFM_DUMMY, TFM_BONESIZE) == 0) {
1310         BKE_report(t->reports, RPT_ERROR, "Cannot change Pose when 'Rest Position' is enabled");
1311         tc->data_len = 0;
1312         continue;
1313       }
1314     }
1315
1316     /* do we need to add temporal IK chains? */
1317     if ((pose->flag & POSE_AUTO_IK) && t->mode == TFM_TRANSLATION) {
1318       ik_on = pose_grab_with_ik(bmain, ob);
1319       if (ik_on) {
1320         t->flag |= T_AUTOIK;
1321         has_translate_rotate[0] = true;
1322       }
1323     }
1324
1325     if (mirror) {
1326       int total_mirrored = 0;
1327       for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
1328         if ((pchan->bone->flag & BONE_TRANSFORM) &&
1329             BKE_pose_channel_get_mirrored(ob->pose, pchan->name)) {
1330           total_mirrored++;
1331         }
1332       }
1333
1334       PoseInitData_Mirror *pid = MEM_mallocN((total_mirrored + 1) * sizeof(PoseInitData_Mirror),
1335                                              "PoseInitData_Mirror");
1336
1337       /* Trick to terminate iteration. */
1338       pid[total_mirrored].pchan = NULL;
1339
1340       tc->custom.type.data = pid;
1341       tc->custom.type.use_free = true;
1342     }
1343   }
1344
1345   /* if there are no translatable bones, do rotation */
1346   if ((t->mode == TFM_TRANSLATION) && !has_translate_rotate[0]) {
1347     if (has_translate_rotate[1]) {
1348       t->mode = TFM_ROTATION;
1349     }
1350     else {
1351       t->mode = TFM_RESIZE;
1352     }
1353   }
1354
1355   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
1356     if (tc->data_len == 0) {
1357       continue;
1358     }
1359     Object *ob = tc->poseobj;
1360     TransData *td;
1361     TransDataExtension *tdx;
1362     short ik_on = 0;
1363     int i;
1364
1365     PoseInitData_Mirror *pid = tc->custom.type.data;
1366     int pid_index = 0;
1367     bPose *pose = ob->pose;
1368
1369     if (pose == NULL) {
1370       continue;
1371     }
1372
1373     const bool mirror = ((pose->flag & POSE_MIRROR_EDIT) != 0);
1374     const bool is_mirror_relative = ((pose->flag & POSE_MIRROR_RELATIVE) != 0);
1375
1376     tc->poseobj = ob; /* we also allow non-active objects to be transformed, in weightpaint */
1377
1378     /* init trans data */
1379     td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransPoseBone");
1380     tdx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension),
1381                                      "TransPoseBoneExt");
1382     for (i = 0; i < tc->data_len; i++, td++, tdx++) {
1383       td->ext = tdx;
1384       td->val = NULL;
1385     }
1386
1387     /* use pose channels to fill trans data */
1388     td = tc->data;
1389     for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
1390       if (pchan->bone->flag & BONE_TRANSFORM) {
1391         add_pose_transdata(t, pchan, ob, tc, td);
1392
1393         if (mirror) {
1394           bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(ob->pose, pchan->name);
1395           if (pchan_mirror) {
1396             pose_mirror_info_init(&pid[pid_index], pchan_mirror, pchan, is_mirror_relative);
1397             pid_index++;
1398           }
1399         }
1400
1401         td++;
1402       }
1403     }
1404
1405     if (td != (tc->data + tc->data_len)) {
1406       BKE_report(t->reports, RPT_DEBUG, "Bone selection count error");
1407     }
1408
1409     /* initialize initial auto=ik chainlen's? */
1410     if (ik_on) {
1411       transform_autoik_update(t, 0);
1412     }
1413   }
1414
1415   t->flag |= T_POSE;
1416   /* disable PET, its not usable in pose mode yet [#32444] */
1417   t->flag &= ~T_PROP_EDIT_ALL;
1418 }
1419
1420 void restoreMirrorPoseBones(TransDataContainer *tc)
1421 {
1422   bPose *pose = tc->poseobj->pose;
1423
1424   if (!(pose->flag & POSE_MIRROR_EDIT)) {
1425     return;
1426   }
1427
1428   for (PoseInitData_Mirror *pid = tc->custom.type.data; pid->pchan; pid++) {
1429     pose_mirror_info_restore(pid);
1430   }
1431 }
1432
1433 void restoreBones(TransDataContainer *tc)
1434 {
1435   bArmature *arm;
1436   BoneInitData *bid = tc->custom.type.data;
1437   EditBone *ebo;
1438
1439   if (tc->obedit) {
1440     arm = tc->obedit->data;
1441   }
1442   else {
1443     BLI_assert(tc->poseobj != NULL);
1444     arm = tc->poseobj->data;
1445   }
1446
1447   while (bid->bone) {
1448     ebo = bid->bone;
1449
1450     ebo->dist = bid->dist;
1451     ebo->rad_tail = bid->rad_tail;
1452     ebo->roll = bid->roll;
1453     ebo->xwidth = bid->xwidth;
1454     ebo->zwidth = bid->zwidth;
1455     copy_v3_v3(ebo->head, bid->head);
1456     copy_v3_v3(ebo->tail, bid->tail);
1457
1458     if (arm->flag & ARM_MIRROR_EDIT) {
1459       EditBone *ebo_child;
1460
1461       /* Also move connected ebo_child, in case ebo_child's name aren't mirrored properly */
1462       for (ebo_child = arm->edbo->first; ebo_child; ebo_child = ebo_child->next) {
1463         if ((ebo_child->flag & BONE_CONNECTED) && (ebo_child->parent == ebo)) {
1464           copy_v3_v3(ebo_child->head, ebo->tail);
1465           ebo_child->rad_head = ebo->rad_tail;
1466         }
1467       }
1468
1469       /* Also move connected parent, in case parent's name isn't mirrored properly */
1470       if ((ebo->flag & BONE_CONNECTED) && ebo->parent) {
1471         EditBone *parent = ebo->parent;
1472         copy_v3_v3(parent->tail, ebo->head);
1473         parent->rad_tail = ebo->rad_head;
1474       }
1475     }
1476
1477     bid++;
1478   }
1479 }
1480
1481 /* ********************* armature ************** */
1482 static void createTransArmatureVerts(TransInfo *t)
1483 {
1484   t->data_len_all = 0;
1485
1486   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
1487     EditBone *ebo, *eboflip;
1488     bArmature *arm = tc->obedit->data;
1489     ListBase *edbo = arm->edbo;
1490     bool mirror = ((arm->flag & ARM_MIRROR_EDIT) != 0);
1491     int total_mirrored = 0;
1492
1493     tc->data_len = 0;
1494     for (ebo = edbo->first; ebo; ebo = ebo->next) {
1495       const int data_len_prev = tc->data_len;
1496
1497       if (EBONE_VISIBLE(arm, ebo) && !(ebo->flag & BONE_EDITMODE_LOCKED)) {
1498         if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
1499           if (ebo->flag & BONE_SELECTED) {
1500             tc->data_len++;
1501           }
1502         }
1503         else if (t->mode == TFM_BONE_ROLL) {
1504           if (ebo->flag & BONE_SELECTED) {
1505             tc->data_len++;
1506           }
1507         }
1508         else {
1509           if (ebo->flag & BONE_TIPSEL) {
1510             tc->data_len++;
1511           }
1512           if (ebo->flag & BONE_ROOTSEL) {
1513             tc->data_len++;
1514           }
1515         }
1516       }
1517
1518       if (mirror && (data_len_prev < tc->data_len)) {
1519         eboflip = ED_armature_ebone_get_mirrored(arm->edbo, ebo);
1520         if (eboflip) {
1521           total_mirrored++;
1522         }
1523       }
1524     }
1525     if (!tc->data_len) {
1526       continue;
1527     }
1528
1529     if (mirror) {
1530       BoneInitData *bid = MEM_mallocN((total_mirrored + 1) * sizeof(BoneInitData), "BoneInitData");
1531
1532       /* trick to terminate iteration */
1533       bid[total_mirrored].bone = NULL;
1534
1535       tc->custom.type.data = bid;
1536       tc->custom.type.use_free = true;
1537     }
1538     t->data_len_all += tc->data_len;
1539   }
1540
1541   transform_around_single_fallback(t);
1542   t->data_len_all = -1;
1543
1544   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
1545     if (!tc->data_len) {
1546       continue;
1547     }
1548
1549     EditBone *ebo, *eboflip;
1550     bArmature *arm = tc->obedit->data;
1551     ListBase *edbo = arm->edbo;
1552     TransData *td, *td_old;
1553     float mtx[3][3], smtx[3][3], bonemat[3][3];
1554     bool mirror = ((arm->flag & ARM_MIRROR_EDIT) != 0);
1555     BoneInitData *bid = tc->custom.type.data;
1556
1557     copy_m3_m4(mtx, tc->obedit->obmat);
1558     pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
1559
1560     td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransEditBone");
1561     int i = 0;
1562
1563     for (ebo = edbo->first; ebo; ebo = ebo->next) {
1564       td_old = td;
1565       ebo->oldlength =
1566           ebo->length;  // length==0.0 on extrude, used for scaling radius of bone points
1567
1568       if (EBONE_VISIBLE(arm, ebo) && !(ebo->flag & BONE_EDITMODE_LOCKED)) {
1569         if (t->mode == TFM_BONE_ENVELOPE) {
1570           if (ebo->flag & BONE_ROOTSEL) {
1571             td->val = &ebo->rad_head;
1572             td->ival = *td->val;
1573
1574             copy_v3_v3(td->center, ebo->head);
1575             td->flag = TD_SELECTED;
1576
1577             copy_m3_m3(td->smtx, smtx);
1578             copy_m3_m3(td->mtx, mtx);
1579
1580             td->loc = NULL;
1581             td->ext = NULL;
1582             td->ob = tc->obedit;
1583
1584             td++;
1585           }
1586           if (ebo->flag & BONE_TIPSEL) {
1587             td->val = &ebo->rad_tail;
1588             td->ival = *td->val;
1589             copy_v3_v3(td->center, ebo->tail);
1590             td->flag = TD_SELECTED;
1591
1592             copy_m3_m3(td->smtx, smtx);
1593             copy_m3_m3(td->mtx, mtx);
1594
1595             td->loc = NULL;
1596             td->ext = NULL;
1597             td->ob = tc->obedit;
1598
1599             td++;
1600           }
1601         }
1602         else if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
1603           if (ebo->flag & BONE_SELECTED) {
1604             if ((t->mode == TFM_BONE_ENVELOPE_DIST) || (arm->drawtype == ARM_ENVELOPE)) {
1605               td->loc = NULL;
1606               td->val = &ebo->dist;
1607               td->ival = ebo->dist;
1608             }
1609             else {
1610               // abusive storage of scale in the loc pointer :)
1611               td->loc = &ebo->xwidth;
1612               copy_v3_v3(td->iloc, td->loc);
1613               td->val = NULL;
1614             }
1615             copy_v3_v3(td->center, ebo->head);
1616             td->flag = TD_SELECTED;
1617
1618             /* use local bone matrix */
1619             ED_armature_ebone_to_mat3(ebo, bonemat);
1620             mul_m3_m3m3(td->mtx, mtx, bonemat);
1621             invert_m3_m3(td->smtx, td->mtx);
1622
1623             copy_m3_m3(td->axismtx, td->mtx);
1624             normalize_m3(td->axismtx);
1625
1626             td->ext = NULL;
1627             td->ob = tc->obedit;
1628
1629             td++;
1630           }
1631         }
1632         else if (t->mode == TFM_BONE_ROLL) {
1633           if (ebo->flag & BONE_SELECTED) {
1634             td->loc = NULL;
1635             td->val = &(ebo->roll);
1636             td->ival = ebo->roll;
1637
1638             copy_v3_v3(td->center, ebo->head);
1639             td->flag = TD_SELECTED;
1640
1641             td->ext = NULL;
1642             td->ob = tc->obedit;
1643
1644             td++;
1645           }
1646         }
1647         else {
1648           if (ebo->flag & BONE_TIPSEL) {
1649             copy_v3_v3(td->iloc, ebo->tail);
1650
1651             /* Don't allow single selected tips to have a modified center,
1652              * causes problem with snapping (see T45974).
1653              * However, in rotation mode, we want to keep that 'rotate bone around root with
1654              * only its tip selected' behavior (see T46325). */
1655             if ((t->around == V3D_AROUND_LOCAL_ORIGINS) &&
1656                 ((t->mode == TFM_ROTATION) || (ebo->flag & BONE_ROOTSEL))) {
1657               copy_v3_v3(td->center, ebo->head);
1658             }
1659             else {
1660               copy_v3_v3(td->center, td->iloc);
1661             }
1662
1663             td->loc = ebo->tail;
1664             td->flag = TD_SELECTED;
1665             if (ebo->flag & BONE_EDITMODE_LOCKED) {
1666               td->protectflag = OB_LOCK_LOC | OB_LOCK_ROT | OB_LOCK_SCALE;
1667             }
1668
1669             copy_m3_m3(td->smtx, smtx);
1670             copy_m3_m3(td->mtx, mtx);
1671
1672             ED_armature_ebone_to_mat3(ebo, td->axismtx);
1673
1674             if ((ebo->flag & BONE_ROOTSEL) == 0) {
1675               td->extra = ebo;
1676               td->ival = ebo->roll;
1677             }
1678
1679             td->ext = NULL;
1680             td->val = NULL;
1681             td->ob = tc->obedit;
1682
1683             td++;
1684           }
1685           if (ebo->flag & BONE_ROOTSEL) {
1686             copy_v3_v3(td->iloc, ebo->head);
1687             copy_v3_v3(td->center, td->iloc);
1688             td->loc = ebo->head;
1689             td->flag = TD_SELECTED;
1690             if (ebo->flag & BONE_EDITMODE_LOCKED) {
1691               td->protectflag = OB_LOCK_LOC | OB_LOCK_ROT | OB_LOCK_SCALE;
1692             }
1693
1694             copy_m3_m3(td->smtx, smtx);
1695             copy_m3_m3(td->mtx, mtx);
1696
1697             ED_armature_ebone_to_mat3(ebo, td->axismtx);
1698
1699             td->extra = ebo; /* to fix roll */
1700             td->ival = ebo->roll;
1701
1702             td->ext = NULL;
1703             td->val = NULL;
1704             td->ob = tc->obedit;
1705
1706             td++;
1707           }
1708         }
1709       }
1710
1711       if (mirror && (td_old != td)) {
1712         eboflip = ED_armature_ebone_get_mirrored(arm->edbo, ebo);
1713         if (eboflip) {
1714           bid[i].bone = eboflip;
1715           bid[i].dist = eboflip->dist;
1716           bid[i].rad_tail = eboflip->rad_tail;
1717           bid[i].roll = eboflip->roll;
1718           bid[i].xwidth = eboflip->xwidth;
1719           bid[i].zwidth = eboflip->zwidth;
1720           copy_v3_v3(bid[i].head, eboflip->head);
1721           copy_v3_v3(bid[i].tail, eboflip->tail);
1722           i++;
1723         }
1724       }
1725     }
1726
1727     if (mirror) {
1728       /* trick to terminate iteration */
1729       BLI_assert(i + 1 == (MEM_allocN_len(bid) / sizeof(*bid)));
1730       bid[i].bone = NULL;
1731     }
1732   }
1733 }
1734
1735 /* ********************* meta elements ********* */
1736
1737 static void createTransMBallVerts(TransInfo *t)
1738 {
1739   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
1740     MetaBall *mb = (MetaBall *)tc->obedit->data;
1741     MetaElem *ml;
1742     TransData *td;
1743     TransDataExtension *tx;
1744     float mtx[3][3], smtx[3][3];
1745     int count = 0, countsel = 0;
1746     const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
1747
1748     /* count totals */
1749     for (ml = mb->editelems->first; ml; ml = ml->next) {
1750       if (ml->flag & SELECT) {
1751         countsel++;
1752       }
1753       if (is_prop_edit) {
1754         count++;
1755       }
1756     }
1757
1758     /* note: in prop mode we need at least 1 selected */
1759     if (countsel == 0) {
1760       continue;
1761     }
1762
1763     if (is_prop_edit) {
1764       tc->data_len = count;
1765     }
1766     else {
1767       tc->data_len = countsel;
1768     }
1769
1770     td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(MBall EditMode)");
1771     tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension),
1772                                     "MetaElement_TransExtension");
1773
1774     copy_m3_m4(mtx, tc->obedit->obmat);
1775     pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
1776
1777     for (ml = mb->editelems->first; ml; ml = ml->next) {
1778       if (is_prop_edit || (ml->flag & SELECT)) {
1779         td->loc = &ml->x;
1780         copy_v3_v3(td->iloc, td->loc);
1781         copy_v3_v3(td->center, td->loc);
1782
1783         quat_to_mat3(td->axismtx, ml->quat);
1784
1785         if (ml->flag & SELECT) {
1786           td->flag = TD_SELECTED | TD_USEQUAT | TD_SINGLESIZE;
1787         }
1788         else {
1789           td->flag = TD_USEQUAT;
1790         }
1791
1792         copy_m3_m3(td->smtx, smtx);
1793         copy_m3_m3(td->mtx, mtx);
1794
1795         td->ext = tx;
1796
1797         /* Radius of MetaElem (mass of MetaElem influence) */
1798         if (ml->flag & MB_SCALE_RAD) {
1799           td->val = &ml->rad;
1800           td->ival = ml->rad;
1801         }
1802         else {
1803           td->val = &ml->s;
1804           td->ival = ml->s;
1805         }
1806
1807         /* expx/expy/expz determine "shape" of some MetaElem types */
1808         tx->size = &ml->expx;
1809         tx->isize[0] = ml->expx;
1810         tx->isize[1] = ml->expy;
1811         tx->isize[2] = ml->expz;
1812
1813         /* quat is used for rotation of MetaElem */
1814         tx->quat = ml->quat;
1815         copy_qt_qt(tx->iquat, ml->quat);
1816
1817         tx->rot = NULL;
1818
1819         td++;
1820         tx++;
1821       }
1822     }
1823   }
1824 }
1825
1826 /* ********************* curve/surface ********* */
1827
1828 static void calc_distanceCurveVerts(TransData *head, TransData *tail)
1829 {
1830   TransData *td, *td_near = NULL;
1831   for (td = head; td <= tail; td++) {
1832     if (td->flag & TD_SELECTED) {
1833       td_near = td;
1834       td->dist = 0.0f;
1835     }
1836     else if (td_near) {
1837       float dist;
1838       float vec[3];
1839
1840       sub_v3_v3v3(vec, td_near->center, td->center);
1841       mul_m3_v3(head->mtx, vec);
1842       dist = len_v3(vec);
1843
1844       if (dist < (td - 1)->dist) {
1845         td->dist = (td - 1)->dist;
1846       }
1847       else {
1848         td->dist = dist;
1849       }
1850     }
1851     else {
1852       td->dist = FLT_MAX;
1853       td->flag |= TD_NOTCONNECTED;
1854     }
1855   }
1856   td_near = NULL;
1857   for (td = tail; td >= head; td--) {
1858     if (td->flag & TD_SELECTED) {
1859       td_near = td;
1860       td->dist = 0.0f;
1861     }
1862     else if (td_near) {
1863       float dist;
1864       float vec[3];
1865
1866       sub_v3_v3v3(vec, td_near->center, td->center);
1867       mul_m3_v3(head->mtx, vec);
1868       dist = len_v3(vec);
1869
1870       if (td->flag & TD_NOTCONNECTED || dist < td->dist || (td + 1)->dist < td->dist) {
1871         td->flag &= ~TD_NOTCONNECTED;
1872         if (dist < (td + 1)->dist) {
1873           td->dist = (td + 1)->dist;
1874         }
1875         else {
1876           td->dist = dist;
1877         }
1878       }
1879     }
1880   }
1881 }
1882
1883 /* Utility function for getting the handle data from bezier's */
1884 static TransDataCurveHandleFlags *initTransDataCurveHandles(TransData *td, struct BezTriple *bezt)
1885 {
1886   TransDataCurveHandleFlags *hdata;
1887   td->flag |= TD_BEZTRIPLE;
1888   hdata = td->hdata = MEM_mallocN(sizeof(TransDataCurveHandleFlags), "CuHandle Data");
1889   hdata->ih1 = bezt->h1;
1890   hdata->h1 = &bezt->h1;
1891   hdata->ih2 = bezt->h2; /* in case the second is not selected */
1892   hdata->h2 = &bezt->h2;
1893   return hdata;
1894 }
1895
1896 /**
1897  * For the purpose of transform code we need to behave as if handles are selected,
1898  * even when they aren't (see special case below).
1899  */
1900 static int bezt_select_to_transform_triple_flag(const BezTriple *bezt, const bool hide_handles)
1901 {
1902   int flag = 0;
1903
1904   if (hide_handles) {
1905     if (bezt->f2 & SELECT) {
1906       flag = (1 << 0) | (1 << 1) | (1 << 2);
1907     }
1908   }
1909   else {
1910     flag = (((bezt->f1 & SELECT) ? (1 << 0) : 0) | ((bezt->f2 & SELECT) ? (1 << 1) : 0) |
1911             ((bezt->f3 & SELECT) ? (1 << 2) : 0));
1912   }
1913
1914   /* Special case for auto & aligned handles:
1915    * When a center point is being moved without the handles,
1916    * leaving the handles stationary makes no sense and only causes strange behavior,
1917    * where one handle is arbitrarily anchored, the other one is aligned and lengthened
1918    * based on where the center point is moved. Also a bug when cancelling, see: T52007.
1919    *
1920    * A more 'correct' solution could be to store handle locations in 'TransDataCurveHandleFlags'.
1921    * However that doesn't resolve odd behavior, so best transform the handles in this case.
1922    */
1923   if ((flag != ((1 << 0) | (1 << 1) | (1 << 2))) && (flag & (1 << 1))) {
1924     if (ELEM(bezt->h1, HD_AUTO, HD_ALIGN) && ELEM(bezt->h2, HD_AUTO, HD_ALIGN)) {
1925       flag = (1 << 0) | (1 << 1) | (1 << 2);
1926     }
1927   }
1928
1929   return flag;
1930 }
1931
1932 static void createTransCurveVerts(TransInfo *t)
1933 {
1934
1935 #define SEL_F1 (1 << 0)
1936 #define SEL_F2 (1 << 1)
1937 #define SEL_F3 (1 << 2)
1938
1939   t->data_len_all = 0;
1940
1941   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
1942     Curve *cu = tc->obedit->data;
1943     BLI_assert(cu->editnurb != NULL);
1944     BezTriple *bezt;
1945     BPoint *bp;
1946     int a;
1947     int count = 0, countsel = 0;
1948     const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
1949     View3D *v3d = t->view;
1950     short hide_handles = (v3d != NULL) ?
1951                              ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) == 0) :
1952                              false;
1953
1954     /* count total of vertices, check identical as in 2nd loop for making transdata! */
1955     ListBase *nurbs = BKE_curve_editNurbs_get(cu);
1956     for (Nurb *nu = nurbs->first; nu; nu = nu->next) {
1957       if (nu->type == CU_BEZIER) {
1958         for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
1959           if (bezt->hide == 0) {
1960             const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, hide_handles);
1961             if (bezt_tx & SEL_F1) {
1962               countsel++;
1963             }
1964             if (bezt_tx & SEL_F2) {
1965               countsel++;
1966             }
1967             if (bezt_tx & SEL_F3) {
1968               countsel++;
1969             }
1970             if (is_prop_edit) {
1971               count += 3;
1972             }
1973           }
1974         }
1975       }
1976       else {
1977         for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) {
1978           if (bp->hide == 0) {
1979             if (is_prop_edit) {
1980               count++;
1981             }
1982             if (bp->f1 & SELECT) {
1983               countsel++;
1984             }
1985           }
1986         }
1987       }
1988     }
1989     /* note: in prop mode we need at least 1 selected */
1990     if (countsel == 0) {
1991       tc->data_len = 0;
1992       continue;
1993     }
1994
1995     if (is_prop_edit) {
1996       tc->data_len = count;
1997     }
1998     else {
1999       tc->data_len = countsel;
2000     }
2001     tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Curve EditMode)");
2002
2003     t->data_len_all += tc->data_len;
2004   }
2005
2006   transform_around_single_fallback(t);
2007   t->data_len_all = -1;
2008
2009   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
2010     if (tc->data_len == 0) {
2011       continue;
2012     }
2013
2014     Curve *cu = tc->obedit->data;
2015     BezTriple *bezt;
2016     BPoint *bp;
2017     int a;
2018     const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
2019     View3D *v3d = t->view;
2020     short hide_handles = (v3d != NULL) ?
2021                              ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) == 0) :
2022                              false;
2023
2024     float mtx[3][3], smtx[3][3];
2025
2026     copy_m3_m4(mtx, tc->obedit->obmat);
2027     pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
2028
2029     TransData *td = tc->data;
2030     ListBase *nurbs = BKE_curve_editNurbs_get(cu);
2031     for (Nurb *nu = nurbs->first; nu; nu = nu->next) {
2032       if (nu->type == CU_BEZIER) {
2033         TransData *head, *tail;
2034         head = tail = td;
2035         for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
2036           if (bezt->hide == 0) {
2037             TransDataCurveHandleFlags *hdata = NULL;
2038             float axismtx[3][3];
2039
2040             if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
2041               float normal[3], plane[3];
2042
2043               BKE_nurb_bezt_calc_normal(nu, bezt, normal);
2044               BKE_nurb_bezt_calc_plane(nu, bezt, plane);
2045
2046               if (createSpaceNormalTangent(axismtx, normal, plane)) {
2047                 /* pass */
2048               }
2049               else {
2050                 normalize_v3(normal);
2051                 axis_dominant_v3_to_m3(axismtx, normal);
2052                 invert_m3(axismtx);
2053               }
2054             }
2055
2056             /* Elements that will be transform (not always a match to selection). */
2057             const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, hide_handles);
2058
2059             if (is_prop_edit || bezt_tx & SEL_F1) {
2060               copy_v3_v3(td->iloc, bezt->vec[0]);
2061               td->loc = bezt->vec[0];
2062               copy_v3_v3(td->center,
2063                          bezt->vec[(hide_handles || (t->around == V3D_AROUND_LOCAL_ORIGINS) ||
2064                                     (bezt->f2 & SELECT)) ?
2065                                        1 :
2066                                        0]);
2067               if (hide_handles) {
2068                 if (bezt->f2 & SELECT) {
2069                   td->flag = TD_SELECTED;
2070                 }
2071                 else {
2072                   td->flag = 0;
2073                 }
2074               }
2075               else {
2076                 if (bezt->f1 & SELECT) {
2077                   td->flag = TD_SELECTED;
2078                 }
2079                 else {
2080                   td->flag = 0;
2081                 }
2082               }
2083               td->ext = NULL;
2084               td->val = NULL;
2085
2086               hdata = initTransDataCurveHandles(td, bezt);
2087
2088               copy_m3_m3(td->smtx, smtx);
2089               copy_m3_m3(td->mtx, mtx);
2090               if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
2091                 copy_m3_m3(td->axismtx, axismtx);
2092               }
2093
2094               td++;
2095               tail++;
2096             }
2097
2098             /* This is the Curve Point, the other two are handles */
2099             if (is_prop_edit || bezt_tx & SEL_F2) {
2100               copy_v3_v3(td->iloc, bezt->vec[1]);
2101               td->loc = bezt->vec[1];
2102               copy_v3_v3(td->center, td->loc);
2103               if (bezt->f2 & SELECT) {
2104                 td->flag = TD_SELECTED;
2105               }
2106               else {
2107                 td->flag = 0;
2108               }
2109               td->ext = NULL;
2110
2111               /* TODO - make points scale */
2112               if (t->mode == TFM_CURVE_SHRINKFATTEN) { /* || t->mode==TFM_RESIZE) {*/
2113                 td->val = &(bezt->radius);
2114                 td->ival = bezt->radius;
2115               }
2116               else if (t->mode == TFM_TILT) {
2117                 td->val = &(bezt->tilt);
2118                 td->ival = bezt->tilt;
2119               }
2120               else {
2121                 td->val = NULL;
2122               }
2123
2124               copy_m3_m3(td->smtx, smtx);
2125               copy_m3_m3(td->mtx, mtx);
2126               if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
2127                 copy_m3_m3(td->axismtx, axismtx);
2128               }
2129
2130               if ((bezt_tx & SEL_F1) == 0 && (bezt_tx & SEL_F3) == 0) {
2131                 /* If the middle is selected but the sides arnt, this is needed */
2132                 if (hdata == NULL) {
2133                   /* if the handle was not saved by the previous handle */
2134                   hdata = initTransDataCurveHandles(td, bezt);
2135                 }
2136               }
2137
2138               td++;
2139               tail++;
2140             }
2141             if (is_prop_edit || bezt_tx & SEL_F3) {
2142               copy_v3_v3(td->iloc, bezt->vec[2]);
2143               td->loc = bezt->vec[2];
2144               copy_v3_v3(td->center,
2145                          bezt->vec[(hide_handles || (t->around == V3D_AROUND_LOCAL_ORIGINS) ||
2146                                     (bezt->f2 & SELECT)) ?
2147                                        1 :
2148                                        2]);
2149               if (hide_handles) {
2150                 if (bezt->f2 & SELECT) {
2151                   td->flag = TD_SELECTED;
2152                 }
2153                 else {
2154                   td->flag = 0;
2155                 }
2156               }
2157               else {
2158                 if (bezt->f3 & SELECT) {
2159                   td->flag = TD_SELECTED;
2160                 }
2161                 else {
2162                   td->flag = 0;
2163                 }
2164               }
2165               td->ext = NULL;
2166               td->val = NULL;
2167
2168               if (hdata == NULL) {
2169                 /* if the handle was not saved by the previous handle */
2170                 hdata = initTransDataCurveHandles(td, bezt);
2171               }
2172
2173               copy_m3_m3(td->smtx, smtx);
2174               copy_m3_m3(td->mtx, mtx);
2175               if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
2176                 copy_m3_m3(td->axismtx, axismtx);
2177               }
2178
2179               td++;
2180               tail++;
2181             }
2182
2183             (void)hdata; /* quiet warning */
2184           }
2185           else if (is_prop_edit && head != tail) {
2186             calc_distanceCurveVerts(head, tail - 1);
2187             head = tail;
2188           }
2189         }
2190         if (is_prop_edit && head != tail) {
2191           calc_distanceCurveVerts(head, tail - 1);
2192         }
2193
2194         /* TODO - in the case of tilt and radius we can also avoid allocating the
2195          * initTransDataCurveHandles but for now just don't change handle types */
2196         if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT, TFM_DUMMY) == 0) {
2197           /* sets the handles based on their selection,
2198            * do this after the data is copied to the TransData */
2199           BKE_nurb_handles_test(nu, !hide_handles);
2200         }
2201       }
2202       else {
2203         TransData *head, *tail;
2204         head = tail = td;
2205         for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) {
2206           if (bp->hide == 0) {
2207             if (is_prop_edit || (bp->f1 & SELECT)) {
2208               float axismtx[3][3];
2209
2210               if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
2211                 if (nu->pntsv == 1) {
2212                   float normal[3], plane[3];
2213
2214                   BKE_nurb_bpoint_calc_normal(nu, bp, normal);
2215                   BKE_nurb_bpoint_calc_plane(nu, bp, plane);
2216
2217                   if (createSpaceNormalTangent(axismtx, normal, plane)) {
2218                     /* pass */
2219                   }
2220                   else {
2221                     normalize_v3(normal);
2222                     axis_dominant_v3_to_m3(axismtx, normal);
2223                     invert_m3(axismtx);
2224                   }
2225                 }
2226               }
2227
2228               copy_v3_v3(td->iloc, bp->vec);
2229               td->loc = bp->vec;
2230               copy_v3_v3(td->center, td->loc);
2231               if (bp->f1 & SELECT) {
2232                 td->flag = TD_SELECTED;
2233               }
2234               else {
2235                 td->flag = 0;
2236               }
2237               td->ext = NULL;
2238
2239               if (t->mode == TFM_CURVE_SHRINKFATTEN || t->mode == TFM_RESIZE) {
2240                 td->val = &(bp->radius);
2241                 td->ival = bp->radius;
2242               }
2243               else {
2244                 td->val = &(bp->tilt);
2245                 td->ival = bp->tilt;
2246               }
2247
2248               copy_m3_m3(td->smtx, smtx);
2249               copy_m3_m3(td->mtx, mtx);
2250               if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
2251                 if (nu->pntsv == 1) {
2252                   copy_m3_m3(td->axismtx, axismtx);
2253                 }
2254               }
2255
2256               td++;
2257               tail++;
2258             }
2259           }
2260           else if (is_prop_edit && head != tail) {
2261             calc_distanceCurveVerts(head, tail - 1);
2262             head = tail;
2263           }
2264         }
2265         if (is_prop_edit && head != tail) {
2266           calc_distanceCurveVerts(head, tail - 1);
2267         }
2268       }
2269     }
2270   }
2271 #undef SEL_F1
2272 #undef SEL_F2
2273 #undef SEL_F3
2274 }
2275
2276 /* ********************* lattice *************** */
2277
2278 static void createTransLatticeVerts(TransInfo *t)
2279 {
2280   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
2281
2282     Lattice *latt = ((Lattice *)tc->obedit->data)->editlatt->latt;
2283     TransData *td = NULL;
2284     BPoint *bp;
2285     float mtx[3][3], smtx[3][3];
2286     int a;
2287     int count = 0, countsel = 0;
2288     const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
2289
2290     bp = latt->def;
2291     a = latt->pntsu * latt->pntsv * latt->pntsw;
2292     while (a--) {
2293       if (bp->hide == 0) {
2294         if (bp->f1 & SELECT) {
2295           countsel++;
2296         }
2297         if (is_prop_edit) {
2298           count++;
2299         }
2300       }
2301       bp++;
2302     }
2303
2304     /* note: in prop mode we need at least 1 selected */
2305     if (countsel == 0) {
2306       return;
2307     }
2308
2309     if (is_prop_edit) {
2310       tc->data_len = count;
2311     }
2312     else {
2313       tc->data_len = countsel;
2314     }
2315     tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Lattice EditMode)");
2316
2317     copy_m3_m4(mtx, tc->obedit->obmat);
2318     pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
2319
2320     td = tc->data;
2321     bp = latt->def;
2322     a = latt->pntsu * latt->pntsv * latt->pntsw;
2323     while (a--) {
2324       if (is_prop_edit || (bp->f1 & SELECT)) {
2325         if (bp->hide == 0) {
2326           copy_v3_v3(td->iloc, bp->vec);
2327           td->loc = bp->vec;
2328           copy_v3_v3(td->center, td->loc);
2329           if (bp->f1 & SELECT) {
2330             td->flag = TD_SELECTED;
2331           }
2332           else {
2333             td->flag = 0;
2334           }
2335           copy_m3_m3(td->smtx, smtx);
2336           copy_m3_m3(td->mtx, mtx);
2337
2338           td->ext = NULL;
2339           td->val = NULL;
2340
2341           td++;
2342         }
2343       }
2344       bp++;
2345     }
2346   }
2347 }
2348
2349 /* ******************* particle edit **************** */
2350 static void createTransParticleVerts(bContext *C, TransInfo *t)
2351 {
2352   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
2353
2354     TransData *td = NULL;
2355     TransDataExtension *tx;
2356     Object *ob = CTX_data_active_object(C);
2357     ParticleEditSettings *pset = PE_settings(t->scene);
2358     PTCacheEdit *edit = PE_get_current(t->scene, ob);
2359     ParticleSystem *psys = NULL;
2360     PTCacheEditPoint *point;
2361     PTCacheEditKey *key;
2362     float mat[4][4];
2363     int i, k, transformparticle;
2364     int count = 0, hasselected = 0;
2365     const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
2366
2367     if (edit == NULL || t->settings->particle.selectmode == SCE_SELECT_PATH) {
2368       return;
2369     }
2370
2371     psys = edit->psys;
2372
2373     for (i = 0, point = edit->points; i < edit->totpoint; i++, point++) {
2374       point->flag &= ~PEP_TRANSFORM;
2375       transformparticle = 0;
2376
2377       if ((point->flag & PEP_HIDE) == 0) {
2378         for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
2379           if ((key->flag & PEK_HIDE) == 0) {
2380             if (key->flag & PEK_SELECT) {
2381               hasselected = 1;
2382               transformparticle = 1;
2383             }
2384             else if (is_prop_edit) {
2385               transformparticle = 1;
2386             }
2387           }
2388         }
2389       }
2390
2391       if (transformparticle) {
2392         count += point->totkey;
2393         point->flag |= PEP_TRANSFORM;
2394       }
2395     }
2396
2397     /* note: in prop mode we need at least 1 selected */
2398     if (hasselected == 0) {
2399       return;
2400     }
2401
2402     tc->data_len = count;
2403     td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Particle Mode)");
2404
2405     if (t->mode == TFM_BAKE_TIME) {
2406       tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension),
2407                                       "Particle_TransExtension");
2408     }
2409     else {
2410       tx = tc->data_ext = NULL;
2411     }
2412
2413     unit_m4(mat);
2414
2415     invert_m4_m4(ob->imat, ob->obmat);
2416
2417     for (i = 0, point = edit->points; i < edit->totpoint; i++, point++) {
2418       TransData *head, *tail;
2419       head = tail = td;
2420
2421       if (!(point->flag & PEP_TRANSFORM)) {
2422         continue;
2423       }
2424
2425       if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
2426         ParticleSystemModifierData *psmd_eval = edit->psmd_eval;
2427         Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval);
2428         psys_mat_hair_to_global(ob, mesh_final, psys->part->from, psys->particles + i, mat);
2429       }
2430
2431       for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
2432         if (key->flag & PEK_USE_WCO) {
2433           copy_v3_v3(key->world_co, key->co);
2434           mul_m4_v3(mat, key->world_co);
2435           td->loc = key->world_co;
2436         }
2437         else {
2438           td->loc = key->co;
2439         }
2440
2441         copy_v3_v3(td->iloc, td->loc);
2442         copy_v3_v3(td->center, td->loc);
2443
2444         if (key->flag & PEK_SELECT) {
2445           td->flag |= TD_SELECTED;
2446         }
2447         else if (!is_prop_edit) {
2448           td->flag |= TD_SKIP;
2449         }
2450
2451         unit_m3(td->mtx);
2452         unit_m3(td->smtx);
2453
2454         /* don't allow moving roots */
2455         if (k == 0 && pset->flag & PE_LOCK_FIRST && (!psys || !(psys->flag & PSYS_GLOBAL_HAIR))) {
2456           td->protectflag |= OB_LOCK_LOC;
2457         }
2458
2459         td->ob = ob;
2460         td->ext = tx;
2461         if (t->mode == TFM_BAKE_TIME) {
2462           td->val = key->time;
2463           td->ival = *(key->time);
2464           /* abuse size and quat for min/max values */
2465           td->flag |= TD_NO_EXT;
2466           if (k == 0) {
2467             tx->size = NULL;
2468           }
2469           else {
2470             tx->size = (key - 1)->time;
2471           }
2472
2473           if (k == point->totkey - 1) {
2474             tx->quat = NULL;
2475           }
2476           else {
2477             tx->quat = (key + 1)->time;
2478           }
2479         }
2480
2481         td++;
2482         if (tx) {
2483           tx++;
2484         }
2485         tail++;
2486       }
2487       if (is_prop_edit && head != tail) {
2488         calc_distanceCurveVerts(head, tail - 1);
2489       }
2490     }
2491   }
2492 }
2493
2494 void flushTransParticles(TransInfo *t)
2495 {
2496   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
2497     Scene *scene = t->scene;
2498     ViewLayer *view_layer = t->view_layer;
2499     Object *ob = OBACT(view_layer);
2500     PTCacheEdit *edit = PE_get_current(scene, ob);
2501     ParticleSystem *psys = edit->psys;
2502     PTCacheEditPoint *point;
2503     PTCacheEditKey *key;
2504     TransData *td;
2505     float mat[4][4], imat[4][4], co[3];
2506     int i, k;
2507     const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
2508
2509     /* we do transform in world space, so flush world space position
2510      * back to particle local space (only for hair particles) */
2511     td = tc->data;
2512     for (i = 0, point = edit->points; i < edit->totpoint; i++, point++, td++) {
2513       if (!(point->flag & PEP_TRANSFORM)) {
2514         continue;
2515       }
2516
2517       if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
2518         ParticleSystemModifierData *psmd_eval = edit->psmd_eval;
2519         Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval);
2520         psys_mat_hair_to_global(ob, mesh_final, psys->part->from, psys->particles + i, mat);
2521         invert_m4_m4(imat, mat);
2522
2523         for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
2524           copy_v3_v3(co, key->world_co);
2525           mul_m4_v3(imat, co);
2526
2527           /* optimization for proportional edit */
2528           if (!is_prop_edit || !compare_v3v3(key->co, co, 0.0001f)) {
2529             copy_v3_v3(key->co, co);
2530             point->flag |= PEP_EDIT_RECALC;
2531           }
2532         }
2533       }
2534       else {
2535         point->flag |= PEP_EDIT_RECALC;
2536       }
2537     }
2538
2539     PE_update_object(t->depsgraph, scene, OBACT(view_layer), 1);
2540     DEG_id_tag_update(&ob->id, ID_RECALC_PSYS_REDO);
2541   }
2542 }
2543
2544 /* ********************* mesh ****************** */
2545
2546 static bool bmesh_test_dist_add(BMVert *v,
2547                                 BMVert *v_other,
2548                                 float *dists,
2549                                 const float *dists_prev,
2550                                 /* optionally track original index */
2551                                 int *index,
2552                                 const int *index_prev,
2553                                 float mtx[3][3])
2554 {
2555   if ((BM_elem_flag_test(v_other, BM_ELEM_SELECT) == 0) &&
2556       (BM_elem_flag_test(v_other, BM_ELEM_HIDDEN) == 0)) {
2557     const int i = BM_elem_index_get(v);
2558     const int i_other = BM_elem_index_get(v_other);
2559     float vec[3];
2560     float dist_other;
2561     sub_v3_v3v3(vec, v->co, v_other->co);
2562     mul_m3_v3(mtx, vec);
2563
2564     dist_other = dists_prev[i] + len_v3(vec);
2565     if (dist_other < dists[i_other]) {
2566       dists[i_other] = dist_other;
2567       if (index != NULL) {
2568         index[i_other] = index_prev[i];
2569       }
2570       return true;
2571     }
2572   }
2573
2574   return false;
2575 }
2576
2577 /**
2578  * \param mtx: Measure distance in this space.
2579  * \param dists: Store the closest connected distance to selected vertices.
2580  * \param index: Optionally store the original index we're measuring the distance to (can be NULL).
2581  */
2582 static void editmesh_set_connectivity_distance(BMesh *bm,
2583                                                float mtx[3][3],
2584                                                float *dists,
2585                                                int *index)
2586 {
2587   BLI_LINKSTACK_DECLARE(queue, BMVert *);
2588
2589   /* any BM_ELEM_TAG'd vertex is in 'queue_next', so we don't add in twice */
2590   BLI_LINKSTACK_DECLARE(queue_next, BMVert *);
2591
2592   BLI_LINKSTACK_INIT(queue);
2593   BLI_LINKSTACK_INIT(queue_next);
2594
2595   {
2596     BMIter viter;
2597     BMVert *v;
2598     int i;
2599
2600     BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
2601       float dist;
2602       BM_elem_index_set(v, i); /* set_inline */
2603       BM_elem_flag_disable(v, BM_ELEM_TAG);
2604
2605       if (BM_elem_flag_test(v, BM_ELEM_SELECT) == 0 || BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
2606         dist = FLT_MAX;
2607         if (index != NULL) {
2608           index[i] = i;
2609         }
2610       }
2611       else {
2612         BLI_LINKSTACK_PUSH(queue, v);
2613         dist = 0.0f;
2614         if (index != NULL) {
2615           index[i] = i;
2616         }
2617       }
2618
2619       dists[i] = dist;
2620     }
2621     bm->elem_index_dirty &= ~BM_VERT;
2622   }
2623
2624   /* need to be very careful of feedback loops here, store previous dist's to avoid feedback */
2625   float *dists_prev = MEM_dupallocN(dists);
2626   int *index_prev = MEM_dupallocN(index); /* may be NULL */
2627
2628   do {
2629     BMVert *v;
2630     LinkNode *lnk;
2631
2632     /* this is correct but slow to do each iteration,
2633      * instead sync the dist's while clearing BM_ELEM_TAG (below) */
2634 #if 0
2635     memcpy(dists_prev, dists, sizeof(float) * bm->totvert);
2636 #endif
2637
2638     while ((v = BLI_LINKSTACK_POP(queue))) {
2639       BLI_assert(dists[BM_elem_index_get(v)] != FLT_MAX);
2640
2641       /* connected edge-verts */
2642       if (v->e != NULL) {
2643         BMEdge *e_iter, *e_first;
2644
2645         e_iter = e_first = v->e;
2646
2647         /* would normally use BM_EDGES_OF_VERT, but this runs so often,
2648          * its faster to iterate on the data directly */
2649         do {
2650
2651           if (BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN) == 0) {
2652
2653             /* edge distance */
2654             {
2655               BMVert *v_other = BM_edge_other_vert(e_iter, v);
2656               if (bmesh_test_dist_add(v, v_other, dists, dists_prev, index, index_prev, mtx)) {
2657                 if (BM_elem_flag_test(v_other, BM_ELEM_TAG) == 0) {
2658                   BM_elem_flag_enable(v_other, BM_ELEM_TAG);
2659                   BLI_LINKSTACK_PUSH(queue_next, v_other);
2660                 }
2661               }
2662             }
2663
2664             /* face distance */
2665             if (e_iter->l) {
2666               BMLoop *l_iter_radial, *l_first_radial;
2667               /**
2668                * imaginary edge diagonally across quad,
2669                * \note, this takes advantage of the rules of winding that we
2670                * know 2 or more of a verts edges wont reference the same face twice.
2671                * Also, if the edge is hidden, the face will be hidden too.
2672                */
2673               l_iter_radial = l_first_radial = e_iter->l;
2674
2675               do {
2676                 if ((l_iter_radial->v == v) && (l_iter_radial->f->len == 4) &&
2677                     (BM_elem_flag_test(l_iter_radial->f, BM_ELEM_HIDDEN) == 0)) {
2678                   BMVert *v_other = l_iter_radial->next->next->v;
2679                   if (bmesh_test_dist_add(v, v_other, dists, dists_prev, index, index_prev, mtx)) {
2680                     if (BM_elem_flag_test(v_other, BM_ELEM_TAG) == 0) {
2681                       BM_elem_flag_enable(v_other, BM_ELEM_TAG);
2682                       BLI_LINKSTACK_PUSH(queue_next, v_other);
2683                     }
2684                   }
2685                 }
2686               } while ((l_iter_radial = l_iter_radial->radial_next) != l_first_radial);
2687             }
2688           }
2689         } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v)) != e_first);
2690       }
2691     }
2692
2693     /* clear for the next loop */
2694     for (lnk = queue_next; lnk; lnk = lnk->next) {
2695       BMVert *v_link = lnk->link;
2696       const int i = BM_elem_index_get(v_link);
2697
2698       BM_elem_flag_disable(v_link, BM_ELEM_TAG);
2699
2700       /* keep in sync, avoid having to do full memcpy each iteration */
2701       dists_prev[i] = dists[i];
2702       if (index != NULL) {
2703         index_prev[i] = index[i];
2704       }
2705     }
2706
2707     BLI_LINKSTACK_SWAP(queue, queue_next);
2708
2709     /* none should be tagged now since 'queue_next' is empty */
2710     BLI_assert(BM_iter_mesh_count_flag(BM_VERTS_OF_MESH, bm, BM_ELEM_TAG, true) == 0);
2711
2712   } while (BLI_LINKSTACK_SIZE(queue));
2713
2714   BLI_LINKSTACK_FREE(queue);
2715   BLI_LINKSTACK_FREE(queue_next);
2716
2717   MEM_freeN(dists_prev);
2718   if (index_prev != NULL) {
2719     MEM_freeN(index_prev);
2720   }
2721 }
2722
2723 static struct TransIslandData *editmesh_islands_info_calc(BMEditMesh *em,
2724                                                           int *r_island_tot,
2725                                                           int **r_island_vert_map,
2726                                                           bool calc_single_islands)
2727 {
2728   BMesh *bm = em->bm;
2729   struct TransIslandData *trans_islands;
2730   char htype;
2731   char itype;
2732   int i;
2733
2734   /* group vars */
2735   int *groups_array;
2736   int(*group_index)[2];
2737   int group_tot;
2738   void **ele_array;
2739
2740   int *vert_map;
2741
2742   if (em->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) {
2743     groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totedgesel, __func__);
2744     group_tot = BM_mesh_calc_edge_groups(
2745         bm, groups_array, &group_index, NULL, NULL, BM_ELEM_SELECT);
2746
2747     htype = BM_EDGE;
2748     itype = BM_VERTS_OF_EDGE;
2749   }
2750   else { /* (bm->selectmode & SCE_SELECT_FACE) */
2751     groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totfacesel, __func__);
2752     group_tot = BM_mesh_calc_face_groups(
2753         bm, groups_array, &group_index, NULL, NULL, BM_ELEM_SELECT, BM_VERT);
2754
2755     htype = BM_FACE;
2756     itype = BM_VERTS_OF_FACE;
2757   }
2758
2759   trans_islands = MEM_mallocN(sizeof(*trans_islands) * group_tot, __func__);
2760
2761   vert_map = MEM_mallocN(sizeof(*vert_map) * bm->totvert, __func__);
2762   /* we shouldn't need this, but with incorrect selection flushing
2763    * its possible we have a selected vertex that's not in a face,
2764    * for now best not crash in that case. */
2765   copy_vn_i(vert_map, bm->totvert, -1);
2766
2767   BM_mesh_elem_table_ensure(bm, htype);
2768   ele_array = (htype == BM_FACE) ? (void **)bm->ftable : (void **)bm->etable;
2769
2770   BM_mesh_elem_index_ensure(bm, BM_VERT);
2771
2772   /* may be an edge OR a face array */
2773   for (i = 0; i < group_tot; i++) {
2774     BMEditSelection ese = {NULL};
2775
2776     const int fg_sta = group_index[i][0];
2777     const int fg_len = group_index[i][1];
2778     float co[3], no[3], tangent[3];
2779     int j;
2780
2781     zero_v3(co);
2782     zero_v3(no);
2783     zero_v3(tangent);
2784
2785     ese.htype = htype;
2786
2787     /* loop on each face in this group:
2788      * - assign r_vert_map
2789      * - calculate (co, no)
2790      */
2791     for (j = 0; j < fg_len; j++) {
2792       float tmp_co[3], tmp_no[3], tmp_tangent[3];
2793
2794       ese.ele = ele_array[groups_array[fg_sta + j]];
2795
2796       BM_editselection_center(&ese, tmp_co);
2797       BM_editselection_normal(&ese, tmp_no);
2798       BM_editselection_plane(&ese, tmp_tangent);
2799
2800       add_v3_v3(co, tmp_co);
2801       add_v3_v3(no, tmp_no);
2802       add_v3_v3(tangent, tmp_tangent);
2803
2804       {
2805         /* setup vertex map */
2806         BMIter iter;
2807         BMVert *v;
2808
2809         /* connected edge-verts */
2810         BM_ITER_ELEM (v, &iter, ese.ele, itype) {
2811           vert_map[BM_elem_index_get(v)] = i;
2812         }
2813       }
2814     }
2815
2816     mul_v3_v3fl(trans_islands[i].co, co, 1.0f / (float)fg_len);
2817
2818     if (createSpaceNormalTangent(trans_islands[i].axismtx, no, tangent)) {
2819       /* pass */
2820     }
2821     else {
2822       if (normalize_v3(no) != 0.0f) {
2823         axis_dominant_v3_to_m3(trans_islands[i].axismtx, no);
2824         invert_m3(trans_islands[i].axismtx);
2825       }
2826       else {
2827         unit_m3(trans_islands[i].axismtx);
2828       }
2829     }
2830   }
2831
2832   MEM_freeN(groups_array);
2833   MEM_freeN(group_index);
2834
2835   /* for PET we need islands of 1 so connected vertices can use it with V3D_AROUND_LOCAL_ORIGINS */
2836   if (calc_single_islands) {
2837     BMIter viter;
2838     BMVert *v;
2839     int group_tot_single = 0;
2840
2841     BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
2842       if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (vert_map[i] == -1)) {
2843         group_tot_single += 1;
2844       }
2845     }
2846
2847     if (group_tot_single != 0) {
2848       trans_islands = MEM_reallocN(trans_islands,
2849                                    sizeof(*trans_islands) * (group_tot + group_tot_single));
2850
2851       BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
2852         if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (vert_map[i] == -1)) {
2853           struct TransIslandData *v_island = &trans_islands[group_tot];
2854           vert_map[i] = group_tot;
2855
2856           copy_v3_v3(v_island->co, v->co);
2857
2858           if (is_zero_v3(v->no) != 0.0f) {
2859             axis_dominant_v3_to_m3(v_island->axismtx, v->no);
2860             invert_m3(v_island->axismtx);
2861           }
2862           else {
2863             unit_m3(v_island->axismtx);
2864           }
2865
2866           group_tot += 1;
2867         }
2868       }
2869     }
2870   }
2871
2872   *r_island_tot = group_tot;
2873   *r_island_vert_map = vert_map;
2874
2875   return trans_islands;
2876 }
2877
2878 /* way to overwrite what data is edited with transform */
2879 static void VertsToTransData(TransInfo *t,
2880                              TransData *td,
2881                              TransDataExtension *tx,
2882                              BMEditMesh *em,
2883                              BMVert *eve,
2884                              float *bweight,
2885                              struct TransIslandData *v_island,
2886                              const bool no_island_center)
2887 {
2888   float *no, _no[3];
2889   BLI_assert(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) == 0);
2890
2891   td->flag = 0;
2892   // if (key)
2893   //  td->loc = key->co;
2894   // else
2895   td->loc = eve->co;
2896   copy_v3_v3(td->iloc, td->loc);
2897
2898   if ((t->mode == TFM_SHRINKFATTEN) && (em->selectmode & SCE_SELECT_FACE) &&
2899       BM_elem_flag_test(eve, BM_ELEM_SELECT) &&
2900       (BM_vert_calc_normal_ex(eve, BM_ELEM_SELECT, _no))) {
2901     no = _no;
2902   }
2903   else {
2904     no = eve->no;
2905   }
2906
2907   if (v_island) {
2908     if (no_island_center) {
2909       copy_v3_v3(td->center, td->loc);
2910     }
2911     else {
2912       copy_v3_v3(td->center, v_island->co);
2913     }
2914     copy_m3_m3(td->axismtx, v_island->axismtx);
2915   }
2916   else if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
2917     copy_v3_v3(td->center, td->loc);
2918     createSpaceNormal(td->axismtx, no);
2919   }
2920   else {
2921     copy_v3_v3(td->center, td->loc);
2922
2923     /* Setting normals */
2924     copy_v3_v3(td->axismtx[2], no);
2925     td->axismtx[0][0] = td->axismtx[0][1] = td->axismtx[0][2] = td->axismtx[1][0] =
2926         td->axismtx[1][1] = td->axismtx[1][2] = 0.0f;
2927   }
2928
2929   td->ext = NULL;
2930   td->val = NULL;
2931   td->extra = NULL;
2932   if (t->mode == TFM_BWEIGHT) {
2933     td->val = bweight;
2934     td->ival = *bweight;
2935   }
2936   else if (t->mode == TFM_SKIN_RESIZE) {
2937     MVertSkin *vs = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MVERT_SKIN);
2938     /* skin node size */
2939     td->ext = tx;
2940     copy_v3_v3(tx->isize, vs->radius);
2941     tx->size = vs->radius;
2942     td->val = vs->radius;
2943   }
2944   else if (t->mode == TFM_SHRINKFATTEN) {
2945     td->ext = tx;
2946     tx->isize[0] = BM_vert_calc_shell_factor_ex(eve, no, BM_ELEM_SELECT);
2947   }
2948 }
2949
2950 static void createTransEditVerts(TransInfo *t)
2951 {
2952   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
2953     TransData *tob = NULL;
2954     TransDataExtension *tx = NULL;
2955     BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
2956     Mesh *me = tc->obedit->data;
2957     BMesh *bm = em->bm;
2958     BMVert *eve;
2959     BMIter iter;
2960     float(*mappedcos)[3] = NULL, (*quats)[4] = NULL;
2961     float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL;
2962     float *dists = NULL;
2963     int a;
2964     const int prop_mode = (t->flag & T_PROP_EDIT) ? (t->flag & T_PROP_EDIT_ALL) : 0;
2965     int mirror = 0;
2966     int cd_vert_bweight_offset = -1;
2967     bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
2968
2969     struct TransIslandData *island_info = NULL;
2970     int island_info_tot;
2971     int *island_vert_map = NULL;
2972
2973     /* Snap rotation along normal needs a common axis for whole islands,
2974      * otherwise one get random crazy results, see T59104.
2975      * However, we do not want to use the island center for the pivot/translation reference. */
2976     const bool is_snap_rotate = ((t->mode == TFM_TRANSLATION) &&
2977                                  /* There is not guarantee that snapping
2978                                   * is initialized yet at this point... */
2979                                  (usingSnappingNormal(t) ||
2980                                   (t->settings->snap_flag & SCE_SNAP_ROTATE) != 0) &&
2981                                  (t->around != V3D_AROUND_LOCAL_ORIGINS));
2982     /* Even for translation this is needed because of island-orientation, see: T51651. */
2983     const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS) || is_snap_rotate;
2984     /* Original index of our connected vertex when connected distances are calculated.
2985      * Optional, allocate if needed. */
2986     int *dists_index = NULL;
2987
2988     if (tc->mirror.axis_flag) {
2989       EDBM_verts_mirror_cache_begin(em, 0, false, (t->flag & T_PROP_EDIT) == 0, use_topology);
2990       mirror = 1;
2991     }
2992
2993     /**
2994      * Quick check if we can transform.
2995      *
2996      * \note ignore modes here, even in edge/face modes,
2997      * transform data is created by selected vertices.
2998      * \note in prop mode we need at least 1 selected.
2999      */
3000     if (bm->totvertsel == 0) {
3001       goto cleanup;
3002     }
3003
3004     if (t->mode == TFM_BWEIGHT) {
3005       BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_VERT_BWEIGHT);
3006       cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
3007     }
3008
3009     if (prop_mode) {
3010       unsigned int count = 0;
3011       BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
3012         if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
3013           count++;
3014         }
3015       }
3016
3017       tc->data_len = count;
3018
3019       /* allocating scratch arrays */
3020       if (prop_mode & T_PROP_CONNECTED) {
3021         dists = MEM_mallocN(em->bm->totvert * sizeof(float), __func__);
3022         if (is_island_center) {
3023           dists_index = MEM_mallocN(em->bm->totvert * sizeof(int), __func__);
3024         }
3025       }
3026     }
3027     else {
3028       tc->data_len = bm->totvertsel;
3029     }
3030
3031     tob = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Mesh EditMode)");
3032     if (ELEM(t->mode, TFM_SKIN_RESIZE, TFM_SHRINKFATTEN)) {
3033       /* warning, this is overkill, we only need 2 extra floats,
3034        * but this stores loads of extra stuff, for TFM_SHRINKFATTEN its even more overkill
3035        * since we may not use the 'alt' transform mode to maintain shell thickness,
3036        * but with generic transform code its hard to lazy init vars */
3037       tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension),
3038                                       "TransObData ext");
3039     }
3040
3041     copy_m3_m4(mtx, tc->obedit->obmat);
3042     /* we use a pseudo-inverse so that when one of the axes is scaled to 0,
3043      * matrix inversion still works and we can still moving along the other */
3044     pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
3045
3046     if (prop_mode & T_PROP_CONNECTED) {
3047       editmesh_set_connectivity_distance(em->bm, mtx, dists, dists_index);
3048     }
3049
3050     if (is_island_center) {
3051       /* In this specific case, near-by vertices will need to know
3052        * the island of the nearest connected vertex. */
3053       const bool calc_single_islands = ((prop_mode & T_PROP_CONNECTED) &&
3054                                         (t->around == V3D_AROUND_LOCAL_ORIGINS) &&
3055                                         (em->selectmode & SCE_SELECT_VERTEX));
3056
3057       island_info = editmesh_islands_info_calc(
3058           em, &island_info_tot, &island_vert_map, calc_single_islands);
3059     }
3060
3061     /* detect CrazySpace [tm] */
3062     if (modifiers_getCageIndex(t->scene, tc->obedit, NULL, 1) != -1) {
3063       int totleft = -1;
3064       if (modifiers_isCorrectableDeformed(t->scene, tc->obedit)) {
3065         BKE_scene_graph_evaluated_ensure(t->depsgraph, CTX_data_main(t->context));
3066
3067         /* Use evaluated state because we need b-bone cache. */
3068         Scene *scene_eval = (Scene *)DEG_get_evaluated_id(t->depsgraph, &t->scene->id);
3069         Object *obedit_eval = (Object *)DEG_get_evaluated_id(t->depsgraph, &tc->obedit->id);
3070         BMEditMesh *em_eval = BKE_editmesh_from_object(obedit_eval);
3071         /* check if we can use deform matrices for modifier from the
3072          * start up to stack, they are more accurate than quats */
3073         totleft = BKE_crazyspace_get_first_deform_matrices_editbmesh(
3074             t->depsgraph, scene_eval, obedit_eval, em_eval, &defmats, &defcos);
3075       }
3076
3077       /* if we still have more modifiers, also do crazyspace
3078        * correction with quats, relative to the coordinates after
3079        * the modifiers that support deform matrices (defcos) */
3080
3081 #if 0 /* TODO, fix crazyspace+extrude so it can be enabled for general use - campbell */
3082       if ((totleft > 0) || (totleft == -1))
3083 #else
3084       if (totleft > 0)
3085 #endif
3086       {
3087         mappedcos = BKE_crazyspace_get_mapped_editverts(t->depsgraph, tc->obedit);
3088         quats = MEM_mallocN(em->bm->totvert * sizeof(*quats), "crazy quats");
3089         BKE_crazyspace_set_quats_editmesh(em, defcos, mappedcos, quats, !prop_mode);
3090         if (mappedcos) {
3091           MEM_freeN(mappedcos);
3092         }
3093       }
3094
3095       if (defcos) {
3096         MEM_freeN(defcos);
3097       }
3098     }
3099
3100     /* find out which half we do */
3101     if (mirror) {
3102       BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
3103         if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && eve->co[0] != 0.0f) {
3104           if (eve->co[0] < 0.0f) {
3105             tc->mirror.sign = -1.0f;
3106             mirror = -1;
3107           }
3108           break;
3109         }
3110       }
3111     }
3112
3113     BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) {
3114       if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
3115         if (prop_mode || BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
3116           struct TransIslandData *v_island = NULL;
3117           float *bweight = (cd_vert_bweight_offset != -1) ?
3118                                BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset) :
3119                                NULL;
3120
3121           if (island_info) {
3122             const int connected_index = (dists_index && dists_index[a] != -1) ? dists_index[a] : a;
3123             v_island = (island_vert_map[connected_index] != -1) ?
3124                            &island_info[island_vert_map[connected_index]] :
3125                            NULL;
3126           }
3127
3128           /* Do not use the island center in case we are using islands
3129            * only to get axis for snap/rotate to normal... */
3130           VertsToTransData(t, tob, tx, em, eve, bweight, v_island, is_snap_rotate);
3131           if (tx) {
3132             tx++;
3133           }
3134
3135           /* selected */
3136           if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
3137             tob->flag |= TD_SELECTED;
3138           }
3139
3140           if (prop_mode) {
3141             if (prop_mode & T_PROP_CONNECTED) {
3142               tob->dist = dists[a];
3143             }
3144             else {
3145               tob->flag |= TD_NOTCONNECTED;
3146               tob->dist = FLT_MAX;
3147             }
3148           }
3149
3150           /* CrazySpace */
3151           const bool use_quats = quats && BM_elem_flag_test(eve, BM_ELEM_TAG);
3152           if (use_quats || defmats) {
3153             float mat[3][3], qmat[3][3], imat[3][3];
3154
3155             /* Use both or either quat and defmat correction. */
3156             if (use_quats) {
3157               quat_to_mat3(qmat, quats[BM_elem_index_get(eve)]);
3158
3159               if (defmats) {
3160                 mul_m3_series(mat, defmats[a], qmat, mtx);
3161               }
3162               else {
3163                 mul_m3_m3m3(mat, mtx, qmat);
3164               }
3165             }
3166             else {
3167               mul_m3_m3m3(mat, mtx, defmats[a]);
3168             }
3169
3170             invert_m3_m3(imat, mat);
3171
3172             copy_m3_m3(tob->smtx, imat);
3173             copy_m3_m3(tob->mtx, mat);
3174           }
3175           else {
3176             copy_m3_m3(tob->smtx, smtx);
3177             copy_m3_m3(tob->mtx, mtx);
3178           }
3179
3180           /* Mirror? */
3181           if ((mirror > 0 && tob->iloc[0] > 0.0f) || (mirror < 0 && tob->iloc[0] < 0.0f)) {
3182             BMVert *vmir = EDBM_verts_mirror_get(em, eve);  // t->obedit, em, eve, tob->iloc, a);
3183             if (vmir && vmir != eve) {
3184               tob->extra = vmir;
3185             }
3186           }
3187           tob++;
3188         }
3189       }
3190     }
3191
3192     if (island_info) {
3193       MEM_freeN(island_info);
3194       MEM_freeN(island_vert_map);
3195     }
3196
3197     if (mirror != 0) {
3198       tob = tc->data;
3199       for (a = 0; a < tc->data_len; a++, tob++) {
3200         if (ABS(tob->loc[0]) <= 0.00001f) {
3201           tob->flag |= TD_MIRROR_EDGE;
3202         }
3203       }
3204     }
3205
3206   cleanup:
3207     /* crazy space free */
3208     if (quats) {
3209       MEM_freeN(quats);
3210     }
3211     if (defmats) {
3212       MEM_freeN(defmats);
3213     }
3214     if (dists) {
3215       MEM_freeN(dists);
3216     }
3217     if (dists_index) {
3218       MEM_freeN(dists_index);
3219     }
3220
3221     if (tc->mirror.axis_flag) {
3222       EDBM_verts_mirror_cache_end(em);
3223     }
3224   }
3225 }
3226
3227 /* *** NODE EDITOR *** */
3228 void flushTransNodes(TransInfo *t)
3229 {
3230   const float dpi_fac = UI_DPI_FAC;
3231
3232   FOREACH_TRANS_DATA_CONTAINER (t, tc) {
3233     int a;
3234     TransData *td;
3235     TransData2D *td2d;
3236
3237     applyGridAbsolute(t);
3238
3239     /* flush to 2d vector from internally used 3d vector */
3240     for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
3241       bNode *node = td->extra;
3242       float locx, locy;
3243
3244       /* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */
3245 #ifdef USE_NODE_CENTER
3246       locx = (td2d->loc[0] - (BLI_rctf_size_x(&node->totr)) * +0.5f) / dpi_fac;
3247       locy = (td2d->loc[1] - (BLI_rctf_size_y(&node->totr)) * -0.5f) / dpi_fac;
3248 #else
3249       locx = td2d->loc[0] / dpi_fac;
3250       locy = td2d->loc[1] / dpi_fac;
3251 #endif
3252
3253       /* account for parents (nested nodes) */
3254       if (node->parent) {
3255         nodeFromView(node->parent, locx, locy, &node->locx, &node->locy);
3256       }
3257       else {
3258         node->locx = locx;
3259         node->locy = locy;
3260       }
3261     }
3262
3263     /* handle intersection with noodles */
3264     if (tc->data_len == 1) {
3265       ED_node_link_intersect_test(t->sa, 1);
3266     }
3267   }
3268 }
3269
3270 /* *** SEQUENCE EDITOR *** */
3271
3272 /* commented _only_ because the meta may have animation data which
3273  * needs moving too [#28158] */
3274
3275 #define SEQ_TX_NESTED_METAS
3276
3277 BLI_INLINE void trans_update_seq(Scene *sce, Sequence *seq, int old_start, int sel_flag)
3278 {
3279   if (seq->depth == 0) {
3280     /* Calculate this strip and all nested strips.
3281      * Children are ALWAYS transformed first so we don't need to do this in another loop.
3282      */
3283     BKE_sequence_calc(sce, seq);
3284   }
3285   else {
3286     BKE_sequence_calc_disp(sce, seq);
3287   }
3288
3289   if (sel_flag == SELECT) {
3290     BKE_sequencer_offset_animdata(sce, seq, seq->start - old_start);
3291   }
3292 }
3293
3294 void flushTransSeq(TransInfo *t)
3295 {
3296   /* Editing null check already done */
3297   ListBase *seqbasep = BKE_sequencer_editing_get(t->scene, false)->seqbasep;
3298
3299   int a, new_frame;
3300   TransData *td = NULL;
3301   TransData2D *td2d = NULL;
3302   TransDataSeq *tdsq = NULL;
3303   Sequence *seq;
3304
3305   TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
3306
3307   /* prevent updating the same seq twice
3308    * if the transdata order is changed this will mess up
3309    * but so will TransDataSeq */
3310   Sequence *seq_prev = NULL;
3311   int old_start_prev = 0, sel_flag_prev = 0;
3312
3313   /* flush to 2d vector from internally used 3d vector */
3314   for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
3315     int old_start;
3316     tdsq = (TransDataSeq *)td->extra;
3317     seq = tdsq->seq;
3318     old_start = seq->start;
3319     new_frame = round_fl_to_int(td2d->loc[0]);
3320
3321     switch (tdsq->sel_flag) {
3322       case SELECT:
3323 #ifdef SEQ_TX_NESTED_METAS
3324         if ((seq->depth != 0 || BKE_sequence_tx_test(seq))) {
3325           /* for meta's, their children move */
3326           seq->start = new_frame - tdsq->start_offset;
3327         }
3328 #else
3329         if (seq->type != SEQ_TYPE_META && (seq->depth != 0 || seq_tx_test(seq))) {
3330           /* for meta's, their children move */
3331           seq->start = new_frame - tdsq->start_offset;
3332         }
3333 #endif
3334         if (seq->depth == 0) {
3335           seq->machine = round_fl_to_int(td2d->loc[1]);
3336           CLAMP(seq->machine, 1, MAXSEQ);
3337         }
3338         break;
3339       case SEQ_LEFTSEL: /* no vertical transform  */
3340         BKE_sequence_tx_set_final_left(seq, new_frame);
3341         BKE_sequence_tx_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL);
3342
3343         /* todo - move this into aftertrans update? - old seq tx needed it anyway */
3344         BKE_sequence_single_fix(seq);
3345         break;
3346       case SEQ_RIGHTSEL: /* no vertical transform  */
3347         BKE_sequence_tx_set_final_right(seq, new_frame);
3348         BKE_sequence_tx_handle_xlimits(seq, tdsq->flag & SEQ_LEFTSEL, tdsq->flag & SEQ_RIGHTSEL);
3349
3350         /* todo - move this into aftertrans update? - old seq tx needed it anyway */
3351         BKE_sequence_single_fix(seq);
3352         break;
3353     }
3354
3355     /* Update *previous* seq! Else, we would update a seq after its first transform,
3356      * and if it has more than one (like e.g. SEQ_LEFTSEL and SEQ_RIGHTSEL),
3357      * the others are not updated! See T38469.
3358      */
3359     if (seq != seq_prev) {
3360       if (seq_prev) {
3361         trans_update_seq(t->scene, seq_prev, old_start_prev, sel_flag_prev);
3362       }
3363
3364       seq_prev = seq;
3365       old_start_prev = old_start;
3366       sel_flag_prev = tdsq->sel_flag;
3367     }
3368     else {
3369       /* We want to accumulate *all* sel_flags for this seq! */
3370       sel_flag_prev |= tdsq->sel_flag;
3371     }
3372   }
3373
3374   /* Don't forget to update the last seq! */
3375   if (seq_prev) {
3376     trans_update_seq(t->scene, seq_prev, old_start_prev, sel_flag_prev);
3377   }
3378
3379   /* originally TFM_TIME_EXTEND, transform changes */
3380   if (ELEM(t->mode, TFM_SEQ_SLIDE, TFM_TIME_TRANSLATE)) {
3381     /* Special annoying case here, need to calc metas with TFM_TIME_EXTEND only */
3382
3383     /* calc all meta's then effects [#27953] */
3384     for (seq = seqbasep->first; seq; seq = seq->next) {
3385       if (seq->type == SEQ_TYPE_META && seq->flag & SELECT) {
3386         BKE_sequence_calc(t->scene, seq);
3387       }
3388     }
3389     for (seq = seqbasep->first; seq; seq = seq->next) {
3390       if (seq->seq1 || seq->seq2 || seq->seq3) {
3391         BKE_sequence_calc(t->scene, seq);
3392       }
3393     }
3394
3395     /* update effects inside meta's */
3396     for (a = 0, seq_prev = NULL, td = tc->data, td2d = tc->data_2d; a < tc->data_len;
3397          a++, td++, td2d++, seq_prev = seq) {
3398       tdsq = (TransDataSeq *)td->extra;
3399       seq = tdsq->seq;
3400       if ((seq != seq_prev) && (seq->depth != 0)) {
3401         if (seq->seq1 || seq->seq2 || seq->seq3) {
3402           BKE_sequence_calc(t->scene, seq);
3403         }
3404       }
3405     }
3406   }
3407
3408   /* need to do the overlap check in a new loop otherwise adjacent strips
3409    * will not be updated and we'll get false positives */
3410   seq_prev = NULL;
3411   for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
3412
3413     tdsq = (TransDataSeq *)td->extra;
3414     seq = tdsq->seq;
3415
3416     if (seq != seq_prev) {
3417       if (seq->depth == 0) {
3418         /* test overlap, displays red outline */
3419         seq->flag &= ~SEQ_OVERLAP;
3420         if (BKE_sequence_test_overlap(seqbasep, seq)) {
3421           seq->flag |= SEQ_OVERLAP;
3422         }
3423       }
3424     }
3425     seq_prev = seq;
3426   }
3427 }
3428
3429 /* ********************* UV ****************** */
3430
3431 static void UVsToTransData(const float aspect[2],
3432                            TransData *td,
3433                            TransData2D *td2d,
3434                            float *uv,
3435                            const float *center,
3436                            bool selected)
3437 {
3438   /* uv coords are scaled by aspects. this is needed for rotations and
3439    * proportional editing to be consistent with the stretched uv coords
3440    * that are displayed. this also means that for display and numinput,
3441    * and when the uv coords are flushed, these are converted each time */
3442   td2d->loc[0] = uv[0] * aspect[0];
3443   td2d->loc[1] = uv[1] * aspect[1];
3444   td2d->loc[2] = 0.0f;
3445   td2d->loc2d = uv;
3446
3447   td->flag = 0;
3448   td->loc = td2d->loc;
3449   copy_v2_v2(td->center, center ? center : td->loc);
3450   td->center[2] = 0.0f;
3451   copy_v3_v3(td->iloc, td->loc);
3452
3453   memset(td->axismtx, 0, sizeof(td->axismtx));
3454   td->axismtx[2][2] = 1.0f;
3455