svn merge -r 12856:12937 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)
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         if (con) {
797                 /* but, if this is a targetless IK, we make it auto anyway (for the children loop) */
798                 data= has_targetless_ik(pchan);
799                 if (data)
800                         data->flag |= CONSTRAINT_IK_AUTO;
801                 return 0;
802         }
803         
804         con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
805         BLI_addtail(&pchan->constraints, con);
806         pchan->constflag |= (PCHAN_HAS_IK|PCHAN_HAS_TARGET);    /* for draw, but also for detecting while pose solving */
807         data= con->data;
808         data->flag= CONSTRAINT_IK_TIP|CONSTRAINT_IK_TEMP|CONSTRAINT_IK_AUTO;
809         VECCOPY(data->grabtarget, pchan->pose_tail);
810         data->rootbone= 1;
811         
812         /* we include only a connected chain */
813         while ((pchan) && (pchan->bone->flag & BONE_CONNECTED)) {
814                 /* here, we set ik-settings for bone from pchan->protectflag */
815                 if (pchan->protectflag & OB_LOCK_ROTX) pchan->ikflag |= BONE_IK_NO_XDOF_TEMP;
816                 if (pchan->protectflag & OB_LOCK_ROTY) pchan->ikflag |= BONE_IK_NO_YDOF_TEMP;
817                 if (pchan->protectflag & OB_LOCK_ROTZ) pchan->ikflag |= BONE_IK_NO_ZDOF_TEMP;
818                 
819                 /* now we count this pchan as being included */
820                 data->rootbone++;
821                 pchan= pchan->parent;
822         }
823         
824         /* make a copy of maximum chain-length */
825         data->max_rootbone= data->rootbone;
826         
827         return 1;
828 }
829
830 /* bone is a canditate to get IK, but we don't do it if it has children connected */
831 static short pose_grab_with_ik_children(bPose *pose, Bone *bone)
832 {
833         Bone *bonec;
834         short wentdeeper=0, added=0;
835
836         /* go deeper if children & children are connected */
837         for (bonec= bone->childbase.first; bonec; bonec= bonec->next) {
838                 if (bonec->flag & BONE_CONNECTED) {
839                         wentdeeper= 1;
840                         added+= pose_grab_with_ik_children(pose, bonec);
841                 }
842         }
843         if (wentdeeper==0) {
844                 bPoseChannel *pchan= get_pose_channel(pose, bone->name);
845                 if (pchan)
846                         added+= pose_grab_with_ik_add(pchan);
847         }
848         
849         return added;
850 }
851
852 /* main call which adds temporal IK chains */
853 static short pose_grab_with_ik(Object *ob)
854 {
855         bArmature *arm;
856         bPoseChannel *pchan, *pchansel= NULL;
857         Bone *bonec;
858         
859         if (ob==NULL || ob->pose==NULL || (ob->flag & OB_POSEMODE)==0)
860                 return 0;
861                 
862         arm = ob->data;
863         
864         /* rule: only one Bone */
865         for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
866                 if (pchan->bone->layer & arm->layer) {
867                         if (pchan->bone->flag & BONE_SELECTED) {
868                                 if (pchansel)
869                                         break;
870                                 pchansel= pchan;
871                         }
872                 }
873         }
874         if (pchan || pchansel==NULL) return 0;
875
876         /* rule: no IK for solitary (unconnected) bone */
877         for (bonec=pchansel->bone->childbase.first; bonec; bonec=bonec->next) {
878                 if (bonec->flag & BONE_CONNECTED) {
879                         break;
880                 }
881         }
882         if ((pchansel->bone->flag & BONE_CONNECTED)==0 && (bonec == NULL)) return 0;
883         
884         /* rule: if selected Bone is not a root bone, it gets a temporal IK */
885         if (pchansel->parent) {
886                 /* only adds if there's no IK yet */
887                 return pose_grab_with_ik_add(pchansel);
888         }
889         else {
890                 /* rule: go over the children and add IK to the tips */
891                 return pose_grab_with_ik_children(ob->pose, pchansel->bone);
892         }
893 }       
894
895
896 /* only called with pose mode active object now */
897 static void createTransPose(TransInfo *t, Object *ob)
898 {
899         bArmature *arm;
900         bPoseChannel *pchan;
901         TransData *td;
902         TransDataExtension *tdx;
903         short ik_on= 0;
904         int i;
905         
906         t->total= 0;
907         
908         /* check validity of state */
909         arm=get_armature (ob);
910         if (arm==NULL || ob->pose==NULL) return;
911         
912         if (arm->flag & ARM_RESTPOS) {
913                 if(t->mode!=TFM_BONESIZE) {
914                         notice ("Pose edit not possible while Rest Position is enabled");
915                         return;
916                 }
917         }
918         if (!(ob->lay & G.vd->lay)) return;
919
920         /* do we need to add temporal IK chains? */
921         if ((arm->flag & ARM_AUTO_IK) && t->mode==TFM_TRANSLATION) {
922                 ik_on= pose_grab_with_ik(ob);
923                 if (ik_on) t->flag |= T_AUTOIK;
924         }
925         
926         /* set flags and count total (warning, can change transform to rotate) */
927         set_pose_transflags(t, ob);
928         
929         if(t->total==0) return;
930
931         t->flag |= T_POSE;
932         t->poseobj= ob; /* we also allow non-active objects to be transformed, in weightpaint */
933         
934         /* make sure the lock is set OK, unlock can be accidentally saved? */
935         ob->pose->flag |= POSE_LOCKED;
936         ob->pose->flag &= ~POSE_DO_UNLOCK;
937
938         /* init trans data */
939     td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransPoseBone");
940     tdx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "TransPoseBoneExt");
941         for(i=0; i<t->total; i++, td++, tdx++) {
942                 td->ext= tdx;
943                 td->tdi = NULL;
944                 td->val = NULL;
945         }       
946         
947         /* use pose channels to fill trans data */
948         td= t->data;
949         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
950                 if(pchan->bone->flag & BONE_TRANSFORM) {
951                         add_pose_transdata(t, pchan, ob, td);
952                         td++;
953                 }
954         }
955         
956         if(td != (t->data+t->total)) printf("Bone selection count error\n");
957         
958         /* initialise initial auto=ik chainlen's? */
959         if (ik_on) transform_autoik_update(t, 0);
960 }
961
962 /* ********************* armature ************** */
963
964 static void createTransArmatureVerts(TransInfo *t)
965 {
966         EditBone *ebo;
967         bArmature *arm= G.obedit->data;
968         TransData *td;
969         float mtx[3][3], smtx[3][3], delta[3], bonemat[3][3];
970
971         t->total = 0;
972         for (ebo=G.edbo.first;ebo;ebo=ebo->next) {
973                 if(ebo->layer & arm->layer) {
974                         if (t->mode==TFM_BONESIZE) {
975                                 if (ebo->flag & BONE_SELECTED)
976                                         t->total++;
977                         }
978                         else if (t->mode==TFM_BONE_ROLL) {
979                                 if (ebo->flag & BONE_SELECTED)
980                                         t->total++;
981                         }
982                         else {
983                                 if (ebo->flag & BONE_TIPSEL)
984                                         t->total++;
985                                 if (ebo->flag & BONE_ROOTSEL)
986                                         t->total++;
987                         }
988                 }
989         }
990
991     if (!t->total) return;
992         
993         Mat3CpyMat4(mtx, G.obedit->obmat);
994         Mat3Inv(smtx, mtx);
995
996     td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransEditBone");
997         
998         for (ebo=G.edbo.first;ebo;ebo=ebo->next){
999                 ebo->oldlength= ebo->length;    // length==0.0 on extrude, used for scaling radius of bone points
1000                 
1001                 if(ebo->layer & arm->layer) {
1002                         if (t->mode==TFM_BONE_ENVELOPE) {
1003                                 
1004                                 if (ebo->flag & BONE_ROOTSEL){
1005                                         td->val= &ebo->rad_head;
1006                                         td->ival= *td->val;
1007                                         
1008                                         VECCOPY (td->center, ebo->head);
1009                                         td->flag= TD_SELECTED;
1010                                         
1011                                         Mat3CpyMat3(td->smtx, smtx);
1012                                         Mat3CpyMat3(td->mtx, mtx);
1013                                         
1014                                         td->loc = NULL;
1015                                         td->ext = NULL;
1016                                         td->tdi = NULL;
1017                                         
1018                                         td++;
1019                                 }
1020                                 if (ebo->flag & BONE_TIPSEL){
1021                                         td->val= &ebo->rad_tail;
1022                                         td->ival= *td->val;
1023                                         VECCOPY (td->center, ebo->tail);
1024                                         td->flag= TD_SELECTED;
1025                                         
1026                                         Mat3CpyMat3(td->smtx, smtx);
1027                                         Mat3CpyMat3(td->mtx, mtx);
1028                                         
1029                                         td->loc = NULL;
1030                                         td->ext = NULL;
1031                                         td->tdi = NULL;
1032                                         
1033                                         td++;
1034                                 }
1035                                 
1036                         }
1037                         else if (t->mode==TFM_BONESIZE) {
1038                                 if (ebo->flag & BONE_SELECTED) {
1039                                         if(arm->drawtype==ARM_ENVELOPE) {
1040                                                 td->loc= NULL;
1041                                                 td->val= &ebo->dist;
1042                                                 td->ival= ebo->dist;
1043                                         }
1044                                         else {
1045                                                 // abusive storage of scale in the loc pointer :)
1046                                                 td->loc= &ebo->xwidth;
1047                                                 VECCOPY (td->iloc, td->loc);
1048                                                 td->val= NULL;
1049                                         }
1050                                         VECCOPY (td->center, ebo->head);
1051                                         td->flag= TD_SELECTED;
1052                                         
1053                                         /* use local bone matrix */
1054                                         VecSubf(delta, ebo->tail, ebo->head);   
1055                                         vec_roll_to_mat3(delta, ebo->roll, bonemat);
1056                                         Mat3MulMat3(td->mtx, mtx, bonemat);
1057                                         Mat3Inv(td->smtx, td->mtx);
1058                                         
1059                                         Mat3CpyMat3(td->axismtx, td->mtx);
1060                                         Mat3Ortho(td->axismtx);
1061
1062                                         td->ext = NULL;
1063                                         td->tdi = NULL;
1064                                         
1065                                         td++;
1066                                 }
1067                         }
1068                         else if (t->mode==TFM_BONE_ROLL) {
1069                                 if (ebo->flag & BONE_SELECTED) {
1070                                         td->loc= NULL;
1071                                         td->val= &(ebo->roll);
1072                                         td->ival= ebo->roll;
1073                                         
1074                                         VECCOPY (td->center, ebo->head);
1075                                         td->flag= TD_SELECTED;
1076
1077                                         td->ext = NULL;
1078                                         td->tdi = NULL;
1079                                         
1080                                         td++;
1081                                 }
1082                         }
1083                         else {
1084                                 if (ebo->flag & BONE_TIPSEL){
1085                                         VECCOPY (td->iloc, ebo->tail);
1086                                         VECCOPY (td->center, td->iloc);
1087                                         td->loc= ebo->tail;
1088                                         td->flag= TD_SELECTED;
1089
1090                                         Mat3CpyMat3(td->smtx, smtx);
1091                                         Mat3CpyMat3(td->mtx, mtx);
1092
1093                                         td->ext = NULL;
1094                                         td->tdi = NULL;
1095                                         td->val = NULL;
1096
1097                                         td++;
1098                                 }
1099                                 if (ebo->flag & BONE_ROOTSEL){
1100                                         VECCOPY (td->iloc, ebo->head);
1101                                         VECCOPY (td->center, td->iloc);
1102                                         td->loc= ebo->head;
1103                                         td->flag= TD_SELECTED;
1104
1105                                         Mat3CpyMat3(td->smtx, smtx);
1106                                         Mat3CpyMat3(td->mtx, mtx);
1107
1108                                         td->ext = NULL;
1109                                         td->tdi = NULL;
1110                                         td->val = NULL;
1111
1112                                         td++;
1113                                 }
1114                         }
1115                 }
1116         }
1117 }
1118
1119 /* ********************* meta elements ********* */
1120
1121 static void createTransMBallVerts(TransInfo *t)
1122 {
1123         MetaElem *ml;
1124         TransData *td;
1125         TransDataExtension *tx;
1126         float mtx[3][3], smtx[3][3];
1127         int count=0, countsel=0;
1128         int propmode = t->flag & T_PROP_EDIT;
1129
1130         /* count totals */
1131         for(ml= editelems.first; ml; ml= ml->next) {
1132                 if(ml->flag & SELECT) countsel++;
1133                 if(propmode) count++;
1134         }
1135
1136         /* note: in prop mode we need at least 1 selected */
1137         if (countsel==0) return;
1138         
1139         if(propmode) t->total = count; 
1140         else t->total = countsel;
1141         
1142         td = t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(MBall EditMode)");
1143         tx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "MetaElement_TransExtension");
1144
1145         Mat3CpyMat4(mtx, G.obedit->obmat);
1146         Mat3Inv(smtx, mtx);
1147     
1148         for(ml= editelems.first; ml; ml= ml->next) {
1149                 if(propmode || (ml->flag & SELECT)) {
1150                         td->loc= &ml->x;
1151                         VECCOPY(td->iloc, td->loc);
1152                         VECCOPY(td->center, td->loc);
1153
1154                         if(ml->flag & SELECT) td->flag= TD_SELECTED | TD_USEQUAT | TD_SINGLESIZE;
1155                         else td->flag= TD_USEQUAT;
1156
1157                         Mat3CpyMat3(td->smtx, smtx);
1158                         Mat3CpyMat3(td->mtx, mtx);
1159
1160                         td->ext = tx;
1161                         td->tdi = NULL;
1162
1163                         /* Radius of MetaElem (mass of MetaElem influence) */
1164                         if(ml->flag & MB_SCALE_RAD){
1165                                 td->val = &ml->rad;
1166                                 td->ival = ml->rad;
1167                         }
1168                         else{
1169                                 td->val = &ml->s;
1170                                 td->ival = ml->s;
1171                         }
1172
1173                         /* expx/expy/expz determine "shape" of some MetaElem types */
1174                         tx->size = &ml->expx;
1175                         tx->isize[0] = ml->expx;
1176                         tx->isize[1] = ml->expy;
1177                         tx->isize[2] = ml->expz;
1178
1179                         /* quat is used for rotation of MetaElem */
1180                         tx->quat = ml->quat;
1181                         QUATCOPY(tx->iquat, ml->quat);
1182
1183                         tx->rot = NULL;
1184
1185                         td++;
1186                         tx++;
1187                 }
1188         }
1189
1190
1191 /* ********************* curve/surface ********* */
1192
1193 static void calc_distanceCurveVerts(TransData *head, TransData *tail) {
1194         TransData *td, *td_near = NULL;
1195         for (td = head; td<=tail; td++) {
1196                 if (td->flag & TD_SELECTED) {
1197                         td_near = td;
1198                         td->dist = 0.0f;
1199                 }
1200                 else if(td_near) {
1201                         float dist;
1202                         dist = VecLenf(td_near->center, td->center);
1203                         if (dist < (td-1)->dist) {
1204                                 td->dist = (td-1)->dist;
1205                         }
1206                         else {
1207                                 td->dist = dist;
1208                         }
1209                 }
1210                 else {
1211                         td->dist = MAXFLOAT;
1212                         td->flag |= TD_NOTCONNECTED;
1213                 }
1214         }
1215         td_near = NULL;
1216         for (td = tail; td>=head; td--) {
1217                 if (td->flag & TD_SELECTED) {
1218                         td_near = td;
1219                         td->dist = 0.0f;
1220                 }
1221                 else if(td_near) {
1222                         float dist;
1223                         dist = VecLenf(td_near->center, td->center);
1224                         if (td->flag & TD_NOTCONNECTED || dist < td->dist || (td+1)->dist < td->dist) {
1225                                 td->flag &= ~TD_NOTCONNECTED;
1226                                 if (dist < (td+1)->dist) {
1227                                         td->dist = (td+1)->dist;
1228                                 }
1229                                 else {
1230                                         td->dist = dist;
1231                                 }
1232                         }
1233                 }
1234         }
1235 }
1236
1237 static void createTransCurveVerts(TransInfo *t)
1238 {
1239         TransData *td = NULL;
1240         Nurb *nu;
1241         BezTriple *bezt;
1242         BPoint *bp;
1243         float mtx[3][3], smtx[3][3];
1244         int a;
1245         int count=0, countsel=0;
1246         int propmode = t->flag & T_PROP_EDIT;
1247
1248         /* count total of vertices, check identical as in 2nd loop for making transdata! */
1249         for(nu= editNurb.first; nu; nu= nu->next) {
1250                 if((nu->type & 7)==CU_BEZIER) {
1251                         for(a=0, bezt= nu->bezt; a<nu->pntsu; a++, bezt++) {
1252                                 if(bezt->hide==0) {
1253                                         if (G.f & G_HIDDENHANDLES) {
1254                                                 if(bezt->f2 & SELECT) countsel+=3;
1255                                                 if(propmode) count+= 3;
1256                                         } else {
1257                                                 if(bezt->f1 & SELECT) countsel++;
1258                                                 if(bezt->f2 & SELECT) countsel++;
1259                                                 if(bezt->f3 & SELECT) countsel++;
1260                                                 if(propmode) count+= 3;
1261                                         }
1262                                 }
1263                         }
1264                 }
1265                 else {
1266                         for(a= nu->pntsu*nu->pntsv, bp= nu->bp; a>0; a--, bp++) {
1267                                 if(bp->hide==0) {
1268                                         if(propmode) count++;
1269                                         if(bp->f1 & SELECT) countsel++;
1270                                 }
1271                         }
1272                 }
1273         }
1274         /* note: in prop mode we need at least 1 selected */
1275         if (countsel==0) return;
1276         
1277         if(propmode) t->total = count; 
1278         else t->total = countsel;
1279         t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Curve EditMode)");
1280
1281         Mat3CpyMat4(mtx, G.obedit->obmat);
1282         Mat3Inv(smtx, mtx);
1283
1284     td = t->data;
1285         for(nu= editNurb.first; nu; nu= nu->next) {
1286                 if((nu->type & 7)==CU_BEZIER) {
1287                         TransData *head, *tail;
1288                         head = tail = td;
1289                         for(a=0, bezt= nu->bezt; a<nu->pntsu; a++, bezt++) {
1290                                 if(bezt->hide==0) {
1291                                         
1292                                         if(             propmode ||
1293                                                         ((bezt->f2 & SELECT) && (G.f & G_HIDDENHANDLES)) ||
1294                                                         ((bezt->f1 & SELECT) && (G.f & G_HIDDENHANDLES)==0)
1295                                           ) {
1296                                                 VECCOPY(td->iloc, bezt->vec[0]);
1297                                                 td->loc= bezt->vec[0];
1298                                                 VECCOPY(td->center, bezt->vec[1]);
1299                                                 if (G.f & G_HIDDENHANDLES) {
1300                                                         if(bezt->f2 & SELECT) td->flag= TD_SELECTED;
1301                                                         else td->flag= 0;
1302                                                 } else {
1303                                                         if(bezt->f1 & SELECT) td->flag= TD_SELECTED;
1304                                                         else td->flag= 0;
1305                                                 }
1306                                                 td->ext = NULL;
1307                                                 td->tdi = NULL;
1308                                                 td->val = NULL;
1309
1310                                                 Mat3CpyMat3(td->smtx, smtx);
1311                                                 Mat3CpyMat3(td->mtx, mtx);
1312
1313                                                 td++;
1314                                                 count++;
1315                                                 tail++;
1316                                         }
1317                                         
1318                                         /* This is the Curve Point, the other two are handles */
1319                                         if(propmode || (bezt->f2 & SELECT)) {
1320                                                 VECCOPY(td->iloc, bezt->vec[1]);
1321                                                 td->loc= bezt->vec[1];
1322                                                 VECCOPY(td->center, td->loc);
1323                                                 if(bezt->f2 & SELECT) td->flag= TD_SELECTED;
1324                                                 else td->flag= 0;
1325                                                 td->ext = NULL;
1326                                                 td->tdi = NULL;
1327                                                 
1328                                                 if (t->mode==TFM_CURVE_SHRINKFATTEN) { /* || t->mode==TFM_RESIZE) {*/ /* TODO - make points scale */
1329                                                         td->val = &(bezt->radius);
1330                                                         td->ival = bezt->radius;
1331                                                 } else if (t->mode==TFM_TILT) {
1332                                                         td->val = &(bezt->alfa);
1333                                                         td->ival = bezt->alfa;
1334                                                 } else {
1335                                                         td->val = NULL;
1336                                                 }
1337
1338                                                 Mat3CpyMat3(td->smtx, smtx);
1339                                                 Mat3CpyMat3(td->mtx, mtx);
1340
1341                                                 td++;
1342                                                 count++;
1343                                                 tail++;
1344                                         }
1345                                         if(             propmode ||
1346                                                         ((bezt->f1 & SELECT) && (G.f & G_HIDDENHANDLES)) ||
1347                                                         ((bezt->f3 & SELECT) && (G.f & G_HIDDENHANDLES)==0)
1348                                           ) {
1349                                                 VECCOPY(td->iloc, bezt->vec[2]);
1350                                                 td->loc= bezt->vec[2];
1351                                                 VECCOPY(td->center, bezt->vec[1]);
1352                                                 if (G.f & G_HIDDENHANDLES) {
1353                                                         if(bezt->f2 & SELECT) td->flag= TD_SELECTED;
1354                                                         else td->flag= 0;
1355                                                 } else {
1356                                                         if(bezt->f3 & SELECT) td->flag= TD_SELECTED;
1357                                                         else td->flag= 0;
1358                                                 }
1359                                                 td->ext = NULL;
1360                                                 td->tdi = NULL;
1361                                                 td->val = NULL;
1362
1363                                                 Mat3CpyMat3(td->smtx, smtx);
1364                                                 Mat3CpyMat3(td->mtx, mtx);
1365
1366                                                 td++;
1367                                                 count++;
1368                                                 tail++;
1369                                         }
1370                                 }
1371                                 else if (propmode && head != tail) {
1372                                         calc_distanceCurveVerts(head, tail-1);
1373                                         head = tail;
1374                                 }
1375                         }
1376                         if (propmode && head != tail)
1377                                 calc_distanceCurveVerts(head, tail-1);
1378                 }
1379                 else {
1380                         TransData *head, *tail;
1381                         head = tail = td;
1382                         for(a= nu->pntsu*nu->pntsv, bp= nu->bp; a>0; a--, bp++) {
1383                                 if(bp->hide==0) {
1384                                         if(propmode || (bp->f1 & SELECT)) {
1385                                                 VECCOPY(td->iloc, bp->vec);
1386                                                 td->loc= bp->vec;
1387                                                 VECCOPY(td->center, td->loc);
1388                                                 if(bp->f1 & SELECT) td->flag= TD_SELECTED;
1389                                                 else td->flag= 0;
1390                                                 td->ext = NULL;
1391                                                 td->tdi = NULL;
1392                                                 
1393                                                 if (t->mode==TFM_CURVE_SHRINKFATTEN || t->mode==TFM_RESIZE) {
1394                                                         td->val = &(bp->radius);
1395                                                         td->ival = bp->radius;
1396                                                 } else {
1397                                                         td->val = &(bp->alfa);
1398                                                         td->ival = bp->alfa;
1399                                                 }
1400
1401                                                 Mat3CpyMat3(td->smtx, smtx);
1402                                                 Mat3CpyMat3(td->mtx, mtx);
1403
1404                                                 td++;
1405                                                 count++;
1406                                                 tail++;
1407                                         }
1408                                 }
1409                                 else if (propmode && head != tail) {
1410                                         calc_distanceCurveVerts(head, tail-1);
1411                                         head = tail;
1412                                 }
1413                         }
1414                         if (propmode && head != tail)
1415                                 calc_distanceCurveVerts(head, tail-1);
1416                 }
1417         }
1418 }
1419
1420 /* ********************* lattice *************** */
1421
1422 static void createTransLatticeVerts(TransInfo *t)
1423 {
1424         TransData *td = NULL;
1425         BPoint *bp;
1426         float mtx[3][3], smtx[3][3];
1427         int a;
1428         int count=0, countsel=0;
1429         int propmode = t->flag & T_PROP_EDIT;
1430
1431         bp= editLatt->def;
1432         a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
1433         while(a--) {
1434                 if(bp->hide==0) {
1435                         if(bp->f1 & SELECT) countsel++;
1436                         if(propmode) count++;
1437                 }
1438                 bp++;
1439         }
1440         
1441         /* note: in prop mode we need at least 1 selected */
1442         if (countsel==0) return;
1443         
1444         if(propmode) t->total = count; 
1445         else t->total = countsel;
1446         t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Lattice EditMode)");
1447         
1448         Mat3CpyMat4(mtx, G.obedit->obmat);
1449         Mat3Inv(smtx, mtx);
1450
1451         td = t->data;
1452         bp= editLatt->def;
1453         a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
1454         while(a--) {
1455                 if(propmode || (bp->f1 & SELECT)) {
1456                         if(bp->hide==0) {
1457                                 VECCOPY(td->iloc, bp->vec);
1458                                 td->loc= bp->vec;
1459                                 VECCOPY(td->center, td->loc);
1460                                 if(bp->f1 & SELECT) td->flag= TD_SELECTED;
1461                                 else td->flag= 0;
1462                                 Mat3CpyMat3(td->smtx, smtx);
1463                                 Mat3CpyMat3(td->mtx, mtx);
1464
1465                                 td->ext = NULL;
1466                                 td->tdi = NULL;
1467                                 td->val = NULL;
1468
1469                                 td++;
1470                                 count++;
1471                         }
1472                 }
1473                 bp++;
1474         }
1475
1476
1477 /* ******************* particle edit **************** */
1478 static void createTransParticleVerts(TransInfo *t)
1479 {
1480         TransData *td = NULL;
1481         TransDataExtension *tx;
1482         Base *base = BASACT;
1483         Object *ob = OBACT;
1484         ParticleSystem *psys = PE_get_current(ob);
1485         ParticleSystemModifierData *psmd = NULL;
1486         ParticleEditSettings *pset = PE_settings();
1487         ParticleData *pa = NULL;
1488         ParticleEdit *edit;
1489         ParticleEditKey *key;
1490         float mat[4][4];
1491         int i,k, totpart, transformparticle;
1492         int count = 0, hasselected = 0;
1493         int propmode = t->flag & T_PROP_EDIT;
1494
1495         if(psys==NULL || G.scene->selectmode==SCE_SELECT_PATH) return;
1496
1497         psmd = psys_get_modifier(ob,psys);
1498
1499         edit = psys->edit;
1500         totpart = psys->totpart;
1501         base->flag |= BA_HAS_RECALC_DATA;
1502
1503         for(i=0, pa=psys->particles; i<totpart; i++, pa++) {
1504                 pa->flag &= ~PARS_TRANSFORM;
1505                 transformparticle= 0;
1506
1507                 if((pa->flag & PARS_HIDE)==0) {
1508                         for(k=0, key=edit->keys[i]; k<pa->totkey; k++, key++) {
1509                                 if((key->flag&PEK_HIDE)==0) {
1510                                         if(key->flag&PEK_SELECT) {
1511                                                 hasselected= 1;
1512                                                 transformparticle= 1;
1513                                         }
1514                                         else if(propmode)
1515                                                 transformparticle= 1;
1516                                 }
1517                         }
1518                 }
1519
1520                 if(transformparticle) {
1521                         count += pa->totkey;
1522                         pa->flag |= PARS_TRANSFORM;
1523                 }
1524         }
1525         
1526         /* note: in prop mode we need at least 1 selected */
1527         if (hasselected==0) return;
1528         
1529         t->total = count;
1530         td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Particle Mode)");
1531
1532         if(t->mode == TFM_BAKE_TIME)
1533                 tx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), "Particle_TransExtension");
1534         else
1535                 tx = t->ext = NULL;
1536
1537         Mat4One(mat);
1538
1539         Mat4Invert(ob->imat,ob->obmat);
1540
1541         for(i=0, pa=psys->particles; i<totpart; i++, pa++) {
1542                 TransData *head, *tail;
1543                 head = tail = td;
1544
1545                 if(!(pa->flag & PARS_TRANSFORM)) continue;
1546
1547                 psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, mat);
1548
1549                 for(k=0, key=edit->keys[i]; k<pa->totkey; k++, key++) {
1550                         VECCOPY(key->world_co, key->co);
1551                         Mat4MulVecfl(mat, key->world_co);
1552                         td->loc = key->world_co;
1553
1554                         VECCOPY(td->iloc, td->loc);
1555                         VECCOPY(td->center, td->loc);
1556
1557                         if(key->flag & PEK_SELECT)
1558                                 td->flag |= TD_SELECTED;
1559                         else if(!propmode)
1560                                 td->flag |= TD_SKIP;
1561
1562                         Mat3One(td->mtx);
1563                         Mat3One(td->smtx);
1564
1565                         /* don't allow moving roots */
1566                         if(k==0 && pset->flag & PE_LOCK_FIRST)
1567                                 td->protectflag |= OB_LOCK_LOC;
1568
1569                         td->ob = ob;
1570                         td->ext = tx;
1571                         td->tdi = NULL;
1572                         if(t->mode == TFM_BAKE_TIME) {
1573                                 td->val = key->time;
1574                                 td->ival = *(key->time);
1575                                 /* abuse size and quat for min/max values */
1576                                 td->flag |= TD_NO_EXT;
1577                                 if(k==0) tx->size = 0;
1578                                 else tx->size = (key - 1)->time;
1579
1580                                 if(k == pa->totkey - 1) tx->quat = 0;
1581                                 else tx->quat = (key + 1)->time;
1582                         }
1583
1584                         td++;
1585                         if(tx)
1586                                 tx++;
1587                         tail++;
1588                 }
1589                 if (propmode && head != tail)
1590                         calc_distanceCurveVerts(head, tail - 1);
1591         }
1592 }
1593
1594 void flushTransParticles(TransInfo *t)
1595 {
1596         Object *ob = OBACT;
1597         ParticleSystem *psys = PE_get_current(ob);
1598         ParticleSystemModifierData *psmd;
1599         ParticleData *pa;
1600         ParticleEditKey *key;
1601         TransData *td;
1602         float mat[4][4], imat[4][4], co[3];
1603         int i, k, propmode = t->flag & T_PROP_EDIT;
1604
1605         psmd = psys_get_modifier(ob, psys);
1606
1607         /* we do transform in world space, so flush world space position
1608          * back to particle local space */
1609         td= t->data;
1610         for(i=0, pa=psys->particles; i<psys->totpart; i++, pa++, td++) {
1611                 if(!(pa->flag & PARS_TRANSFORM)) continue;
1612
1613                 psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, mat);
1614                 Mat4Invert(imat,mat);
1615
1616                 for(k=0, key=psys->edit->keys[i]; k<pa->totkey; k++, key++) {
1617                         VECCOPY(co, key->world_co);
1618                         Mat4MulVecfl(imat, co);
1619
1620                         /* optimization for proportional edit */
1621                         if(!propmode || !FloatCompare(key->co, co, 0.0001f)) {
1622                                 VECCOPY(key->co, co);
1623                                 pa->flag |= PARS_EDIT_RECALC;
1624                         }
1625                 }
1626         }
1627
1628         PE_update_object(OBACT, 1);
1629 }
1630
1631 /* ********************* mesh ****************** */
1632
1633 /* proportional distance based on connectivity  */
1634 #define E_VEC(a)        (vectors + (3 * (a)->tmp.l))
1635 #define E_NEAR(a)       (nears[((a)->tmp.l)])
1636 #define THRESHOLD       0.0001f
1637 static void editmesh_set_connectivity_distance(int total, float *vectors, EditVert **nears)
1638 {
1639         EditMesh *em = G.editMesh;
1640         EditVert *eve;
1641         EditEdge *eed;
1642         int i= 0, done= 1;
1643
1644         /* f2 flag is used for 'selection' */
1645         /* tmp.l is offset on scratch array   */
1646         for(eve= em->verts.first; eve; eve= eve->next) {
1647                 if(eve->h==0) {
1648                         eve->tmp.l = i++;
1649
1650                         if(eve->f & SELECT) {
1651                                 eve->f2= 2;
1652                                 E_NEAR(eve) = eve;
1653                                 E_VEC(eve)[0] = 0.0f;
1654                                 E_VEC(eve)[1] = 0.0f;
1655                                 E_VEC(eve)[2] = 0.0f;
1656                         }
1657                         else {
1658                                 eve->f2 = 0;
1659                         }
1660                 }
1661         }
1662
1663
1664         /* Floodfill routine */
1665         /*
1666         At worst this is n*n of complexity where n is number of edges 
1667         Best case would be n if the list is ordered perfectly.
1668         Estimate is n log n in average (so not too bad)
1669         */
1670         while(done) {
1671                 done= 0;
1672                 
1673                 for(eed= em->edges.first; eed; eed= eed->next) {
1674                         if(eed->h==0) {
1675                                 EditVert *v1= eed->v1, *v2= eed->v2;
1676                                 float *vec2 = E_VEC(v2);
1677                                 float *vec1 = E_VEC(v1);
1678
1679                                 if (v1->f2 + v2->f2 == 4)
1680                                         continue;
1681
1682                                 if (v1->f2) {
1683                                         if (v2->f2) {
1684                                                 float nvec[3];
1685                                                 float len1 = VecLength(vec1);
1686                                                 float len2 = VecLength(vec2);
1687                                                 float lenn;
1688                                                 /* for v2 if not selected */
1689                                                 if (v2->f2 != 2) {
1690                                                         VecSubf(nvec, v2->co, E_NEAR(v1)->co);
1691                                                         lenn = VecLength(nvec);
1692                                                         /* 1 < n < 2 */
1693                                                         if (lenn - len1 > THRESHOLD && len2 - lenn > THRESHOLD) {
1694                                                                 VECCOPY(vec2, nvec);
1695                                                                 E_NEAR(v2) = E_NEAR(v1);
1696                                                                 done = 1;
1697                                                         }
1698                                                         /* n < 1 < 2 */
1699                                                         else if (len2 - len1 > THRESHOLD && len1 - lenn > THRESHOLD) {
1700                                                                 VECCOPY(vec2, vec1);
1701                                                                 E_NEAR(v2) = E_NEAR(v1);
1702                                                                 done = 1;
1703                                                         }
1704                                                 }
1705                                                 /* for v1 if not selected */
1706                                                 if (v1->f2 != 2) {
1707                                                         VecSubf(nvec, v1->co, E_NEAR(v2)->co);
1708                                                         lenn = VecLength(nvec);
1709                                                         /* 2 < n < 1 */
1710                                                         if (lenn - len2 > THRESHOLD && len1 - lenn > THRESHOLD) {
1711                                                                 VECCOPY(vec1, nvec);
1712                                                                 E_NEAR(v1) = E_NEAR(v2);
1713                                                                 done = 1;
1714                                                         }
1715                                                         /* n < 2 < 1 */
1716                                                         else if (len1 - len2 > THRESHOLD && len2 - lenn > THRESHOLD) {
1717                                                                 VECCOPY(vec1, vec2);
1718                                                                 E_NEAR(v1) = E_NEAR(v2);
1719                                                                 done = 1;
1720                                                         }
1721                                                 }
1722                                         }
1723                                         else {
1724                                                 v2->f2 = 1;
1725                                                 VecSubf(vec2, v2->co, E_NEAR(v1)->co);
1726                                                 /* 2 < 1 */
1727                                                 if (VecLength(vec1) - VecLength(vec2) > THRESHOLD) {
1728                                                         VECCOPY(vec2, vec1);
1729                                                 }
1730                                                 E_NEAR(v2) = E_NEAR(v1);
1731                                                 done = 1;
1732                                         }
1733                                 }
1734                                 else if (v2->f2) {
1735                                         v1->f2 = 1;
1736                                         VecSubf(vec1, v1->co, E_NEAR(v2)->co);
1737                                         /* 2 < 1 */
1738                                         if (VecLength(vec2) - VecLength(vec1) > THRESHOLD) {
1739                                                 VECCOPY(vec1, vec2);
1740                                         }
1741                                         E_NEAR(v1) = E_NEAR(v2);
1742                                         done = 1;
1743                                 }
1744                         }
1745                 }
1746         }
1747 }
1748
1749 /* loop-in-a-loop I know, but we need it! (ton) */
1750 static void get_face_center(float *cent, EditVert *eve)
1751 {
1752         EditMesh *em = G.editMesh;
1753         EditFace *efa;
1754         
1755         for(efa= em->faces.first; efa; efa= efa->next)
1756                 if(efa->f & SELECT)
1757                         if(efa->v1==eve || efa->v2==eve || efa->v3==eve || efa->v4==eve)
1758                                 break;
1759         if(efa) {
1760                 VECCOPY(cent, efa->cent);
1761         }
1762 }
1763
1764 //way to overwrite what data is edited with transform
1765 //static void VertsToTransData(TransData *td, EditVert *eve, BakeKey *key)
1766 static void VertsToTransData(TransData *td, EditVert *eve)
1767 {
1768         td->flag = 0;
1769         //if(key)
1770         //      td->loc = key->co;
1771         //else
1772         td->loc = eve->co;
1773         
1774         VECCOPY(td->center, td->loc);
1775         if(G.vd->around==V3D_LOCAL && (G.scene->selectmode & SCE_SELECT_FACE))
1776                 get_face_center(td->center, eve);
1777         VECCOPY(td->iloc, td->loc);
1778
1779         // Setting normals
1780         VECCOPY(td->axismtx[2], eve->no);
1781         td->axismtx[0][0]               =
1782                 td->axismtx[0][1]       =
1783                 td->axismtx[0][2]       =
1784                 td->axismtx[1][0]       =
1785                 td->axismtx[1][1]       =
1786                 td->axismtx[1][2]       = 0.0f;
1787
1788         td->ext = NULL;
1789         td->tdi = NULL;
1790         td->val = NULL;
1791         td->tdmir= NULL;
1792
1793 #ifdef WITH_VERSE
1794         if(eve->vvert) {
1795                 td->verse = (void*)eve->vvert;
1796                 td->flag |= TD_VERSE_VERT;
1797         }
1798         else
1799                 td->flag &= ~TD_VERSE_VERT;
1800 #endif
1801 }
1802
1803 /* *********************** CrazySpace correction. Now without doing subsurf optimal ****************** */
1804
1805 static void make_vertexcos__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
1806 {
1807         float *vec = userData;
1808         
1809         vec+= 3*index;
1810         VECCOPY(vec, co);
1811 }
1812
1813 static int modifiers_disable_subsurf_temporary(Object *ob)
1814 {
1815         ModifierData *md;
1816         int disabled = 0;
1817         
1818         for(md=ob->modifiers.first; md; md=md->next)
1819                 if(md->type==eModifierType_Subsurf)
1820                         if(md->mode & eModifierMode_OnCage) {
1821                                 md->mode ^= eModifierMode_DisableTemporary;
1822                                 disabled= 1;
1823                         }
1824         
1825         return disabled;
1826 }
1827
1828 /* disable subsurf temporal, get mapped cos, and enable it */
1829 static float *get_crazy_mapped_editverts(void)
1830 {
1831         DerivedMesh *dm;
1832         float *vertexcos;
1833
1834         /* disable subsurf temporal, get mapped cos, and enable it */
1835         if(modifiers_disable_subsurf_temporary(G.obedit)) {
1836                 /* need to make new derivemesh */
1837                 makeDerivedMesh(G.obedit, CD_MASK_BAREMESH);
1838         }
1839
1840         /* now get the cage */
1841         dm= editmesh_get_derived_cage(CD_MASK_BAREMESH);
1842
1843         vertexcos= MEM_mallocN(3*sizeof(float)*G.totvert, "vertexcos map");
1844         dm->foreachMappedVert(dm, make_vertexcos__mapFunc, vertexcos);
1845         
1846         dm->release(dm);
1847         
1848         /* set back the flag, no new cage needs to be built, transform does it */
1849         modifiers_disable_subsurf_temporary(G.obedit);
1850         
1851         return vertexcos;
1852 }
1853
1854 #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])
1855 static void set_crazy_vertex_quat(float *quat, float *v1, float *v2, float *v3, float *def1, float *def2, float *def3)
1856 {
1857         float vecu[3], vecv[3];
1858         float q1[4], q2[4];
1859         
1860         TAN_MAKE_VEC(vecu, v1, v2);
1861         TAN_MAKE_VEC(vecv, v1, v3);
1862         triatoquat(v1, vecu, vecv, q1);
1863         
1864         TAN_MAKE_VEC(vecu, def1, def2);
1865         TAN_MAKE_VEC(vecv, def1, def3);
1866         triatoquat(def1, vecu, vecv, q2);
1867         
1868         QuatSub(quat, q2, q1);
1869 }
1870 #undef TAN_MAKE_VEC
1871
1872 static void set_crazyspace_quats(float *origcos, float *mappedcos, float *quats)
1873 {
1874         EditMesh *em = G.editMesh;
1875         EditVert *eve, *prev;
1876         EditFace *efa;
1877         float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4;
1878         long index= 0;
1879         
1880         /* two abused locations in vertices */
1881         for(eve= em->verts.first; eve; eve= eve->next, index++) {
1882                 eve->tmp.p = NULL;
1883                 eve->prev= (EditVert *)index;
1884         }
1885         
1886         /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */
1887         for(efa= em->faces.first; efa; efa= efa->next) {
1888                 
1889                 /* retrieve mapped coordinates */
1890                 v1= mappedcos + 3*(long)(efa->v1->prev);
1891                 v2= mappedcos + 3*(long)(efa->v2->prev);
1892                 v3= mappedcos + 3*(long)(efa->v3->prev);
1893
1894                 co1= (origcos)? origcos + 3*(long)(efa->v1->prev): efa->v1->co;
1895                 co2= (origcos)? origcos + 3*(long)(efa->v2->prev): efa->v2->co;
1896                 co3= (origcos)? origcos + 3*(long)(efa->v3->prev): efa->v3->co;
1897
1898                 if(efa->v2->tmp.p==NULL && efa->v2->f1) {
1899                         set_crazy_vertex_quat(quats, co2, co3, co1, v2, v3, v1);
1900                         efa->v2->tmp.p= (void*)quats;
1901                         quats+= 4;
1902                 }
1903                 
1904                 if(efa->v4) {
1905                         v4= mappedcos + 3*(long)(efa->v4->prev);
1906                         co4= (origcos)? origcos + 3*(long)(efa->v4->prev): efa->v4->co;
1907
1908                         if(efa->v1->tmp.p==NULL && efa->v1->f1) {
1909                                 set_crazy_vertex_quat(quats, co1, co2, co4, v1, v2, v4);
1910                                 efa->v1->tmp.p= (void*)quats;
1911                                 quats+= 4;
1912                         }
1913                         if(efa->v3->tmp.p==NULL && efa->v3->f1) {
1914                                 set_crazy_vertex_quat(quats, co3, co4, co2, v3, v4, v2);
1915                                 efa->v3->tmp.p= (void*)quats;
1916                                 quats+= 4;
1917                         }
1918                         if(efa->v4->tmp.p==NULL && efa->v4->f1) {
1919                                 set_crazy_vertex_quat(quats, co4, co1, co3, v4, v1, v3);
1920                                 efa->v4->tmp.p= (void*)quats;
1921                                 quats+= 4;
1922                         }
1923                 }
1924                 else {
1925                         if(efa->v1->tmp.p==NULL && efa->v1->f1) {
1926                                 set_crazy_vertex_quat(quats, co1, co2, co3, v1, v2, v3);
1927                                 efa->v1->tmp.p= (void*)quats;
1928                                 quats+= 4;
1929                         }
1930                         if(efa->v3->tmp.p==NULL && efa->v3->f1) {
1931                                 set_crazy_vertex_quat(quats, co3, co1, co2, v3, v1, v2);
1932                                 efa->v3->tmp.p= (void*)quats;
1933                                 quats+= 4;
1934                         }
1935                 }
1936         }
1937
1938         /* restore abused prev pointer */
1939         for(prev= NULL, eve= em->verts.first; eve; prev= eve, eve= eve->next)
1940                 eve->prev= prev;
1941
1942 }
1943
1944 static void createTransEditVerts(TransInfo *t)
1945 {
1946         TransData *tob = NULL;
1947         EditMesh *em = G.editMesh;
1948         EditVert *eve;
1949         EditVert **nears = NULL;
1950         float *vectors = NULL, *mappedcos = NULL, *quats= NULL;
1951         float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL;
1952         int count=0, countsel=0, a, totleft;
1953         int propmode = t->flag & T_PROP_EDIT;
1954         int mirror = 0;
1955         
1956         if ((t->context & CTX_NO_MIRROR) == 0 || (G.scene->toolsettings->editbutflag & B_MESH_X_MIRROR))
1957         {
1958                 mirror = 1;
1959         }
1960
1961         // transform now requires awareness for select mode, so we tag the f1 flags in verts
1962         if(G.scene->selectmode & SCE_SELECT_VERTEX) {
1963                 for(eve= em->verts.first; eve; eve= eve->next) {
1964                         if(eve->h==0 && (eve->f & SELECT)) 
1965                                 eve->f1= SELECT;
1966                         else
1967                                 eve->f1= 0;
1968                 }
1969         }
1970         else if(G.scene->selectmode & SCE_SELECT_EDGE) {
1971                 EditEdge *eed;
1972                 for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
1973                 for(eed= em->edges.first; eed; eed= eed->next) {
1974                         if(eed->h==0 && (eed->f & SELECT))
1975                                 eed->v1->f1= eed->v2->f1= SELECT;
1976                 }
1977         }
1978         else {
1979                 EditFace *efa;
1980                 for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
1981                 for(efa= em->faces.first; efa; efa= efa->next) {
1982                         if(efa->h==0 && (efa->f & SELECT)) {
1983                                 efa->v1->f1= efa->v2->f1= efa->v3->f1= SELECT;
1984                                 if(efa->v4) efa->v4->f1= SELECT;
1985                         }
1986                 }
1987         }
1988         
1989         /* now we can count */
1990         for(eve= em->verts.first; eve; eve= eve->next) {
1991                 if(eve->h==0) {
1992                         if(eve->f1) countsel++;
1993                         if(propmode) count++;
1994                 }
1995         }
1996         
1997         /* note: in prop mode we need at least 1 selected */
1998         if (countsel==0) return;
1999         
2000         if(propmode) {
2001                 t->total = count; 
2002         
2003                 /* allocating scratch arrays */
2004                 vectors = (float *)MEM_mallocN(t->total * 3 * sizeof(float), "scratch vectors");
2005                 nears = (EditVert**)MEM_mallocN(t->total * sizeof(EditVert*), "scratch nears");
2006         }
2007         else t->total = countsel;
2008         tob= t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Mesh EditMode)");
2009         
2010         Mat3CpyMat4(mtx, G.obedit->obmat);
2011         Mat3Inv(smtx, mtx);
2012
2013         if(propmode) editmesh_set_connectivity_distance(t->total, vectors, nears);
2014         
2015         /* detect CrazySpace [tm] */
2016         if(propmode==0) {
2017                 if(modifiers_getCageIndex(G.obedit, NULL)>=0) {
2018                         if(modifiers_isDeformed(G.obedit)) {
2019                                 /* check if we can use deform matrices for modifier from the
2020                                    start up to stack, they are more accurate than quats */
2021                                 totleft= editmesh_get_first_deform_matrices(&defmats, &defcos);
2022
2023                                 /* if we still have more modifiers, also do crazyspace
2024                                    correction with quats, relative to the coordinates after
2025                                    the modifiers that support deform matrices (defcos) */
2026                                 if(totleft > 0) {
2027                                         mappedcos= get_crazy_mapped_editverts();
2028                                         quats= MEM_mallocN( (t->total)*sizeof(float)*4, "crazy quats");
2029                                         set_crazyspace_quats((float*)defcos, mappedcos, quats);
2030                                         if(mappedcos)
2031                                                 MEM_freeN(mappedcos);
2032                                 }
2033
2034                                 if(defcos)
2035                                         MEM_freeN(defcos);
2036                         }
2037                 }
2038         }
2039         
2040         /* find out which half we do */
2041         if(mirror) {
2042                 for (eve=em->verts.first; eve; eve=eve->next) {
2043                         if(eve->h==0 && eve->f1 && eve->co[0]!=0.0f) {
2044                                 if(eve->co[0]<0.0f)
2045                                         mirror = -1;
2046                                 break;
2047                         }
2048                 }
2049         }
2050         
2051         for (a=0, eve=em->verts.first; eve; eve=eve->next, a++) {
2052                 if(eve->h==0) {
2053                         if(propmode || eve->f1) {
2054                                 VertsToTransData(tob, eve);
2055
2056                                 if(eve->f1) tob->flag |= TD_SELECTED;
2057                                 if(propmode) {
2058                                         if (eve->f2) {
2059                                                 float vec[3];
2060                                                 VECCOPY(vec, E_VEC(eve));
2061                                                 Mat3MulVecfl(mtx, vec);
2062                                                 tob->dist= VecLength(vec);
2063                                         }
2064                                         else {
2065                                                 tob->flag |= TD_NOTCONNECTED;
2066                                                 tob->dist = MAXFLOAT;
2067                                         }
2068                                 }
2069                                 
2070                                 /* CrazySpace */
2071                                 if(defmats || (quats && eve->tmp.p)) {
2072                                         float mat[3][3], imat[3][3], qmat[3][3];
2073                                         
2074                                         /* use both or either quat and defmat correction */
2075                                         if(quats && eve->tmp.f) {
2076                                                 QuatToMat3(eve->tmp.p, qmat);
2077
2078                                                 if(defmats)
2079                                                         Mat3MulSerie(mat, mtx, qmat, defmats[a],
2080                                                                 NULL, NULL, NULL, NULL, NULL);
2081                                                 else
2082                                                         Mat3MulMat3(mat, mtx, qmat);
2083                                         }
2084                                         else
2085                                                 Mat3MulMat3(mat, mtx, defmats[a]);
2086
2087                                         Mat3Inv(imat, mat);
2088                                         
2089                                         Mat3CpyMat3(tob->smtx, imat);
2090                                         Mat3CpyMat3(tob->mtx, mat);
2091                                 }
2092                                 else {
2093                                         Mat3CpyMat3(tob->smtx, smtx);
2094                                         Mat3CpyMat3(tob->mtx, mtx);
2095                                 }
2096                                 
2097                                 /* Mirror? */
2098                                 if( (mirror>0 && tob->iloc[0]>0.0f) || (mirror<0 && tob->iloc[0]<0.0f)) {
2099                                         EditVert *vmir= editmesh_get_x_mirror_vert(G.obedit, tob->iloc);        /* initializes octree on first call */
2100                                         if(vmir!=eve) tob->tdmir= vmir;
2101                                 }
2102                                 tob++;
2103                         }
2104                 }       
2105         }
2106         if (propmode) {
2107                 MEM_freeN(vectors);
2108                 MEM_freeN(nears);
2109         }
2110         /* crazy space free */
2111         if(quats)
2112                 MEM_freeN(quats);
2113         if(defmats)
2114                 MEM_freeN(defmats);
2115 }
2116
2117 /* ********************* UV ****************** */
2118
2119 static void UVsToTransData(TransData *td, TransData2D *td2d, float *uv, int selected)
2120 {
2121         float aspx, aspy;
2122
2123         transform_aspect_ratio_tface_uv(&aspx, &aspy);
2124
2125         /* uv coords are scaled by aspects. this is needed for rotations and
2126            proportional editing to be consistent with the stretchted uv coords
2127            that are displayed. this also means that for display and numinput,
2128            and when the the uv coords are flushed, these are converted each time */
2129         td2d->loc[0] = uv[0]*aspx;
2130         td2d->loc[1] = uv[1]*aspy;
2131         td2d->loc[2] = 0.0f;
2132         td2d->loc2d = uv;
2133
2134         td->flag = 0;
2135         td->loc = td2d->loc;
2136         VECCOPY(td->center, td->loc);
2137         VECCOPY(td->iloc, td->loc);
2138
2139         memset(td->axismtx, 0, sizeof(td->axismtx));
2140         td->axismtx[2][2] = 1.0f;
2141
2142         td->ext= NULL; td->tdi= NULL; td->val= NULL;
2143
2144         if(selected) {
2145                 td->flag |= TD_SELECTED;
2146                 td->dist= 0.0;
2147         }
2148         else
2149                 td->dist= MAXFLOAT;
2150         
2151         Mat3One(td->mtx);
2152         Mat3One(td->smtx);
2153 }
2154
2155 static void createTransUVs(TransInfo *t)
2156 {
2157         TransData *td = NULL;
2158         TransData2D *td2d = NULL;
2159         MTFace *tf;
2160         int count=0, countsel=0;
2161         int propmode = t->flag & T_PROP_EDIT;
2162         
2163         EditMesh *em = G.editMesh;
2164         EditFace *efa;
2165         
2166         if(is_uv_tface_editing_allowed()==0) return;
2167
2168         /* count */
2169         for (efa= em->faces.first; efa; efa= efa->next) {
2170                 tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
2171                 if (simaFaceDraw_Check(efa, tf)) {
2172                         if (simaUVSel_Check(efa, tf, 0)) countsel++; 
2173                         if (simaUVSel_Check(efa, tf, 1)) countsel++; 
2174                         if (simaUVSel_Check(efa, tf, 2)) countsel++; 
2175                         if (efa->v4 && simaUVSel_Check(efa, tf, 3)) countsel++;
2176                         if(propmode)
2177                                 count += (efa->v4)? 4: 3;
2178                 }
2179         }
2180
2181         /* note: in prop mode we need at least 1 selected */
2182         if (countsel==0) return;
2183         
2184         t->total= (propmode)? count: countsel;
2185         t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(UV Editing)");
2186         /* for each 2d uv coord a 3d vector is allocated, so that they can be
2187            treated just as if they were 3d verts */
2188         t->data2d= MEM_callocN(t->total*sizeof(TransData2D), "TransObData2D(UV Editing)");
2189
2190         if(G.sima->flag & SI_CLIP_UV)
2191                 t->flag |= T_CLIP_UV;
2192
2193         td= t->data;
2194         td2d= t->data2d;
2195         for (efa= em->faces.first; efa; efa= efa->next) {
2196                 tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
2197                 if (simaFaceDraw_Check(efa, tf)) {
2198                         if(propmode || simaUVSel_Check(efa, tf, 0))
2199                                 UVsToTransData(td++, td2d++, tf->uv[0], simaUVSel_Check(efa, tf, 0));
2200                         if(propmode || simaUVSel_Check(efa, tf, 1))
2201                                 UVsToTransData(td++, td2d++, tf->uv[1], simaUVSel_Check(efa, tf, 1));
2202                         if(propmode || simaUVSel_Check(efa, tf, 2))
2203                                 UVsToTransData(td++, td2d++, tf->uv[2], simaUVSel_Check(efa, tf, 2));
2204
2205                         if(efa->v4 && (propmode || simaUVSel_Check(efa, tf, 3)))
2206                                 UVsToTransData(td++, td2d++, tf->uv[3], simaUVSel_Check(efa, tf, 3));
2207                 }
2208         }
2209
2210         if (G.sima->flag & SI_LIVE_UNWRAP)
2211                 unwrap_lscm_live_begin();
2212 }
2213
2214 void flushTransUVs(TransInfo *t)
2215 {
2216         TransData2D *td;
2217         int a, width, height;
2218         Object *ob= OBACT;
2219         EditMesh *em = G.editMesh;
2220         float aspx, aspy, invx, invy;
2221
2222         transform_aspect_ratio_tface_uv(&aspx, &aspy);
2223         transform_width_height_tface_uv(&width, &height);
2224         invx= 1.0f/aspx;
2225         invy= 1.0f/aspy;
2226
2227         /* flush to 2d vector from internally used 3d vector */
2228         for(a=0, td= t->data2d; a<t->total; a++, td++) {
2229                 td->loc2d[0]= td->loc[0]*invx;
2230                 td->loc2d[1]= td->loc[1]*invy;
2231                 
2232                 if((G.sima->flag & SI_PIXELSNAP) && (t->state != TRANS_CANCEL)) {
2233                         td->loc2d[0]= floor(width*td->loc2d[0] + 0.5f)/width;
2234                         td->loc2d[1]= floor(height*td->loc2d[1] + 0.5f)/height;
2235                 }
2236         }
2237
2238         /* always call this, also for cancel (it transforms non-selected vertices...) */
2239         if((G.sima->flag & SI_BE_SQUARE))
2240                 be_square_tface_uv(em);
2241
2242         /* this is overkill if G.sima->lock is not set, but still needed */
2243         object_uvs_changed(ob);
2244 }
2245
2246 int clipUVTransform(TransInfo *t, float *vec, int resize)
2247 {
2248         TransData *td;
2249         int a, clipx=1, clipy=1;
2250         float aspx, aspy, min[2], max[2];
2251
2252         transform_aspect_ratio_tface_uv(&aspx, &aspy);
2253         min[0]= min[1]= 0.0f;
2254         max[0]= aspx; max[1]= aspy;
2255
2256         for(a=0, td= t->data; a<t->total; a++, td++) {
2257                 DO_MINMAX2(td->loc, min, max);
2258         }
2259
2260         if(resize) {
2261                 if(min[0] < 0.0f && t->center[0] > 0.0f && t->center[0] < aspx*0.5f)
2262                         vec[0] *= t->center[0]/(t->center[0] - min[0]);
2263                 else if(max[0] > aspx && t->center[0] < aspx)
2264                         vec[0] *= (t->center[0] - aspx)/(t->center[0] - max[0]);
2265                 else
2266                         clipx= 0;
2267
2268                 if(min[1] < 0.0f && t->center[1] > 0.0f && t->center[1] < aspy*0.5f)
2269                         vec[1] *= t->center[1]/(t->center[1] - min[1]);
2270                 else if(max[1] > aspy && t->center[1] < aspy)
2271                         vec[1] *= (t->center[1] - aspy)/(t->center[1] - max[1]);
2272                 else
2273                         clipy= 0;
2274         }
2275         else {
2276                 if(min[0] < 0.0f)
2277                         vec[0] -= min[0];
2278                 else if(max[0] > aspx)
2279                         vec[0] -= max[0]-aspx;
2280                 else
2281                         clipx= 0;
2282
2283                 if(min[1] < 0.0f)
2284                         vec[1] -= min[1];
2285                 else if(max[1] > aspy)
2286                         vec[1] -= max[1]-aspy;
2287                 else
2288                         clipy= 0;
2289         }       
2290
2291         return (clipx || clipy);
2292 }
2293
2294 /* ********************* IPO EDITOR ************************* */
2295
2296 /* for IPO Editor transform - but actual creation of transform structures is not performed here
2297  * due to bad globals that would need to be imported specially for this
2298  */
2299 static void createTransIpoData(TransInfo *t)
2300 {
2301         /* in editipo.c due to some globals that are defined in that file... */
2302         make_ipo_transdata(t);
2303 }
2304
2305 /* this function is called on recalcData to apply the transforms applied
2306  * to the transdata on to the actual keyframe data 
2307  */
2308 void flushTransIpoData(TransInfo *t)
2309 {
2310         TransData2D *td;
2311         int a;
2312         
2313         /* flush to 2d vector from internally used 3d vector */
2314         for (a=0, td= t->data2d; a<t->total; a++, td++) {
2315                 /* we need to unapply the nla-scaling from the time in some situations */
2316                 if (NLA_IPO_SCALED)
2317                         td->loc2d[0]= get_action_frame(OBACT, td->loc[0]);
2318                 else
2319                         td->loc2d[0]= td->loc[0];
2320                 
2321                 /* when the icu that point comes from is a bitflag holder, don't allow adjusting values */
2322                 if ((t->data[a].flag & TD_TIMEONLY)==0)
2323                         td->loc2d[1]= td->loc[1];
2324         }
2325 }
2326
2327 /* ********************* ACTION/NLA EDITOR ****************** */
2328
2329 /* This function tests if a point is on the "mouse" side of the cursor/frame-marking */
2330 static short FrameOnMouseSide(char side, float frame, float cframe)
2331 {
2332         /* both sides, so it doesn't matter */
2333         if (side == 'B') return 1;
2334         
2335         /* only on the named side */
2336         if (side == 'R')
2337                 return (frame >= cframe) ? 1 : 0;
2338         else
2339                 return (frame <= cframe) ? 1 : 0;
2340 }
2341
2342 /* fully select selected beztriples, but only include if it's on the right side of cfra */
2343 static int count_ipo_keys(Ipo *ipo, char side, float cfra)
2344 {
2345         IpoCurve *icu;
2346         BezTriple *bezt;
2347         int i, count = 0;
2348         
2349         if (ipo == NULL)
2350                 return count;
2351         
2352         /* only include points that occur on the right side of cfra */
2353         for (icu= ipo->curve.first; icu; icu= icu->next) {
2354                 for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
2355                         if (bezt->f2 & SELECT) {
2356                                 /* fully select the other two keys */
2357                                 bezt->f1 |= SELECT;
2358                                 bezt->f3 |= SELECT;
2359                                 
2360                                 /* increment by 3, as there are 3 points (3 * x-coordinates) that need transform */
2361                                 if (FrameOnMouseSide(side, bezt->vec[1][0], cfra))
2362                                         count += 3;
2363                         }
2364                 }
2365         }
2366         
2367         return count;
2368 }
2369
2370 /* This function assigns the information to transdata */
2371 static void TimeToTransData(TransData *td, float *time, Object *ob)
2372 {
2373         /* memory is calloc'ed, so that should zero everything nicely for us */
2374         td->val = time;
2375         td->ival = *(time);
2376         
2377         /* store the Object where this keyframe exists as a keyframe of the 
2378          * active action as td->ob. Usually, this member is only used for constraints 
2379          * drawing
2380          */
2381         td->ob= ob;
2382 }
2383
2384 /* This function advances the address to which td points to, so it must return
2385  * the new address so that the next time new transform data is added, it doesn't
2386  * overwrite the existing ones...  i.e.   td = IpoToTransData(td, ipo, ob, side, cfra);
2387  *
2388  * The 'side' argument is needed for the extend mode. 'B' = both sides, 'R'/'L' mean only data
2389  * on the named side are used. 
2390  */
2391 static TransData *IpoToTransData(TransData *td, Ipo *ipo, Object *ob, char side, float cfra)
2392 {
2393         IpoCurve *icu;
2394         BezTriple *bezt;
2395         int i;
2396         
2397         if (ipo == NULL)
2398                 return td;
2399         
2400         for (icu= ipo->curve.first; icu; icu= icu->next) {
2401                 for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
2402                         /* only add selected keyframes (for now, proportional edit is not enabled) */
2403                         if (BEZSELECTED(bezt)) {
2404                                 /* only add if on the right 'side' of the current frame */
2405                                 if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) {
2406                                         /* each control point needs to be added separetely */
2407                                         TimeToTransData(td, bezt->vec[0], ob);
2408                                         td++;
2409                                         
2410                                         TimeToTransData(td, bezt->vec[1], ob);
2411                                         td++;
2412                                         
2413                                         TimeToTransData(td, bezt->vec[2], ob);
2414                                         td++;
2415                                 }
2416                         }       
2417                 }
2418         }
2419         
2420         return td;
2421 }
2422
2423 static void createTransActionData(TransInfo *t)
2424 {
2425         TransData *td = NULL;
2426         Object *ob= NULL;
2427         
2428         ListBase act_data = {NULL, NULL};
2429         bActListElem *ale;
2430         void *data;
2431         short datatype;
2432         int filter;
2433         
2434         int count=0;
2435         float cfra;
2436         char side;
2437         
2438         /* determine what type of data we are operating on */
2439         data = get_action_context(&datatype);
2440         if (data == NULL) return;
2441         
2442         /* filter data */
2443         filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
2444         actdata_filter(&act_data, filter, data, datatype);
2445         
2446         /* is the action scaled? if so, the it should belong to the active object */
2447         if (NLA_ACTION_SCALED)
2448                 ob= OBACT;
2449                 
2450         /* which side of the current frame should be allowed */
2451         if (t->mode == TFM_TIME_EXTEND) {
2452                 /* only side on which mouse is gets transformed */
2453                 float xmouse, ymouse;
2454                 
2455                 areamouseco_to_ipoco(G.v2d, t->imval, &xmouse, &ymouse);
2456                 side = (xmouse > CFRA) ? 'R' : 'L';
2457         }
2458         else {
2459                 /* normal transform - both sides of current frame are considered */
2460                 side = 'B';
2461         }
2462         
2463         /* convert current-frame to action-time (slightly less accurate, espcially under
2464          * higher scaling ratios, but is faster than converting all points) 
2465          */
2466         if (ob) 
2467                 cfra = get_action_frame(ob, CFRA);
2468         else
2469                 cfra = CFRA;
2470         
2471         /* loop 1: fully select ipo-keys and count how many BezTriples are selected */
2472         for (ale= act_data.first; ale; ale= ale->next)
2473                 count += count_ipo_keys(ale->key_data, side, cfra);
2474         
2475         /* stop if trying to build list if nothing selected */
2476         if (count == 0) {
2477                 /* cleanup temp list */
2478                 BLI_freelistN(&act_data);
2479                 return;
2480         }
2481         
2482         /* allocate memory for data */
2483         t->total= count;
2484         t->data= MEM_callocN(t->total*sizeof(TransData), "TransData(Action Editor)");
2485         if (t->mode == TFM_TIME_SLIDE)
2486                 t->customData= MEM_callocN(sizeof(float)*2, "TimeSlide Min/Max");
2487         
2488         td= t->data;
2489         /* loop 2: build transdata array */
2490         for (ale= act_data.first; ale; ale= ale->next) {
2491                 Ipo *ipo= (Ipo *)ale->key_data;
2492                 
2493                 td= IpoToTransData(td, ipo, ob, side, cfra);
2494         }
2495         
2496         /* check if we're supposed to be setting minx/maxx for TimeSlide */
2497         if (t->mode == TFM_TIME_SLIDE) {
2498                 float min = 0, max = 0;
2499                 int i;
2500                 
2501                 td= (t->data + 1);
2502                 for (i=1; i < count; i+=3, td+=3) {
2503                         if (min > *(td->val)) min= *(td->val);
2504                         if (max < *(td->val)) max= *(td->val);
2505                 }
2506                 
2507                 /* minx/maxx values used by TimeSlide are stored as a 
2508                  * calloced 2-float array in t->customData. This gets freed
2509                  * in postTrans (T_FREE_CUSTOMDATA). 
2510                  */
2511                 *((float *)(t->customData)) = min;
2512                 *((float *)(t->customData) + 1) = max;
2513         }
2514         
2515         /* cleanup temp list */
2516         BLI_freelistN(&act_data);
2517 }
2518
2519 static void createTransNlaData(TransInfo *t)
2520 {
2521         Base *base;
2522         bActionStrip *strip;
2523         bActionChannel *achan;
2524         bConstraintChannel *conchan;
2525         
2526         TransData *td = NULL;
2527         int count=0, i;
2528         float cfra;
2529         char side;
2530         
2531         /* which side of the current frame should be allowed */
2532         if (t->mode == TFM_TIME_EXTEND) {
2533                 /* only side on which mouse is gets transformed */
2534                 float xmouse, ymouse;
2535                 
2536                 areamouseco_to_ipoco(G.v2d, t->imval, &xmouse, &ymouse);
2537                 side = (xmouse > CFRA) ? 'R' : 'L';
2538         }
2539         else {
2540                 /* normal transform - both sides of current frame are considered */
2541                 side = 'B';
2542         }
2543         
2544         /* Ensure that partial selections result in beztriple selections */
2545         for (base=G.scene->base.first; base; base=base->next) {
2546                 /* Check object ipos */
2547                 i= count_ipo_keys(base->object->ipo, side, CFRA);
2548                 if (i) base->flag |= BA_HAS_RECALC_OB;
2549                 count += i;
2550                 
2551                 /* Check object constraint ipos */
2552                 for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next)
2553                         count += count_ipo_keys(conchan->ipo, side, CFRA);                      
2554                 
2555                 /* skip actions and nlastrips if object is collapsed */
2556                 if (base->object->nlaflag & OB_NLA_COLLAPSED)
2557                         continue;
2558                 
2559                 /* Check action ipos */
2560                 if (base->object->action) {
2561                         /* exclude if strip is selected too */
2562                         for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
2563                                 if (strip->flag & ACTSTRIP_SELECT)
2564                                         if (strip->act == base->object->action)
2565                                                 break;
2566                         }
2567                         if (strip==NULL) {
2568                                 cfra = get_action_frame(base->object, CFRA);
2569                                 
2570                                 for (achan=base->object->action->chanbase.first; achan; achan=achan->next) {
2571                                         if (EDITABLE_ACHAN(achan)) {
2572                                                 i= count_ipo_keys(achan->ipo, side, cfra);
2573                                                 if (i) base->flag |= BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA;
2574                                                 count += i;
2575                                                 
2576                                                 /* Check action constraint ipos */
2577                                                 if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
2578                                                         for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
2579                                                                 if (EDITABLE_CONCHAN(conchan))
2580                                                                         count += count_ipo_keys(conchan->ipo, side, cfra);
2581                                                         }
2582                                                 }
2583                                         }
2584                                 }
2585                         }               
2586                 }
2587                 
2588                 /* Check nlastrips */
2589                 for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
2590                         if (strip->flag & ACTSTRIP_SELECT) {
2591                                 base->flag |= BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA;
2592                                 
2593                                 if (FrameOnMouseSide(side, strip->start, CFRA)) count++;
2594                                 if (FrameOnMouseSide(side, strip->end, CFRA)) count++;
2595                         }
2596                 }
2597         }
2598         
2599         /* If nothing is selected, bail out */
2600         if (count == 0)
2601                 return;
2602         
2603         /* allocate memory for data */
2604         t->total= count;
2605         t->data= MEM_callocN(t->total*sizeof(TransData), "TransData (NLA Editor)");
2606         
2607         /* build the transdata structure */
2608         td= t->data;
2609         for (base=G.scene->base.first; base; base=base->next) {
2610                 /* Manipulate object ipos */
2611                 /*      - no scaling of keyframe times is allowed here  */
2612                 td= IpoToTransData(td, base->object->ipo, NULL, side, CFRA);
2613                 
2614                 /* Manipulate object constraint ipos */
2615                 /*      - no scaling of keyframe times is allowed here  */
2616                 for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next)
2617                         td= IpoToTransData(td, conchan->ipo, NULL, side, CFRA);
2618                 
2619                 /* skip actions and nlastrips if object collapsed */
2620                 if (base->object->nlaflag & OB_NLA_COLLAPSED)
2621                         continue;
2622                         
2623                 /* Manipulate action ipos */
2624                 if (base->object->action) {
2625                         /* exclude if strip that active action belongs to is selected too */
2626                         for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
2627                                 if (strip->flag & ACTSTRIP_SELECT)
2628                                         if (strip->act == base->object->action)
2629                                                 break;
2630                         }
2631                         
2632                         /* can include if no strip found */
2633                         if (strip==NULL) {
2634                                 cfra = get_action_frame(base->object, CFRA);
2635                                 
2636                                 for (achan=base->object->action->chanbase.first; achan; achan=achan->next) {
2637                                         if (EDITABLE_ACHAN(achan)) {
2638                                                 td= IpoToTransData(td, achan->ipo, base->object, side, cfra);
2639                                                 
2640                                                 /* Manipulate action constraint ipos */
2641                                                 if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
2642                                                         for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
2643                                                                 if (EDITABLE_CONCHAN(conchan))
2644                                                                         td= IpoToTransData(td, conchan->ipo, base->object, side, cfra);
2645                                                         }
2646                                                 }
2647                                         }
2648                                 }
2649                         }
2650                 }
2651                 
2652                 /* Manipulate nlastrips */
2653                 for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
2654                         if (strip->flag & ACTSTRIP_SELECT) {
2655                                 /* first TransData is the start, second is the end */
2656                                 if (FrameOnMouseSide(side, strip->start, CFRA)) {
2657                                         td->val = &strip->start;
2658                                         td->ival = strip->start;
2659                                         td++;
2660                                 }
2661                                 if (FrameOnMouseSide(side, strip->end, CFRA)) {
2662                                         td->val = &strip->end;
2663                                         td->ival = strip->end;
2664                                         td++;
2665                                 }
2666                         }
2667                 }
2668         }
2669 }
2670
2671 /* **************** IpoKey stuff, for Object TransData ********** */
2672
2673 /* storage of bezier triple. thats why -3 and +3! */
2674 static void set_tdi_old(float *old, float *poin)
2675 {
2676         old[0]= *(poin);
2677         old[3]= *(poin-3);
2678         old[6]= *(poin+3);
2679 }
2680
2681 /* while transforming */
2682 void add_tdi_poin(float *poin, float *old, float delta)
2683 {
2684         if(poin) {
2685                 poin[0]= old[0]+delta;
2686                 poin[-3]= old[3]+delta;
2687                 poin[3]= old[6]+delta;
2688         }
2689 }
2690
2691 /* fill ipokey transdata with old vals and pointers */
2692 static void ipokey_to_transdata(IpoKey *ik, TransData *td)
2693 {
2694         extern int ob_ar[];             // blenkernel ipo.c
2695         TransDataIpokey *tdi= td->tdi;
2696         BezTriple *bezt;
2697         int a, delta= 0;
2698         
2699         td->val= NULL;  // is read on ESC
2700         
2701         for(a=0; a<OB_TOTIPO; a++) {
2702                 if(ik->data[a]) {
2703                         bezt= ik->data[a];
2704                         
2705                         switch( ob_ar[a] ) {
2706                                 case OB_LOC_X:
2707                                 case OB_DLOC_X:
2708                                         tdi->locx= &(bezt->vec[1][1]); break;
2709                                 case OB_LOC_Y:
2710                                 case OB_DLOC_Y:
2711                                         tdi->locy= &(bezt->vec[1][1]); break;
2712                                 case OB_LOC_Z:
2713                                 case OB_DLOC_Z:
2714                                         tdi->locz= &(bezt->vec[1][1]); break;
2715                                         
2716                                 case OB_DROT_X:
2717                                         delta= 1;
2718                                 case OB_ROT_X:
2719                                         tdi->rotx= &(bezt->vec[1][1]); break;
2720                                 case OB_DROT_Y:
2721                                         delta= 1;
2722                                 case OB_ROT_Y:
2723                                         tdi->roty= &(bezt->vec[1][1]); break;
2724                                 case OB_DROT_Z:
2725                                         delta= 1;
2726                                 case OB_ROT_Z:
2727                                         tdi->rotz= &(bezt->vec[1][1]); break;
2728                                         
2729                                 case OB_SIZE_X:
2730                                 case OB_DSIZE_X:
2731                                         tdi->sizex= &(bezt->vec[1][1]); break;
2732                                 case OB_SIZE_Y:
2733                                 case OB_DSIZE_Y:
2734                                         tdi->sizey= &(bezt->vec[1][1]); break;
2735                                 case OB_SIZE_Z:
2736                                 case OB_DSIZE_Z:
2737                                         tdi->sizez= &(bezt->vec[1][1]); break;          
2738                         }       
2739                 }
2740         }
2741         
2742         /* oldvals for e.g. undo */
2743         if(tdi->locx) set_tdi_old(tdi->oldloc, tdi->locx);
2744         if(tdi->locy) set_tdi_old(tdi->oldloc+1, tdi->locy);
2745         if(tdi->locz) set_tdi_old(tdi->oldloc+2, tdi->locz);
2746         
2747         /* remember, for mapping curves ('1'=10 degrees)  */
2748         if(tdi->rotx) set_tdi_old(tdi->oldrot, tdi->rotx);
2749         if(tdi->roty) set_tdi_old(tdi->oldrot+1, tdi->roty);
2750         if(tdi->rotz) set_tdi_old(tdi->oldrot+2, tdi->rotz);
2751         
2752         /* this is not allowed to be dsize! */
2753         if(tdi->sizex) set_tdi_old(tdi->oldsize, tdi->sizex);
2754         if(tdi->sizey) set_tdi_old(tdi->oldsize+1, tdi->sizey);
2755         if(tdi->sizez) set_tdi_old(tdi->oldsize+2, tdi->sizez);
2756         
2757         tdi->flag= TOB_IPO;
2758         if(delta) tdi->flag |= TOB_IPODROT;
2759 }
2760
2761
2762 /* *************************** Object Transform data ******************* */
2763
2764 /* Little helper function for ObjectToTransData used to give certain
2765  * constraints (ChildOf, FollowPath, and others that may be added)
2766  * inverse corrections for transform, so that they aren't in CrazySpace.
2767  * These particular constraints benefit from this, but others don't, hence
2768  * this semi-hack ;-)    - Aligorith
2769  */
2770 static short constraints_list_needinv(TransInfo *t, ListBase *list)
2771 {
2772         bConstraint *con;
2773         
2774         /* loop through constraints, checking if there's one of the mentioned 
2775          * constraints needing special crazyspace corrections
2776          */
2777         if (list) {
2778                 for (con= list->first; con; con=con->next) {
2779                         /* only consider constraint if it is enabled, and has influence on result */
2780                         if ((con->flag & CONSTRAINT_DISABLE)==0 && (con->enforce!=0.0)) {
2781                                 /* (affirmative) returns for specific constraints here... */
2782                                         /* constraints that require this regardless  */
2783                                 if (con->type == CONSTRAINT_TYPE_CHILDOF) return 1;
2784                                 if (con->type == CONSTRAINT_TYPE_FOLLOWPATH) return 1;
2785                                 if (con->type == CONSTRAINT_TYPE_CLAMPTO) return 1;
2786                                 
2787                                         /* constraints that require this only under special conditions */
2788                                 if (con->type == CONSTRAINT_TYPE_ROTLIKE) {
2789                                         /* CopyRot constraint only does this when rotating, and offset is on */
2790                                         bRotateLikeConstraint *data = (bRotateLikeConstraint *)con->data;
2791                                         
2792                                         if ((data->flag & ROTLIKE_OFFSET) && (t->mode == TFM_ROTATION))
2793                                                 return 1;
2794                                 }
2795                         }
2796                 }
2797         }
2798         
2799         /* no appropriate candidates found */
2800         return 0;
2801 }
2802
2803 /* transcribe given object into TransData for Transforming */
2804 static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) 
2805 {
2806         Object *track;
2807         ListBase fakecons = {NULL, NULL};
2808         float obmtx[3][3];
2809         short constinv;
2810
2811         /* axismtx has the real orientation */
2812         Mat3CpyMat4(td->axismtx, ob->obmat);
2813         Mat3Ortho(td->axismtx);
2814
2815         td->con= ob->constraints.first;
2816         
2817         /* hack: tempolarily disable tracking and/or constraints when getting 
2818          *              object matrix, if tracking is on, or if constraints don't need
2819          *              inverse correction to stop it from screwing up space conversion
2820          *              matrix later
2821          */
2822         constinv= constraints_list_needinv(t, &ob->constraints);
2823         if (ob->track || constinv==0) {
2824                 track= ob->track;
2825                 ob->track= NULL;
2826                 
2827                 if (constinv == 0) {
2828                         fakecons.first = ob->constraints.first;
2829                         fakecons.last = ob->constraints.last;
2830                         ob->constraints.first = ob->constraints.last = NULL;
2831                 }
2832                 
2833                 where_is_object(ob);
2834                 
2835                 if (constinv == 0) {
2836                         ob->constraints.first = fakecons.first;
2837                         ob->constraints.last = fakecons.last;
2838                 }
2839                 
2840                 ob->track= track;
2841         }
2842         else
2843                 where_is_object(ob);
2844
2845         td->ob = ob;
2846
2847         td->loc = ob->loc;
2848         VECCOPY(td->iloc, td->loc);
2849         
2850         td->ext->rot = ob->rot;
2851         VECCOPY(td->ext->irot, ob->rot);
2852         VECCOPY(td->ext->drot, ob->drot);
2853         
2854         td->ext->size = ob->size;
2855         VECCOPY(td->ext->isize, ob->size);
2856         VECCOPY(td->ext->dsize, ob->dsize);
2857
2858         VECCOPY(td->center, ob->obmat[3]);
2859
2860         /* is there a need to set the global<->data space conversion matrices? */
2861         if (ob->parent || constinv) {
2862                 float totmat[3][3], obinv[3][3];
2863                 
2864                 /* Get the effect of parenting, and/or certain constraints.
2865                  * NOTE: some Constraints, and also Tracking should never get this
2866                  *              done, as it doesn't work well.
2867                  */
2868                 object_to_mat3(ob, obmtx);
2869                 Mat3CpyMat4(totmat, ob->obmat);
2870                 Mat3Inv(obinv, totmat);
2871                 Mat3MulMat3(td->smtx, obmtx, obinv);
2872                 Mat3Inv(td->mtx, td->smtx);
2873         }
2874         else {
2875                 /* no conversion to/from dataspace */
2876                 Mat3One(td->smtx);
2877                 Mat3One(td->mtx);
2878         }
2879 #ifdef WITH_VERSE
2880         if(ob->vnode) {
2881                 td->verse = (void*)ob;
2882                 td->flag |= TD_VERSE_OBJECT;
2883         }
2884         else
2885                 td->flag &= ~TD_VERSE_OBJECT;
2886 #endif
2887 }
2888
2889
2890 /* sets flags in Bases to define whether they take part in transform */
2891 /* it deselects Bases, so we have to call the clear function always after */
2892 static void set_trans_object_base_flags(TransInfo *t)
2893 {
2894         /*
2895          if Base selected and has parent selected:
2896          base->flag= BA_WAS_SEL
2897          */
2898         Base *base;
2899         
2900         /* makes sure base flags and object flags are identical */
2901         copy_baseflags();
2902         
2903         /* handle pending update events, otherwise they got copied below */
2904         for (base= FIRSTBASE; base; base= base->next) {
2905                 if(base->object->recalc) 
2906                         object_handle_update(base->object);
2907         }
2908         
2909         for (base= FIRSTBASE; base; base= base->next) {
2910                 base->flag &= ~BA_WAS_SEL;
2911                 
2912                 if(TESTBASELIB(base)) {
2913                         Object *ob= base->object;
2914                         Object *parsel= ob->parent;
2915                         
2916                         /* if parent selected, deselect */
2917                         while(parsel) {
2918                                 if(parsel->flag & SELECT) break;
2919                                 parsel= parsel->parent;
2920                         }
2921                         
2922                         if(parsel) {