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