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