Fixes for some long standing transform bugs.
[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 = 0;
1693         
1694         if ((t->context & CTX_NO_MIRROR) == 0 || (G.scene->toolsettings->editbutflag & B_MESH_X_MIRROR))
1695         {
1696                 mirror = 1;
1697         }
1698
1699         // transform now requires awareness for select mode, so we tag the f1 flags in verts
1700         if(G.scene->selectmode & SCE_SELECT_VERTEX) {
1701                 for(eve= em->verts.first; eve; eve= eve->next) {
1702                         if(eve->h==0 && (eve->f & SELECT)) 
1703                                 eve->f1= SELECT;
1704                         else
1705                                 eve->f1= 0;
1706                 }
1707         }
1708         else if(G.scene->selectmode & SCE_SELECT_EDGE) {
1709                 EditEdge *eed;
1710                 for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
1711                 for(eed= em->edges.first; eed; eed= eed->next) {
1712                         if(eed->h==0 && (eed->f & SELECT))
1713                                 eed->v1->f1= eed->v2->f1= SELECT;
1714                 }
1715         }
1716         else {
1717                 EditFace *efa;
1718                 for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
1719                 for(efa= em->faces.first; efa; efa= efa->next) {
1720                         if(efa->h==0 && (efa->f & SELECT)) {
1721                                 efa->v1->f1= efa->v2->f1= efa->v3->f1= SELECT;
1722                                 if(efa->v4) efa->v4->f1= SELECT;
1723                         }
1724                 }
1725         }
1726         
1727         /* now we can count */
1728         for(eve= em->verts.first; eve; eve= eve->next) {
1729                 if(eve->h==0) {
1730                         if(eve->f1) countsel++;
1731                         if(propmode) count++;
1732                 }
1733         }
1734         
1735         /* note: in prop mode we need at least 1 selected */
1736         if (countsel==0) return;
1737         
1738         if(propmode) {
1739                 t->total = count; 
1740         
1741                 /* allocating scratch arrays */
1742                 vectors = (float *)MEM_mallocN(t->total * 3 * sizeof(float), "scratch vectors");
1743                 nears = (EditVert**)MEM_mallocN(t->total * sizeof(EditVert*), "scratch nears");
1744         }
1745         else t->total = countsel;
1746         tob= t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Mesh EditMode)");
1747         
1748         Mat3CpyMat4(mtx, G.obedit->obmat);
1749         Mat3Inv(smtx, mtx);
1750
1751         if(propmode) editmesh_set_connectivity_distance(t->total, vectors, nears);
1752         
1753         /* detect CrazySpace [tm] */
1754         if(propmode==0) {
1755                 if(modifiers_getCageIndex(G.obedit, NULL)>=0) {
1756                         if(modifiers_isDeformed(G.obedit)) {
1757                                 /* check if we can use deform matrices for modifier from the
1758                                    start up to stack, they are more accurate than quats */
1759                                 totleft= editmesh_get_first_deform_matrices(&defmats, &defcos);
1760
1761                                 /* if we still have more modifiers, also do crazyspace
1762                                    correction with quats, relative to the coordinates after
1763                                    the modifiers that support deform matrices (defcos) */
1764                                 if(totleft > 0) {
1765                                         mappedcos= get_crazy_mapped_editverts();
1766                                         quats= MEM_mallocN( (t->total)*sizeof(float)*4, "crazy quats");
1767                                         set_crazyspace_quats((float*)defcos, mappedcos, quats);
1768                                         if(mappedcos)
1769                                                 MEM_freeN(mappedcos);
1770                                 }
1771
1772                                 if(defcos)
1773                                         MEM_freeN(defcos);
1774                         }
1775                 }
1776         }
1777         
1778         /* find out which half we do */
1779         if(mirror) {
1780                 for (eve=em->verts.first; eve; eve=eve->next) {
1781                         if(eve->h==0 && eve->f1 && eve->co[0]!=0.0f) {
1782                                 if(eve->co[0]<0.0f)
1783                                         mirror = -1;
1784                                 break;
1785                         }
1786                 }
1787         }
1788         
1789         for (a=0, eve=em->verts.first; eve; eve=eve->next, a++) {
1790                 if(eve->h==0) {
1791                         if(propmode || eve->f1) {
1792                                 VertsToTransData(tob, eve);
1793
1794                                 if(eve->f1) tob->flag |= TD_SELECTED;
1795                                 if(propmode) {
1796                                         if (eve->f2) {
1797                                                 float vec[3];
1798                                                 VECCOPY(vec, E_VEC(eve));
1799                                                 Mat3MulVecfl(mtx, vec);
1800                                                 tob->dist= VecLength(vec);
1801                                         }
1802                                         else {
1803                                                 tob->flag |= TD_NOTCONNECTED;
1804                                                 tob->dist = MAXFLOAT;
1805                                         }
1806                                 }
1807                                 
1808                                 /* CrazySpace */
1809                                 if(defmats || (quats && eve->tmp.p)) {
1810                                         float mat[3][3], imat[3][3], qmat[3][3];
1811                                         
1812                                         /* use both or either quat and defmat correction */
1813                                         if(quats && eve->tmp.f) {
1814                                                 QuatToMat3(eve->tmp.p, qmat);
1815
1816                                                 if(defmats)
1817                                                         Mat3MulSerie(mat, mtx, qmat, defmats[a],
1818                                                                 NULL, NULL, NULL, NULL, NULL);
1819                                                 else
1820                                                         Mat3MulMat3(mat, mtx, qmat);
1821                                         }
1822                                         else
1823                                                 Mat3MulMat3(mat, mtx, defmats[a]);
1824
1825                                         Mat3Inv(imat, mat);
1826                                         
1827                                         Mat3CpyMat3(tob->smtx, imat);
1828                                         Mat3CpyMat3(tob->mtx, mat);
1829                                 }
1830                                 else {
1831                                         Mat3CpyMat3(tob->smtx, smtx);
1832                                         Mat3CpyMat3(tob->mtx, mtx);
1833                                 }
1834                                 
1835                                 /* Mirror? */
1836                                 if( (mirror>0 && tob->iloc[0]>0.0f) || (mirror<0 && tob->iloc[0]<0.0f)) {
1837                                         EditVert *vmir= editmesh_get_x_mirror_vert(G.obedit, tob->iloc);        /* initializes octree on first call */
1838                                         if(vmir!=eve) tob->tdmir= vmir;
1839                                 }
1840                                 tob++;
1841                         }
1842                 }       
1843         }
1844         if (propmode) {
1845                 MEM_freeN(vectors);
1846                 MEM_freeN(nears);
1847         }
1848         /* crazy space free */
1849         if(quats)
1850                 MEM_freeN(quats);
1851         if(defmats)
1852                 MEM_freeN(defmats);
1853 }
1854
1855 /* ********************* UV ****************** */
1856
1857 static void UVsToTransData(TransData *td, TransData2D *td2d, float *uv, int selected)
1858 {
1859         float aspx, aspy;
1860
1861         transform_aspect_ratio_tface_uv(&aspx, &aspy);
1862
1863         /* uv coords are scaled by aspects. this is needed for rotations and
1864            proportional editing to be consistent with the stretchted uv coords
1865            that are displayed. this also means that for display and numinput,
1866            and when the the uv coords are flushed, these are converted each time */
1867         td2d->loc[0] = uv[0]*aspx;
1868         td2d->loc[1] = uv[1]*aspy;
1869         td2d->loc[2] = 0.0f;
1870         td2d->loc2d = uv;
1871
1872         td->flag = 0;
1873         td->loc = td2d->loc;
1874         VECCOPY(td->center, td->loc);
1875         VECCOPY(td->iloc, td->loc);
1876
1877         memset(td->axismtx, 0, sizeof(td->axismtx));
1878         td->axismtx[2][2] = 1.0f;
1879
1880         td->ext= NULL; td->tdi= NULL; td->val= NULL;
1881
1882         if(selected) {
1883                 td->flag |= TD_SELECTED;
1884                 td->dist= 0.0;
1885         }
1886         else
1887                 td->dist= MAXFLOAT;
1888         
1889         Mat3One(td->mtx);
1890         Mat3One(td->smtx);
1891 }
1892
1893 static void createTransUVs(TransInfo *t)
1894 {
1895         TransData *td = NULL;
1896         TransData2D *td2d = NULL;
1897         MTFace *tf;
1898         int count=0, countsel=0;
1899         int propmode = t->flag & T_PROP_EDIT;
1900         
1901         EditMesh *em = G.editMesh;
1902         EditFace *efa;
1903         
1904         if(is_uv_tface_editing_allowed()==0) return;
1905
1906         /* count */
1907         for (efa= em->faces.first; efa; efa= efa->next) {
1908                 tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1909                 if (simaFaceDraw_Check(efa, tf)) {
1910                         if (simaUVSel_Check(efa, tf, 0)) countsel++; 
1911                         if (simaUVSel_Check(efa, tf, 1)) countsel++; 
1912                         if (simaUVSel_Check(efa, tf, 2)) countsel++; 
1913                         if (efa->v4 && simaUVSel_Check(efa, tf, 3)) countsel++;
1914                         if(propmode)
1915                                 count += (efa->v4)? 4: 3;
1916                 }
1917         }
1918
1919         /* note: in prop mode we need at least 1 selected */
1920         if (countsel==0) return;
1921         
1922         t->total= (propmode)? count: countsel;
1923         t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(UV Editing)");
1924         /* for each 2d uv coord a 3d vector is allocated, so that they can be
1925            treated just as if they were 3d verts */
1926         t->data2d= MEM_callocN(t->total*sizeof(TransData2D), "TransObData2D(UV Editing)");
1927
1928         if(G.sima->flag & SI_CLIP_UV)
1929                 t->flag |= T_CLIP_UV;
1930
1931         td= t->data;
1932         td2d= t->data2d;
1933         for (efa= em->faces.first; efa; efa= efa->next) {
1934                 tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
1935                 if (simaFaceDraw_Check(efa, tf)) {
1936                         if(propmode || simaUVSel_Check(efa, tf, 0))
1937                                 UVsToTransData(td++, td2d++, tf->uv[0], simaUVSel_Check(efa, tf, 0));
1938                         if(propmode || simaUVSel_Check(efa, tf, 1))
1939                                 UVsToTransData(td++, td2d++, tf->uv[1], simaUVSel_Check(efa, tf, 1));
1940                         if(propmode || simaUVSel_Check(efa, tf, 2))
1941                                 UVsToTransData(td++, td2d++, tf->uv[2], simaUVSel_Check(efa, tf, 2));
1942
1943                         if(efa->v4 && (propmode || simaUVSel_Check(efa, tf, 3)))
1944                                 UVsToTransData(td++, td2d++, tf->uv[3], simaUVSel_Check(efa, tf, 3));
1945                 }
1946         }
1947
1948         if (G.sima->flag & SI_LIVE_UNWRAP)
1949                 unwrap_lscm_live_begin();
1950 }
1951
1952 void flushTransUVs(TransInfo *t)
1953 {
1954         TransData2D *td;
1955         int a, width, height;
1956         Object *ob= OBACT;
1957         EditMesh *em = G.editMesh;
1958         float aspx, aspy, invx, invy;
1959
1960         transform_aspect_ratio_tface_uv(&aspx, &aspy);
1961         transform_width_height_tface_uv(&width, &height);
1962         invx= 1.0f/aspx;
1963         invy= 1.0f/aspy;
1964
1965         /* flush to 2d vector from internally used 3d vector */
1966         for(a=0, td= t->data2d; a<t->total; a++, td++) {
1967                 td->loc2d[0]= td->loc[0]*invx;
1968                 td->loc2d[1]= td->loc[1]*invy;
1969                 
1970                 if((G.sima->flag & SI_PIXELSNAP) && (t->state != TRANS_CANCEL)) {
1971                         td->loc2d[0]= floor(width*td->loc2d[0] + 0.5f)/width;
1972                         td->loc2d[1]= floor(height*td->loc2d[1] + 0.5f)/height;
1973                 }
1974         }
1975
1976         /* always call this, also for cancel (it transforms non-selected vertices...) */
1977         if((G.sima->flag & SI_BE_SQUARE))
1978                 be_square_tface_uv(em);
1979
1980         /* this is overkill if G.sima->lock is not set, but still needed */
1981         object_uvs_changed(ob);
1982 }
1983
1984 int clipUVTransform(TransInfo *t, float *vec, int resize)
1985 {
1986         TransData *td;
1987         int a, clipx=1, clipy=1;
1988         float aspx, aspy, min[2], max[2];
1989
1990         transform_aspect_ratio_tface_uv(&aspx, &aspy);
1991         min[0]= min[1]= 0.0f;
1992         max[0]= aspx; max[1]= aspy;
1993
1994         for(a=0, td= t->data; a<t->total; a++, td++) {
1995                 DO_MINMAX2(td->loc, min, max);
1996         }
1997
1998         if(resize) {
1999                 if(min[0] < 0.0f && t->center[0] > 0.0f && t->center[0] < aspx*0.5f)
2000                         vec[0] *= t->center[0]/(t->center[0] - min[0]);
2001                 else if(max[0] > aspx && t->center[0] < aspx)
2002                         vec[0] *= (t->center[0] - aspx)/(t->center[0] - max[0]);
2003                 else
2004                         clipx= 0;
2005
2006                 if(min[1] < 0.0f && t->center[1] > 0.0f && t->center[1] < aspy*0.5f)
2007                         vec[1] *= t->center[1]/(t->center[1] - min[1]);
2008                 else if(max[1] > aspy && t->center[1] < aspy)
2009                         vec[1] *= (t->center[1] - aspy)/(t->center[1] - max[1]);
2010                 else
2011                         clipy= 0;
2012         }
2013         else {
2014                 if(min[0] < 0.0f)
2015                         vec[0] -= min[0];
2016                 else if(max[0] > aspx)
2017                         vec[0] -= max[0]-aspx;
2018                 else
2019                         clipx= 0;
2020
2021                 if(min[1] < 0.0f)
2022                         vec[1] -= min[1];
2023                 else if(max[1] > aspy)
2024                         vec[1] -= max[1]-aspy;
2025                 else
2026                         clipy= 0;
2027         }       
2028
2029         return (clipx || clipy);
2030 }
2031
2032 /* ********************* IPO EDITOR ************************* */
2033
2034 /* for IPO Editor transform - but actual creation of transform structures is not performed here
2035  * due to bad globals that would need to be imported specially for this
2036  */
2037 static void createTransIpoData(TransInfo *t)
2038 {
2039         /* in editipo.c due to some globals that are defined in that file... */
2040         make_ipo_transdata(t);
2041 }
2042
2043 /* this function is called on recalcData to apply the transforms applied
2044  * to the transdata on to the actual keyframe data 
2045  */
2046 void flushTransIpoData(TransInfo *t)
2047 {
2048         TransData2D *td;
2049         int a;
2050         
2051         /* flush to 2d vector from internally used 3d vector */
2052         for (a=0, td= t->data2d; a<t->total; a++, td++) {
2053                 /* we need to unapply the nla-scaling from the time in some situations */
2054                 if (NLA_IPO_SCALED)
2055                         td->loc2d[0]= get_action_frame(OBACT, td->loc[0]);
2056                 else
2057                         td->loc2d[0]= td->loc[0];
2058                 
2059                 /* when the icu that point comes from is a bitflag holder, don't allow adjusting values */
2060                 if ((t->data[a].flag & TD_TIMEONLY)==0)
2061                         td->loc2d[1]= td->loc[1];
2062         }
2063 }
2064
2065 /* ********************* ACTION/NLA EDITOR ****************** */
2066
2067 /* This function tests if a point is on the "mouse" side of the cursor/frame-marking */
2068 static short FrameOnMouseSide(char side, float frame, float cframe)
2069 {
2070         /* both sides, so it doesn't matter */
2071         if (side == 'B') return 1;
2072         
2073         /* only on the named side */
2074         if (side == 'R')
2075                 return (frame >= cframe) ? 1 : 0;
2076         else
2077                 return (frame <= cframe) ? 1 : 0;
2078 }
2079
2080 /* fully select selected beztriples, but only include if it's on the right side of cfra */
2081 static int count_ipo_keys(Ipo *ipo, char side, float cfra)
2082 {
2083         IpoCurve *icu;
2084         BezTriple *bezt;
2085         int i, count = 0;
2086         
2087         if (ipo == NULL)
2088                 return count;
2089         
2090         /* only include points that occur on the right side of cfra */
2091         for (icu= ipo->curve.first; icu; icu= icu->next) {
2092                 for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
2093                         if (bezt->f2) {
2094                                 /* fully select the other two keys */
2095                                 bezt->f1 |= 1;
2096                                 bezt->f3 |= 1;
2097                                 
2098                                 /* increment by 3, as there are 3 points (3 * x-coordinates) that need transform */
2099                                 if (FrameOnMouseSide(side, bezt->vec[1][0], cfra))
2100                                         count += 3;
2101                         }
2102                 }
2103         }
2104         
2105         return count;
2106 }
2107
2108 /* This function assigns the information to transdata */
2109 static void TimeToTransData(TransData *td, float *time, Object *ob)
2110 {
2111         /* memory is calloc'ed, so that should zero everything nicely for us */
2112         td->val = time;
2113         td->ival = *(time);
2114         
2115         /* store the Object where this keyframe exists as a keyframe of the 
2116          * active action as td->ob. Usually, this member is only used for constraints 
2117          * drawing
2118          */
2119         td->ob= ob;
2120 }
2121
2122 /* This function advances the address to which td points to, so it must return
2123  * the new address so that the next time new transform data is added, it doesn't
2124  * overwrite the existing ones...  i.e.   td = IpoToTransData(td, ipo, ob, side, cfra);
2125  *
2126  * The 'side' argument is needed for the extend mode. 'B' = both sides, 'R'/'L' mean only data
2127  * on the named side are used. 
2128  */
2129 static TransData *IpoToTransData(TransData *td, Ipo *ipo, Object *ob, char side, float cfra)
2130 {
2131         IpoCurve *icu;
2132         BezTriple *bezt;
2133         int i;
2134         
2135         if (ipo == NULL)
2136                 return td;
2137         
2138         for (icu= ipo->curve.first; icu; icu= icu->next) {
2139                 for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
2140                         /* only add selected keyframes (for now, proportional edit is not enabled) */
2141                         if (BEZSELECTED(bezt)) {
2142                                 /* only add if on the right 'side' of the current frame */
2143                                 if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) {
2144                                         /* each control point needs to be added separetely */
2145                                         TimeToTransData(td, bezt->vec[0], ob);
2146                                         td++;
2147                                         
2148                                         TimeToTransData(td, bezt->vec[1], ob);
2149                                         td++;
2150                                         
2151                                         TimeToTransData(td, bezt->vec[2], ob);
2152                                         td++;
2153                                 }
2154                         }       
2155                 }
2156         }
2157         
2158         return td;
2159 }
2160
2161 static void createTransActionData(TransInfo *t)
2162 {
2163         TransData *td = NULL;
2164         Object *ob= NULL;
2165         
2166         ListBase act_data = {NULL, NULL};
2167         bActListElem *ale;
2168         void *data;
2169         short datatype;
2170         int filter;
2171         
2172         int count=0;
2173         float cfra;
2174         char side;
2175         
2176         /* determine what type of data we are operating on */
2177         data = get_action_context(&datatype);
2178         if (data == NULL) return;
2179         
2180         /* filter data */
2181         filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
2182         actdata_filter(&act_data, filter, data, datatype);
2183         
2184         /* is the action scaled? if so, the it should belong to the active object */
2185         if (NLA_ACTION_SCALED)
2186                 ob= OBACT;
2187                 
2188         /* which side of the current frame should be allowed */
2189         if (t->mode == TFM_TIME_EXTEND) {
2190                 /* only side on which mouse is gets transformed */
2191                 float xmouse, ymouse;
2192                 
2193                 areamouseco_to_ipoco(G.v2d, t->imval, &xmouse, &ymouse);
2194                 side = (xmouse > CFRA) ? 'R' : 'L';
2195         }
2196         else {
2197                 /* normal transform - both sides of current frame are considered */
2198                 side = 'B';
2199         }
2200         
2201         /* convert current-frame to action-time (slightly less accurate, espcially under
2202          * higher scaling ratios, but is faster than converting all points) 
2203          */
2204         if (ob) 
2205                 cfra = get_action_frame(ob, CFRA);
2206         else
2207                 cfra = CFRA;
2208         
2209         /* loop 1: fully select ipo-keys and count how many BezTriples are selected */
2210         for (ale= act_data.first; ale; ale= ale->next)
2211                 count += count_ipo_keys(ale->key_data, side, cfra);
2212         
2213         /* stop if trying to build list if nothing selected */
2214         if (count == 0) {
2215                 /* cleanup temp list */
2216                 BLI_freelistN(&act_data);
2217                 return;
2218         }
2219         
2220         /* allocate memory for data */
2221         t->total= count;
2222         t->data= MEM_callocN(t->total*sizeof(TransData), "TransData(Action Editor)");
2223         if (t->mode == TFM_TIME_SLIDE)
2224                 t->customData= MEM_callocN(sizeof(float)*2, "TimeSlide Min/Max");
2225         
2226         td= t->data;
2227         /* loop 2: build transdata array */
2228         for (ale= act_data.first; ale; ale= ale->next) {
2229                 Ipo *ipo= (Ipo *)ale->key_data;
2230                 
2231                 td= IpoToTransData(td, ipo, ob, side, cfra);
2232         }
2233         
2234         /* check if we're supposed to be setting minx/maxx for TimeSlide */
2235         if (t->mode == TFM_TIME_SLIDE) {
2236                 float min = 0, max = 0;
2237                 int i;
2238                 
2239                 td= (t->data + 1);
2240                 for (i=1; i < count; i+=3, td+=3) {
2241                         if (min > *(td->val)) min= *(td->val);
2242                         if (max < *(td->val)) max= *(td->val);
2243                 }
2244                 
2245                 /* minx/maxx values used by TimeSlide are stored as a 
2246                  * calloced 2-float array in t->customData. This gets freed
2247                  * in postTrans (T_FREE_CUSTOMDATA). 
2248                  */
2249                 *((float *)(t->customData)) = min;
2250                 *((float *)(t->customData) + 1) = max;
2251         }
2252         
2253         /* cleanup temp list */
2254         BLI_freelistN(&act_data);
2255 }
2256
2257 static void createTransNlaData(TransInfo *t)
2258 {
2259         Base *base;
2260         bActionStrip *strip;
2261         bActionChannel *achan;
2262         bConstraintChannel *conchan;
2263         
2264         TransData *td = NULL;
2265         int count=0, i;
2266         float cfra;
2267         char side;
2268         
2269         /* which side of the current frame should be allowed */
2270         if (t->mode == TFM_TIME_EXTEND) {
2271                 /* only side on which mouse is gets transformed */
2272                 float xmouse, ymouse;
2273                 
2274                 areamouseco_to_ipoco(G.v2d, t->imval, &xmouse, &ymouse);
2275                 side = (xmouse > CFRA) ? 'R' : 'L';
2276         }
2277         else {
2278                 /* normal transform - both sides of current frame are considered */
2279                 side = 'B';
2280         }
2281         
2282         /* Ensure that partial selections result in beztriple selections */
2283         for (base=G.scene->base.first; base; base=base->next) {
2284                 /* Check object ipos */
2285                 i= count_ipo_keys(base->object->ipo, side, CFRA);
2286                 if (i) base->flag |= BA_HAS_RECALC_OB;
2287                 count += i;
2288                 
2289                 /* Check object constraint ipos */
2290                 for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next)
2291                         count += count_ipo_keys(conchan->ipo, side, CFRA);                      
2292                 
2293                 /* skip actions and nlastrips if object is collapsed */
2294                 if (base->object->nlaflag & OB_NLA_COLLAPSED)
2295                         continue;
2296                 
2297                 /* Check action ipos */
2298                 if (base->object->action) {
2299                         /* exclude if strip is selected too */
2300                         for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
2301                                 if (strip->flag & ACTSTRIP_SELECT)
2302                                         if (strip->act == base->object->action)
2303                                                 break;
2304                         }
2305                         if (strip==NULL) {
2306                                 cfra = get_action_frame(base->object, CFRA);
2307                                 
2308                                 for (achan=base->object->action->chanbase.first; achan; achan=achan->next) {
2309                                         if (EDITABLE_ACHAN(achan)) {
2310                                                 i= count_ipo_keys(achan->ipo, side, cfra);
2311                                                 if (i) base->flag |= BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA;
2312                                                 count += i;
2313                                                 
2314                                                 /* Check action constraint ipos */
2315                                                 if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
2316                                                         for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
2317                                                                 if (EDITABLE_CONCHAN(conchan))
2318                                                                         count += count_ipo_keys(conchan->ipo, side, cfra);
2319                                                         }
2320                                                 }
2321                                         }
2322                                 }
2323                         }               
2324                 }
2325                 
2326                 /* Check nlastrips */
2327                 for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
2328                         if (strip->flag & ACTSTRIP_SELECT) {
2329                                 base->flag |= BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA;
2330                                 
2331                                 if (FrameOnMouseSide(side, strip->start, CFRA)) count++;
2332                                 if (FrameOnMouseSide(side, strip->end, CFRA)) count++;
2333                         }
2334                 }
2335         }
2336         
2337         /* If nothing is selected, bail out */
2338         if (count == 0)
2339                 return;
2340         
2341         /* allocate memory for data */
2342         t->total= count;
2343         t->data= MEM_callocN(t->total*sizeof(TransData), "TransData (NLA Editor)");
2344         
2345         /* build the transdata structure */
2346         td= t->data;
2347         for (base=G.scene->base.first; base; base=base->next) {
2348                 /* Manipulate object ipos */
2349                 /*      - no scaling of keyframe times is allowed here  */
2350                 td= IpoToTransData(td, base->object->ipo, NULL, side, CFRA);
2351                 
2352                 /* Manipulate object constraint ipos */
2353                 /*      - no scaling of keyframe times is allowed here  */
2354                 for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next)
2355                         td= IpoToTransData(td, conchan->ipo, NULL, side, CFRA);
2356                 
2357                 /* skip actions and nlastrips if object collapsed */
2358                 if (base->object->nlaflag & OB_NLA_COLLAPSED)
2359                         continue;
2360                         
2361                 /* Manipulate action ipos */
2362                 if (base->object->action) {
2363                         /* exclude if strip that active action belongs to is selected too */
2364                         for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
2365                                 if (strip->flag & ACTSTRIP_SELECT)
2366                                         if (strip->act == base->object->action)
2367                                                 break;
2368                         }
2369                         
2370                         /* can include if no strip found */
2371                         if (strip==NULL) {
2372                                 cfra = get_action_frame(base->object, CFRA);
2373                                 
2374                                 for (achan=base->object->action->chanbase.first; achan; achan=achan->next) {
2375                                         if (EDITABLE_ACHAN(achan)) {
2376                                                 td= IpoToTransData(td, achan->ipo, base->object, side, cfra);
2377                                                 
2378                                                 /* Manipulate action constraint ipos */
2379                                                 if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
2380                                                         for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
2381                                                                 if (EDITABLE_CONCHAN(conchan))
2382                                                                         td= IpoToTransData(td, conchan->ipo, base->object, side, cfra);
2383                                                         }
2384                                                 }
2385                                         }
2386                                 }
2387                         }
2388                 }
2389                 
2390                 /* Manipulate nlastrips */
2391                 for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
2392                         if (strip->flag & ACTSTRIP_SELECT) {
2393                                 /* first TransData is the start, second is the end */
2394                                 if (FrameOnMouseSide(side, strip->start, CFRA)) {
2395                                         td->val = &strip->start;
2396                                         td->ival = strip->start;
2397                                         td++;
2398                                 }
2399                                 if (FrameOnMouseSide(side, strip->end, CFRA)) {
2400                                         td->val = &strip->end;
2401                                         td->ival = strip->end;
2402                                         td++;
2403                                 }
2404                         }
2405                 }
2406         }
2407 }
2408
2409 /* **************** IpoKey stuff, for Object TransData ********** */
2410
2411 /* storage of bezier triple. thats why -3 and +3! */
2412 static void set_tdi_old(float *old, float *poin)
2413 {
2414         old[0]= *(poin);
2415         old[3]= *(poin-3);
2416         old[6]= *(poin+3);
2417 }
2418
2419 /* while transforming */
2420 void add_tdi_poin(float *poin, float *old, float delta)
2421 {
2422         if(poin) {
2423                 poin[0]= old[0]+delta;
2424                 poin[-3]= old[3]+delta;
2425                 poin[3]= old[6]+delta;
2426         }
2427 }
2428
2429 /* fill ipokey transdata with old vals and pointers */
2430 static void ipokey_to_transdata(IpoKey *ik, TransData *td)
2431 {
2432         extern int ob_ar[];             // blenkernel ipo.c
2433         TransDataIpokey *tdi= td->tdi;
2434         BezTriple *bezt;
2435         int a, delta= 0;
2436         
2437         td->val= NULL;  // is read on ESC
2438         
2439         for(a=0; a<OB_TOTIPO; a++) {
2440                 if(ik->data[a]) {
2441                         bezt= ik->data[a];
2442                         
2443                         switch( ob_ar[a] ) {
2444                                 case OB_LOC_X:
2445                                 case OB_DLOC_X:
2446                                         tdi->locx= &(bezt->vec[1][1]); break;
2447                                 case OB_LOC_Y:
2448                                 case OB_DLOC_Y:
2449                                         tdi->locy= &(bezt->vec[1][1]); break;
2450                                 case OB_LOC_Z:
2451                                 case OB_DLOC_Z:
2452                                         tdi->locz= &(bezt->vec[1][1]); break;
2453                                         
2454                                 case OB_DROT_X:
2455                                         delta= 1;
2456                                 case OB_ROT_X:
2457                                         tdi->rotx= &(bezt->vec[1][1]); break;
2458                                 case OB_DROT_Y:
2459                                         delta= 1;
2460                                 case OB_ROT_Y:
2461                                         tdi->roty= &(bezt->vec[1][1]); break;
2462                                 case OB_DROT_Z:
2463                                         delta= 1;
2464                                 case OB_ROT_Z:
2465                                         tdi->rotz= &(bezt->vec[1][1]); break;
2466                                         
2467                                 case OB_SIZE_X:
2468                                 case OB_DSIZE_X:
2469                                         tdi->sizex= &(bezt->vec[1][1]); break;
2470                                 case OB_SIZE_Y:
2471                                 case OB_DSIZE_Y:
2472                                         tdi->sizey= &(bezt->vec[1][1]); break;
2473                                 case OB_SIZE_Z:
2474                                 case OB_DSIZE_Z:
2475                                         tdi->sizez= &(bezt->vec[1][1]); break;          
2476                         }       
2477                 }
2478         }
2479         
2480         /* oldvals for e.g. undo */
2481         if(tdi->locx) set_tdi_old(tdi->oldloc, tdi->locx);
2482         if(tdi->locy) set_tdi_old(tdi->oldloc+1, tdi->locy);
2483         if(tdi->locz) set_tdi_old(tdi->oldloc+2, tdi->locz);
2484         
2485         /* remember, for mapping curves ('1'=10 degrees)  */
2486         if(tdi->rotx) set_tdi_old(tdi->oldrot, tdi->rotx);
2487         if(tdi->roty) set_tdi_old(tdi->oldrot+1, tdi->roty);
2488         if(tdi->rotz) set_tdi_old(tdi->oldrot+2, tdi->rotz);
2489         
2490         /* this is not allowed to be dsize! */
2491         if(tdi->sizex) set_tdi_old(tdi->oldsize, tdi->sizex);
2492         if(tdi->sizey) set_tdi_old(tdi->oldsize+1, tdi->sizey);
2493         if(tdi->sizez) set_tdi_old(tdi->oldsize+2, tdi->sizez);
2494         
2495         tdi->flag= TOB_IPO;
2496         if(delta) tdi->flag |= TOB_IPODROT;
2497 }
2498
2499
2500 /* *************************** Object Transform data ******************* */
2501
2502 /* Little helper function for ObjectToTransData used to give certain
2503  * constraints (ChildOf, FollowPath, and others that may be added)
2504  * inverse corrections for transform, so that they aren't in CrazySpace.
2505  * These particular constraints benefit from this, but others don't, hence
2506  * this semi-hack ;-)    - Aligorith
2507  */
2508 static short constraints_list_needinv(TransInfo *t, ListBase *list)
2509 {
2510         bConstraint *con;
2511         
2512         /* loop through constraints, checking if there's one of the mentioned 
2513          * constraints needing special crazyspace corrections
2514          */
2515         if (list) {
2516                 for (con= list->first; con; con=con->next) {
2517                         /* only consider constraint if it is enabled, and has influence on result */
2518                         if ((con->flag & CONSTRAINT_DISABLE)==0 && (con->enforce!=0.0)) {
2519                                 /* (affirmative) returns for specific constraints here... */
2520                                         /* constraints that require this regardless  */
2521                                 if (con->type == CONSTRAINT_TYPE_CHILDOF) return 1;
2522                                 if (con->type == CONSTRAINT_TYPE_FOLLOWPATH) return 1;
2523                                 if (con->type == CONSTRAINT_TYPE_CLAMPTO) return 1;
2524                                 
2525                                         /* constraints that require this only under special conditions */
2526                                 if (con->type == CONSTRAINT_TYPE_ROTLIKE) {
2527                                         /* CopyRot constraint only does this when rotating, and offset is on */
2528                                         bRotateLikeConstraint *data = (bRotateLikeConstraint *)con->data;
2529                                         
2530                                         if ((data->flag & ROTLIKE_OFFSET) && (t->mode == TFM_ROTATION))
2531                                                 return 1;
2532                                 }
2533                         }
2534                 }
2535         }
2536         
2537         /* no appropriate candidates found */
2538         return 0;
2539 }
2540
2541 /* transcribe given object into TransData for Transforming */
2542 static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) 
2543 {
2544         Object *track;
2545         ListBase fakecons = {NULL, NULL};
2546         float obmtx[3][3];
2547         short constinv;
2548
2549         /* axismtx has the real orientation */
2550         Mat3CpyMat4(td->axismtx, ob->obmat);
2551         Mat3Ortho(td->axismtx);
2552
2553         /* hack: tempolarily disable tracking and/or constraints when getting 
2554          *              object matrix, if tracking is on, or if constraints don't need
2555          *              inverse correction to stop it from screwing up space conversion
2556          *              matrix later
2557          */
2558         constinv= constraints_list_needinv(t, &ob->constraints);
2559         if (ob->track || constinv==0) {
2560                 track= ob->track;
2561                 ob->track= NULL;
2562                 
2563                 if (constinv == 0) {
2564                         fakecons.first = ob->constraints.first;
2565                         fakecons.last = ob->constraints.last;
2566                         ob->constraints.first = ob->constraints.last = NULL;
2567                 }
2568                 
2569                 where_is_object(ob);
2570                 
2571                 if (constinv == 0) {
2572                         ob->constraints.first = fakecons.first;
2573                         ob->constraints.last = fakecons.last;
2574                 }
2575                 
2576                 ob->track= track;
2577         }
2578         else
2579                 where_is_object(ob);
2580
2581         td->ob = ob;
2582
2583         td->loc = ob->loc;
2584         VECCOPY(td->iloc, td->loc);
2585         
2586         td->ext->rot = ob->rot;
2587         VECCOPY(td->ext->irot, ob->rot);
2588         VECCOPY(td->ext->drot, ob->drot);
2589         
2590         td->ext->size = ob->size;
2591         VECCOPY(td->ext->isize, ob->size);
2592         VECCOPY(td->ext->dsize, ob->dsize);
2593
2594         VECCOPY(td->center, ob->obmat[3]);
2595
2596         /* is there a need to set the global<->data space conversion matrices? */
2597         if (ob->parent || constinv) {
2598                 float totmat[3][3], obinv[3][3];
2599                 
2600                 /* Get the effect of parenting, and/or certain constraints.
2601                  * NOTE: some Constraints, and also Tracking should never get this
2602                  *              done, as it doesn't work well.
2603                  */
2604                 object_to_mat3(ob, obmtx);
2605                 Mat3CpyMat4(totmat, ob->obmat);
2606                 Mat3Inv(obinv, totmat);
2607                 Mat3MulMat3(td->smtx, obmtx, obinv);
2608                 Mat3Inv(td->mtx, td->smtx);
2609         }
2610         else {
2611                 /* no conversion to/from dataspace */
2612                 Mat3One(td->smtx);
2613                 Mat3One(td->mtx);
2614         }
2615 #ifdef WITH_VERSE
2616         if(ob->vnode) {
2617                 td->verse = (void*)ob;
2618                 td->flag |= TD_VERSE_OBJECT;
2619         }
2620         else
2621                 td->flag &= ~TD_VERSE_OBJECT;
2622 #endif
2623 }
2624
2625
2626 /* sets flags in Bases to define whether they take part in transform */
2627 /* it deselects Bases, so we have to call the clear function always after */
2628 static void set_trans_object_base_flags(TransInfo *t)
2629 {
2630         /*
2631          if Base selected and has parent selected:
2632          base->flag= BA_WAS_SEL
2633          */
2634         Base *base;
2635         
2636         /* makes sure base flags and object flags are identical */
2637         copy_baseflags();
2638         
2639         /* handle pending update events, otherwise they got copied below */
2640         for (base= FIRSTBASE; base; base= base->next) {
2641                 if(base->object->recalc) 
2642                         object_handle_update(base->object);
2643         }
2644         
2645         for (base= FIRSTBASE; base; base= base->next) {
2646                 base->flag &= ~BA_WAS_SEL;
2647                 
2648                 if(TESTBASELIB(base)) {
2649                         Object *ob= base->object;
2650                         Object *parsel= ob->parent;
2651                         
2652                         /* if parent selected, deselect */
2653                         while(parsel) {
2654                                 if(parsel->flag & SELECT) break;
2655                                 parsel= parsel->parent;
2656                         }
2657                         
2658                         if(parsel) {
2659                                 base->flag &= ~SELECT;
2660                                 base->flag |= BA_WAS_SEL;
2661                         }
2662                         /* used for flush, depgraph will change recalcs if needed :) */
2663                         ob->recalc |= OB_RECALC_OB;
2664                 }
2665         }
2666         /* all recalc flags get flushed to all layers, so a layer flip later on works fine */
2667         DAG_scene_flush_update(G.scene, -1);
2668         
2669         /* and we store them temporal in base (only used for transform code) */
2670         /* this because after doing updates, the object->recalc is cleared */
2671         for (base= FIRSTBASE; base; base= base->next) {
2672                 if(base->object->recalc & OB_RECALC_OB)
2673                         base->flag |= BA_HAS_RECALC_OB;
2674                 if(base->object->recalc & OB_RECALC_DATA)
2675                         base->flag |= BA_HAS_RECALC_DATA;
2676         }
2677 }
2678
2679 static void clear_trans_object_base_flags(void)
2680 {
2681         Base *base;
2682         
2683         base= FIRSTBASE;
2684         while(base) {
2685                 if(base->flag & BA_WAS_SEL) base->flag |= SELECT;
2686                 base->flag &= ~(BA_WAS_SEL|BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA|BA_DO_IPO);
2687                 
2688                 base = base->next;
2689         }
2690 }
2691
2692 /* auto-keyframing feature - for objects 
2693  *      tmode: should be a transform mode 
2694  */
2695 void autokeyframe_ob_cb_func(Object *ob, int tmode)
2696 {
2697         IpoCurve *icu;
2698         char *actname="";
2699         
2700         if (G.flags & G_RECORDKEYS) {
2701                 if (ob->ipoflag & OB_ACTION_OB)
2702                         actname= "Object";
2703                 
2704                 if (U.uiflag & USER_KEYINSERTAVAI) {
2705                         if (ob->ipo || ob->action) {
2706                                 ID *id= (ID *)(ob);
2707                                 
2708                                 if (ob->ipo) {
2709                                         icu= ob->ipo->curve.first;
2710                                 }
2711                                 else {
2712                                         bActionChannel *achan;
2713                                         achan= get_action_channel(ob->action, actname);
2714                                         
2715                                         if (achan && achan->ipo)
2716                                                 icu= achan->ipo->curve.first;
2717                                         else
2718                                                 icu= NULL;
2719                                 }
2720                                 
2721                                 while (icu) {
2722                                         icu->flag &= ~IPO_SELECT;
2723                                         if (U.uiflag & USER_KEYINSERTNEED)
2724                                                 insertkey_smarter(id, ID_OB, actname, NULL, icu->adrcode);
2725                                         else
2726                                                 insertkey(id, ID_OB, actname, NULL, icu->adrcode, 0);
2727                                         icu= icu->next;
2728                                 }
2729                         }
2730                 }
2731                 else if (U.uiflag & USER_KEYINSERTNEED) {
2732                         short doLoc=0, doRot=0, doScale=0;
2733                         
2734                         /* filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D) */
2735                         if (tmode == TFM_TRANSLATION) {
2736                                 doLoc = 1;
2737                         }
2738                         else if (tmode == TFM_ROTATION) {
2739                                 if (G.vd->around == V3D_ACTIVE) {
2740                                         if (ob != OBACT)
2741                                                 doLoc = 1;
2742                                 }
2743                                 else if (G.vd->around == V3D_CURSOR)
2744                                         doLoc = 1;      
2745                                 
2746                                 if ((G.vd->flag & V3D_ALIGN)==0) 
2747                                         doRot = 1;
2748                         }
2749                         else if (tmode == TFM_RESIZE) {
2750                                 if (G.vd->around == V3D_ACTIVE) {
2751                                         if (ob != OBACT)
2752                                                 doLoc = 1;
2753                                 }
2754                                 else if (G.vd->around == V3D_CURSOR)
2755                                         doLoc = 1;      
2756                                 
2757                                 if ((G.vd->flag & V3D_ALIGN)==0)
2758                                         doScale = 1;
2759                         }
2760                         
2761                         if (doLoc) {
2762                                 insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_LOC_X);
2763                                 insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_LOC_Y);
2764                                 insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_LOC_Z);
2765                         }
2766                         if (doRot) {
2767                                 insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_ROT_X);
2768                                 insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_ROT_Y);
2769                                 insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_ROT_Z);
2770                         }
2771                         if (doScale) {
2772                                 insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_SIZE_X);
2773                                 insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_SIZE_Y);
2774                                 insertkey_smarter(&ob->id, ID_OB, actname, NULL, OB_SIZE_Z);
2775                         }
2776                 }
2777                 else {
2778                         insertkey(&ob->id, ID_OB, actname, NULL, OB_ROT_X, 0);
2779                         insertkey(&ob->id, ID_OB, actname, NULL, OB_ROT_Y, 0);
2780                         insertkey(&ob->id, ID_OB, actname, NULL, OB_ROT_Z, 0);
2781                         
2782                         insertkey(&ob->id, ID_OB, actname, NULL, OB_LOC_X, 0);
2783                         insertkey(&ob->id, ID_OB, actname, NULL, OB_LOC_Y, 0);
2784                         insertkey(&ob->id, ID_OB, actname, NULL, OB_LOC_Z, 0);
2785                         
2786                         insertkey(&ob->id, ID_OB, actname, NULL, OB_SIZE_X, 0);
2787                         insertkey(&ob->id, ID_OB, actname, NULL, OB_SIZE_Y, 0);
2788                         insertkey(&ob->id, ID_OB, actname, NULL, OB_SIZE_Z, 0);
2789                 }
2790                 
2791                 remake_object_ipos(ob);
2792                 allqueue(REDRAWMARKER, 0);
2793         }
2794 }
2795
2796 /* auto-keyframing feature - for poses/pose-channels 
2797  *      tmode: should be a transform mode 
2798  *      targetless_ik: has targetless ik been done on any channels?
2799  */
2800 void autokeyframe_pose_cb_func(Object *ob, int tmode, short targetless_ik)
2801 {
2802         bArmature *arm= ob->data;
2803         bAction *act;
2804         bPose   *pose;
2805         bPoseChannel *pchan;
2806         IpoCurve *icu;
2807         
2808         pose= ob->pose;
2809         act= ob->action;
2810         
2811         if (G.flags & G_RECORDKEYS) {
2812                 if (!act)
2813                         act= ob->action= add_empty_action("Action");
2814                 
2815                 for (pchan=pose->chanbase.first; pchan; pchan=pchan->next) {
2816                         if (pchan->bone->flag & BONE_TRANSFORM) {
2817                                 /* clear any 'unkeyed' flag it may have */
2818                                 pchan->bone->flag &= ~BONE_UNKEYED;
2819                                 
2820                                 /* only insert into available channels? */
2821                                 if (U.uiflag & USER_KEYINSERTAVAI) {
2822                                         bActionChannel *achan; 
2823                                         
2824                                         for (achan = act->chanbase.first; achan; achan=achan->next){
2825                                                 if (achan->ipo && !strcmp (achan->name, pchan->name)){
2826                                                         for (icu = achan->ipo->curve.first; icu; icu=icu->next){
2827                                                                 /* only insert keyframe if needed? */
2828                                                                 if (U.uiflag & USER_KEYINSERTNEED)
2829                                                                         insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, icu->adrcode);
2830                                                                 else
2831                                                                         insertkey(&ob->id, ID_PO, pchan->name, NULL, icu->adrcode, 0);
2832                                                         }
2833                                                         break;
2834                                                 }
2835                                         }
2836                                 }
2837                                 /* only insert keyframe if needed? */
2838                                 else if (U.uiflag & USER_KEYINSERTNEED) {
2839                                         short doLoc=0, doRot=0, doScale=0;
2840                                         
2841                                         /* filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D) */
2842                                         if (tmode == TFM_TRANSLATION) {
2843                                                 if (targetless_ik) 
2844                                                         doRot= 1;
2845                                                 else 
2846                                                         doLoc = 1;
2847                                         }
2848                                         else if (tmode == TFM_ROTATION) {
2849                                                 if (ELEM(G.vd->around, V3D_CURSOR, V3D_ACTIVE))
2850                                                         doLoc = 1;
2851                                                         
2852                                                 if ((G.vd->flag & V3D_ALIGN)==0) 
2853                                                         doRot = 1;
2854                                         }
2855                                         else if (tmode == TFM_RESIZE) {
2856                                                 if (ELEM(G.vd->around, V3D_CURSOR, V3D_ACTIVE))
2857                                                         doLoc = 1;
2858                                                 
2859                                                 if ((G.vd->flag & V3D_ALIGN)==0)
2860                                                         doScale = 1;
2861                                         }
2862                                         
2863                                         if (doLoc) {
2864                                                 insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_X);
2865                                                 insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Y);
2866                                                 insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Z);
2867                                         }
2868                                         if (doRot) {
2869                                                 insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_W);
2870                                                 insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_X);
2871                                                 insertkey_smarter(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Y);