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