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