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