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