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