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