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