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