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