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