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