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