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