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