Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / transform / transform_conversions.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/transform/transform_conversions.c
29  *  \ingroup edtransform
30  */
31
32 #include <string.h>
33 #include <math.h>
34 #include <limits.h>
35
36 #include "DNA_anim_types.h"
37 #include "DNA_brush_types.h"
38 #include "DNA_armature_types.h"
39 #include "DNA_lattice_types.h"
40 #include "DNA_mesh_types.h"
41 #include "DNA_meta_types.h"
42 #include "DNA_node_types.h"
43 #include "DNA_screen_types.h"
44 #include "DNA_space_types.h"
45 #include "DNA_sequence_types.h"
46 #include "DNA_view3d_types.h"
47 #include "DNA_constraint_types.h"
48 #include "DNA_scene_types.h"
49 #include "DNA_meshdata_types.h"
50 #include "DNA_gpencil_types.h"
51 #include "DNA_movieclip_types.h"
52 #include "DNA_mask_types.h"
53
54 #include "MEM_guardedalloc.h"
55
56 #include "BLI_math.h"
57 #include "BLI_utildefines.h"
58 #include "BLI_listbase.h"
59 #include "BLI_linklist_stack.h"
60 #include "BLI_string.h"
61 #include "BLI_bitmap.h"
62 #include "BLI_rect.h"
63
64 #include "BKE_action.h"
65 #include "BKE_armature.h"
66 #include "BKE_constraint.h"
67 #include "BKE_context.h"
68 #include "BKE_crazyspace.h"
69 #include "BKE_curve.h"
70 #include "BKE_fcurve.h"
71 #include "BKE_global.h"
72 #include "BKE_gpencil.h"
73 #include "BKE_layer.h"
74 #include "BKE_key.h"
75 #include "BKE_main.h"
76 #include "BKE_mesh.h"
77 #include "BKE_mesh_mapping.h"
78 #include "BKE_modifier.h"
79 #include "BKE_movieclip.h"
80 #include "BKE_nla.h"
81 #include "BKE_node.h"
82 #include "BKE_object.h"
83 #include "BKE_particle.h"
84 #include "BKE_paint.h"
85 #include "BKE_pointcache.h"
86 #include "BKE_report.h"
87 #include "BKE_rigidbody.h"
88 #include "BKE_scene.h"
89 #include "BKE_sequencer.h"
90 #include "BKE_editmesh.h"
91 #include "BKE_tracking.h"
92 #include "BKE_mask.h"
93 #include "BKE_colortools.h"
94
95 #include "BIK_api.h"
96
97 #include "ED_anim_api.h"
98 #include "ED_armature.h"
99 #include "ED_particle.h"
100 #include "ED_image.h"
101 #include "ED_keyframing.h"
102 #include "ED_keyframes_edit.h"
103 #include "ED_object.h"
104 #include "ED_markers.h"
105 #include "ED_mesh.h"
106 #include "ED_node.h"
107 #include "ED_uvedit.h"
108 #include "ED_clip.h"
109 #include "ED_mask.h"
110 #include "ED_gpencil.h"
111
112 #include "WM_api.h"  /* for WM_event_add_notifier to deal with stabilization nodes */
113 #include "WM_types.h"
114
115 #include "UI_view2d.h"
116 #include "UI_interface.h"
117
118 #include "RNA_access.h"
119
120 #include "DEG_depsgraph.h"
121 #include "DEG_depsgraph_build.h"
122 #include "DEG_depsgraph_query.h"
123
124 #include "transform.h"
125 #include "bmesh.h"
126
127 /**
128  * Transforming around ourselves is no use, fallback to individual origins,
129  * useful for curve/armatures.
130  */
131 static void transform_around_single_fallback(TransInfo *t)
132 {
133         if ((t->data_len_all == 1) &&
134             (ELEM(t->around, V3D_AROUND_CENTER_BOUNDS, V3D_AROUND_CENTER_MEAN, V3D_AROUND_ACTIVE)) &&
135             (ELEM(t->mode, TFM_RESIZE, TFM_ROTATION, TFM_TRACKBALL)))
136         {
137                 t->around = V3D_AROUND_LOCAL_ORIGINS;
138         }
139 }
140
141 /* when transforming islands */
142 struct TransIslandData {
143         float co[3];
144         float axismtx[3][3];
145 };
146
147 /* local function prototype - for Object/Bone Constraints */
148 static bool constraints_list_needinv(TransInfo *t, ListBase *list);
149
150 /* ************************** Functions *************************** */
151
152 static int trans_data_compare_dist(const void *a, const void *b)
153 {
154         const TransData *td_a = (const TransData *)a;
155         const TransData *td_b = (const TransData *)b;
156
157         if      (td_a->dist < td_b->dist) return -1;
158         else if (td_a->dist > td_b->dist) return  1;
159         else                              return  0;
160 }
161
162 static int trans_data_compare_rdist(const void *a, const void *b)
163 {
164         const TransData *td_a = (const TransData *)a;
165         const TransData *td_b = (const TransData *)b;
166
167         if      (td_a->rdist < td_b->rdist) return -1;
168         else if (td_a->rdist > td_b->rdist) return  1;
169         else                                return  0;
170 }
171
172 static void sort_trans_data_dist_container(const TransInfo *t, TransDataContainer *tc)
173 {
174         TransData *start = tc->data;
175         int i;
176
177         for (i = 0; i < tc->data_len && start->flag & TD_SELECTED; i++) {
178                 start++;
179         }
180
181         if (i < tc->data_len) {
182                 if (t->flag & T_PROP_CONNECTED) {
183                         qsort(start, tc->data_len - i, sizeof(TransData), trans_data_compare_dist);
184                 }
185                 else {
186                         qsort(start, tc->data_len - i, sizeof(TransData), trans_data_compare_rdist);
187                 }
188         }
189 }
190 void sort_trans_data_dist(TransInfo *t)
191 {
192         FOREACH_TRANS_DATA_CONTAINER (t, tc) {
193                 sort_trans_data_dist_container(t, tc);
194         }
195 }
196
197 static void sort_trans_data_container(TransDataContainer *tc)
198 {
199         TransData *sel, *unsel;
200         TransData temp;
201         unsel = tc->data;
202         sel = tc->data;
203         sel += tc->data_len - 1;
204         while (sel > unsel) {
205                 while (unsel->flag & TD_SELECTED) {
206                         unsel++;
207                         if (unsel == sel) {
208                                 return;
209                         }
210                 }
211                 while (!(sel->flag & TD_SELECTED)) {
212                         sel--;
213                         if (unsel == sel) {
214                                 return;
215                         }
216                 }
217                 temp = *unsel;
218                 *unsel = *sel;
219                 *sel = temp;
220                 sel--;
221                 unsel++;
222         }
223 }
224 static void sort_trans_data(TransInfo *t)
225 {
226         FOREACH_TRANS_DATA_CONTAINER (t, tc) {
227                 sort_trans_data_container(tc);
228         }
229 }
230
231 /* distance calculated from not-selected vertex to nearest selected vertex
232  * warning; this is loops inside loop, has minor N^2 issues, but by sorting list it is OK */
233 static void set_prop_dist(TransInfo *t, const bool with_dist)
234 {
235         int a;
236
237         float _proj_vec[3];
238         const float *proj_vec = NULL;
239
240         /* support for face-islands */
241         const bool use_island = transdata_check_local_islands(t, t->around);
242
243         if (t->flag & T_PROP_PROJECTED) {
244                 if (t->spacetype == SPACE_VIEW3D && t->ar && t->ar->regiontype == RGN_TYPE_WINDOW) {
245                         RegionView3D *rv3d = t->ar->regiondata;
246                         normalize_v3_v3(_proj_vec, rv3d->viewinv[2]);
247                         proj_vec = _proj_vec;
248                 }
249         }
250
251         FOREACH_TRANS_DATA_CONTAINER (t, tc) {
252                 TransData *tob = tc->data;
253                 for (a = 0; a < tc->data_len; a++, tob++) {
254
255                         tob->rdist = 0.0f; // init, it was mallocced
256
257                         if ((tob->flag & TD_SELECTED) == 0) {
258                                 TransData *td;
259                                 int i;
260                                 float dist_sq, vec[3];
261
262                                 tob->rdist = -1.0f; // signal for next loop
263
264                                 for (i = 0, td = tc->data; i < tc->data_len; i++, td++) {
265                                         if (td->flag & TD_SELECTED) {
266                                                 if (use_island) {
267                                                         sub_v3_v3v3(vec, tob->iloc, td->iloc);
268                                                 }
269                                                 else {
270                                                         sub_v3_v3v3(vec, tob->center, td->center);
271                                                 }
272                                                 mul_m3_v3(tob->mtx, vec);
273
274                                                 if (proj_vec) {
275                                                         float vec_p[3];
276                                                         project_v3_v3v3(vec_p, vec, proj_vec);
277                                                         sub_v3_v3(vec, vec_p);
278                                                 }
279
280                                                 dist_sq = len_squared_v3(vec);
281                                                 if ((tob->rdist == -1.0f) || (dist_sq < SQUARE(tob->rdist))) {
282                                                         tob->rdist = sqrtf(dist_sq);
283                                                         if (use_island) {
284                                                                 copy_v3_v3(tob->center, td->center);
285                                                                 copy_m3_m3(tob->axismtx, td->axismtx);
286                                                         }
287                                                 }
288                                         }
289                                         else {
290                                                 break;  /* by definition transdata has selected items in beginning */
291                                         }
292                                 }
293                                 if (with_dist) {
294                                         tob->dist = tob->rdist;
295                                 }
296                         }
297                 }
298         }
299 }
300
301 /* ************************** CONVERSIONS ************************* */
302
303 /* ********************* texture space ********* */
304
305 static void createTransTexspace(TransInfo *t)
306 {
307         ViewLayer *view_layer = t->view_layer;
308         TransData *td;
309         Object *ob;
310         ID *id;
311         short *texflag;
312
313         ob = OBACT(view_layer);
314
315         if (ob == NULL) { // Shouldn't logically happen, but still...
316                 return;
317         }
318
319         id = ob->data;
320         if (id == NULL || !ELEM(GS(id->name), ID_ME, ID_CU, ID_MB)) {
321                 BKE_report(t->reports, RPT_ERROR, "Unsupported object type for text-space transform");
322                 return;
323         }
324
325         if (BKE_object_obdata_is_libdata(ob)) {
326                 BKE_report(t->reports, RPT_ERROR, "Linked data can't text-space transform");
327                 return;
328         }
329
330
331         {
332                 BLI_assert(t->data_container_len == 1);
333                 TransDataContainer *tc = t->data_container;
334                 tc->data_len = 1;
335                 td = tc->data = MEM_callocN(sizeof(TransData), "TransTexspace");
336                 td->ext = tc->data_ext = MEM_callocN(sizeof(TransDataExtension), "TransTexspace");
337         }
338
339         td->flag = TD_SELECTED;
340         copy_v3_v3(td->center, ob->obmat[3]);
341         td->ob = ob;
342
343         copy_m3_m4(td->mtx, ob->obmat);
344         copy_m3_m4(td->axismtx, ob->obmat);
345         normalize_m3(td->axismtx);
346         pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
347
348         if (BKE_object_obdata_texspace_get(ob, &texflag, &td->loc, &td->ext->size, &td->ext->rot)) {
349                 ob->dtx |= OB_TEXSPACE;
350                 *texflag &= ~ME_AUTOSPACE;
351         }
352
353         copy_v3_v3(td->iloc, td->loc);
354         copy_v3_v3(td->ext->irot, td->ext->rot);
355         copy_v3_v3(td->ext->isize, td->ext->size);
356 }
357
358 /* -------------------------------------------------------------------- */
359 /** \name Cursor Transform Creation
360  *
361  * Instead of transforming the selection, move the 2D/3D cursor.
362  *
363  * \{ */
364
365 static void createTransCursor_image(TransInfo *t)
366 {
367         TransData *td;
368         SpaceImage *sima = t->sa->spacedata.first;
369         float *cursor_location = sima->cursor;
370
371         {
372                 BLI_assert(t->data_container_len == 1);
373                 TransDataContainer *tc = t->data_container;
374                 tc->data_len = 1;
375                 td = tc->data = MEM_callocN(sizeof(TransData), "TransTexspace");
376                 td->ext = tc->data_ext = MEM_callocN(sizeof(TransDataExtension), "TransTexspace");
377         }
378
379         td->flag = TD_SELECTED;
380         copy_v3_v3(td->center, cursor_location);
381         td->ob = NULL;
382
383         unit_m3(td->mtx);
384         unit_m3(td->axismtx);
385         pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
386
387         td->loc = cursor_location;
388         copy_v3_v3(td->iloc, cursor_location);
389 }
390
391 static void createTransCursor_view3d(TransInfo *t)
392 {
393         TransData *td;
394
395         Scene *scene = t->scene;
396         if (ID_IS_LINKED(scene)) {
397                 BKE_report(t->reports, RPT_ERROR, "Linked data can't text-space transform");
398                 return;
399         }
400
401         View3DCursor *cursor = &scene->cursor;
402         {
403                 BLI_assert(t->data_container_len == 1);
404                 TransDataContainer *tc = t->data_container;
405                 tc->data_len = 1;
406                 td = tc->data = MEM_callocN(sizeof(TransData), "TransTexspace");
407                 td->ext = tc->data_ext = MEM_callocN(sizeof(TransDataExtension), "TransTexspace");
408         }
409
410         td->flag = TD_SELECTED;
411         copy_v3_v3(td->center, cursor->location);
412         td->ob = NULL;
413
414         unit_m3(td->mtx);
415         quat_to_mat3(td->axismtx, cursor->rotation);
416         normalize_m3(td->axismtx);
417         pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
418
419         td->loc = cursor->location;
420         copy_v3_v3(td->iloc, cursor->location);
421
422         td->ext->quat = cursor->rotation;
423         copy_qt_qt(td->ext->iquat, cursor->rotation);
424 }
425
426 /** \} */
427
428 /* ********************* edge (for crease) ***** */
429
430 static void createTransEdge(TransInfo *t)
431 {
432         FOREACH_TRANS_DATA_CONTAINER (t, tc) {
433
434                 BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
435                 TransData *td = NULL;
436                 BMEdge *eed;
437                 BMIter iter;
438                 float mtx[3][3], smtx[3][3];
439                 int count = 0, countsel = 0;
440                 const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
441                 int cd_edge_float_offset;
442
443                 BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
444                         if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
445                                 if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) countsel++;
446                                 if (is_prop_edit) count++;
447                         }
448                 }
449
450                 if (countsel == 0) {
451                         tc->data_len = 0;
452                         continue;
453                 }
454
455                 if (is_prop_edit) {
456                         tc->data_len = count;
457                 }
458                 else {
459                         tc->data_len = countsel;
460                 }
461
462                 td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransCrease");
463
464                 copy_m3_m4(mtx, tc->obedit->obmat);
465                 pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
466
467                 /* create data we need */
468                 if (t->mode == TFM_BWEIGHT) {
469                         BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_EDGE_BWEIGHT);
470                         cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT);
471                 }
472                 else { //if (t->mode == TFM_CREASE) {
473                         BLI_assert(t->mode == TFM_CREASE);
474                         BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_EDGE_CREASE);
475                         cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE);
476                 }
477
478                 BLI_assert(cd_edge_float_offset != -1);
479
480                 BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
481                         if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && (BM_elem_flag_test(eed, BM_ELEM_SELECT) || is_prop_edit)) {
482                                 float *fl_ptr;
483                                 /* need to set center for center calculations */
484                                 mid_v3_v3v3(td->center, eed->v1->co, eed->v2->co);
485
486                                 td->loc = NULL;
487                                 if (BM_elem_flag_test(eed, BM_ELEM_SELECT))
488                                         td->flag = TD_SELECTED;
489                                 else
490                                         td->flag = 0;
491
492                                 copy_m3_m3(td->smtx, smtx);
493                                 copy_m3_m3(td->mtx, mtx);
494
495                                 td->ext = NULL;
496
497                                 fl_ptr = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_float_offset);
498                                 td->val  =  fl_ptr;
499                                 td->ival = *fl_ptr;
500
501                                 td++;
502                         }
503                 }
504         }
505 }
506
507 /* ********************* pose mode ************* */
508
509 static bKinematicConstraint *has_targetless_ik(bPoseChannel *pchan)
510 {
511         bConstraint *con = pchan->constraints.first;
512
513         for (; con; con = con->next) {
514                 if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce != 0.0f)) {
515                         bKinematicConstraint *data = con->data;
516
517                         if (data->tar == NULL)
518                                 return data;
519                         if (data->tar->type == OB_ARMATURE && data->subtarget[0] == 0)
520                                 return data;
521                 }
522         }
523         return NULL;
524 }
525
526 static short apply_targetless_ik(Object *ob)
527 {
528         bPoseChannel *pchan, *parchan, *chanlist[256];
529         bKinematicConstraint *data;
530         int segcount, apply = 0;
531
532         /* now we got a difficult situation... we have to find the
533          * target-less IK pchans, and apply transformation to the all
534          * pchans that were in the chain */
535
536         for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
537                 data = has_targetless_ik(pchan);
538                 if (data && (data->flag & CONSTRAINT_IK_AUTO)) {
539
540                         /* fill the array with the bones of the chain (armature.c does same, keep it synced) */
541                         segcount = 0;
542
543                         /* exclude tip from chain? */
544                         if (!(data->flag & CONSTRAINT_IK_TIP))
545                                 parchan = pchan->parent;
546                         else
547                                 parchan = pchan;
548
549                         /* Find the chain's root & count the segments needed */
550                         for (; parchan; parchan = parchan->parent) {
551                                 chanlist[segcount] = parchan;
552                                 segcount++;
553
554                                 if (segcount == data->rootbone || segcount > 255) break;  // 255 is weak
555                         }
556                         for (; segcount; segcount--) {
557                                 Bone *bone;
558                                 float rmat[4][4] /*, tmat[4][4], imat[4][4]*/;
559
560                                 /* pose_mat(b) = pose_mat(b-1) * offs_bone * channel * constraint * IK  */
561                                 /* we put in channel the entire result of rmat = (channel * constraint * IK) */
562                                 /* pose_mat(b) = pose_mat(b-1) * offs_bone * rmat  */
563                                 /* rmat = pose_mat(b) * inv(pose_mat(b-1) * offs_bone ) */
564
565                                 parchan = chanlist[segcount - 1];
566                                 bone = parchan->bone;
567                                 bone->flag |= BONE_TRANSFORM;   /* ensures it gets an auto key inserted */
568
569                                 BKE_armature_mat_pose_to_bone(parchan, parchan->pose_mat, rmat);
570
571                                 /* apply and decompose, doesn't work for constraints or non-uniform scale well */
572                                 {
573                                         float rmat3[3][3], qrmat[3][3], imat3[3][3], smat[3][3];
574
575                                         copy_m3_m4(rmat3, rmat);
576
577                                         /* rotation */
578                                         /* [#22409] is partially caused by this, as slight numeric error introduced during
579                                          * the solving process leads to locked-axis values changing. However, we cannot modify
580                                          * the values here, or else there are huge discrepancies between IK-solver (interactive)
581                                          * and applied poses.
582                                          */
583                                         if (parchan->rotmode > 0)
584                                                 mat3_to_eulO(parchan->eul, parchan->rotmode, rmat3);
585                                         else if (parchan->rotmode == ROT_MODE_AXISANGLE)
586                                                 mat3_to_axis_angle(parchan->rotAxis, &parchan->rotAngle, rmat3);
587                                         else
588                                                 mat3_to_quat(parchan->quat, rmat3);
589
590                                         /* for size, remove rotation */
591                                         /* causes problems with some constraints (so apply only if needed) */
592                                         if (data->flag & CONSTRAINT_IK_STRETCH) {
593                                                 if (parchan->rotmode > 0)
594                                                         eulO_to_mat3(qrmat, parchan->eul, parchan->rotmode);
595                                                 else if (parchan->rotmode == ROT_MODE_AXISANGLE)
596                                                         axis_angle_to_mat3(qrmat, parchan->rotAxis, parchan->rotAngle);
597                                                 else
598                                                         quat_to_mat3(qrmat, parchan->quat);
599
600                                                 invert_m3_m3(imat3, qrmat);
601                                                 mul_m3_m3m3(smat, rmat3, imat3);
602                                                 mat3_to_size(parchan->size, smat);
603                                         }
604
605                                         /* causes problems with some constraints (e.g. childof), so disable this */
606                                         /* as it is IK shouldn't affect location directly */
607                                         /* copy_v3_v3(parchan->loc, rmat[3]); */
608                                 }
609
610                         }
611
612                         apply = 1;
613                         data->flag &= ~CONSTRAINT_IK_AUTO;
614                 }
615         }
616
617         return apply;
618 }
619
620 static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, TransDataContainer *tc, TransData *td)
621 {
622         Bone *bone = pchan->bone;
623         float pmat[3][3], omat[3][3];
624         float cmat[3][3], tmat[3][3];
625         float vec[3];
626
627         copy_v3_v3(vec, pchan->pose_mat[3]);
628         copy_v3_v3(td->center, vec);
629
630         td->ob = ob;
631         td->flag = TD_SELECTED;
632         if (bone->flag & BONE_HINGE_CHILD_TRANSFORM) {
633                 td->flag |= TD_NOCENTER;
634         }
635
636         if (bone->flag & BONE_TRANSFORM_CHILD) {
637                 td->flag |= TD_NOCENTER;
638                 td->flag |= TD_NO_LOC;
639         }
640
641         td->protectflag = pchan->protectflag;
642
643         td->loc = pchan->loc;
644         copy_v3_v3(td->iloc, pchan->loc);
645
646         td->ext->size = pchan->size;
647         copy_v3_v3(td->ext->isize, pchan->size);
648
649         if (pchan->rotmode > 0) {
650                 td->ext->rot = pchan->eul;
651                 td->ext->rotAxis = NULL;
652                 td->ext->rotAngle = NULL;
653                 td->ext->quat = NULL;
654
655                 copy_v3_v3(td->ext->irot, pchan->eul);
656         }
657         else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
658                 td->ext->rot = NULL;
659                 td->ext->rotAxis = pchan->rotAxis;
660                 td->ext->rotAngle = &pchan->rotAngle;
661                 td->ext->quat = NULL;
662
663                 td->ext->irotAngle = pchan->rotAngle;
664                 copy_v3_v3(td->ext->irotAxis, pchan->rotAxis);
665         }
666         else {
667                 td->ext->rot = NULL;
668                 td->ext->rotAxis = NULL;
669                 td->ext->rotAngle = NULL;
670                 td->ext->quat = pchan->quat;
671
672                 copy_qt_qt(td->ext->iquat, pchan->quat);
673         }
674         td->ext->rotOrder = pchan->rotmode;
675
676
677         /* proper way to get parent transform + own transform + constraints transform */
678         copy_m3_m4(omat, ob->obmat);
679
680         /* New code, using "generic" BKE_pchan_to_pose_mat(). */
681         {
682                 float rotscale_mat[4][4], loc_mat[4][4];
683                 float rpmat[3][3];
684
685                 BKE_pchan_to_pose_mat(pchan, rotscale_mat, loc_mat);
686                 if (t->mode == TFM_TRANSLATION)
687                         copy_m3_m4(pmat, loc_mat);
688                 else
689                         copy_m3_m4(pmat, rotscale_mat);
690
691                 /* Grrr! Exceptional case: When translating pose bones that are either Hinge or NoLocal,
692                  * and want align snapping, we just need both loc_mat and rotscale_mat.
693                  * So simply always store rotscale mat in td->ext, and always use it to apply rotations...
694                  * Ugly to need such hacks! :/ */
695                 copy_m3_m4(rpmat, rotscale_mat);
696
697                 if (constraints_list_needinv(t, &pchan->constraints)) {
698                         copy_m3_m4(tmat, pchan->constinv);
699                         invert_m3_m3(cmat, tmat);
700                         mul_m3_series(td->mtx, cmat, omat, pmat);
701                         mul_m3_series(td->ext->r_mtx, cmat, omat, rpmat);
702                 }
703                 else {
704                         mul_m3_series(td->mtx, omat, pmat);
705                         mul_m3_series(td->ext->r_mtx, omat, rpmat);
706                 }
707                 invert_m3_m3(td->ext->r_smtx, td->ext->r_mtx);
708         }
709
710         pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
711
712         /* exceptional case: rotate the pose bone which also applies transformation
713          * when a parentless bone has BONE_NO_LOCAL_LOCATION [] */
714         if (!ELEM(t->mode, TFM_TRANSLATION, TFM_RESIZE) && (pchan->bone->flag & BONE_NO_LOCAL_LOCATION)) {
715                 if (pchan->parent) {
716                         /* same as td->smtx but without pchan->bone->bone_mat */
717                         td->flag |= TD_PBONE_LOCAL_MTX_C;
718                         mul_m3_m3m3(td->ext->l_smtx, pchan->bone->bone_mat, td->smtx);
719                 }
720                 else {
721                         td->flag |= TD_PBONE_LOCAL_MTX_P;
722                 }
723         }
724
725         /* for axismat we use bone's own transform */
726         copy_m3_m4(pmat, pchan->pose_mat);
727         mul_m3_m3m3(td->axismtx, omat, pmat);
728         normalize_m3(td->axismtx);
729
730         if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
731                 bArmature *arm = tc->poseobj->data;
732
733                 if ((t->mode == TFM_BONE_ENVELOPE_DIST) || (arm->drawtype == ARM_ENVELOPE)) {
734                         td->loc = NULL;
735                         td->val = &bone->dist;
736                         td->ival = bone->dist;
737                 }
738                 else {
739                         // abusive storage of scale in the loc pointer :)
740                         td->loc = &bone->xwidth;
741                         copy_v3_v3(td->iloc, td->loc);
742                         td->val = NULL;
743                 }
744         }
745
746         /* in this case we can do target-less IK grabbing */
747         if (t->mode == TFM_TRANSLATION) {
748                 bKinematicConstraint *data = has_targetless_ik(pchan);
749                 if (data) {
750                         if (data->flag & CONSTRAINT_IK_TIP) {
751                                 copy_v3_v3(data->grabtarget, pchan->pose_tail);
752                         }
753                         else {
754                                 copy_v3_v3(data->grabtarget, pchan->pose_head);
755                         }
756                         td->loc = data->grabtarget;
757                         copy_v3_v3(td->iloc, td->loc);
758                         data->flag |= CONSTRAINT_IK_AUTO;
759
760                         /* only object matrix correction */
761                         copy_m3_m3(td->mtx, omat);
762                         pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
763                 }
764         }
765
766         /* store reference to first constraint */
767         td->con = pchan->constraints.first;
768 }
769
770 static void bone_children_clear_transflag(int mode, short around, ListBase *lb)
771 {
772         Bone *bone = lb->first;
773
774         for (; bone; bone = bone->next) {
775                 if ((bone->flag & BONE_HINGE) && (bone->flag & BONE_CONNECTED)) {
776                         bone->flag |= BONE_HINGE_CHILD_TRANSFORM;
777                 }
778                 else if ((bone->flag & BONE_TRANSFORM) &&
779                          (mode == TFM_ROTATION || mode == TFM_TRACKBALL) &&
780                          (around == V3D_AROUND_LOCAL_ORIGINS))
781                 {
782                         bone->flag |= BONE_TRANSFORM_CHILD;
783                 }
784                 else {
785                         bone->flag &= ~BONE_TRANSFORM;
786                 }
787
788                 bone_children_clear_transflag(mode, around, &bone->childbase);
789         }
790 }
791
792 /* sets transform flags in the bones
793  * returns total number of bones with BONE_TRANSFORM */
794 int count_set_pose_transflags(Object *ob, const int mode, const short around, bool has_translate_rotate[2])
795 {
796         bArmature *arm = ob->data;
797         bPoseChannel *pchan;
798         Bone *bone;
799         int total = 0;
800
801         for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
802                 bone = pchan->bone;
803                 if (PBONE_VISIBLE(arm, bone)) {
804                         if ((bone->flag & BONE_SELECTED))
805                                 bone->flag |= BONE_TRANSFORM;
806                         else
807                                 bone->flag &= ~BONE_TRANSFORM;
808
809                         bone->flag &= ~BONE_HINGE_CHILD_TRANSFORM;
810                         bone->flag &= ~BONE_TRANSFORM_CHILD;
811                 }
812                 else
813                         bone->flag &= ~BONE_TRANSFORM;
814         }
815
816         /* make sure no bone can be transformed when a parent is transformed */
817         /* since pchans are depsgraph sorted, the parents are in beginning of list */
818         if (!ELEM(mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
819                 for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
820                         bone = pchan->bone;
821                         if (bone->flag & BONE_TRANSFORM)
822                                 bone_children_clear_transflag(mode, around, &bone->childbase);
823                 }
824         }
825         /* now count, and check if we have autoIK or have to switch from translate to rotate */
826         for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
827                 bone = pchan->bone;
828                 if (bone->flag & BONE_TRANSFORM) {
829                         total++;
830
831                         if (has_translate_rotate != NULL) {
832                                 if (has_targetless_ik(pchan) == NULL) {
833                                         if (pchan->parent && (pchan->bone->flag & BONE_CONNECTED)) {
834                                                 if (pchan->bone->flag & BONE_HINGE_CHILD_TRANSFORM) {
835                                                         has_translate_rotate[0] = true;
836                                                 }
837                                         }
838                                         else {
839                                                 if ((pchan->protectflag & OB_LOCK_LOC) != OB_LOCK_LOC) {
840                                                         has_translate_rotate[0] = true;
841                                                 }
842                                         }
843                                         if ((pchan->protectflag & OB_LOCK_ROT) != OB_LOCK_ROT) {
844                                                 has_translate_rotate[1] = true;
845                                         }
846                                 }
847                                 else {
848                                         has_translate_rotate[0] = true;
849                                 }
850                         }
851                 }
852         }
853
854         return total;
855 }
856
857
858 /* -------- Auto-IK ---------- */
859
860 /* adjust pose-channel's auto-ik chainlen */
861 static bool pchan_autoik_adjust(bPoseChannel *pchan, short chainlen)
862 {
863         bConstraint *con;
864         bool changed = false;
865
866         /* don't bother to search if no valid constraints */
867         if ((pchan->constflag & (PCHAN_HAS_IK | PCHAN_HAS_TARGET)) == 0) {
868                 return changed;
869         }
870
871         /* check if pchan has ik-constraint */
872         for (con = pchan->constraints.first; con; con = con->next) {
873                 if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce != 0.0f)) {
874                         bKinematicConstraint *data = con->data;
875
876                         /* only accept if a temporary one (for auto-ik) */
877                         if (data->flag & CONSTRAINT_IK_TEMP) {
878                                 /* chainlen is new chainlen, but is limited by maximum chainlen */
879                                 const int old_rootbone = data->rootbone;
880                                 if ((chainlen == 0) || (chainlen > data->max_rootbone)) {
881                                         data->rootbone = data->max_rootbone;
882                                 }
883                                 else {
884                                         data->rootbone = chainlen;
885                                 }
886                                 changed |= (data->rootbone != old_rootbone);
887                         }
888                 }
889         }
890
891         return changed;
892 }
893
894 /* change the chain-length of auto-ik */
895 void transform_autoik_update(TransInfo *t, short mode)
896 {
897         Main *bmain = CTX_data_main(t->context);
898
899         short *chainlen = &t->settings->autoik_chainlen;
900         bPoseChannel *pchan;
901
902         /* mode determines what change to apply to chainlen */
903         if (mode == 1) {
904                 /* mode=1 is from WHEELMOUSEDOWN... increases len */
905                 (*chainlen)++;
906         }
907         else if (mode == -1) {
908                 /* mode==-1 is from WHEELMOUSEUP... decreases len */
909                 if (*chainlen > 0) {
910                         (*chainlen)--;
911                 }
912                 else {
913                         /* IK length did not change, skip updates. */
914                         return;
915                 }
916         }
917
918         /* apply to all pose-channels */
919         bool changed = false;
920
921         FOREACH_TRANS_DATA_CONTAINER (t, tc) {
922
923                 /* sanity checks (don't assume t->poseobj is set, or that it is an armature) */
924                 if (ELEM(NULL, tc->poseobj, tc->poseobj->pose)) {
925                         continue;
926                 }
927
928                 for (pchan = tc->poseobj->pose->chanbase.first; pchan; pchan = pchan->next) {
929                         changed |= pchan_autoik_adjust(pchan, *chainlen);
930                 }
931         }
932
933         if (changed) {
934                 /* TODO(sergey): Consider doing partial update only. */
935                 DEG_relations_tag_update(bmain);
936         }
937 }
938
939 /* frees temporal IKs */
940 static void pose_grab_with_ik_clear(Main *bmain, Object *ob)
941 {
942         bKinematicConstraint *data;
943         bPoseChannel *pchan;
944         bConstraint *con, *next;
945         bool relations_changed = false;
946
947         for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
948                 /* clear all temporary lock flags */
949                 pchan->ikflag &= ~(BONE_IK_NO_XDOF_TEMP | BONE_IK_NO_YDOF_TEMP | BONE_IK_NO_ZDOF_TEMP);
950
951                 pchan->constflag &= ~(PCHAN_HAS_IK | PCHAN_HAS_TARGET);
952
953                 /* remove all temporary IK-constraints added */
954                 for (con = pchan->constraints.first; con; con = next) {
955                         next = con->next;
956                         if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
957                                 data = con->data;
958                                 if (data->flag & CONSTRAINT_IK_TEMP) {
959                                         relations_changed = true;
960
961                                         /* iTaSC needs clear for removed constraints */
962                                         BIK_clear_data(ob->pose);
963
964                                         BLI_remlink(&pchan->constraints, con);
965                                         MEM_freeN(con->data);
966                                         MEM_freeN(con);
967                                         continue;
968                                 }
969                                 pchan->constflag |= PCHAN_HAS_IK;
970                                 if (data->tar == NULL || (data->tar->type == OB_ARMATURE && data->subtarget[0] == 0))
971                                         pchan->constflag |= PCHAN_HAS_TARGET;
972                         }
973                 }
974         }
975
976         if (relations_changed) {
977                 /* TODO(sergey): Consider doing partial update only. */
978                 DEG_relations_tag_update(bmain);
979         }
980 }
981
982 /* adds the IK to pchan - returns if added */
983 static short pose_grab_with_ik_add(bPoseChannel *pchan)
984 {
985         bKinematicConstraint *targetless = NULL;
986         bKinematicConstraint *data;
987         bConstraint *con;
988
989         /* Sanity check */
990         if (pchan == NULL)
991                 return 0;
992
993         /* Rule: not if there's already an IK on this channel */
994         for (con = pchan->constraints.first; con; con = con->next) {
995                 if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
996                         data = con->data;
997
998                         if (data->tar == NULL || (data->tar->type == OB_ARMATURE && data->subtarget[0] == '\0')) {
999                                 /* make reference to constraint to base things off later (if it's the last targetless constraint encountered) */
1000                                 targetless = (bKinematicConstraint *)con->data;
1001
1002                                 /* but, if this is a targetless IK, we make it auto anyway (for the children loop) */
1003                                 if (con->enforce != 0.0f) {
1004                                         data->flag |= CONSTRAINT_IK_AUTO;
1005
1006                                         /* if no chain length has been specified, just make things obey standard rotation locks too */
1007                                         if (data->rootbone == 0) {
1008                                                 for (; pchan; pchan = pchan->parent) {
1009                                                         /* here, we set ik-settings for bone from pchan->protectflag */
1010                                                         // XXX: careful with quats/axis-angle rotations where we're locking 4d components
1011                                                         if (pchan->protectflag & OB_LOCK_ROTX) pchan->ikflag |= BONE_IK_NO_XDOF_TEMP;
1012                                                         if (pchan->protectflag & OB_LOCK_ROTY) pchan->ikflag |= BONE_IK_NO_YDOF_TEMP;
1013                                                         if (pchan->protectflag & OB_LOCK_ROTZ) pchan->ikflag |= BONE_IK_NO_ZDOF_TEMP;
1014                                                 }
1015                                         }
1016
1017                                         return 0;
1018                                 }
1019                         }
1020
1021                         if ((con->flag & CONSTRAINT_DISABLE) == 0 && (con->enforce != 0.0f))
1022                                 return 0;
1023                 }
1024         }
1025
1026         con = BKE_constraint_add_for_pose(NULL, pchan, "TempConstraint", CONSTRAINT_TYPE_KINEMATIC);
1027         pchan->constflag |= (PCHAN_HAS_IK | PCHAN_HAS_TARGET);    /* for draw, but also for detecting while pose solving */
1028         data = con->data;
1029         if (targetless) {
1030                 /* if exists, use values from last targetless (but disabled) IK-constraint as base */
1031                 *data = *targetless;
1032         }
1033         else
1034                 data->flag = CONSTRAINT_IK_TIP;
1035         data->flag |= CONSTRAINT_IK_TEMP | CONSTRAINT_IK_AUTO | CONSTRAINT_IK_POS;
1036         copy_v3_v3(data->grabtarget, pchan->pose_tail);
1037         data->rootbone = 0; /* watch-it! has to be 0 here, since we're still on the same bone for the first time through the loop [#25885] */
1038
1039         /* we only include bones that are part of a continual connected chain */
1040         do {
1041                 /* here, we set ik-settings for bone from pchan->protectflag */
1042                 // XXX: careful with quats/axis-angle rotations where we're locking 4d components
1043                 if (pchan->protectflag & OB_LOCK_ROTX) pchan->ikflag |= BONE_IK_NO_XDOF_TEMP;
1044                 if (pchan->protectflag & OB_LOCK_ROTY) pchan->ikflag |= BONE_IK_NO_YDOF_TEMP;
1045                 if (pchan->protectflag & OB_LOCK_ROTZ) pchan->ikflag |= BONE_IK_NO_ZDOF_TEMP;
1046
1047                 /* now we count this pchan as being included */
1048                 data->rootbone++;
1049
1050                 /* continue to parent, but only if we're connected to it */
1051                 if (pchan->bone->flag & BONE_CONNECTED)
1052                         pchan = pchan->parent;
1053                 else
1054                         pchan = NULL;
1055         } while (pchan);
1056
1057         /* make a copy of maximum chain-length */
1058         data->max_rootbone = data->rootbone;
1059
1060         return 1;
1061 }
1062
1063 /* bone is a candidate to get IK, but we don't do it if it has children connected */
1064 static short pose_grab_with_ik_children(bPose *pose, Bone *bone)
1065 {
1066         Bone *bonec;
1067         short wentdeeper = 0, added = 0;
1068
1069         /* go deeper if children & children are connected */
1070         for (bonec = bone->childbase.first; bonec; bonec = bonec->next) {
1071                 if (bonec->flag & BONE_CONNECTED) {
1072                         wentdeeper = 1;
1073                         added += pose_grab_with_ik_children(pose, bonec);
1074                 }
1075         }
1076         if (wentdeeper == 0) {
1077                 bPoseChannel *pchan = BKE_pose_channel_find_name(pose, bone->name);
1078                 if (pchan)
1079                         added += pose_grab_with_ik_add(pchan);
1080         }
1081
1082         return added;
1083 }
1084
1085 /* main call which adds temporal IK chains */
1086 static short pose_grab_with_ik(Main *bmain, Object *ob)
1087 {
1088         bArmature *arm;
1089         bPoseChannel *pchan, *parent;
1090         Bone *bonec;
1091         short tot_ik = 0;
1092
1093         if ((ob == NULL) || (ob->pose == NULL) || (ob->mode & OB_MODE_POSE) == 0)
1094                 return 0;
1095
1096         arm = ob->data;
1097
1098         /* Rule: allow multiple Bones (but they must be selected, and only one ik-solver per chain should get added) */
1099         for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
1100                 if (pchan->bone->layer & arm->layer) {
1101                         if (pchan->bone->flag & BONE_SELECTED) {
1102                                 /* Rule: no IK for solitatry (unconnected) bones */
1103                                 for (bonec = pchan->bone->childbase.first; bonec; bonec = bonec->next) {
1104                                         if (bonec->flag & BONE_CONNECTED) {
1105                                                 break;
1106                                         }
1107                                 }
1108                                 if ((pchan->bone->flag & BONE_CONNECTED) == 0 && (bonec == NULL))
1109                                         continue;
1110
1111                                 /* rule: if selected Bone is not a root bone, it gets a temporal IK */
1112                                 if (pchan->parent) {
1113                                         /* only adds if there's no IK yet (and no parent bone was selected) */
1114                                         for (parent = pchan->parent; parent; parent = parent->parent) {
1115                                                 if (parent->bone->flag & BONE_SELECTED)
1116                                                         break;
1117                                         }
1118                                         if (parent == NULL)
1119                                                 tot_ik += pose_grab_with_ik_add(pchan);
1120                                 }
1121                                 else {
1122                                         /* rule: go over the children and add IK to the tips */
1123                                         tot_ik += pose_grab_with_ik_children(ob->pose, pchan->bone);
1124                                 }
1125                         }
1126                 }
1127         }
1128
1129         /* iTaSC needs clear for new IK constraints */
1130         if (tot_ik) {
1131                 BIK_clear_data(ob->pose);
1132                 /* TODO(sergey): Consider doing partial update only. */
1133                 DEG_relations_tag_update(bmain);
1134         }
1135
1136         return (tot_ik) ? 1 : 0;
1137 }
1138
1139
1140 /**
1141  * When objects array is NULL, use 't->data_container' as is.
1142  */
1143 static void createTransPose(TransInfo *t)
1144 {
1145         Main *bmain = CTX_data_main(t->context);
1146
1147         t->data_len_all = 0;
1148
1149         bool has_translate_rotate_buf[2] = {false, false};
1150         bool *has_translate_rotate = (t->mode == TFM_TRANSLATION) ? has_translate_rotate_buf : NULL;
1151
1152         FOREACH_TRANS_DATA_CONTAINER (t, tc) {
1153                 Object *ob = tc->poseobj;
1154
1155                 bArmature *arm;
1156                 short ik_on = 0;
1157
1158                 /* check validity of state */
1159                 arm = BKE_armature_from_object(tc->poseobj);
1160                 if ((arm == NULL) || (ob->pose == NULL)) {
1161                         continue;
1162                 }
1163
1164                 if (arm->flag & ARM_RESTPOS) {
1165                         if (ELEM(t->mode, TFM_DUMMY, TFM_BONESIZE) == 0) {
1166                                 BKE_report(t->reports, RPT_ERROR, "Cannot change Pose when 'Rest Position' is enabled");
1167                                 return;
1168                         }
1169                 }
1170
1171                 /* do we need to add temporal IK chains? */
1172                 if ((arm->flag & ARM_AUTO_IK) && t->mode == TFM_TRANSLATION) {
1173                         ik_on = pose_grab_with_ik(bmain, ob);
1174                         if (ik_on) t->flag |= T_AUTOIK;
1175                 }
1176
1177                 /* set flags and count total (warning, can change transform to rotate) */
1178                 tc->data_len = count_set_pose_transflags(ob, t->mode, t->around, has_translate_rotate);
1179                 /* len may be zero, skip next iteration. */
1180         }
1181
1182         /* if there are no translatable bones, do rotation */
1183         if ((t->mode == TFM_TRANSLATION) && !has_translate_rotate[0]) {
1184                 if (has_translate_rotate[1]) {
1185                         t->mode = TFM_ROTATION;
1186                 }
1187                 else {
1188                         t->mode = TFM_RESIZE;
1189                 }
1190         }
1191
1192         FOREACH_TRANS_DATA_CONTAINER (t, tc) {
1193                 if (tc->data_len == 0) {
1194                         continue;
1195                 }
1196                 Object *ob = tc->poseobj;
1197                 TransData *td;
1198                 TransDataExtension *tdx;
1199                 short ik_on = 0;
1200                 int i;
1201
1202                 tc->poseobj = ob; /* we also allow non-active objects to be transformed, in weightpaint */
1203
1204                 /* init trans data */
1205                 td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransPoseBone");
1206                 tdx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "TransPoseBoneExt");
1207                 for (i = 0; i < tc->data_len; i++, td++, tdx++) {
1208                         td->ext = tdx;
1209                         td->val = NULL;
1210                 }
1211
1212                 /* use pose channels to fill trans data */
1213                 td = tc->data;
1214                 for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
1215                         if (pchan->bone->flag & BONE_TRANSFORM) {
1216                                 add_pose_transdata(t, pchan, ob, tc, td);
1217                                 td++;
1218                         }
1219                 }
1220
1221                 if (td != (tc->data + tc->data_len)) {
1222                         BKE_report(t->reports, RPT_DEBUG, "Bone selection count error");
1223                 }
1224
1225                 /* initialize initial auto=ik chainlen's? */
1226                 if (ik_on) {
1227                         transform_autoik_update(t, 0);
1228                 }
1229         }
1230
1231         t->flag |= T_POSE;
1232         /* disable PET, its not usable in pose mode yet [#32444] */
1233         t->flag &= ~T_PROP_EDIT_ALL;
1234
1235 }
1236
1237 void restoreBones(TransDataContainer *tc)
1238 {
1239         bArmature *arm = tc->obedit->data;
1240         BoneInitData *bid = tc->custom.type.data;
1241         EditBone *ebo;
1242
1243         while (bid->bone) {
1244                 ebo = bid->bone;
1245
1246                 ebo->dist = bid->dist;
1247                 ebo->rad_tail = bid->rad_tail;
1248                 ebo->roll = bid->roll;
1249                 ebo->xwidth = bid->xwidth;
1250                 ebo->zwidth = bid->zwidth;
1251                 copy_v3_v3(ebo->head, bid->head);
1252                 copy_v3_v3(ebo->tail, bid->tail);
1253
1254                 if (arm->flag & ARM_MIRROR_EDIT) {
1255                         EditBone *ebo_child;
1256
1257                         /* Also move connected ebo_child, in case ebo_child's name aren't mirrored properly */
1258                         for (ebo_child = arm->edbo->first; ebo_child; ebo_child = ebo_child->next) {
1259                                 if ((ebo_child->flag & BONE_CONNECTED) && (ebo_child->parent == ebo)) {
1260                                         copy_v3_v3(ebo_child->head, ebo->tail);
1261                                         ebo_child->rad_head = ebo->rad_tail;
1262                                 }
1263                         }
1264
1265                         /* Also move connected parent, in case parent's name isn't mirrored properly */
1266                         if ((ebo->flag & BONE_CONNECTED) && ebo->parent) {
1267                                 EditBone *parent = ebo->parent;
1268                                 copy_v3_v3(parent->tail, ebo->head);
1269                                 parent->rad_tail = ebo->rad_head;
1270                         }
1271                 }
1272
1273                 bid++;
1274         }
1275 }
1276
1277
1278 /* ********************* armature ************** */
1279 static void createTransArmatureVerts(TransInfo *t)
1280 {
1281         FOREACH_TRANS_DATA_CONTAINER (t, tc) {
1282                 EditBone *ebo, *eboflip;
1283                 bArmature *arm = tc->obedit->data;
1284                 ListBase *edbo = arm->edbo;
1285                 TransData *td, *td_old;
1286                 float mtx[3][3], smtx[3][3], bonemat[3][3];
1287                 bool mirror = ((arm->flag & ARM_MIRROR_EDIT) != 0);
1288                 int total_mirrored = 0, i;
1289                 int oldtot;
1290                 BoneInitData *bid = NULL;
1291
1292                 tc->data_len = 0;
1293                 for (ebo = edbo->first; ebo; ebo = ebo->next) {
1294                         oldtot = tc->data_len;
1295
1296                         if (EBONE_VISIBLE(arm, ebo) && !(ebo->flag & BONE_EDITMODE_LOCKED)) {
1297                                 if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
1298                                         if (ebo->flag & BONE_SELECTED)
1299                                                 tc->data_len++;
1300                                 }
1301                                 else if (t->mode == TFM_BONE_ROLL) {
1302                                         if (ebo->flag & BONE_SELECTED)
1303                                                 tc->data_len++;
1304                                 }
1305                                 else {
1306                                         if (ebo->flag & BONE_TIPSEL)
1307                                                 tc->data_len++;
1308                                         if (ebo->flag & BONE_ROOTSEL)
1309                                                 tc->data_len++;
1310                                 }
1311                         }
1312
1313                         if (mirror && (oldtot < tc->data_len)) {
1314                                 eboflip = ED_armature_ebone_get_mirrored(arm->edbo, ebo);
1315                                 if (eboflip)
1316                                         total_mirrored++;
1317                         }
1318                 }
1319
1320                 if (!tc->data_len) {
1321                         continue;
1322                 }
1323
1324                 transform_around_single_fallback(t);
1325
1326                 copy_m3_m4(mtx, tc->obedit->obmat);
1327                 pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
1328
1329                 td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransEditBone");
1330
1331                 if (mirror) {
1332                         tc->custom.type.data = bid = MEM_mallocN((total_mirrored + 1) * sizeof(BoneInitData), "BoneInitData");
1333                         tc->custom.type.use_free = true;
1334                 }
1335
1336                 i = 0;
1337
1338                 for (ebo = edbo->first; ebo; ebo = ebo->next) {
1339                         td_old = td;
1340                         ebo->oldlength = ebo->length;   // length==0.0 on extrude, used for scaling radius of bone points
1341
1342                         if (EBONE_VISIBLE(arm, ebo) && !(ebo->flag & BONE_EDITMODE_LOCKED)) {
1343                                 if (t->mode == TFM_BONE_ENVELOPE) {
1344                                         if (ebo->flag & BONE_ROOTSEL) {
1345                                                 td->val = &ebo->rad_head;
1346                                                 td->ival = *td->val;
1347
1348                                                 copy_v3_v3(td->center, ebo->head);
1349                                                 td->flag = TD_SELECTED;
1350
1351                                                 copy_m3_m3(td->smtx, smtx);
1352                                                 copy_m3_m3(td->mtx, mtx);
1353
1354                                                 td->loc = NULL;
1355                                                 td->ext = NULL;
1356                                                 td->ob = tc->obedit;
1357
1358                                                 td++;
1359                                         }
1360                                         if (ebo->flag & BONE_TIPSEL) {
1361                                                 td->val = &ebo->rad_tail;
1362                                                 td->ival = *td->val;
1363                                                 copy_v3_v3(td->center, ebo->tail);
1364                                                 td->flag = TD_SELECTED;
1365
1366                                                 copy_m3_m3(td->smtx, smtx);
1367                                                 copy_m3_m3(td->mtx, mtx);
1368
1369                                                 td->loc = NULL;
1370                                                 td->ext = NULL;
1371                                                 td->ob = tc->obedit;
1372
1373                                                 td++;
1374                                         }
1375
1376                                 }
1377                                 else if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
1378                                         if (ebo->flag & BONE_SELECTED) {
1379                                                 if ((t->mode == TFM_BONE_ENVELOPE_DIST) || (arm->drawtype == ARM_ENVELOPE)) {
1380                                                         td->loc = NULL;
1381                                                         td->val = &ebo->dist;
1382                                                         td->ival = ebo->dist;
1383                                                 }
1384                                                 else {
1385                                                         // abusive storage of scale in the loc pointer :)
1386                                                         td->loc = &ebo->xwidth;
1387                                                         copy_v3_v3(td->iloc, td->loc);
1388                                                         td->val = NULL;
1389                                                 }
1390                                                 copy_v3_v3(td->center, ebo->head);
1391                                                 td->flag = TD_SELECTED;
1392
1393                                                 /* use local bone matrix */
1394                                                 ED_armature_ebone_to_mat3(ebo, bonemat);
1395                                                 mul_m3_m3m3(td->mtx, mtx, bonemat);
1396                                                 invert_m3_m3(td->smtx, td->mtx);
1397
1398                                                 copy_m3_m3(td->axismtx, td->mtx);
1399                                                 normalize_m3(td->axismtx);
1400
1401                                                 td->ext = NULL;
1402                                                 td->ob = tc->obedit;
1403
1404                                                 td++;
1405                                         }
1406                                 }
1407                                 else if (t->mode == TFM_BONE_ROLL) {
1408                                         if (ebo->flag & BONE_SELECTED) {
1409                                                 td->loc = NULL;
1410                                                 td->val = &(ebo->roll);
1411                                                 td->ival = ebo->roll;
1412
1413                                                 copy_v3_v3(td->center, ebo->head);
1414                                                 td->flag = TD_SELECTED;
1415
1416                                                 td->ext = NULL;
1417                                                 td->ob = tc->obedit;
1418
1419                                                 td++;
1420                                         }
1421                                 }
1422                                 else {
1423                                         if (ebo->flag & BONE_TIPSEL) {
1424                                                 copy_v3_v3(td->iloc, ebo->tail);
1425
1426                                                 /* Don't allow single selected tips to have a modified center,
1427                                                  * causes problem with snapping (see T45974).
1428                                                  * However, in rotation mode, we want to keep that 'rotate bone around root with
1429                                                  * only its tip selected' behavior (see T46325). */
1430                                                 if ((t->around == V3D_AROUND_LOCAL_ORIGINS) &&
1431                                                     ((t->mode == TFM_ROTATION) || (ebo->flag & BONE_ROOTSEL)))
1432                                                 {
1433                                                         copy_v3_v3(td->center, ebo->head);
1434                                                 }
1435                                                 else {
1436                                                         copy_v3_v3(td->center, td->iloc);
1437                                                 }
1438
1439                                                 td->loc = ebo->tail;
1440                                                 td->flag = TD_SELECTED;
1441                                                 if (ebo->flag & BONE_EDITMODE_LOCKED)
1442                                                         td->protectflag = OB_LOCK_LOC | OB_LOCK_ROT | OB_LOCK_SCALE;
1443
1444                                                 copy_m3_m3(td->smtx, smtx);
1445                                                 copy_m3_m3(td->mtx, mtx);
1446
1447                                                 ED_armature_ebone_to_mat3(ebo, td->axismtx);
1448
1449                                                 if ((ebo->flag & BONE_ROOTSEL) == 0) {
1450                                                         td->extra = ebo;
1451                                                         td->ival = ebo->roll;
1452                                                 }
1453
1454                                                 td->ext = NULL;
1455                                                 td->val = NULL;
1456                                                 td->ob = tc->obedit;
1457
1458                                                 td++;
1459                                         }
1460                                         if (ebo->flag & BONE_ROOTSEL) {
1461                                                 copy_v3_v3(td->iloc, ebo->head);
1462                                                 copy_v3_v3(td->center, td->iloc);
1463                                                 td->loc = ebo->head;
1464                                                 td->flag = TD_SELECTED;
1465                                                 if (ebo->flag & BONE_EDITMODE_LOCKED)
1466                                                         td->protectflag = OB_LOCK_LOC | OB_LOCK_ROT | OB_LOCK_SCALE;
1467
1468                                                 copy_m3_m3(td->smtx, smtx);
1469                                                 copy_m3_m3(td->mtx, mtx);
1470
1471                                                 ED_armature_ebone_to_mat3(ebo, td->axismtx);
1472
1473                                                 td->extra = ebo; /* to fix roll */
1474                                                 td->ival = ebo->roll;
1475
1476                                                 td->ext = NULL;
1477                                                 td->val = NULL;
1478                                                 td->ob = tc->obedit;
1479
1480                                                 td++;
1481                                         }
1482                                 }
1483                         }
1484
1485                         if (mirror && (td_old != td)) {
1486                                 eboflip = ED_armature_ebone_get_mirrored(arm->edbo, ebo);
1487                                 if (eboflip) {
1488                                         bid[i].bone = eboflip;
1489                                         bid[i].dist = eboflip->dist;
1490                                         bid[i].rad_tail = eboflip->rad_tail;
1491                                         bid[i].roll = eboflip->roll;
1492                                         bid[i].xwidth = eboflip->xwidth;
1493                                         bid[i].zwidth = eboflip->zwidth;
1494                                         copy_v3_v3(bid[i].head, eboflip->head);
1495                                         copy_v3_v3(bid[i].tail, eboflip->tail);
1496                                         i++;
1497                                 }
1498                         }
1499                 }
1500
1501                 if (mirror) {
1502                         /* trick to terminate iteration */
1503                         bid[total_mirrored].bone = NULL;
1504                 }
1505         }
1506 }
1507
1508 /* ********************* meta elements ********* */
1509
1510 static void createTransMBallVerts(TransInfo *t)
1511 {
1512         FOREACH_TRANS_DATA_CONTAINER (t, tc) {
1513                 MetaBall *mb = (MetaBall *)tc->obedit->data;
1514                 MetaElem *ml;
1515                 TransData *td;
1516                 TransDataExtension *tx;
1517                 float mtx[3][3], smtx[3][3];
1518                 int count = 0, countsel = 0;
1519                 const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
1520
1521                 /* count totals */
1522                 for (ml = mb->editelems->first; ml; ml = ml->next) {
1523                         if (ml->flag & SELECT) countsel++;
1524                         if (is_prop_edit) count++;
1525                 }
1526
1527                 /* note: in prop mode we need at least 1 selected */
1528                 if (countsel == 0) {
1529                         continue;
1530                 }
1531
1532                 if (is_prop_edit) tc->data_len = count;
1533                 else tc->data_len = countsel;
1534
1535                 td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(MBall EditMode)");
1536                 tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "MetaElement_TransExtension");
1537
1538                 copy_m3_m4(mtx, tc->obedit->obmat);
1539                 pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
1540
1541                 for (ml = mb->editelems->first; ml; ml = ml->next) {
1542                         if (is_prop_edit || (ml->flag & SELECT)) {
1543                                 td->loc = &ml->x;
1544                                 copy_v3_v3(td->iloc, td->loc);
1545                                 copy_v3_v3(td->center, td->loc);
1546
1547                                 quat_to_mat3(td->axismtx, ml->quat);
1548
1549                                 if (ml->flag & SELECT) td->flag = TD_SELECTED | TD_USEQUAT | TD_SINGLESIZE;
1550                                 else td->flag = TD_USEQUAT;
1551
1552                                 copy_m3_m3(td->smtx, smtx);
1553                                 copy_m3_m3(td->mtx, mtx);
1554
1555                                 td->ext = tx;
1556
1557                                 /* Radius of MetaElem (mass of MetaElem influence) */
1558                                 if (ml->flag & MB_SCALE_RAD) {
1559                                         td->val = &ml->rad;
1560                                         td->ival = ml->rad;
1561                                 }
1562                                 else {
1563                                         td->val = &ml->s;
1564                                         td->ival = ml->s;
1565                                 }
1566
1567                                 /* expx/expy/expz determine "shape" of some MetaElem types */
1568                                 tx->size = &ml->expx;
1569                                 tx->isize[0] = ml->expx;
1570                                 tx->isize[1] = ml->expy;
1571                                 tx->isize[2] = ml->expz;
1572
1573                                 /* quat is used for rotation of MetaElem */
1574                                 tx->quat = ml->quat;
1575                                 copy_qt_qt(tx->iquat, ml->quat);
1576
1577                                 tx->rot = NULL;
1578
1579                                 td++;
1580                                 tx++;
1581                         }
1582                 }
1583         }
1584 }
1585
1586 /* ********************* curve/surface ********* */
1587
1588 static void calc_distanceCurveVerts(TransData *head, TransData *tail)
1589 {
1590         TransData *td, *td_near = NULL;
1591         for (td = head; td <= tail; td++) {
1592                 if (td->flag & TD_SELECTED) {
1593                         td_near = td;
1594                         td->dist = 0.0f;
1595                 }
1596                 else if (td_near) {
1597                         float dist;
1598                         dist = len_v3v3(td_near->center, td->center);
1599                         if (dist < (td - 1)->dist) {
1600                                 td->dist = (td - 1)->dist;
1601                         }
1602                         else {
1603                                 td->dist = dist;
1604                         }
1605                 }
1606                 else {
1607                         td->dist = FLT_MAX;
1608                         td->flag |= TD_NOTCONNECTED;
1609                 }
1610         }
1611         td_near = NULL;
1612         for (td = tail; td >= head; td--) {
1613                 if (td->flag & TD_SELECTED) {
1614                         td_near = td;
1615                         td->dist = 0.0f;
1616                 }
1617                 else if (td_near) {
1618                         float dist;
1619                         dist = len_v3v3(td_near->center, td->center);
1620                         if (td->flag & TD_NOTCONNECTED || dist < td->dist || (td + 1)->dist < td->dist) {
1621                                 td->flag &= ~TD_NOTCONNECTED;
1622                                 if (dist < (td + 1)->dist) {
1623                                         td->dist = (td + 1)->dist;
1624                                 }
1625                                 else {
1626                                         td->dist = dist;
1627                                 }
1628                         }
1629                 }
1630         }
1631 }
1632
1633 /* Utility function for getting the handle data from bezier's */
1634 static TransDataCurveHandleFlags *initTransDataCurveHandles(TransData *td, struct BezTriple *bezt)
1635 {
1636         TransDataCurveHandleFlags *hdata;
1637         td->flag |= TD_BEZTRIPLE;
1638         hdata = td->hdata = MEM_mallocN(sizeof(TransDataCurveHandleFlags), "CuHandle Data");
1639         hdata->ih1 = bezt->h1;
1640         hdata->h1 = &bezt->h1;
1641         hdata->ih2 = bezt->h2; /* in case the second is not selected */
1642         hdata->h2 = &bezt->h2;
1643         return hdata;
1644 }
1645
1646 /**
1647  * For the purpose of transform code we need to behave as if handles are selected,
1648  * even when they aren't (see special case below).
1649  */
1650 static int bezt_select_to_transform_triple_flag(
1651         const BezTriple *bezt, const bool hide_handles)
1652 {
1653         int flag = 0;
1654
1655         if (hide_handles) {
1656                 if (bezt->f2 & SELECT) {
1657                         flag = (1 << 0) | (1 << 1) | (1 << 2);
1658                 }
1659         }
1660         else {
1661                 flag = (
1662                         ((bezt->f1 & SELECT) ? (1 << 0) : 0) |
1663                         ((bezt->f2 & SELECT) ? (1 << 1) : 0) |
1664                         ((bezt->f3 & SELECT) ? (1 << 2) : 0)
1665                 );
1666         }
1667
1668         /* Special case for auto & aligned handles:
1669          * When a center point is being moved without the handles,
1670          * leaving the handles stationary makes no sense and only causes strange behavior,
1671          * where one handle is arbitrarily anchored, the other one is aligned and lengthened
1672          * based on where the center point is moved. Also a bug when cancelling, see: T52007.
1673          *
1674          * A more 'correct' solution could be to store handle locations in 'TransDataCurveHandleFlags'.
1675          * However that doesn't resolve odd behavior, so best transform the handles in this case.
1676          */
1677         if ((flag != ((1 << 0) | (1 << 1) | (1 << 2))) && (flag & (1 << 1))) {
1678                 if (ELEM(bezt->h1, HD_AUTO, HD_ALIGN) &&
1679                     ELEM(bezt->h2, HD_AUTO, HD_ALIGN))
1680                 {
1681                         flag = (1 << 0) | (1 << 1) | (1 << 2);
1682                 }
1683         }
1684
1685         return flag;
1686 }
1687
1688 static void createTransCurveVerts(TransInfo *t)
1689 {
1690
1691 #define SEL_F1 (1 << 0)
1692 #define SEL_F2 (1 << 1)
1693 #define SEL_F3 (1 << 2)
1694
1695         FOREACH_TRANS_DATA_CONTAINER (t, tc) {
1696
1697                 Curve *cu = tc->obedit->data;
1698                 TransData *td = NULL;
1699                 Nurb *nu;
1700                 BezTriple *bezt;
1701                 BPoint *bp;
1702                 float mtx[3][3], smtx[3][3];
1703                 int a;
1704                 int count = 0, countsel = 0;
1705                 const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
1706                 View3D *v3d = t->view;
1707                 short hide_handles = (v3d != NULL) ? ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_CU_HANDLES) == 0) : false;
1708                 ListBase *nurbs;
1709
1710                 /* to be sure */
1711                 if (cu->editnurb == NULL) return;
1712
1713                 /* count total of vertices, check identical as in 2nd loop for making transdata! */
1714                 nurbs = BKE_curve_editNurbs_get(cu);
1715                 for (nu = nurbs->first; nu; nu = nu->next) {
1716                         if (nu->type == CU_BEZIER) {
1717                                 for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
1718                                         if (bezt->hide == 0) {
1719                                                 const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, hide_handles);
1720                                                 if (bezt_tx & SEL_F1) { countsel++; }
1721                                                 if (bezt_tx & SEL_F2) { countsel++; }
1722                                                 if (bezt_tx & SEL_F3) { countsel++; }
1723                                                 if (is_prop_edit) count += 3;
1724
1725                                         }
1726                                 }
1727                         }
1728                         else {
1729                                 for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) {
1730                                         if (bp->hide == 0) {
1731                                                 if (is_prop_edit) count++;
1732                                                 if (bp->f1 & SELECT) countsel++;
1733                                         }
1734                                 }
1735                         }
1736                 }
1737                 /* note: in prop mode we need at least 1 selected */
1738                 if (countsel == 0) {
1739                         tc->data_len = 0;
1740                         continue;
1741                 }
1742
1743                 if (is_prop_edit) tc->data_len = count;
1744                 else tc->data_len = countsel;
1745                 tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Curve EditMode)");
1746
1747                 transform_around_single_fallback(t);
1748
1749                 copy_m3_m4(mtx, tc->obedit->obmat);
1750                 pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
1751
1752                 td = tc->data;
1753                 for (nu = nurbs->first; nu; nu = nu->next) {
1754                         if (nu->type == CU_BEZIER) {
1755                                 TransData *head, *tail;
1756                                 head = tail = td;
1757                                 for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
1758                                         if (bezt->hide == 0) {
1759                                                 TransDataCurveHandleFlags *hdata = NULL;
1760                                                 float axismtx[3][3];
1761
1762                                                 if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
1763                                                         float normal[3], plane[3];
1764
1765                                                         BKE_nurb_bezt_calc_normal(nu, bezt, normal);
1766                                                         BKE_nurb_bezt_calc_plane(nu, bezt, plane);
1767
1768                                                         if (createSpaceNormalTangent(axismtx, normal, plane)) {
1769                                                                 /* pass */
1770                                                         }
1771                                                         else {
1772                                                                 normalize_v3(normal);
1773                                                                 axis_dominant_v3_to_m3(axismtx, normal);
1774                                                                 invert_m3(axismtx);
1775                                                         }
1776                                                 }
1777
1778                                                 /* Elements that will be transform (not always a match to selection). */
1779                                                 const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, hide_handles);
1780
1781                                                 if (is_prop_edit || bezt_tx & SEL_F1) {
1782                                                         copy_v3_v3(td->iloc, bezt->vec[0]);
1783                                                         td->loc = bezt->vec[0];
1784                                                         copy_v3_v3(td->center, bezt->vec[(hide_handles ||
1785                                                                                           (t->around == V3D_AROUND_LOCAL_ORIGINS) ||
1786                                                                                           (bezt->f2 & SELECT)) ? 1 : 0]);
1787                                                         if (hide_handles) {
1788                                                                 if (bezt->f2 & SELECT) td->flag = TD_SELECTED;
1789                                                                 else td->flag = 0;
1790                                                         }
1791                                                         else {
1792                                                                 if (bezt->f1 & SELECT) td->flag = TD_SELECTED;
1793                                                                 else td->flag = 0;
1794                                                         }
1795                                                         td->ext = NULL;
1796                                                         td->val = NULL;
1797
1798                                                         hdata = initTransDataCurveHandles(td, bezt);
1799
1800                                                         copy_m3_m3(td->smtx, smtx);
1801                                                         copy_m3_m3(td->mtx, mtx);
1802                                                         if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
1803                                                                 copy_m3_m3(td->axismtx, axismtx);
1804                                                         }
1805
1806                                                         td++;
1807                                                         tail++;
1808                                                 }
1809
1810                                                 /* This is the Curve Point, the other two are handles */
1811                                                 if (is_prop_edit || bezt_tx & SEL_F2) {
1812                                                         copy_v3_v3(td->iloc, bezt->vec[1]);
1813                                                         td->loc = bezt->vec[1];
1814                                                         copy_v3_v3(td->center, td->loc);
1815                                                         if (bezt->f2 & SELECT) td->flag = TD_SELECTED;
1816                                                         else td->flag = 0;
1817                                                         td->ext = NULL;
1818
1819                                                         if (t->mode == TFM_CURVE_SHRINKFATTEN) { /* || t->mode==TFM_RESIZE) {*/ /* TODO - make points scale */
1820                                                                 td->val = &(bezt->radius);
1821                                                                 td->ival = bezt->radius;
1822                                                         }
1823                                                         else if (t->mode == TFM_TILT) {
1824                                                                 td->val = &(bezt->alfa);
1825                                                                 td->ival = bezt->alfa;
1826                                                         }
1827                                                         else {
1828                                                                 td->val = NULL;
1829                                                         }
1830
1831                                                         copy_m3_m3(td->smtx, smtx);
1832                                                         copy_m3_m3(td->mtx, mtx);
1833                                                         if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
1834                                                                 copy_m3_m3(td->axismtx, axismtx);
1835                                                         }
1836
1837                                                         if ((bezt_tx & SEL_F1) == 0 && (bezt_tx & SEL_F3) == 0)
1838                                                                 /* If the middle is selected but the sides arnt, this is needed */
1839                                                                 if (hdata == NULL) { /* if the handle was not saved by the previous handle */
1840                                                                         hdata = initTransDataCurveHandles(td, bezt);
1841                                                                 }
1842
1843                                                         td++;
1844                                                         tail++;
1845                                                 }
1846                                                 if (is_prop_edit || bezt_tx & SEL_F3) {
1847                                                         copy_v3_v3(td->iloc, bezt->vec[2]);
1848                                                         td->loc = bezt->vec[2];
1849                                                         copy_v3_v3(td->center, bezt->vec[(hide_handles ||
1850                                                                                           (t->around == V3D_AROUND_LOCAL_ORIGINS) ||
1851                                                                                           (bezt->f2 & SELECT)) ? 1 : 2]);
1852                                                         if (hide_handles) {
1853                                                                 if (bezt->f2 & SELECT) td->flag = TD_SELECTED;
1854                                                                 else td->flag = 0;
1855                                                         }
1856                                                         else {
1857                                                                 if (bezt->f3 & SELECT) td->flag = TD_SELECTED;
1858                                                                 else td->flag = 0;
1859                                                         }
1860                                                         td->ext = NULL;
1861                                                         td->val = NULL;
1862
1863                                                         if (hdata == NULL) { /* if the handle was not saved by the previous handle */
1864                                                                 hdata = initTransDataCurveHandles(td, bezt);
1865                                                         }
1866
1867                                                         copy_m3_m3(td->smtx, smtx);
1868                                                         copy_m3_m3(td->mtx, mtx);
1869                                                         if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
1870                                                                 copy_m3_m3(td->axismtx, axismtx);
1871                                                         }
1872
1873                                                         td++;
1874                                                         tail++;
1875                                                 }
1876
1877                                                 (void)hdata;  /* quiet warning */
1878                                         }
1879                                         else if (is_prop_edit && head != tail) {
1880                                                 calc_distanceCurveVerts(head, tail - 1);
1881                                                 head = tail;
1882                                         }
1883                                 }
1884                                 if (is_prop_edit && head != tail)
1885                                         calc_distanceCurveVerts(head, tail - 1);
1886
1887                                 /* TODO - in the case of tilt and radius we can also avoid allocating the initTransDataCurveHandles
1888                                  * but for now just don't change handle types */
1889                                 if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT, TFM_DUMMY) == 0) {
1890                                         /* sets the handles based on their selection, do this after the data is copied to the TransData */
1891                                         BKE_nurb_handles_test(nu, !hide_handles);
1892                                 }
1893                         }
1894                         else {
1895                                 TransData *head, *tail;
1896                                 head = tail = td;
1897                                 for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) {
1898                                         if (bp->hide == 0) {
1899                                                 if (is_prop_edit || (bp->f1 & SELECT)) {
1900                                                         float axismtx[3][3];
1901
1902                                                         if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
1903                                                                 if (nu->pntsv == 1) {
1904                                                                         float normal[3], plane[3];
1905
1906                                                                         BKE_nurb_bpoint_calc_normal(nu, bp, normal);
1907                                                                         BKE_nurb_bpoint_calc_plane(nu, bp, plane);
1908
1909                                                                         if (createSpaceNormalTangent(axismtx, normal, plane)) {
1910                                                                                 /* pass */
1911                                                                         }
1912                                                                         else {
1913                                                                                 normalize_v3(normal);
1914                                                                                 axis_dominant_v3_to_m3(axismtx, normal);
1915                                                                                 invert_m3(axismtx);
1916                                                                         }
1917                                                                 }
1918                                                         }
1919
1920                                                         copy_v3_v3(td->iloc, bp->vec);
1921                                                         td->loc = bp->vec;
1922                                                         copy_v3_v3(td->center, td->loc);
1923                                                         if (bp->f1 & SELECT) td->flag = TD_SELECTED;
1924                                                         else td->flag = 0;
1925                                                         td->ext = NULL;
1926
1927                                                         if (t->mode == TFM_CURVE_SHRINKFATTEN || t->mode == TFM_RESIZE) {
1928                                                                 td->val = &(bp->radius);
1929                                                                 td->ival = bp->radius;
1930                                                         }
1931                                                         else {
1932                                                                 td->val = &(bp->alfa);
1933                                                                 td->ival = bp->alfa;
1934                                                         }
1935
1936                                                         copy_m3_m3(td->smtx, smtx);
1937                                                         copy_m3_m3(td->mtx, mtx);
1938                                                         if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
1939                                                                 if (nu->pntsv == 1) {
1940                                                                         copy_m3_m3(td->axismtx, axismtx);
1941                                                                 }
1942                                                         }
1943
1944                                                         td++;
1945                                                         tail++;
1946                                                 }
1947                                         }
1948                                         else if (is_prop_edit && head != tail) {
1949                                                 calc_distanceCurveVerts(head, tail - 1);
1950                                                 head = tail;
1951                                         }
1952                                 }
1953                                 if (is_prop_edit && head != tail)
1954                                         calc_distanceCurveVerts(head, tail - 1);
1955                         }
1956                 }
1957         }
1958 #undef SEL_F1
1959 #undef SEL_F2
1960 #undef SEL_F3
1961 }
1962
1963 /* ********************* lattice *************** */
1964
1965 static void createTransLatticeVerts(TransInfo *t)
1966 {
1967         FOREACH_TRANS_DATA_CONTAINER (t, tc) {
1968
1969                 Lattice *latt = ((Lattice *)tc->obedit->data)->editlatt->latt;
1970                 TransData *td = NULL;
1971                 BPoint *bp;
1972                 float mtx[3][3], smtx[3][3];
1973                 int a;
1974                 int count = 0, countsel = 0;
1975                 const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
1976
1977                 bp = latt->def;
1978                 a  = latt->pntsu * latt->pntsv * latt->pntsw;
1979                 while (a--) {
1980                         if (bp->hide == 0) {
1981                                 if (bp->f1 & SELECT) countsel++;
1982                                 if (is_prop_edit) count++;
1983                         }
1984                         bp++;
1985                 }
1986
1987                 /* note: in prop mode we need at least 1 selected */
1988                 if (countsel == 0) return;
1989
1990                 if (is_prop_edit) tc->data_len = count;
1991                 else tc->data_len = countsel;
1992                 tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Lattice EditMode)");
1993
1994                 copy_m3_m4(mtx, tc->obedit->obmat);
1995                 pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
1996
1997                 td = tc->data;
1998                 bp = latt->def;
1999                 a  = latt->pntsu * latt->pntsv * latt->pntsw;
2000                 while (a--) {
2001                         if (is_prop_edit || (bp->f1 & SELECT)) {
2002                                 if (bp->hide == 0) {
2003                                         copy_v3_v3(td->iloc, bp->vec);
2004                                         td->loc = bp->vec;
2005                                         copy_v3_v3(td->center, td->loc);
2006                                         if (bp->f1 & SELECT) {
2007                                                 td->flag = TD_SELECTED;
2008                                         }
2009                                         else {
2010                                                 td->flag = 0;
2011                                         }
2012                                         copy_m3_m3(td->smtx, smtx);
2013                                         copy_m3_m3(td->mtx, mtx);
2014
2015                                         td->ext = NULL;
2016                                         td->val = NULL;
2017
2018                                         td++;
2019                                 }
2020                         }
2021                         bp++;
2022                 }
2023         }
2024 }
2025
2026 /* ******************* particle edit **************** */
2027 static void createTransParticleVerts(bContext *C, TransInfo *t)
2028 {
2029         FOREACH_TRANS_DATA_CONTAINER (t, tc) {
2030
2031                 TransData *td = NULL;
2032                 TransDataExtension *tx;
2033                 Object *ob = CTX_data_active_object(C);
2034                 ParticleEditSettings *pset = PE_settings(t->scene);
2035                 PTCacheEdit *edit = PE_get_current(t->scene, ob);
2036                 ParticleSystem *psys = NULL;
2037                 ParticleSystemModifierData *psmd = NULL;
2038                 PTCacheEditPoint *point;
2039                 PTCacheEditKey *key;
2040                 float mat[4][4];
2041                 int i, k, transformparticle;
2042                 int count = 0, hasselected = 0;
2043                 const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
2044
2045                 if (edit == NULL || t->settings->particle.selectmode == SCE_SELECT_PATH) return;
2046
2047                 psys = edit->psys;
2048
2049                 if (psys)
2050                         psmd = psys_get_modifier(ob, psys);
2051
2052                 for (i = 0, point = edit->points; i < edit->totpoint; i++, point++) {
2053                         point->flag &= ~PEP_TRANSFORM;
2054                         transformparticle = 0;
2055
2056                         if ((point->flag & PEP_HIDE) == 0) {
2057                                 for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
2058                                         if ((key->flag & PEK_HIDE) == 0) {
2059                                                 if (key->flag & PEK_SELECT) {
2060                                                         hasselected = 1;
2061                                                         transformparticle = 1;
2062                                                 }
2063                                                 else if (is_prop_edit)
2064                                                         transformparticle = 1;
2065                                         }
2066                                 }
2067                         }
2068
2069                         if (transformparticle) {
2070                                 count += point->totkey;
2071                                 point->flag |= PEP_TRANSFORM;
2072                         }
2073                 }
2074
2075                 /* note: in prop mode we need at least 1 selected */
2076                 if (hasselected == 0) return;
2077
2078                 tc->data_len = count;
2079                 td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Particle Mode)");
2080
2081                 if (t->mode == TFM_BAKE_TIME)
2082                         tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "Particle_TransExtension");
2083                 else
2084                         tx = tc->data_ext = NULL;
2085
2086                 unit_m4(mat);
2087
2088                 invert_m4_m4(ob->imat, ob->obmat);
2089
2090                 for (i = 0, point = edit->points; i < edit->totpoint; i++, point++) {
2091                         TransData *head, *tail;
2092                         head = tail = td;
2093
2094                         if (!(point->flag & PEP_TRANSFORM)) continue;
2095
2096                         if (psys && !(psys->flag & PSYS_GLOBAL_HAIR))
2097                                 psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, psys->particles + i, mat);
2098
2099                         for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
2100                                 if (key->flag & PEK_USE_WCO) {
2101                                         copy_v3_v3(key->world_co, key->co);
2102                                         mul_m4_v3(mat, key->world_co);
2103                                         td->loc = key->world_co;
2104                                 }
2105                                 else
2106                                         td->loc = key->co;
2107
2108                                 copy_v3_v3(td->iloc, td->loc);
2109                                 copy_v3_v3(td->center, td->loc);
2110
2111                                 if (key->flag & PEK_SELECT)
2112                                         td->flag |= TD_SELECTED;
2113                                 else if (!is_prop_edit)
2114                                         td->flag |= TD_SKIP;
2115
2116                                 unit_m3(td->mtx);
2117                                 unit_m3(td->smtx);
2118
2119                                 /* don't allow moving roots */
2120                                 if (k == 0 && pset->flag & PE_LOCK_FIRST && (!psys || !(psys->flag & PSYS_GLOBAL_HAIR)))
2121                                         td->protectflag |= OB_LOCK_LOC;
2122
2123                                 td->ob = ob;
2124                                 td->ext = tx;
2125                                 if (t->mode == TFM_BAKE_TIME) {
2126                                         td->val = key->time;
2127                                         td->ival = *(key->time);
2128                                         /* abuse size and quat for min/max values */
2129                                         td->flag |= TD_NO_EXT;
2130                                         if (k == 0) tx->size = NULL;
2131                                         else tx->size = (key - 1)->time;
2132
2133                                         if (k == point->totkey - 1) tx->quat = NULL;
2134                                         else tx->quat = (key + 1)->time;
2135                                 }
2136
2137                                 td++;
2138                                 if (tx)
2139                                         tx++;
2140                                 tail++;
2141                         }
2142                         if (is_prop_edit && head != tail)
2143                                 calc_distanceCurveVerts(head, tail - 1);
2144                 }
2145         }
2146 }
2147
2148 void flushTransParticles(TransInfo *t)
2149 {
2150         FOREACH_TRANS_DATA_CONTAINER (t, tc) {
2151                 Scene *scene = t->scene;
2152                 ViewLayer *view_layer = t->view_layer;
2153                 Object *ob = OBACT(view_layer);
2154                 PTCacheEdit *edit = PE_get_current(scene, ob);
2155                 ParticleSystem *psys = edit->psys;
2156                 ParticleSystemModifierData *psmd = NULL;
2157                 PTCacheEditPoint *point;
2158                 PTCacheEditKey *key;
2159                 TransData *td;
2160                 float mat[4][4], imat[4][4], co[3];
2161                 int i, k;
2162                 const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
2163
2164                 if (psys)
2165                         psmd = psys_get_modifier(ob, psys);
2166
2167                 /* we do transform in world space, so flush world space position
2168                  * back to particle local space (only for hair particles) */
2169                 td = tc->data;
2170                 for (i = 0, point = edit->points; i < edit->totpoint; i++, point++, td++) {
2171                         if (!(point->flag & PEP_TRANSFORM)) continue;
2172
2173                         if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
2174                                 psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, psys->particles + i, mat);
2175                                 invert_m4_m4(imat, mat);
2176
2177                                 for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
2178                                         copy_v3_v3(co, key->world_co);
2179                                         mul_m4_v3(imat, co);
2180
2181
2182                                         /* optimization for proportional edit */
2183                                         if (!is_prop_edit || !compare_v3v3(key->co, co, 0.0001f)) {
2184                                                 copy_v3_v3(key->co, co);
2185                                                 point->flag |= PEP_EDIT_RECALC;
2186                                         }
2187                                 }
2188                         }
2189                         else
2190                                 point->flag |= PEP_EDIT_RECALC;
2191                 }
2192
2193                 PE_update_object(t->depsgraph, scene, OBACT(view_layer), 1);
2194         }
2195 }
2196
2197 /* ********************* mesh ****************** */
2198
2199 static bool bmesh_test_dist_add(
2200         BMVert *v, BMVert *v_other,
2201         float *dists, const float *dists_prev,
2202         /* optionally track original index */
2203         int *index, const int *index_prev,
2204         float mtx[3][3])
2205 {
2206         if ((BM_elem_flag_test(v_other, BM_ELEM_SELECT) == 0) &&
2207             (BM_elem_flag_test(v_other, BM_ELEM_HIDDEN) == 0))
2208         {
2209                 const int i = BM_elem_index_get(v);
2210                 const int i_other = BM_elem_index_get(v_other);
2211                 float vec[3];
2212                 float dist_other;
2213                 sub_v3_v3v3(vec, v->co, v_other->co);
2214                 mul_m3_v3(mtx, vec);
2215
2216                 dist_other = dists_prev[i] + len_v3(vec);
2217                 if (dist_other < dists[i_other]) {
2218                         dists[i_other] = dist_other;
2219                         if (index != NULL) {
2220                                 index[i_other] = index_prev[i];
2221                         }
2222                         return true;
2223                 }
2224         }
2225
2226         return false;
2227 }
2228
2229 /**
2230  * \param mtx: Measure disatnce in this space.
2231  * \param dists: Store the closest connected distance to selected vertices.
2232  * \param index: Optionally store the original index we're measuring the distance to (can be NULL).
2233  */
2234 static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float *dists, int *index)
2235 {
2236         BLI_LINKSTACK_DECLARE(queue, BMVert *);
2237
2238         /* any BM_ELEM_TAG'd vertex is in 'queue_next', so we don't add in twice */
2239         BLI_LINKSTACK_DECLARE(queue_next, BMVert *);
2240
2241         BLI_LINKSTACK_INIT(queue);
2242         BLI_LINKSTACK_INIT(queue_next);
2243
2244         {
2245                 BMIter viter;
2246                 BMVert *v;
2247                 int i;
2248
2249                 BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
2250                         float dist;
2251                         BM_elem_index_set(v, i); /* set_inline */
2252                         BM_elem_flag_disable(v, BM_ELEM_TAG);
2253
2254                         if (BM_elem_flag_test(v, BM_ELEM_SELECT) == 0 || BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
2255                                 dist = FLT_MAX;
2256                                 if (index != NULL) {
2257                                         index[i] = i;
2258                                 }
2259                         }
2260                         else {
2261                                 BLI_LINKSTACK_PUSH(queue, v);
2262                                 dist = 0.0f;
2263                                 if (index != NULL) {
2264                                         index[i] = i;
2265                                 }
2266                         }
2267
2268                         dists[i] = dist;
2269                 }
2270                 bm->elem_index_dirty &= ~BM_VERT;
2271         }
2272
2273         /* need to be very careful of feedback loops here, store previous dist's to avoid feedback */
2274         float *dists_prev = MEM_dupallocN(dists);
2275         int *index_prev = MEM_dupallocN(index);  /* may be NULL */
2276
2277         do {
2278                 BMVert *v;
2279                 LinkNode *lnk;
2280
2281                 /* this is correct but slow to do each iteration,
2282                  * instead sync the dist's while clearing BM_ELEM_TAG (below) */
2283 #if 0
2284                 memcpy(dists_prev, dists, sizeof(float) * bm->totvert);
2285 #endif
2286
2287                 while ((v = BLI_LINKSTACK_POP(queue))) {
2288                         BLI_assert(dists[BM_elem_index_get(v)] != FLT_MAX);
2289
2290                         /* connected edge-verts */
2291                         if (v->e != NULL) {
2292                                 BMEdge *e_iter, *e_first;
2293
2294                                 e_iter = e_first = v->e;
2295
2296                                 /* would normally use BM_EDGES_OF_VERT, but this runs so often,
2297                                  * its faster to iterate on the data directly */
2298                                 do {
2299
2300                                         if (BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN) == 0) {
2301
2302                                                 /* edge distance */
2303                                                 {
2304                                                         BMVert *v_other = BM_edge_other_vert(e_iter, v);
2305                                                         if (bmesh_test_dist_add(v, v_other, dists, dists_prev, index, index_prev, mtx)) {
2306                                                                 if (BM_elem_flag_test(v_other, BM_ELEM_TAG) == 0) {
2307                                                                         BM_elem_flag_enable(v_other, BM_ELEM_TAG);
2308                                                                         BLI_LINKSTACK_PUSH(queue_next, v_other);
2309                                                                 }
2310                                                         }
2311                                                 }
2312
2313                                                 /* face distance */
2314                                                 if (e_iter->l) {
2315                                                         BMLoop *l_iter_radial, *l_first_radial;
2316                                                         /**
2317                                                          * imaginary edge diagonally across quad,
2318                                                          * \note, this takes advantage of the rules of winding that we
2319                                                          * know 2 or more of a verts edges wont reference the same face twice.
2320                                                          * Also, if the edge is hidden, the face will be hidden too.
2321                                                          */
2322                                                         l_iter_radial = l_first_radial = e_iter->l;
2323
2324                                                         do {
2325                                                                 if ((l_iter_radial->v == v) &&
2326                                                                     (l_iter_radial->f->len == 4) &&
2327                                                                     (BM_elem_flag_test(l_iter_radial->f, BM_ELEM_HIDDEN) == 0))
2328                                                                 {
2329                                                                         BMVert *v_other = l_iter_radial->next->next->v;
2330                                                                         if (bmesh_test_dist_add(v, v_other, dists, dists_prev, index, index_prev, mtx)) {
2331                                                                                 if (BM_elem_flag_test(v_other, BM_ELEM_TAG) == 0) {
2332                                                                                         BM_elem_flag_enable(v_other, BM_ELEM_TAG);
2333                                                                                         BLI_LINKSTACK_PUSH(queue_next, v_other);
2334                                                                                 }
2335                                                                         }
2336                                                                 }
2337                                                         } while ((l_iter_radial = l_iter_radial->radial_next) != l_first_radial);
2338                                                 }
2339                                         }
2340                                 } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v)) != e_first);
2341                         }
2342                 }
2343
2344
2345                 /* clear for the next loop */
2346                 for (lnk = queue_next; lnk; lnk = lnk->next) {
2347                         BMVert *v_link = lnk->link;
2348                         const int i = BM_elem_index_get(v_link);
2349
2350                         BM_elem_flag_disable(v_link, BM_ELEM_TAG);
2351
2352                         /* keep in sync, avoid having to do full memcpy each iteration */
2353                         dists_prev[i] = dists[i];
2354                         if (index != NULL) {
2355                                 index_prev[i] = index[i];
2356                         }
2357                 }
2358
2359                 BLI_LINKSTACK_SWAP(queue, queue_next);
2360
2361                 /* none should be tagged now since 'queue_next' is empty */
2362                 BLI_assert(BM_iter_mesh_count_flag(BM_VERTS_OF_MESH, bm, BM_ELEM_TAG, true) == 0);
2363
2364         } while (BLI_LINKSTACK_SIZE(queue));
2365
2366         BLI_LINKSTACK_FREE(queue);
2367         BLI_LINKSTACK_FREE(queue_next);
2368
2369         MEM_freeN(dists_prev);
2370         if (index_prev != NULL) {
2371                 MEM_freeN(index_prev);
2372         }
2373 }
2374
2375 static struct TransIslandData *editmesh_islands_info_calc(
2376         BMEditMesh *em, int *r_island_tot, int **r_island_vert_map,
2377         bool calc_single_islands)
2378 {
2379         BMesh *bm = em->bm;
2380         struct TransIslandData *trans_islands;
2381         char htype;
2382         char itype;
2383         int i;
2384
2385         /* group vars */
2386         int *groups_array;
2387         int (*group_index)[2];
2388         int group_tot;
2389         void **ele_array;
2390
2391         int *vert_map;
2392
2393         if (em->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) {
2394                 groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totedgesel, __func__);
2395                 group_tot = BM_mesh_calc_edge_groups(bm, groups_array, &group_index,
2396                                                      NULL, NULL,
2397                                                      BM_ELEM_SELECT);
2398
2399                 htype = BM_EDGE;
2400                 itype = BM_VERTS_OF_EDGE;
2401
2402         }
2403         else {  /* (bm->selectmode & SCE_SELECT_FACE) */
2404                 groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totfacesel, __func__);
2405                 group_tot = BM_mesh_calc_face_groups(bm, groups_array, &group_index,
2406                                                      NULL, NULL,
2407                                                      BM_ELEM_SELECT, BM_VERT);
2408
2409                 htype = BM_FACE;
2410                 itype = BM_VERTS_OF_FACE;
2411         }
2412
2413
2414         trans_islands = MEM_mallocN(sizeof(*trans_islands) * group_tot, __func__);
2415
2416         vert_map = MEM_mallocN(sizeof(*vert_map) * bm->totvert, __func__);
2417         /* we shouldn't need this, but with incorrect selection flushing
2418          * its possible we have a selected vertex that's not in a face, for now best not crash in that case. */
2419         copy_vn_i(vert_map, bm->totvert, -1);
2420
2421         BM_mesh_elem_table_ensure(bm, htype);
2422         ele_array = (htype == BM_FACE) ? (void **)bm->ftable : (void **)bm->etable;
2423
2424         BM_mesh_elem_index_ensure(bm, BM_VERT);
2425
2426         /* may be an edge OR a face array */
2427         for (i = 0; i < group_tot; i++) {
2428                 BMEditSelection ese = {NULL};
2429
2430                 const int fg_sta = group_index[i][0];
2431                 const int fg_len = group_index[i][1];
2432                 float co[3], no[3], tangent[3];
2433                 int j;
2434
2435                 zero_v3(co);
2436                 zero_v3(no);
2437                 zero_v3(tangent);
2438
2439                 ese.htype = htype;
2440
2441                 /* loop on each face in this group:
2442                  * - assign r_vert_map
2443                  * - calculate (co, no)
2444                  */
2445                 for (j = 0; j < fg_len; j++) {
2446                         float tmp_co[3], tmp_no[3], tmp_tangent[3];
2447
2448                         ese.ele = ele_array[groups_array[fg_sta + j]];
2449
2450                         BM_editselection_center(&ese, tmp_co);
2451                         BM_editselection_normal(&ese, tmp_no);
2452                         BM_editselection_plane(&ese, tmp_tangent);
2453
2454                         add_v3_v3(co, tmp_co);
2455                         add_v3_v3(no, tmp_no);
2456                         add_v3_v3(tangent, tmp_tangent);
2457
2458                         {
2459                                 /* setup vertex map */
2460                                 BMIter iter;
2461                                 BMVert *v;
2462
2463                                 /* connected edge-verts */
2464                                 BM_ITER_ELEM (v, &iter, ese.ele, itype) {
2465                                         vert_map[BM_elem_index_get(v)] = i;
2466                                 }
2467                         }
2468                 }
2469
2470                 mul_v3_v3fl(trans_islands[i].co, co, 1.0f / (float)fg_len);
2471
2472                 if (createSpaceNormalTangent(trans_islands[i].axismtx, no, tangent)) {
2473                         /* pass */
2474                 }
2475                 else {
2476                         if (normalize_v3(no) != 0.0f) {
2477                                 axis_dominant_v3_to_m3(trans_islands[i].axismtx, no);
2478                                 invert_m3(trans_islands[i].axismtx);
2479                         }
2480                         else {
2481                                 unit_m3(trans_islands[i].axismtx);
2482                         }
2483                 }
2484         }
2485
2486         MEM_freeN(groups_array);
2487         MEM_freeN(group_index);
2488
2489         /* for PET we need islands of 1 so connected vertices can use it with V3D_AROUND_LOCAL_ORIGINS */
2490         if (calc_single_islands) {
2491                 BMIter viter;
2492                 BMVert *v;
2493                 int group_tot_single = 0;
2494
2495                 BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
2496                         if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (vert_map[i] == -1)) {
2497                                 group_tot_single += 1;
2498                         }
2499                 }
2500
2501                 if (group_tot_single != 0) {
2502                         trans_islands = MEM_reallocN(trans_islands, sizeof(*trans_islands) * (group_tot + group_tot_single));
2503
2504                         BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
2505                                 if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (vert_map[i] == -1)) {
2506                                         struct TransIslandData *v_island = &trans_islands[group_tot];
2507                                         vert_map[i] = group_tot;
2508
2509                                         copy_v3_v3(v_island->co, v->co);
2510
2511                                         if (is_zero_v3(v->no) != 0.0f) {
2512                                                 axis_dominant_v3_to_m3(v_island->axismtx, v->no);
2513                                                 invert_m3(v_island->axismtx);
2514                                         }
2515                                         else {
2516                                                 unit_m3(v_island->axismtx);
2517                                         }
2518
2519                                         group_tot += 1;
2520                                 }
2521                         }
2522                 }
2523         }
2524
2525         *r_island_tot = group_tot;
2526         *r_island_vert_map = vert_map;
2527
2528         return trans_islands;
2529 }
2530
2531 /* way to overwrite what data is edited with transform */
2532 static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx,
2533                              BMEditMesh *em, BMVert *eve, float *bweight,
2534                              struct TransIslandData *v_island)
2535 {
2536         float *no, _no[3];
2537         BLI_assert(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) == 0);
2538
2539         td->flag = 0;
2540         //if (key)
2541         //      td->loc = key->co;
2542         //else
2543         td->loc = eve->co;
2544         copy_v3_v3(td->iloc, td->loc);
2545
2546         if ((t->mode == TFM_SHRINKFATTEN) &&
2547             (em->selectmode & SCE_SELECT_FACE) &&
2548             BM_elem_flag_test(eve, BM_ELEM_SELECT) &&
2549             (BM_vert_calc_normal_ex(eve, BM_ELEM_SELECT, _no)))
2550         {
2551                 no = _no;
2552         }
2553         else {
2554                 no = eve->no;
2555         }
2556
2557         if (v_island) {
2558                 copy_v3_v3(td->center, v_island->co);
2559                 copy_m3_m3(td->axismtx, v_island->axismtx);
2560         }
2561         else if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
2562                 copy_v3_v3(td->center, td->loc);
2563                 createSpaceNormal(td->axismtx, no);
2564         }
2565         else {
2566                 copy_v3_v3(td->center, td->loc);
2567
2568                 /* Setting normals */
2569                 copy_v3_v3(td->axismtx[2], no);
2570                 td->axismtx[0][0]        =
2571                     td->axismtx[0][1]    =
2572                     td->axismtx[0][2]    =
2573                     td->axismtx[1][0]    =
2574                     td->axismtx[1][1]    =
2575                     td->axismtx[1][2]    = 0.0f;
2576         }
2577
2578
2579         td->ext = NULL;
2580         td->val = NULL;
2581         td->extra = NULL;
2582         if (t->mode == TFM_BWEIGHT) {
2583                 td->val  =  bweight;
2584                 td->ival = *bweight;
2585         }
2586         else if (t->mode == TFM_SKIN_RESIZE) {
2587                 MVertSkin *vs = CustomData_bmesh_get(&em->bm->vdata,
2588                                                      eve->head.data,
2589                                                      CD_MVERT_SKIN);
2590                 /* skin node size */
2591                 td->ext = tx;
2592                 copy_v3_v3(tx->isize, vs->radius);
2593                 tx->size = vs->radius;
2594                 td->val = vs->radius;
2595         }
2596         else if (t->mode == TFM_SHRINKFATTEN) {
2597                 td->ext = tx;
2598                 tx->isize[0] = BM_vert_calc_shell_factor_ex(eve, no, BM_ELEM_SELECT);
2599         }
2600 }
2601
2602 static void createTransEditVerts(TransInfo *t)
2603 {
2604         FOREACH_TRANS_DATA_CONTAINER (t, tc) {
2605
2606                 TransData *tob = NULL;
2607                 TransDataExtension *tx = NULL;
2608                 BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
2609                 Mesh *me = tc->obedit->data;
2610                 BMesh *bm = em->bm;
2611                 BMVert *eve;
2612                 BMIter iter;
2613                 float (*mappedcos)[3] = NULL, (*quats)[4] = NULL;
2614                 float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL;
2615                 float *dists = NULL;
2616                 int a;
2617                 const int prop_mode = (t->flag & T_PROP_EDIT) ? (t->flag & T_PROP_EDIT_ALL) : 0;
2618                 int mirror = 0;
2619                 int cd_vert_bweight_offset = -1;
2620                 bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
2621
2622                 struct TransIslandData *island_info = NULL;
2623                 int island_info_tot;
2624                 int *island_vert_map = NULL;
2625
2626                 /* Even for translation this is needed because of island-orientation, see: T51651. */
2627                 const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS);
2628                 /* Original index of our connected vertex when connected distances are calculated.
2629                  * Optional, allocate if needed. */
2630                 int *dists_index = NULL;
2631
2632                 if (t->flag & T_MIRROR) {
2633                         /* TODO(campbell): xform: We need support for many mirror objects at once! */
2634                         if (tc->is_active) {
2635                                 EDBM_verts_mirror_cache_begin(em, 0, false, (t->flag & T_PROP_EDIT) == 0, use_topology);
2636                                 mirror = 1;
2637                         }
2638                 }
2639
2640                 /**
2641                  * Quick check if we can transform.
2642                  *
2643                  * \note ignore modes here, even in edge/face modes, transform data is created by selected vertices.
2644                  * \note in prop mode we need at least 1 selected.
2645                  */
2646                 if (bm->totvertsel == 0) {
2647                         goto cleanup;
2648                 }
2649
2650                 if (t->mode == TFM_BWEIGHT) {
2651                         BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_VERT_BWEIGHT);
2652                         cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
2653                 }
2654
2655                 if (prop_mode) {
2656                         unsigned int count = 0;
2657                         BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
2658                                 if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
2659                                         count++;
2660                                 }
2661                         }
2662
2663                         tc->data_len = count;
2664
2665                         /* allocating scratch arrays */
2666                         if (prop_mode & T_PROP_CONNECTED) {
2667                                 dists = MEM_mallocN(em->bm->totvert * sizeof(float), __func__);
2668                                 if (is_island_center) {
2669                                         dists_index =  MEM_mallocN(em->bm->totvert * sizeof(int), __func__);
2670                                 }
2671                         }
2672                 }
2673                 else {
2674                         tc->data_len = bm->totvertsel;
2675                 }
2676
2677                 tob = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Mesh EditMode)");
2678                 if (ELEM(t->mode, TFM_SKIN_RESIZE, TFM_SHRINKFATTEN)) {
2679                         /* warning, this is overkill, we only need 2 extra floats,
2680                          * but this stores loads of extra stuff, for TFM_SHRINKFATTEN its even more overkill
2681                          * since we may not use the 'alt' transform mode to maintain shell thickness,
2682                          * but with generic transform code its hard to lazy init vars */
2683                         tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "TransObData ext");
2684                 }
2685
2686                 copy_m3_m4(mtx, tc->obedit->obmat);
2687                 /* we use a pseudoinverse so that when one of the axes is scaled to 0,
2688                  * matrix inversion still works and we can still moving along the other */
2689                 pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
2690
2691                 if (prop_mode & T_PROP_CONNECTED) {
2692                         editmesh_set_connectivity_distance(em->bm, mtx, dists, dists_index);
2693                 }
2694
2695                 if (is_island_center) {
2696                         /* In this specific case, near-by vertices will need to know the island of the nearest connected vertex. */
2697                         const bool calc_single_islands = (
2698                                 (prop_mode & T_PROP_CONNECTED) &&
2699                                 (t->around == V3D_AROUND_LOCAL_ORIGINS) &&
2700                                 (em->selectmode & SCE_SELECT_VERTEX));
2701