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