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