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