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