More work on the new unwrapper code (orange branch):
[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_object_types.h"
62 #include "DNA_object_force.h"
63 #include "DNA_scene_types.h"
64 #include "DNA_screen_types.h"
65 #include "DNA_space_types.h"
66 #include "DNA_texture_types.h"
67 #include "DNA_view3d_types.h"
68 #include "DNA_world_types.h"
69 #include "DNA_userdef_types.h"
70 #include "DNA_property_types.h"
71 #include "DNA_vfont_types.h"
72 #include "DNA_constraint_types.h"
73
74 #include "BKE_action.h"
75 #include "BKE_armature.h"
76 #include "BKE_blender.h"
77 #include "BKE_curve.h"
78 #include "BKE_constraint.h"
79 #include "BKE_depsgraph.h"
80 #include "BKE_displist.h"
81 #include "BKE_DerivedMesh.h"
82 #include "BKE_effect.h"
83 #include "BKE_font.h"
84 #include "BKE_global.h"
85 #include "BKE_ipo.h"
86 #include "BKE_lattice.h"
87 #include "BKE_mball.h"
88 #include "BKE_mesh.h"
89 #include "BKE_modifier.h"
90 #include "BKE_object.h"
91 #include "BKE_softbody.h"
92 #include "BKE_utildefines.h"
93
94 #include "BIF_editaction.h"
95 #include "BIF_editview.h"
96 #include "BIF_editlattice.h"
97 #include "BIF_editconstraint.h"
98 #include "BIF_editarmature.h"
99 #include "BIF_editmesh.h"
100 #include "BIF_editsima.h"
101 #include "BIF_gl.h"
102 #include "BIF_poseobject.h"
103 #include "BIF_meshtools.h"
104 #include "BIF_mywindow.h"
105 #include "BIF_resources.h"
106 #include "BIF_screen.h"
107 #include "BIF_space.h"
108 #include "BIF_toolbox.h"
109
110 #include "BSE_view.h"
111 #include "BSE_edit.h"
112 #include "BSE_editipo.h"
113 #include "BSE_editipo_types.h"
114
115 #include "BDR_editobject.h"             // reset_slowparents()
116
117 #include "BLI_arithb.h"
118 #include "BLI_blenlib.h"
119 #include "BLI_editVert.h"
120
121 #include "blendef.h"
122
123 #include "mydevice.h"
124
125 extern ListBase editNurb;
126 extern ListBase editelems;
127
128 #include "transform.h"
129
130
131 /* ************************** Functions *************************** */
132
133 static void qsort_trans_data(TransInfo *t, TransData *head, TransData *tail) {
134         TransData pivot = *head;
135         TransData *ihead = head;
136         TransData *itail = tail;
137         short connected = t->flag & T_PROP_CONNECTED;
138
139         while (head < tail)
140         {
141                 if (connected) {
142                         while ((tail->dist >= pivot.dist) && (head < tail))
143                                 tail--;
144                 }
145                 else {
146                         while ((tail->rdist >= pivot.rdist) && (head < tail))
147                                 tail--;
148                 }
149
150                 if (head != tail)
151                 {
152                         *head = *tail;
153                         head++;
154                 }
155
156                 if (connected) {
157                         while ((head->dist <= pivot.dist) && (head < tail))
158                                 head++;
159                 }
160                 else {
161                         while ((head->rdist <= pivot.rdist) && (head < tail))
162                                 head++;
163                 }
164
165                 if (head != tail)
166                 {
167                         *tail = *head;
168                         tail--;
169                 }
170         }
171
172         *head = pivot;
173         if (ihead < head) {
174                 qsort_trans_data(t, ihead, head-1);
175         }
176         if (itail > head) {
177                 qsort_trans_data(t, head+1, itail);
178         }
179 }
180
181 void sort_trans_data_dist(TransInfo *t) {
182         TransData *start = t->data;
183         int i = 1;
184
185         while(i < t->total && start->flag & TD_SELECTED) {
186                 start++;
187                 i++;
188         }
189         qsort_trans_data(t, start, t->data + t->total - 1);
190 }
191
192 static void sort_trans_data(TransInfo *t) 
193 {
194         TransData *sel, *unsel;
195         TransData temp;
196         unsel = t->data;
197         sel = t->data;
198         sel += t->total - 1;
199         while (sel > unsel) {
200                 while (unsel->flag & TD_SELECTED) {
201                         unsel++;
202                         if (unsel == sel) {
203                                 return;
204                         }
205                 }
206                 while (!(sel->flag & TD_SELECTED)) {
207                         sel--;
208                         if (unsel == sel) {
209                                 return;
210                         }
211                 }
212                 temp = *unsel;
213                 *unsel = *sel;
214                 *sel = temp;
215                 sel--;
216                 unsel++;
217         }
218 }
219
220 /* distance calculated from not-selected vertex to nearest selected vertex
221    warning; this is loops inside loop, has minor N^2 issues, but by sorting list it is OK */
222 static void set_prop_dist(TransInfo *t, short with_dist)
223 {
224         TransData *tob;
225         int a;
226
227         for(a=0, tob= t->data; a<t->total; a++, tob++) {
228                 
229                 tob->rdist= 0.0f; // init, it was mallocced
230                 
231                 if((tob->flag & TD_SELECTED)==0) {
232                         TransData *td;
233                         int i;
234                         float dist, vec[3];
235
236                         tob->rdist = -1.0f; // signal for next loop
237                                 
238                         for (i = 0, td= t->data; i < t->total; i++, td++) {
239                                 if(td->flag & TD_SELECTED) {
240                                         VecSubf(vec, tob->center, td->center);
241                                         Mat3MulVecfl(tob->mtx, vec);
242                                         dist = Normalise(vec);
243                                         if (tob->rdist == -1.0f) {
244                                                 tob->rdist = dist;
245                                         }
246                                         else if (dist < tob->rdist) {
247                                                 tob->rdist = dist;
248                                         }
249                                 }
250                                 else break;     // by definition transdata has selected items in beginning
251                         }
252                         if (with_dist) {
253                                 tob->dist = tob->rdist;
254                         }
255                 }       
256         }
257 }
258
259 /* ************************** CONVERSIONS ************************* */
260
261 /* ********************* texture space ********* */
262
263 static void createTransTexspace(TransInfo *t)
264 {
265         TransData *td;
266         Object *ob;
267         ID *id;
268         
269         ob= OBACT;
270
271         id= ob->data;
272         if(id==NULL || !ELEM3( GS(id->name), ID_ME, ID_CU, ID_MB )) {
273                 t->total = 0;
274                 return;
275         }
276
277         t->total = 1;
278         td= t->data= MEM_callocN(sizeof(TransData), "TransTexspace");
279         td->ext= t->ext= MEM_callocN(sizeof(TransDataExtension), "TransTexspace");
280         
281         td->flag= TD_SELECTED;
282         VECCOPY(td->center, ob->obmat[3]);
283         td->ob = ob;
284         
285         Mat3CpyMat4(td->mtx, ob->obmat);
286         Mat3Inv(td->smtx, td->mtx);
287         
288         if( GS(id->name)==ID_ME) {
289                 Mesh *me= ob->data;
290                 me->texflag &= ~AUTOSPACE;
291                 td->loc= me->loc;
292                 td->ext->rot= me->rot;
293                 td->ext->size= me->size;
294         }
295         else if( GS(id->name)==ID_CU) {
296                 Curve *cu= ob->data;
297                 cu->texflag &= ~CU_AUTOSPACE;
298                 td->loc= cu->loc;
299                 td->ext->rot= cu->rot;
300                 td->ext->size= cu->size;
301         }
302         else if( GS(id->name)==ID_MB) {
303                 MetaBall *mb= ob->data;
304                 mb->texflag &= ~MB_AUTOSPACE;
305                 td->loc= mb->loc;
306                 td->ext->rot= mb->rot;
307                 td->ext->size= mb->size;
308         }
309         
310         VECCOPY(td->iloc, td->loc);
311         VECCOPY(td->ext->irot, td->ext->rot);
312         VECCOPY(td->ext->isize, td->ext->size);
313 }
314
315 /* ********************* edge (for crease) ***** */
316
317 static void createTransEdge(TransInfo *t) {
318         TransData *td = NULL;
319         EditMesh *em = G.editMesh;
320         EditEdge *eed;
321         float mtx[3][3], smtx[3][3];
322         int count=0, countsel=0;
323         int propmode = t->flag & T_PROP_EDIT;
324
325         for(eed= em->edges.first; eed; eed= eed->next) {
326                 if(eed->h==0) {
327                         if (eed->f & SELECT) countsel++;
328                         if (propmode) count++;
329                 }
330         }
331
332         if (countsel == 0)
333                 return;
334
335         if(propmode) {
336                 t->total = count;
337         }
338         else {
339                 t->total = countsel;
340         }
341
342         td= t->data= MEM_callocN(t->total * sizeof(TransData), "TransCrease");
343
344         Mat3CpyMat4(mtx, G.obedit->obmat);
345         Mat3Inv(smtx, mtx);
346
347         for(eed= em->edges.first; eed; eed= eed->next) {
348                 if(eed->h==0 && (eed->f & SELECT || propmode)) {
349                         /* need to set center for center calculations */
350                         VecAddf(td->center, eed->v1->co, eed->v2->co);
351                         VecMulf(td->center, 0.5f);
352
353                         td->loc= NULL;
354                         if (eed->f & SELECT)
355                                 td->flag= TD_SELECTED;
356                         else 
357                                 td->flag= 0;
358
359
360                         Mat3CpyMat3(td->smtx, smtx);
361                         Mat3CpyMat3(td->mtx, mtx);
362
363                         td->ext = NULL;
364                         td->tdi = NULL;
365                         td->val = &(eed->crease);
366                         td->ival = eed->crease;
367
368                         td++;
369                 }
370         }
371 }
372
373 /* ********************* pose mode ************* */
374
375 /* recursive, make sure it's identical structured as next one */
376 /* only counts the parent selection, and tags transform flag */
377 /* exported for manipulator */
378 void count_bone_select(TransInfo *t, ListBase *lb, int do_it) 
379 {
380         Bone *bone;
381         int do_next;
382         
383         for(bone= lb->first; bone; bone= bone->next) {
384                 bone->flag &= ~BONE_TRANSFORM;
385                 do_next= do_it;
386                 if(do_it) {
387                         if (bone->flag & BONE_SELECTED) {
388                                 /* We don't let connected children get "grabbed" */
389                                 if ( (t->mode!=TFM_TRANSLATION) || (bone->flag & BONE_CONNECTED)==0 ) {
390                                         bone->flag |= BONE_TRANSFORM;
391                                         t->total++;
392                                         do_next= 0;     // no transform on children if one parent bone is selected
393                                 }
394                         }
395                 }
396                 count_bone_select(t, &bone->childbase, do_next);
397         }
398 }
399
400 static bKinematicConstraint *has_targetless_ik(bPoseChannel *pchan)
401 {
402         bConstraint *con= pchan->constraints.first;
403         
404         for(;con; con= con->next) {
405                 if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
406                         bKinematicConstraint *data= con->data;
407                         
408                         if(data->tar==NULL) 
409                                 return data;
410                         if(data->tar->type==OB_ARMATURE && data->subtarget[0]==0) 
411                                 return data;
412                 }
413         }
414         return NULL;
415 }
416
417 static void apply_targetless_ik(Object *ob)
418 {
419         bPoseChannel *pchan, *parchan, *chanlist[256];
420         bKinematicConstraint *data;
421         int segcount;
422         
423         /* now we got a difficult situation... we have to find the
424            target-less IK pchans, and apply transformation to the all 
425            pchans that were in the chain */
426         
427         for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
428                 data= has_targetless_ik(pchan);
429                 if(data && (data->flag & CONSTRAINT_IK_AUTO)) {
430                         
431                         /* fill the array with the bones of the chain (armature.c does same, keep it synced) */
432                         segcount= 0;
433                         
434                         /* exclude tip from chain? */
435                         if(!(data->flag & CONSTRAINT_IK_TIP))
436                                 parchan= pchan->parent;
437                         else
438                                 parchan= pchan;
439                         
440                         /* Find the chain's root & count the segments needed */
441                         for (; parchan; parchan=parchan->parent){
442                                 chanlist[segcount]= parchan;
443                                 segcount++;
444                                 
445                                 if(segcount==data->rootbone || segcount>255) break; // 255 is weak
446                         }
447                         for(;segcount;segcount--) {
448                                 Bone *bone;
449                                 float rmat[4][4], tmat[4][4], imat[4][4];
450                                 
451                                 /* pose_mat(b) = pose_mat(b-1) * offs_bone * channel * constraint * IK  */
452                                 /* we put in channel the entire result of rmat= (channel * constraint * IK) */
453                                 /* pose_mat(b) = pose_mat(b-1) * offs_bone * rmat  */
454                                 /* rmat = pose_mat(b) * inv( pose_mat(b-1) * offs_bone ) */
455                                 
456                                 parchan= chanlist[segcount-1];
457                                 bone= parchan->bone;
458                                 bone->flag |= BONE_TRANSFORM;   /* ensures it gets an auto key inserted */
459                                 
460                                 if(parchan->parent) {
461                                         Bone *parbone= parchan->parent->bone;
462                                         float offs_bone[4][4];
463                                         
464                                         /* offs_bone =  yoffs(b-1) + root(b) + bonemat(b) */
465                                         Mat4CpyMat3(offs_bone, bone->bone_mat);
466                                         
467                                         /* The bone's root offset (is in the parent's coordinate system) */
468                                         VECCOPY(offs_bone[3], bone->head);
469                                         
470                                         /* Get the length translation of parent (length along y axis) */
471                                         offs_bone[3][1]+= parbone->length;
472                                         
473                                         /* pose_mat(b-1) * offs_bone */
474                                         if(parchan->bone->flag & BONE_HINGE) {
475                                                 /* the rotation of the parent restposition */
476                                                 Mat4CpyMat4(rmat, parbone->arm_mat);    /* rmat used as temp */
477                                                 
478                                                 /* the location of actual parent transform */
479                                                 VECCOPY(rmat[3], offs_bone[3]);
480                                                 offs_bone[3][0]= offs_bone[3][1]= offs_bone[3][2]= 0.0f;
481                                                 Mat4MulVecfl(parchan->parent->pose_mat, rmat[3]);
482                                                 
483                                                 Mat4MulMat4(tmat, offs_bone, rmat);
484                                         }
485                                         else
486                                                 Mat4MulMat4(tmat, offs_bone, parchan->parent->pose_mat);
487                                         
488                                         Mat4Invert(imat, tmat);
489                                 }
490                                 else {
491                                         Mat4CpyMat3(tmat, bone->bone_mat);
492
493                                         VECCOPY(tmat[3], bone->head);
494                                         Mat4Invert(imat, tmat);
495                                 }
496                                 /* result matrix */
497                                 Mat4MulMat4(rmat, parchan->pose_mat, imat);
498                                 
499                                 /* apply and decompose, doesn't work for constraints or non-uniform scale well */
500                                 {
501                                         float rmat3[3][3], qmat[3][3], imat[3][3], smat[3][3];
502                                         
503                                         Mat3CpyMat4(rmat3, rmat);
504                                         
505                                         /* quaternion */
506                                         Mat3ToQuat(rmat3, parchan->quat);
507                                         
508                                         /* for size, remove rotation */
509                                         QuatToMat3(parchan->quat, qmat);
510                                         Mat3Inv(imat, qmat);
511                                         Mat3MulMat3(smat, rmat3, imat);
512                                         Mat3ToSize(smat, parchan->size);
513                                         
514                                         VECCOPY(parchan->loc, rmat[3]);
515                                 }
516                                 
517                         }
518                         
519                         data->flag &= ~CONSTRAINT_IK_AUTO;
520                 }
521         }               
522         
523 }
524
525 static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, TransData *td)
526 {
527         Bone *bone= pchan->bone;
528         float pmat[3][3], omat[3][3];
529         float vec[3];
530
531         VECCOPY(vec, pchan->pose_mat[3]);
532         VECCOPY(td->center, vec);
533         
534         td->ob = ob;
535         td->flag= TD_SELECTED|TD_USEQUAT;
536         td->protectflag= pchan->protectflag;
537         
538         td->loc = pchan->loc;
539         VECCOPY(td->iloc, pchan->loc);
540         
541         td->ext->rot= NULL;
542         td->ext->quat= pchan->quat;
543         td->ext->size= pchan->size;
544
545         QUATCOPY(td->ext->iquat, pchan->quat);
546         VECCOPY(td->ext->isize, pchan->size);
547
548         /* proper way to get the parent transform + own transform */
549         Mat3CpyMat4(omat, ob->obmat);
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                 Mat3MulSerie(td->mtx, pchan->bone->bone_mat, pmat, omat, 0,0,0,0,0);    // dang mulserie swaps args
557         }
558         else {
559                 Mat3MulMat3(td->mtx, omat, pchan->bone->bone_mat);      // huh, transposed?
560         }
561         
562         Mat3Inv (td->smtx, td->mtx);
563         
564         /* for axismat we use bone's own transform */
565         Mat3CpyMat4(pmat, pchan->pose_mat);
566         Mat3MulMat3(td->axismtx, omat, pmat);
567         Mat3Ortho(td->axismtx);
568         
569         if(t->mode==TFM_BONESIZE) {
570                 bArmature *arm= t->poseobj->data;
571                 
572                 if(arm->drawtype==ARM_ENVELOPE) {
573                         td->loc= NULL;
574                         td->val= &bone->dist;
575                         td->ival= bone->dist;
576                 }
577                 else {
578                         // abusive storage of scale in the loc pointer :)
579                         td->loc= &bone->xwidth;
580                         VECCOPY (td->iloc, td->loc);
581                         td->val= NULL;
582                 }
583         }
584         
585         /* in this case we can do target-less IK grabbing */
586         if(t->mode==TFM_TRANSLATION) {
587                 bKinematicConstraint *data= has_targetless_ik(pchan);
588                 if(data) {
589                         if(data->flag & CONSTRAINT_IK_TIP) {
590                                 VECCOPY(data->grabtarget, pchan->pose_tail);
591                         }
592                         else {
593                                 VECCOPY(data->grabtarget, pchan->pose_head);
594                         }
595                         td->loc = data->grabtarget;
596                         VECCOPY(td->iloc, td->loc);
597                         data->flag |= CONSTRAINT_IK_AUTO;
598                         
599                         /* only object matrix correction */
600                         Mat3CpyMat3 (td->mtx, omat);
601                         Mat3Inv (td->smtx, td->mtx);
602                 }
603         }
604 }
605
606 static void bone_children_clear_transflag(ListBase *lb)
607 {
608         Bone *bone= lb->first;
609         
610         for(;bone;bone= bone->next) {
611                 bone->flag &= ~BONE_TRANSFORM;
612                 bone_children_clear_transflag(&bone->childbase);
613         }
614 }
615
616 /* sets transform flags in the bones, returns total */
617 static void set_pose_transflags(TransInfo *t, Object *ob)
618 {
619         bPoseChannel *pchan;
620         Bone *bone;
621         
622         t->total= 0;
623         
624         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
625                 bone= pchan->bone;
626                 if(bone->flag & BONE_SELECTED)
627                         bone->flag |= BONE_TRANSFORM;
628                 else
629                         bone->flag &= ~BONE_TRANSFORM;
630         }
631         
632         /* make sure no bone can be transformed when a parent is transformed */
633         /* since pchans are depsgraph sorted, the parents are in beginning of list */
634         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
635                 bone= pchan->bone;
636                 if(bone->flag & BONE_TRANSFORM)
637                         bone_children_clear_transflag(&bone->childbase);
638         }
639         
640         /* now count, and check if we have autoIK or have to switch from translate to rotate */
641         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
642                 bone= pchan->bone;
643                 if(bone->flag & BONE_TRANSFORM) {
644                         t->total++;
645                         
646                         if(t->mode==TFM_TRANSLATION) {
647                                 if( has_targetless_ik(pchan)==NULL ) {
648                                         if(pchan->parent && (pchan->bone->flag & BONE_CONNECTED))
649                                                 t->mode= TFM_ROTATION;
650                                         else if((pchan->protectflag & OB_LOCK_LOC)==OB_LOCK_LOC)
651                                                 t->mode= TFM_ROTATION;
652                                 }
653                         }
654                 }
655         }
656 }
657
658 /* frees temporal IKs */
659 static void pose_grab_with_ik_clear(Object *ob)
660 {
661         bKinematicConstraint *data;
662         bPoseChannel *pchan;
663         bConstraint *con;
664         
665         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
666                 for(con= pchan->constraints.first; con; con= con->next) {
667                         if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
668                                 data= con->data;
669                                 if(data->flag & CONSTRAINT_IK_TEMP) {
670                                         BLI_remlink(&pchan->constraints, con);
671                                         MEM_freeN(con->data);
672                                         MEM_freeN(con);
673                                         pchan->constflag &= ~(PCHAN_HAS_IK|PCHAN_HAS_TARGET);
674                                         break;
675                                 }
676                         }
677                 }
678         }
679 }
680
681 /* adds the IK to pchan */
682 static void pose_grab_with_ik_add(bPoseChannel *pchan)
683 {
684         bKinematicConstraint *data;
685         bConstraint *con;
686         
687         /* rule: not if there's already an IK on this channel */
688         for(con= pchan->constraints.first; con; con= con->next)
689                 if(con->type==CONSTRAINT_TYPE_KINEMATIC)
690                         break;
691         
692         if(con) {
693                 /* but, if this is a targetless IK, we make it auto anyway (for the children loop) */
694                 data= has_targetless_ik(pchan);
695                 if(data)
696                         data->flag |= CONSTRAINT_IK_AUTO;
697                 return;
698         }
699         
700         con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
701         BLI_addtail(&pchan->constraints, con);
702         pchan->constflag |= (PCHAN_HAS_IK|PCHAN_HAS_TARGET);    /* for draw, but also for detecting while pose solving */
703         data= con->data;
704         data->flag= CONSTRAINT_IK_TIP|CONSTRAINT_IK_TEMP|CONSTRAINT_IK_AUTO;
705         VECCOPY(data->grabtarget, pchan->pose_tail);
706         data->rootbone= 1;
707         
708         /* we include only a connected chain */
709         while(pchan && (pchan->bone->flag & BONE_CONNECTED)) {
710                 data->rootbone++;
711                 pchan= pchan->parent;
712         }
713 }
714
715 /* bone is a canditate to get IK, but we don't do it if it has children connected */
716 static void pose_grab_with_ik_children(bPose *pose, Bone *bone)
717 {
718         Bone *bonec;
719         int wentdeeper= 0;
720
721         /* go deeper if children & children are connected */
722         for(bonec= bone->childbase.first; bonec; bonec= bonec->next) {
723                 if(bonec->flag & BONE_CONNECTED) {
724                         wentdeeper= 1;
725                         pose_grab_with_ik_children(pose, bonec);
726                 }
727         }
728         if(wentdeeper==0) {
729                 bPoseChannel *pchan= get_pose_channel(pose, bone->name);
730                 if(pchan)
731                         pose_grab_with_ik_add(pchan);
732         }
733 }
734
735 /* main call which adds temporal IK chains */
736 static void pose_grab_with_ik(Object *ob)
737 {
738         bPoseChannel *pchan, *pchansel= NULL;
739         
740         if(ob==NULL || ob->pose==NULL || (ob->flag & OB_POSEMODE)==0)
741                 return;
742         
743         /* rule: only one Bone */
744         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
745                 if(pchan->bone->flag & BONE_SELECTED) {
746                         if(pchansel)
747                                 break;
748                         pchansel= pchan;
749                 }
750         }
751         if(pchan || pchansel==NULL) return;
752         
753         /* rule: if selected Bone is not a root bone, it gets a temporal IK */
754         if(pchansel->parent) {
755                 /* only adds if there's no IK yet */
756                 pose_grab_with_ik_add(pchansel);
757         }
758         else {
759                 /* rule: go over the children and add IK to the tips */
760                 pose_grab_with_ik_children(ob->pose, pchansel->bone);
761         }
762 }       
763
764
765
766 /* only called with pose mode active object now */
767 static void createTransPose(TransInfo *t, Object *ob)
768 {
769         bArmature *arm;
770         bPoseChannel *pchan;
771         TransData *td;
772         TransDataExtension *tdx;
773         int i;
774         
775         t->total= 0;
776         
777         /* check validity of state */
778         arm=get_armature (ob);
779         if (arm==NULL || ob->pose==NULL) return;
780         
781         if (arm->flag & ARM_RESTPOS) {
782                 if(t->mode!=TFM_BONESIZE) {
783                         notice ("Pose edit not possible while Rest Position is enabled");
784                         return;
785                 }
786         }
787         if (!(ob->lay & G.vd->lay)) return;
788
789         /* do we need to add temporal IK chains? */
790         if((arm->flag & ARM_AUTO_IK) && t->mode==TFM_TRANSLATION)
791                 pose_grab_with_ik(ob);
792         
793         /* set flags and count total (warning, can change transform to rotate) */
794         set_pose_transflags(t, ob);
795         
796         if(t->total==0) return;
797
798         t->flag |= T_POSE;
799         t->poseobj= ob; /* we also allow non-active objects to be transformed, in weightpaint */
800         
801         /* make sure the lock is set OK, unlock can be accidentally saved? */
802         ob->pose->flag |= POSE_LOCKED;
803         ob->pose->flag &= ~POSE_DO_UNLOCK;
804
805         /* init trans data */
806     td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransPoseBone");
807     tdx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "TransPoseBoneExt");
808         for(i=0; i<t->total; i++, td++, tdx++) {
809                 td->ext= tdx;
810                 td->tdi = NULL;
811                 td->val = NULL;
812         }       
813         
814         /* use pose channels to fill trans data */
815         td= t->data;
816         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
817                 if(pchan->bone->flag & BONE_TRANSFORM) {
818                         add_pose_transdata(t, pchan, ob, td);
819                         td++;
820                 }
821         }
822         
823         if(td != (t->data+t->total)) printf("Bone selection count error\n");
824         
825 }
826
827 /* ********************* armature ************** */
828
829 static void createTransArmatureVerts(TransInfo *t)
830 {
831         EditBone *ebo;
832         bArmature *arm= G.obedit->data;
833         TransData *td;
834         float mtx[3][3], smtx[3][3], delta[3], bonemat[3][3];
835
836         t->total = 0;
837         for (ebo=G.edbo.first;ebo;ebo=ebo->next) {
838                 if (t->mode==TFM_BONESIZE) {
839                         if (ebo->flag & BONE_SELECTED)
840                                 t->total++;
841                 }
842                 else {
843                         if (ebo->flag & BONE_TIPSEL)
844                                 t->total++;
845                         if (ebo->flag & BONE_ROOTSEL)
846                                 t->total++;
847                 }
848         }
849
850     if (!t->total) return;
851         
852         Mat3CpyMat4(mtx, G.obedit->obmat);
853         Mat3Inv(smtx, mtx);
854
855     td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransEditBone");
856         
857         for (ebo=G.edbo.first;ebo;ebo=ebo->next){
858                 
859                 ebo->oldlength= ebo->length;    // length==0.0 on extrude, used for scaling radius of bone points
860                 
861                 if (t->mode==TFM_BONE_ENVELOPE) {
862                         
863                         if (ebo->flag & BONE_ROOTSEL){
864                                 td->val= &ebo->rad_head;
865                                 td->ival= *td->val;
866                                 
867                                 VECCOPY (td->center, ebo->head);
868                                 td->flag= TD_SELECTED;
869                                 
870                                 Mat3CpyMat3(td->smtx, smtx);
871                                 Mat3CpyMat3(td->mtx, mtx);
872                                 
873                                 td->loc = NULL;
874                                 td->ext = NULL;
875                                 td->tdi = NULL;
876                                 
877                                 td++;
878                         }
879                         if (ebo->flag & BONE_TIPSEL){
880                                 td->val= &ebo->rad_tail;
881                                 td->ival= *td->val;
882                                 VECCOPY (td->center, ebo->tail);
883                                 td->flag= TD_SELECTED;
884                                 
885                                 Mat3CpyMat3(td->smtx, smtx);
886                                 Mat3CpyMat3(td->mtx, mtx);
887                                 
888                                 td->loc = NULL;
889                                 td->ext = NULL;
890                                 td->tdi = NULL;
891                                 
892                                 td++;
893                         }
894                         
895                 }
896                 else if (t->mode==TFM_BONESIZE) {
897                         if (ebo->flag & BONE_SELECTED) {
898                                 if(arm->drawtype==ARM_ENVELOPE) {
899                                         td->loc= NULL;
900                                         td->val= &ebo->dist;
901                                         td->ival= ebo->dist;
902                                 }
903                                 else {
904                                         // abusive storage of scale in the loc pointer :)
905                                         td->loc= &ebo->xwidth;
906                                         VECCOPY (td->iloc, td->loc);
907                                         td->val= NULL;
908                                 }
909                                 VECCOPY (td->center, ebo->head);
910                                 td->flag= TD_SELECTED;
911                                 
912                                 /* use local bone matrix */
913                                 VecSubf(delta, ebo->tail, ebo->head);   
914                                 vec_roll_to_mat3(delta, ebo->roll, bonemat);
915                                 Mat3MulMat3(td->mtx, mtx, bonemat);
916                                 Mat3Inv(td->smtx, td->mtx);
917                                 
918                                 Mat3CpyMat3(td->axismtx, td->mtx);
919                                 Mat3Ortho(td->axismtx);
920
921                                 td->ext = NULL;
922                                 td->tdi = NULL;
923                                 
924                                 td++;
925                         }
926                 }
927                 else {
928                         if (ebo->flag & BONE_TIPSEL){
929                                 VECCOPY (td->iloc, ebo->tail);
930                                 VECCOPY (td->center, td->iloc);
931                                 td->loc= ebo->tail;
932                                 td->flag= TD_SELECTED;
933
934                                 Mat3CpyMat3(td->smtx, smtx);
935                                 Mat3CpyMat3(td->mtx, mtx);
936
937                                 td->ext = NULL;
938                                 td->tdi = NULL;
939                                 td->val = NULL;
940
941                                 td++;
942                         }
943                         if (ebo->flag & BONE_ROOTSEL){
944                                 VECCOPY (td->iloc, ebo->head);
945                                 VECCOPY (td->center, td->iloc);
946                                 td->loc= ebo->head;
947                                 td->flag= TD_SELECTED;
948
949                                 Mat3CpyMat3(td->smtx, smtx);
950                                 Mat3CpyMat3(td->mtx, mtx);
951
952                                 td->ext = NULL;
953                                 td->tdi = NULL;
954                                 td->val = NULL;
955
956                                 td++;
957                         }
958                 }
959         }
960 }
961
962 /* ********************* meta elements ********* */
963
964 static void createTransMBallVerts(TransInfo *t)
965 {
966         MetaElem *ml;
967         TransData *td;
968         TransDataExtension *tx;
969         float mtx[3][3], smtx[3][3];
970         int count=0, countsel=0;
971         int propmode = t->flag & T_PROP_EDIT;
972
973         /* count totals */
974         for(ml= editelems.first; ml; ml= ml->next) {
975                 if(ml->flag & SELECT) countsel++;
976                 if(propmode) count++;
977         }
978
979         /* note: in prop mode we need at least 1 selected */
980         if (countsel==0) return;
981         
982         if(propmode) t->total = count; 
983         else t->total = countsel;
984         
985         td = t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(MBall EditMode)");
986         tx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "MetaElement_TransExtension");
987
988         Mat3CpyMat4(mtx, G.obedit->obmat);
989         Mat3Inv(smtx, mtx);
990     
991         for(ml= editelems.first; ml; ml= ml->next) {
992                 if(propmode || (ml->flag & SELECT)) {
993                         td->loc= &ml->x;
994                         VECCOPY(td->iloc, td->loc);
995                         VECCOPY(td->center, td->loc);
996
997                         if(ml->flag & SELECT) td->flag= TD_SELECTED | TD_USEQUAT | TD_SINGLESIZE;
998                         else td->flag= TD_USEQUAT;
999
1000                         Mat3CpyMat3(td->smtx, smtx);
1001                         Mat3CpyMat3(td->mtx, mtx);
1002
1003                         td->ext = tx;
1004                         td->tdi = NULL;
1005
1006                         /* Radius of MetaElem (mass of MetaElem influence) */
1007                         if(ml->flag & MB_SCALE_RAD){
1008                                 td->val = &ml->rad;
1009                                 td->ival = ml->rad;
1010                         }
1011                         else{
1012                                 td->val = &ml->s;
1013                                 td->ival = ml->s;
1014                         }
1015
1016                         /* expx/expy/expz determine "shape" of some MetaElem types */
1017                         tx->size = &ml->expx;
1018                         tx->isize[0] = ml->expx;
1019                         tx->isize[1] = ml->expy;
1020                         tx->isize[2] = ml->expz;
1021
1022                         /* quat is used for rotation of MetaElem */
1023                         tx->quat = ml->quat;
1024                         QUATCOPY(tx->iquat, ml->quat);
1025
1026                         tx->rot = NULL;
1027
1028                         td++;
1029                         tx++;
1030                 }
1031         }
1032
1033
1034 /* ********************* curve/surface ********* */
1035
1036 static void calc_distanceCurveVerts(TransData *head, TransData *tail) {
1037         TransData *td, *td_near = NULL;
1038         for (td = head; td<=tail; td++) {
1039                 if (td->flag & TD_SELECTED) {
1040                         td_near = td;
1041                         td->dist = 0.0f;
1042                 }
1043                 else if(td_near) {
1044                         float dist;
1045                         dist = VecLenf(td_near->center, td->center);
1046                         if (dist < (td-1)->dist) {
1047                                 td->dist = (td-1)->dist;
1048                         }
1049                         else {
1050                                 td->dist = dist;
1051                         }
1052                 }
1053                 else {
1054                         td->dist = MAXFLOAT;
1055                         td->flag |= TD_NOTCONNECTED;
1056                 }
1057         }
1058         td_near = NULL;
1059         for (td = tail; td>=head; td--) {
1060                 if (td->flag & TD_SELECTED) {
1061                         td_near = td;
1062                         td->dist = 0.0f;
1063                 }
1064                 else if(td_near) {
1065                         float dist;
1066                         dist = VecLenf(td_near->center, td->center);
1067                         if (td->flag & TD_NOTCONNECTED || dist < td->dist || (td+1)->dist < td->dist) {
1068                                 td->flag &= ~TD_NOTCONNECTED;
1069                                 if (dist < (td+1)->dist) {
1070                                         td->dist = (td+1)->dist;
1071                                 }
1072                                 else {
1073                                         td->dist = dist;
1074                                 }
1075                         }
1076                 }
1077         }
1078 }
1079
1080 static void createTransCurveVerts(TransInfo *t)
1081 {
1082         TransData *td = NULL;
1083         Nurb *nu;
1084         BezTriple *bezt;
1085         BPoint *bp;
1086         float mtx[3][3], smtx[3][3];
1087         int a;
1088         int count=0, countsel=0;
1089         int propmode = t->flag & T_PROP_EDIT;
1090
1091         /* count total of vertices, check identical as in 2nd loop for making transdata! */
1092         for(nu= editNurb.first; nu; nu= nu->next) {
1093                 if((nu->type & 7)==CU_BEZIER) {
1094                         for(a=0, bezt= nu->bezt; a<nu->pntsu; a++, bezt++) {
1095                                 if(bezt->hide==0) {
1096                                         if(bezt->f1 & 1) countsel++;
1097                                         if(bezt->f2 & 1) countsel++;
1098                                         if(bezt->f3 & 1) countsel++;
1099                                         if(propmode) count+= 3;
1100                                 }
1101                         }
1102                 }
1103                 else {
1104                         for(a= nu->pntsu*nu->pntsv, bp= nu->bp; a>0; a--, bp++) {
1105                                 if(bp->hide==0) {
1106                                         if(propmode) count++;
1107                                         if(bp->f1 & 1) countsel++;
1108                                 }
1109                         }
1110                 }
1111         }
1112         /* note: in prop mode we need at least 1 selected */
1113         if (countsel==0) return;
1114         
1115         if(propmode) t->total = count; 
1116         else t->total = countsel;
1117         t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Curve EditMode)");
1118
1119         Mat3CpyMat4(mtx, G.obedit->obmat);
1120         Mat3Inv(smtx, mtx);
1121
1122     td = t->data;
1123         for(nu= editNurb.first; nu; nu= nu->next) {
1124                 if((nu->type & 7)==CU_BEZIER) {
1125                         TransData *head, *tail;
1126                         head = tail = td;
1127                         for(a=0, bezt= nu->bezt; a<nu->pntsu; a++, bezt++) {
1128                                 if(bezt->hide==0) {
1129                                         if(propmode || (bezt->f1 & 1)) {
1130                                                 VECCOPY(td->iloc, bezt->vec[0]);
1131                                                 td->loc= bezt->vec[0];
1132                                                 VECCOPY(td->center, bezt->vec[1]);
1133                                                 if(bezt->f1 & 1) td->flag= TD_SELECTED;
1134                                                 else td->flag= 0;
1135                                                 td->ext = NULL;
1136                                                 td->tdi = NULL;
1137                                                 td->val = NULL;
1138
1139                                                 Mat3CpyMat3(td->smtx, smtx);
1140                                                 Mat3CpyMat3(td->mtx, mtx);
1141
1142                                                 td++;
1143                                                 count++;
1144                                                 tail++;
1145                                         }
1146                                         /* THIS IS THE CV, the other two are handles */
1147                                         if(propmode || (bezt->f2 & 1)) {
1148                                                 VECCOPY(td->iloc, bezt->vec[1]);
1149                                                 td->loc= bezt->vec[1];
1150                                                 VECCOPY(td->center, td->loc);
1151                                                 if(bezt->f2 & 1) td->flag= TD_SELECTED;
1152                                                 else td->flag= 0;
1153                                                 td->ext = NULL;
1154                                                 td->tdi = NULL;
1155                                                 td->val = &(bezt->alfa);
1156                                                 td->ival = bezt->alfa;
1157
1158                                                 Mat3CpyMat3(td->smtx, smtx);
1159                                                 Mat3CpyMat3(td->mtx, mtx);
1160
1161                                                 td++;
1162                                                 count++;
1163                                                 tail++;
1164                                         }
1165                                         if(propmode || (bezt->f3 & 1)) {
1166                                                 VECCOPY(td->iloc, bezt->vec[2]);
1167                                                 td->loc= bezt->vec[2];
1168                                                 VECCOPY(td->center, bezt->vec[1]);
1169                                                 if(bezt->f3 & 1) td->flag= TD_SELECTED;
1170                                                 else td->flag= 0;
1171                                                 td->ext = NULL;
1172                                                 td->tdi = NULL;
1173                                                 td->val = NULL;
1174
1175                                                 Mat3CpyMat3(td->smtx, smtx);
1176                                                 Mat3CpyMat3(td->mtx, mtx);
1177
1178                                                 td++;
1179                                                 count++;
1180                                                 tail++;
1181                                         }
1182                                 }
1183                                 else if (propmode && head != tail) {
1184                                         calc_distanceCurveVerts(head, tail-1);
1185                                         head = tail;
1186                                 }
1187                         }
1188                         if (propmode && head != tail)
1189                                 calc_distanceCurveVerts(head, tail-1);
1190                 }
1191                 else {
1192                         TransData *head, *tail;
1193                         head = tail = td;
1194                         for(a= nu->pntsu*nu->pntsv, bp= nu->bp; a>0; a--, bp++) {
1195                                 if(bp->hide==0) {
1196                                         if(propmode || (bp->f1 & 1)) {
1197                                                 VECCOPY(td->iloc, bp->vec);
1198                                                 td->loc= bp->vec;
1199                                                 VECCOPY(td->center, td->loc);
1200                                                 if(bp->f1 & 1) td->flag= TD_SELECTED;
1201                                                 else td->flag= 0;
1202                                                 td->ext = NULL;
1203                                                 td->tdi = NULL;
1204                                                 td->val = &(bp->alfa);
1205                                                 td->ival = bp->alfa;
1206
1207                                                 Mat3CpyMat3(td->smtx, smtx);
1208                                                 Mat3CpyMat3(td->mtx, mtx);
1209
1210                                                 td++;
1211                                                 count++;
1212                                                 tail++;
1213                                         }
1214                                 }
1215                                 else if (propmode && head != tail) {
1216                                         calc_distanceCurveVerts(head, tail-1);
1217                                         head = tail;
1218                                 }
1219                         }
1220                         if (propmode && head != tail)
1221                                 calc_distanceCurveVerts(head, tail-1);
1222                 }
1223         }
1224 }
1225
1226 /* ********************* lattice *************** */
1227
1228 static void createTransLatticeVerts(TransInfo *t)
1229 {
1230         TransData *td = NULL;
1231         BPoint *bp;
1232         float mtx[3][3], smtx[3][3];
1233         int a;
1234         int count=0, countsel=0;
1235         int propmode = t->flag & T_PROP_EDIT;
1236
1237         bp= editLatt->def;
1238         a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
1239         while(a--) {
1240                 if(bp->hide==0) {
1241                         if(bp->f1 & 1) countsel++;
1242                         if(propmode) count++;
1243                 }
1244                 bp++;
1245         }
1246         
1247         /* note: in prop mode we need at least 1 selected */
1248         if (countsel==0) return;
1249         
1250         if(propmode) t->total = count; 
1251         else t->total = countsel;
1252         t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Lattice EditMode)");
1253         
1254         Mat3CpyMat4(mtx, G.obedit->obmat);
1255         Mat3Inv(smtx, mtx);
1256
1257         td = t->data;
1258         bp= editLatt->def;
1259         a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
1260         while(a--) {
1261                 if(propmode || (bp->f1 & 1)) {
1262                         if(bp->hide==0) {
1263                                 VECCOPY(td->iloc, bp->vec);
1264                                 td->loc= bp->vec;
1265                                 VECCOPY(td->center, td->loc);
1266                                 if(bp->f1 & 1) td->flag= TD_SELECTED;
1267                                 else td->flag= 0;
1268                                 Mat3CpyMat3(td->smtx, smtx);
1269                                 Mat3CpyMat3(td->mtx, mtx);
1270
1271                                 td->ext = NULL;
1272                                 td->tdi = NULL;
1273                                 td->val = NULL;
1274
1275                                 td++;
1276                                 count++;
1277                         }
1278                 }
1279                 bp++;
1280         }
1281
1282
1283 /* ********************* mesh ****************** */
1284
1285 /* proportional distance based on connectivity  */
1286 #define E_VEC(a)        (vectors + (3 * (int)(a)->vn))
1287 #define E_NEAR(a)       (nears[((int)(a)->vn)])
1288 static void editmesh_set_connectivity_distance(int total, float *vectors, EditVert **nears)
1289 {
1290         EditMesh *em = G.editMesh;
1291         EditVert *eve;
1292         EditEdge *eed;
1293         int i= 0, done= 1;
1294
1295         /* f2 flag is used for 'selection' */
1296         /* vn is offset on scratch array   */
1297         for(eve= em->verts.first; eve; eve= eve->next) {
1298                 if(eve->h==0) {
1299                         eve->vn = (EditVert *)(i++);
1300
1301                         if(eve->f & SELECT) {
1302                                 eve->f2= 2;
1303                                 E_NEAR(eve) = eve;
1304                                 E_VEC(eve)[0] = 0.0f;
1305                                 E_VEC(eve)[1] = 0.0f;
1306                                 E_VEC(eve)[2] = 0.0f;
1307                         }
1308                         else {
1309                                 eve->f2 = 0;
1310                         }
1311                 }
1312         }
1313
1314
1315         /* Floodfill routine */
1316         /*
1317         At worst this is n*n of complexity where n is number of edges 
1318         Best case would be n if the list is ordered perfectly.
1319         Estimate is n log n in average (so not too bad)
1320         */
1321         while(done) {
1322                 done= 0;
1323                 
1324                 for(eed= em->edges.first; eed; eed= eed->next) {
1325                         if(eed->h==0) {
1326                                 EditVert *v1= eed->v1, *v2= eed->v2;
1327                                 float *vec2 = E_VEC(v2);
1328                                 float *vec1 = E_VEC(v1);
1329
1330                                 if (v1->f2 + v2->f2 == 4)
1331                                         continue;
1332
1333                                 if (v1->f2) {
1334                                         if (v2->f2) {
1335                                                 float nvec[3];
1336                                                 float len1 = VecLength(vec1);
1337                                                 float len2 = VecLength(vec2);
1338                                                 float lenn;
1339                                                 /* for v2 if not selected */
1340                                                 if (v2->f2 != 2) {
1341                                                         VecSubf(nvec, v2->co, E_NEAR(v1)->co);
1342                                                         lenn = VecLength(nvec);
1343                                                         if (lenn - len1 > 0.00001f && len2 - lenn > 0.00001f) {
1344                                                                 VECCOPY(vec2, nvec);
1345                                                                 E_NEAR(v2) = E_NEAR(v1);
1346                                                                 done = 1;
1347                                                         }
1348                                                         else if (len2 - len1 > 0.00001f && len1 - lenn > 0.00001f) {
1349                                                                 VECCOPY(vec2, vec1);
1350                                                                 E_NEAR(v2) = E_NEAR(v1);
1351                                                                 done = 1;
1352                                                         }
1353                                                 }
1354                                                 /* for v1 if not selected */
1355                                                 if (v1->f2 != 2) {
1356                                                         VecSubf(nvec, v1->co, E_NEAR(v2)->co);
1357                                                         lenn = VecLength(nvec);
1358                                                         if (lenn - len2 > 0.00001f && len1 - lenn > 0.00001f) {
1359                                                                 VECCOPY(vec1, nvec);
1360                                                                 E_NEAR(v1) = E_NEAR(v2);
1361                                                                 done = 1;
1362                                                         }
1363                                                         else if (len1 - len2 > 0.00001f && len2 - lenn > 0.00001f) {
1364                                                                 VECCOPY(vec1, vec2);
1365                                                                 E_NEAR(v1) = E_NEAR(v2);
1366                                                                 done = 1;
1367                                                         }
1368                                                 }
1369                                         }
1370                                         else {
1371                                                 v2->f2 = 1;
1372                                                 VecSubf(vec2, v2->co, E_NEAR(v1)->co);
1373                                                 if (VecLength(vec1) - VecLength(vec2) > 0.00001f) {
1374                                                         VECCOPY(vec2, vec1);
1375                                                 }
1376                                                 E_NEAR(v2) = E_NEAR(v1);
1377                                                 done = 1;
1378                                         }
1379                                 }
1380                                 else if (v2->f2) {
1381                                         v1->f2 = 1;
1382                                         VecSubf(vec1, v1->co, E_NEAR(v2)->co);
1383                                         if (VecLength(vec2) - VecLength(vec1) > 0.00001f) {
1384                                                 VECCOPY(vec1, vec2);
1385                                         }
1386                                         E_NEAR(v1) = E_NEAR(v2);
1387                                         done = 1;
1388                                 }
1389                         }
1390                 }
1391         }
1392 }
1393
1394 static void VertsToTransData(TransData *td, EditVert *eve)
1395 {
1396         td->flag = 0;
1397         td->loc = eve->co;
1398         VECCOPY(td->center, td->loc);
1399         VECCOPY(td->iloc, td->loc);
1400
1401         // Setting normals
1402         VECCOPY(td->axismtx[2], eve->no);
1403         td->axismtx[0][0]               =
1404                 td->axismtx[0][1]       =
1405                 td->axismtx[0][2]       =
1406                 td->axismtx[1][0]       =
1407                 td->axismtx[1][1]       =
1408                 td->axismtx[1][2]       = 0.0f;
1409
1410         td->ext = NULL;
1411         td->tdi = NULL;
1412         td->val = NULL;
1413         td->tdmir= NULL;
1414 }
1415
1416 static void make_vertexcos__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
1417 {
1418         float *vec = userData;
1419         
1420         vec+= 3*index;
1421         VECCOPY(vec, co);
1422 }
1423
1424 static float *get_mapped_editverts(void)
1425 {
1426         int needsFree;
1427         DerivedMesh *dm= editmesh_get_derived_cage(&needsFree);
1428         float *vertexcos;
1429         
1430         vertexcos= MEM_mallocN(3*sizeof(float)*G.totvert, "vertexcos map");
1431         
1432         dm->foreachMappedVert(dm, make_vertexcos__mapFunc, vertexcos);
1433         
1434         if (needsFree) dm->release(dm);
1435         return vertexcos;
1436 }
1437
1438 /* helper for below, interpolates or assigns and increments */
1439 static float *crazy_quat_blend(EditVert *eve, float *quat)
1440 {
1441         if(eve->vn==NULL) {
1442                 eve->vn= (EditVert *)quat;
1443                 QUATCOPY(quat+4, quat);
1444                 return quat+4;
1445         }
1446         else {
1447                 float *q1= (float *)eve->vn;
1448                 QuatInterpol(q1, q1, quat, 0.5f);
1449                 return quat;
1450         }
1451 }
1452
1453 static void set_crazyspace_quats(float *mappedcos, float *quats)
1454 {
1455         EditMesh *em = G.editMesh;
1456         EditVert *eve, *prev;
1457         EditFace *efa;
1458         float q1[4], q2[4];
1459         float *v1, *v2, *v3, *quatp;
1460         int index= 0;
1461         
1462         /* 2 abused locations in vertices */
1463         for(eve= em->verts.first; eve; eve= eve->next, index++) {
1464                 eve->vn= NULL;
1465                 eve->prev= (EditVert *)index;
1466         }
1467         
1468         quatp= quats;
1469         for(efa= em->faces.first; efa; efa= efa->next) {
1470                 /* vertex f1 flags were set for transform */
1471                 
1472                 if( (efa->v1->f1 && efa->v1->vn==NULL) || (efa->v2->f1 && efa->v2->vn==NULL)
1473                         || (efa->v3->f1 && efa->v3->vn==NULL) || (efa->v4 && efa->v4->f1 && efa->v4->vn==NULL) ) {
1474                 
1475                         triatoquat(efa->v1->co, efa->v2->co, efa->v3->co, q1);
1476                         
1477                         /* retrieve mapped coordinates */
1478                         v1= mappedcos + 3*( (int)(efa->v1->prev) );
1479                         v2= mappedcos + 3*( (int)(efa->v2->prev) );
1480                         v3= mappedcos + 3*( (int)(efa->v3->prev) );
1481                         triatoquat(v1, v2, v3, q2);
1482                         
1483                         QuatSub(quatp, q2, q1);
1484                         
1485                         if(efa->v1->f1) quatp= crazy_quat_blend(efa->v1, quatp);
1486                         if(efa->v2->f1) quatp= crazy_quat_blend(efa->v2, quatp);
1487                         if(efa->v3->f1) quatp= crazy_quat_blend(efa->v3, quatp);
1488                         if(efa->v4 && efa->v4->f1) quatp= crazy_quat_blend(efa->v4, quatp);
1489                 }
1490         }
1491
1492         /* restore abused prev pointer */
1493         for(prev= NULL, eve= em->verts.first; eve; prev= eve, eve= eve->next)
1494                 eve->prev= prev;
1495
1496 }
1497
1498 static void createTransEditVerts(TransInfo *t)
1499 {
1500         TransData *tob = NULL;
1501         EditMesh *em = G.editMesh;
1502         EditVert *eve;
1503         EditVert **nears = NULL;
1504         float *vectors = NULL, *mappedcos = NULL, *quats= NULL;
1505         float mtx[3][3], smtx[3][3];
1506         int count=0, countsel=0;
1507         int propmode = t->flag & T_PROP_EDIT;
1508         int mirror= (G.scene->toolsettings->editbutflag & B_MESH_X_MIRROR);
1509
1510         // transform now requires awareness for select mode, so we tag the f1 flags in verts
1511         if(G.scene->selectmode & SCE_SELECT_VERTEX) {
1512                 for(eve= em->verts.first; eve; eve= eve->next) {
1513                         if(eve->h==0 && (eve->f & SELECT)) 
1514                                 eve->f1= SELECT;
1515                         else
1516                                 eve->f1= 0;
1517                 }
1518         }
1519         else if(G.scene->selectmode & SCE_SELECT_EDGE) {
1520                 EditEdge *eed;
1521                 for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
1522                 for(eed= em->edges.first; eed; eed= eed->next) {
1523                         if(eed->h==0 && (eed->f & SELECT))
1524                                 eed->v1->f1= eed->v2->f1= SELECT;
1525                 }
1526         }
1527         else {
1528                 EditFace *efa;
1529                 for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
1530                 for(efa= em->faces.first; efa; efa= efa->next) {
1531                         if(efa->h==0 && (efa->f & SELECT)) {
1532                                 efa->v1->f1= efa->v2->f1= efa->v3->f1= SELECT;
1533                                 if(efa->v4) efa->v4->f1= SELECT;
1534                         }
1535                 }
1536         }
1537         
1538         /* now we can count */
1539         for(eve= em->verts.first; eve; eve= eve->next) {
1540                 if(eve->h==0) {
1541                         if(eve->f1) countsel++;
1542                         if(propmode) count++;
1543                 }
1544         }
1545         
1546         /* note: in prop mode we need at least 1 selected */
1547         if (countsel==0) return;
1548         
1549         if(propmode) {
1550                 t->total = count; 
1551         
1552                 /* allocating scratch arrays */
1553                 vectors = (float *)MEM_mallocN(t->total * 3 * sizeof(float), "scratch vectors");
1554                 nears = (EditVert**)MEM_mallocN(t->total * sizeof(EditVert*), "scratch nears");
1555         }
1556         else t->total = countsel;
1557         tob= t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Mesh EditMode)");
1558         
1559         Mat3CpyMat4(mtx, G.obedit->obmat);
1560         Mat3Inv(smtx, mtx);
1561
1562         if(propmode) editmesh_set_connectivity_distance(t->total, vectors, nears);
1563         
1564         /* detect CrazySpace [tm] */
1565         if(propmode==0) {
1566                 if(modifiers_getCageIndex(G.obedit, NULL)>=0) {
1567                         if(modifiers_isDeformed(G.obedit)) {
1568                                 mappedcos= get_mapped_editverts();
1569                                 /* add one more quaternion, because of crazy_quat_blend */
1570                                 quats= MEM_mallocN( (t->total+1)*sizeof(float)*4, "crazy quats");
1571                                 set_crazyspace_quats(mappedcos, quats);
1572                         }
1573                 }
1574         }
1575         
1576         /* find out which half we do */
1577         if(mirror) {
1578                 for (eve=em->verts.first; eve; eve=eve->next) {
1579                         if(eve->h==0 && eve->f1 && eve->co[0]!=0.0f) {
1580                                 if(eve->co[0]<0.0f)
1581                                         mirror = -1;
1582                                 break;
1583                         }
1584                 }
1585         }
1586         
1587         for (eve=em->verts.first; eve; eve=eve->next) {
1588                 if(eve->h==0) {
1589                         if(propmode || eve->f1) {
1590                                 VertsToTransData(tob, eve);
1591
1592                                 if(eve->f1) tob->flag |= TD_SELECTED;
1593                                 if(propmode) {
1594                                         if (eve->f2) {
1595                                                 float vec[3];
1596                                                 VECCOPY(vec, E_VEC(eve));
1597                                                 Mat3MulVecfl(mtx, vec);
1598                                                 tob->dist= VecLength(vec);
1599                                         }
1600                                         else {
1601                                                 tob->flag |= TD_NOTCONNECTED;
1602                                                 tob->dist = MAXFLOAT;
1603                                         }
1604                                 }
1605                                 
1606                                 /* CrazySpace */
1607                                 if(quats && eve->vn) {
1608                                         float mat[3][3], imat[3][3], qmat[3][3];
1609                                         
1610                                         QuatToMat3((float *)eve->vn, qmat);
1611                                         Mat3MulMat3(mat, mtx, qmat);
1612                                         Mat3Inv(imat, mat);
1613                                         
1614                                         Mat3CpyMat3(tob->smtx, imat);
1615                                         Mat3CpyMat3(tob->mtx, mat);
1616                                 }
1617                                 else {
1618                                         Mat3CpyMat3(tob->smtx, smtx);
1619                                         Mat3CpyMat3(tob->mtx, mtx);
1620                                 }
1621                                 
1622                                 /* Mirror? */
1623                                 if( (mirror>0 && tob->iloc[0]>0.0f) || (mirror<0 && tob->iloc[0]<0.0f)) {
1624                                         EditVert *vmir= editmesh_get_x_mirror_vert(G.obedit, tob->iloc);        /* initializes octree on first call */
1625                                         if(vmir!=eve) tob->tdmir= vmir;
1626                                 }
1627                                 tob++;
1628                         }
1629                 }       
1630         }
1631         if (propmode) {
1632                 MEM_freeN(vectors);
1633                 MEM_freeN(nears);
1634         }
1635         /* crazy space free */
1636         if(mappedcos)
1637                 MEM_freeN(mappedcos);
1638         if(quats)
1639                 MEM_freeN(quats);
1640 }
1641
1642 /* ********************* UV ****************** */
1643
1644 static void UVsToTransData(TransData *td, TransData2D *td2d, float *uv, int selected)
1645 {
1646         float aspx, aspy;
1647
1648         transform_aspect_ratio_tface_uv(&aspx, &aspy);
1649
1650         /* uv coords are scaled by aspects. this is needed for rotations and
1651            proportional editing to be consistent with the stretchted uv coords
1652            that are displayed. this also means that for display and numinput,
1653            and when the the uv coords are flushed, these are converted each time */
1654         td2d->loc[0] = uv[0]*aspx;
1655         td2d->loc[1] = uv[1]*aspy;
1656         td2d->loc[2] = 0.0f;
1657         td2d->loc2d = uv;
1658
1659         td->flag = 0;
1660         td->loc = td2d->loc;
1661         VECCOPY(td->center, td->loc);
1662         VECCOPY(td->iloc, td->loc);
1663
1664         memset(td->axismtx, 0, sizeof(td->axismtx));
1665         td->axismtx[2][2] = 1.0f;
1666
1667         td->ext= NULL; td->tdi= NULL; td->val= NULL;
1668
1669         if(selected) {
1670                 td->flag |= TD_SELECTED;
1671                 td->dist= 0.0;
1672         }
1673         else
1674                 td->dist= MAXFLOAT;
1675         
1676         Mat3One(td->mtx);
1677         Mat3One(td->smtx);
1678 }
1679
1680 static void createTransUVs(TransInfo *t)
1681 {
1682         TransData *td = NULL;
1683         TransData2D *td2d = NULL;
1684         Mesh *me;
1685         TFace *tf;
1686         MFace *mf;
1687         int a, count=0, countsel=0;
1688         int propmode = t->flag & T_PROP_EDIT;
1689         
1690         if(is_uv_tface_editing_allowed()==0) return;
1691         me= get_mesh(OBACT);
1692
1693         /* count */
1694         tf= me->tface;
1695         mf= me->mface;
1696         for(a=me->totface; a>0; a--, tf++, mf++) {
1697                 if(mf->v3 && tf->flag & TF_SELECT) {
1698                         if(tf->flag & TF_SEL1) countsel++;
1699                         if(tf->flag & TF_SEL2) countsel++;
1700                         if(tf->flag & TF_SEL3) countsel++;
1701                         if(mf->v4 && (tf->flag & TF_SEL4)) countsel++;
1702                         if(propmode)
1703                                 count += (mf->v4)? 4: 3;
1704                 }
1705         }
1706
1707         /* note: in prop mode we need at least 1 selected */
1708         if (countsel==0) return;
1709         
1710         t->total= (propmode)? count: countsel;
1711         t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(UV Editing)");
1712         /* for each 2d uv coord a 3d vector is allocated, so that they can be
1713            treated just as if they were 3d verts */
1714         t->data2d= MEM_mallocN(t->total*sizeof(TransData2D), "TransObData2D(UV Editing)");
1715
1716         if(G.sima->flag & SI_CLIP_UV)
1717                 t->flag |= T_CLIP_UV;
1718
1719         td= t->data;
1720         td2d= t->data2d;
1721         tf= me->tface;
1722         mf= me->mface;
1723         for(a=me->totface; a>0; a--, tf++, mf++) {
1724                 if(mf->v3 && tf->flag & TF_SELECT) {
1725                         if(tf->flag & TF_SEL1 || propmode)
1726                                 UVsToTransData(td++, td2d++, tf->uv[0], (tf->flag & TF_SEL1));
1727                         if(tf->flag & TF_SEL2 || propmode)
1728                                 UVsToTransData(td++, td2d++, tf->uv[1], (tf->flag & TF_SEL2));
1729                         if(tf->flag & TF_SEL3 || propmode)
1730                                 UVsToTransData(td++, td2d++, tf->uv[2], (tf->flag & TF_SEL3));
1731
1732                         if(mf->v4 && (tf->flag & TF_SEL4 || propmode))
1733                                 UVsToTransData(td++, td2d++, tf->uv[3], (tf->flag & TF_SEL4));
1734                 }
1735         }
1736
1737         if (G.sima->flag & SI_LSCM_LIVE)
1738                 unwrap_lscm_live_begin();
1739 }
1740
1741 void flushTransUVs(TransInfo *t)
1742 {
1743         TransData2D *td;
1744         int a, width, height;
1745         Object *ob= OBACT;
1746         Mesh *me= get_mesh(ob);
1747         float aspx, aspy, invx, invy;
1748
1749         transform_aspect_ratio_tface_uv(&aspx, &aspy);
1750         transform_width_height_tface_uv(&width, &height);
1751         invx= 1.0f/aspx;
1752         invy= 1.0f/aspy;
1753
1754         /* flush to 2d vector from internally used 3d vector */
1755         for(a=0, td= t->data2d; a<t->total; a++, td++) {
1756                 td->loc2d[0]= td->loc[0]*invx;
1757                 td->loc2d[1]= td->loc[1]*invy;
1758                 
1759                 if((G.sima->flag & SI_PIXELSNAP) && (t->state != TRANS_CANCEL)) {
1760                         td->loc2d[0]= floor(width*td->loc2d[0])/width;
1761                         td->loc2d[1]= floor(height*td->loc2d[1])/height;
1762                 }
1763         }
1764
1765         if((G.sima->flag & SI_BE_SQUARE) && (t->state != TRANS_CANCEL))
1766                 be_square_tface_uv(me);
1767
1768         /* this is overkill if G.sima->lock is not set, but still needed */
1769         object_uvs_changed(ob);
1770 }
1771
1772 int clipUVTransform(TransInfo *t, float *vec, int resize)
1773 {
1774         TransData *td;
1775         int a, clipx=1, clipy=1;
1776         float aspx, aspy, min[2], max[2];
1777
1778         transform_aspect_ratio_tface_uv(&aspx, &aspy);
1779         min[0]= min[1]= 0.0f;
1780         max[0]= aspx; max[1]= aspy;
1781
1782         for(a=0, td= t->data; a<t->total; a++, td++) {
1783                 DO_MINMAX2(td->loc, min, max);
1784         }
1785
1786         if(resize) {
1787                 if(min[0] < 0.0f && t->center[0] > 0.0f && t->center[0] < aspx*0.5f)
1788                         vec[0] *= t->center[0]/(t->center[0] - min[0]);
1789                 else if(max[0] > aspx && t->center[0] < aspx)
1790                         vec[0] *= (t->center[0] - aspx)/(t->center[0] - max[0]);
1791                 else
1792                         clipx= 0;
1793
1794                 if(min[1] < 0.0f && t->center[1] > 0.0f && t->center[1] < aspy*0.5f)
1795                         vec[1] *= t->center[1]/(t->center[1] - min[1]);
1796                 else if(max[1] > aspy && t->center[1] < aspy)
1797                         vec[1] *= (t->center[1] - aspy)/(t->center[1] - max[1]);
1798                 else
1799                         clipy= 0;
1800         }
1801         else {
1802                 if(min[0] < 0.0f)
1803                         vec[0] -= min[0];
1804                 else if(max[0] > aspx)
1805                         vec[0] -= max[0]-aspx;
1806                 else
1807                         clipx= 0;
1808
1809                 if(min[1] < 0.0f)
1810                         vec[1] -= min[1];
1811                 else if(max[1] > aspy)
1812                         vec[1] -= max[1]-aspy;
1813                 else
1814                         clipy= 0;
1815         }       
1816
1817         return (clipx || clipy);
1818 }
1819
1820 /* **************** IpoKey stuff, for Object TransData ********** */
1821
1822 /* storage of bezier triple. thats why -3 and +3! */
1823 static void set_tdi_old(float *old, float *poin)
1824 {
1825         old[0]= *(poin);
1826         old[3]= *(poin-3);
1827         old[6]= *(poin+3);
1828 }
1829
1830 /* while transforming */
1831 void add_tdi_poin(float *poin, float *old, float delta)
1832 {
1833         if(poin) {
1834                 poin[0]= old[0]+delta;
1835                 poin[-3]= old[3]+delta;
1836                 poin[3]= old[6]+delta;
1837         }
1838 }
1839
1840 /* fill ipokey transdata with old vals and pointers */
1841 static void ipokey_to_transdata(IpoKey *ik, TransData *td)
1842 {
1843         extern int ob_ar[];             // blenkernel ipo.c
1844         TransDataIpokey *tdi= td->tdi;
1845         BezTriple *bezt;
1846         int a, delta= 0;
1847         
1848         td->val= NULL;  // is read on ESC
1849         
1850         for(a=0; a<OB_TOTIPO; a++) {
1851                 if(ik->data[a]) {
1852                         bezt= ik->data[a];
1853                         
1854                         switch( ob_ar[a] ) {
1855                                 case OB_LOC_X:
1856                                 case OB_DLOC_X:
1857                                         tdi->locx= &(bezt->vec[1][1]); break;
1858                                 case OB_LOC_Y:
1859                                 case OB_DLOC_Y:
1860                                         tdi->locy= &(bezt->vec[1][1]); break;
1861                                 case OB_LOC_Z:
1862                                 case OB_DLOC_Z:
1863                                         tdi->locz= &(bezt->vec[1][1]); break;
1864                                         
1865                                 case OB_DROT_X:
1866                                         delta= 1;
1867                                 case OB_ROT_X:
1868                                         tdi->rotx= &(bezt->vec[1][1]); break;
1869                                 case OB_DROT_Y:
1870                                         delta= 1;
1871                                 case OB_ROT_Y:
1872                                         tdi->roty= &(bezt->vec[1][1]); break;
1873                                 case OB_DROT_Z:
1874                                         delta= 1;
1875                                 case OB_ROT_Z:
1876                                         tdi->rotz= &(bezt->vec[1][1]); break;
1877                                         
1878                                 case OB_SIZE_X:
1879                                 case OB_DSIZE_X:
1880                                         tdi->sizex= &(bezt->vec[1][1]); break;
1881                                 case OB_SIZE_Y:
1882                                 case OB_DSIZE_Y:
1883                                         tdi->sizey= &(bezt->vec[1][1]); break;
1884                                 case OB_SIZE_Z:
1885                                 case OB_DSIZE_Z:
1886                                         tdi->sizez= &(bezt->vec[1][1]); break;          
1887                         }       
1888                 }
1889         }
1890         
1891         /* oldvals for e.g. undo */
1892         if(tdi->locx) set_tdi_old(tdi->oldloc, tdi->locx);
1893         if(tdi->locy) set_tdi_old(tdi->oldloc+1, tdi->locy);
1894         if(tdi->locz) set_tdi_old(tdi->oldloc+2, tdi->locz);
1895         
1896         /* remember, for mapping curves ('1'=10 degrees)  */
1897         if(tdi->rotx) set_tdi_old(tdi->oldrot, tdi->rotx);
1898         if(tdi->roty) set_tdi_old(tdi->oldrot+1, tdi->roty);
1899         if(tdi->rotz) set_tdi_old(tdi->oldrot+2, tdi->rotz);
1900         
1901         /* this is not allowed to be dsize! */
1902         if(tdi->sizex) set_tdi_old(tdi->oldsize, tdi->sizex);
1903         if(tdi->sizey) set_tdi_old(tdi->oldsize+1, tdi->sizey);
1904         if(tdi->sizez) set_tdi_old(tdi->oldsize+2, tdi->sizez);
1905         
1906         tdi->flag= TOB_IPO;
1907         if(delta) tdi->flag |= TOB_IPODROT;
1908 }
1909
1910
1911 /* *************************** Object Transform data ******************* */
1912
1913 static void ObjectToTransData(TransData *td, Object *ob) 
1914 {
1915         float obmtx[3][3];
1916         Object *tr;
1917         void *cfirst, *clast;
1918
1919         /* set axismtx BEFORE clearing constraints to have the real orientation */
1920         Mat3CpyMat4(td->axismtx, ob->obmat);
1921         Mat3Ortho(td->axismtx);
1922
1923         /* then why are constraints and track disabled here? 
1924                 they dont alter loc/rot/size itself (ton) */
1925         cfirst = ob->constraints.first;
1926         clast = ob->constraints.last;
1927         ob->constraints.first=ob->constraints.last=NULL;
1928
1929         tr= ob->track;
1930         ob->track= NULL;
1931
1932         where_is_object(ob);
1933
1934         ob->track= tr;
1935
1936         ob->constraints.first = cfirst;
1937         ob->constraints.last = clast;
1938
1939         td->ob = ob;
1940
1941         td->loc = ob->loc;
1942         VECCOPY(td->iloc, td->loc);
1943         
1944         td->ext->rot = ob->rot;
1945         VECCOPY(td->ext->irot, ob->rot);
1946         VECCOPY(td->ext->drot, ob->drot);
1947         
1948         td->ext->size = ob->size;
1949         VECCOPY(td->ext->isize, ob->size);
1950         VECCOPY(td->ext->dsize, ob->dsize);
1951
1952         VECCOPY(td->center, ob->obmat[3]);
1953
1954         if (ob->parent)
1955         {
1956                 float totmat[3][3], obinv[3][3];
1957                 
1958                 /* we calculate smtx without obmat: so a parmat */
1959                 object_to_mat3(ob, obmtx);
1960                 Mat3CpyMat4(totmat, ob->obmat);
1961                 Mat3Inv(obinv, totmat);
1962                 Mat3MulMat3(td->smtx, obmtx, obinv);
1963                 Mat3Inv(td->mtx, td->smtx);
1964         }
1965         else
1966         {
1967                 Mat3One(td->smtx);
1968                 Mat3One(td->mtx);
1969         }
1970 }
1971
1972
1973 /* sets flags in Bases to define whether they take part in transform */
1974 /* it deselects Bases, so we have to call the clear function always after */
1975 static void set_trans_object_base_flags(TransInfo *t)
1976 {
1977         /*
1978          if Base selected and has parent selected:
1979          base->flag= BA_WAS_SEL
1980          */
1981         Base *base;
1982         
1983         /* makes sure base flags and object flags are identical */
1984         copy_baseflags();
1985         
1986         /* handle pending update events, otherwise they got copied below */
1987         for (base= FIRSTBASE; base; base= base->next) {
1988                 if(base->object->recalc) 
1989                         object_handle_update(base->object);
1990         }
1991         
1992         for (base= FIRSTBASE; base; base= base->next) {
1993                 base->flag &= ~BA_WAS_SEL;
1994                 
1995                 if(TESTBASELIB(base)) {
1996                         Object *ob= base->object;
1997                         Object *parsel= ob->parent;
1998                         
1999                         /* if parent selected, deselect */
2000                         while(parsel) {
2001                                 if(parsel->flag & SELECT) break;
2002                                 parsel= parsel->parent;
2003                         }
2004                         
2005                         if(parsel) {
2006                                 base->flag &= ~SELECT;
2007                                 base->flag |= BA_WAS_SEL;
2008                         }
2009                         /* used for flush, depgraph will change recalcs if needed :) */
2010                         ob->recalc |= OB_RECALC_OB;
2011                 }
2012         }
2013         /* all recalc flags get flushed */
2014         DAG_scene_flush_update(G.scene, screen_view3d_layers());
2015         
2016         /* and we store them temporal in base (only used for transform code) */
2017         /* this because after doing updates, the object->recalc is cleared */
2018         for (base= FIRSTBASE; base; base= base->next) {
2019                 if(base->object->recalc & OB_RECALC_OB)
2020                         base->flag |= BA_HAS_RECALC_OB;
2021                 if(base->object->recalc & OB_RECALC_DATA)
2022                         base->flag |= BA_HAS_RECALC_DATA;
2023         }
2024 }
2025
2026 static void clear_trans_object_base_flags(void)
2027 {
2028         Base *base;
2029         
2030         base= FIRSTBASE;
2031         while(base) {
2032                 if(base->flag & BA_WAS_SEL) base->flag |= SELECT;
2033                 base->flag &= ~(BA_WAS_SEL|BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA|BA_DO_IPO);
2034                 
2035                 base = base->next;
2036         }
2037 }
2038
2039 /* inserting keys, refresh ipo-keys, softbody, redraw events... (ton) */
2040 /* note; transdata has been freed already! */
2041 void special_aftertrans_update(TransInfo *t)
2042 {
2043         Object *ob;
2044         Base *base;
2045         int redrawipo=0;
2046         int cancelled= (t->state == TRANS_CANCEL);
2047                 
2048         if(G.obedit) {
2049                 if(t->mode==TFM_BONESIZE || t->mode==TFM_BONE_ENVELOPE)
2050                         allqueue(REDRAWBUTSEDIT, 0);
2051                 
2052                 /* table needs to be created for each edit command, since vertices can move etc */
2053                 mesh_octree_table(G.obedit, NULL, 'e');
2054         }
2055         else if( (t->flag & T_POSE) && t->poseobj) {
2056                 bArmature *arm;
2057                 bAction *act;
2058                 bPose   *pose;
2059                 bPoseChannel *pchan;
2060
2061                 ob= t->poseobj;
2062                 arm= ob->data;
2063                 pose= ob->pose;
2064                 
2065                 /* this signal does one recalc on pose, then unlocks, so ESC or edit will work */
2066                 pose->flag |= POSE_DO_UNLOCK;
2067
2068                 /* if target-less IK grabbing, we calculate the pchan transforms and clear flag */
2069                 if(!cancelled && t->mode==TFM_TRANSLATION)
2070                         apply_targetless_ik(ob);
2071                 else {
2072                         /* not forget to clear the auto flag */
2073                         for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
2074                                 bKinematicConstraint *data= has_targetless_ik(pchan);
2075                                 if(data) data->flag &= ~CONSTRAINT_IK_AUTO;
2076                         }
2077                 }
2078                 
2079                 if(t->mode==TFM_TRANSLATION)
2080                         pose_grab_with_ik_clear(ob);
2081                 
2082                 /* automatic inserting of keys */
2083                 if((G.flags & G_RECORDKEYS) && (!cancelled)) {
2084                         act= ob->action;
2085                         
2086                         if (!act)
2087                                 act= ob->action= add_empty_action(ID_PO);
2088                         
2089                         for (pchan=pose->chanbase.first; pchan; pchan=pchan->next){
2090                                 if (pchan->bone->flag & BONE_TRANSFORM){
2091                                         
2092                                         insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_X);
2093                                         insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Y);
2094                                         insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Z);
2095                                         
2096                                         insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_W);
2097                                         insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_X);
2098                                         insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Y);
2099                                         insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Z);
2100                                         
2101                                         insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_X);
2102                                         insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Y);
2103                                         insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Z);
2104                                 }
2105                         }
2106                         
2107                         remake_action_ipos (act);
2108                         allspace(REMAKEIPO, 0);
2109                         allqueue(REDRAWACTION, 0);
2110                         allqueue(REDRAWIPO, 0);
2111                         allqueue(REDRAWNLA, 0);
2112                         
2113                         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2114                 }
2115                 else if(arm->flag & ARM_DELAYDEFORM) {
2116                         /* old optimize trick... this enforces to bypass the depgraph */
2117                         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2118                         ob->recalc= 0;  // is set on OK position already by recalcData()
2119                 }
2120                 else 
2121                         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2122                 
2123                 if(t->mode==TFM_BONESIZE || t->mode==TFM_BONE_ENVELOPE)
2124                         allqueue(REDRAWBUTSEDIT, 0);
2125
2126         }
2127         else {
2128                 base= FIRSTBASE;
2129                 while(base) {   
2130                         
2131                         if(base->flag & BA_DO_IPO) redrawipo= 1;
2132                         
2133                         ob= base->object;
2134
2135                         if(modifiers_isSoftbodyEnabled(ob)) ob->softflag |= OB_SB_REDO;
2136                         
2137                         /* Set autokey if necessary */
2138                         if ((G.flags & G_RECORDKEYS) && (!cancelled) && (base->flag & SELECT)){
2139                                 char *actname="";
2140                                 
2141                                 if(ob->ipoflag & OB_ACTION_OB)
2142                                         actname= "Object";
2143                                 
2144                                 insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_X);
2145                                 insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_Y);
2146                                 insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_Z);
2147                         
2148                                 insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_X);
2149                                 insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_Y);
2150                                 insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_Z);
2151                         
2152                                 insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_X);
2153                                 insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_Y);
2154                                 insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_Z);
2155                                 
2156                                 remake_object_ipos (ob);
2157                                 allqueue(REDRAWIPO, 0);
2158                                 allspace(REMAKEIPO, 0);
2159                                 allqueue(REDRAWVIEW3D, 0);
2160                                 allqueue(REDRAWNLA, 0);
2161                         }
2162                         
2163                         base= base->next;
2164                 }
2165                 
2166         }
2167         
2168         clear_trans_object_base_flags();
2169         
2170         if(redrawipo) {
2171                 allqueue(REDRAWNLA, 0);
2172                 allqueue(REDRAWACTION, 0);
2173                 allqueue(REDRAWIPO, 0);
2174         }
2175         
2176         reset_slowparents();
2177         
2178         /* note; should actually only be done for all objects when a lamp is moved... (ton) */
2179         if(t->spacetype==SPACE_VIEW3D && G.vd->drawtype == OB_SHADED)
2180                 reshadeall_displist();
2181 }
2182
2183 static void createTransObject(TransInfo *t)
2184 {
2185         TransData *td = NULL;
2186         TransDataExtension *tx;
2187         Object *ob;
2188         Base *base;
2189         IpoKey *ik;
2190         ListBase elems;
2191         
2192         set_trans_object_base_flags(t);
2193
2194         /* count */     
2195         for(base= FIRSTBASE; base; base= base->next) {
2196                 if TESTBASELIB(base) {
2197                         ob= base->object;
2198                         
2199                         /* store ipo keys? */
2200                         if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) {
2201                                 elems.first= elems.last= NULL;
2202                                 make_ipokey_transform(ob, &elems, 1); /* '1' only selected keys */
2203                                 
2204                                 pushdata(&elems, sizeof(ListBase));
2205                                 
2206                                 for(ik= elems.first; ik; ik= ik->next) t->total++;
2207
2208                                 if(elems.first==NULL) t->total++;
2209                         }
2210                         else {
2211                                 t->total++;
2212                         }
2213                 }
2214         }
2215
2216         if(!t->total) {
2217                 /* clear here, main transform function escapes too */
2218                 clear_trans_object_base_flags();
2219                 return;
2220         }
2221         
2222         td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransOb");
2223         tx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "TransObExtension");
2224
2225         for(base= FIRSTBASE; base; base= base->next) {
2226                 if TESTBASELIB(base) {
2227                         ob= base->object;
2228                         
2229                         td->flag= TD_SELECTED;
2230                         td->protectflag= ob->protectflag;
2231                         td->ext = tx;
2232
2233                         /* store ipo keys? */
2234                         if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) {
2235                                 
2236                                 popfirst(&elems);       // bring back pushed listbase
2237                                 
2238                                 if(elems.first) {
2239                                         float cfraont;
2240                                         int ipoflag;
2241                                         
2242                                         base->flag |= BA_DO_IPO+BA_WAS_SEL;
2243                                         base->flag &= ~SELECT;
2244                                         
2245                                         cfraont= CFRA;
2246                                         set_no_parent_ipo(1);
2247                                         ipoflag= ob->ipoflag;
2248                                         ob->ipoflag &= ~OB_OFFS_OB;
2249                                         
2250                                         pushdata(ob->loc, 7*3*4); // tsk! tsk!
2251                                         
2252                                         for(ik= elems.first; ik; ik= ik->next) {
2253                                                 
2254                                                 /* weak... this doesn't correct for floating values, giving small errors */
2255                                                 CFRA= (short)(ik->val/G.scene->r.framelen);
2256                                                 
2257                                                 do_ob_ipo(ob);
2258                                                 ObjectToTransData(td, ob);      // does where_is_object()
2259                                                 
2260                                                 td->flag= TD_SELECTED;
2261                                                 
2262                                                 td->tdi= MEM_callocN(sizeof(TransDataIpokey), "TransDataIpokey");
2263                                                 /* also does tdi->flag and oldvals, needs to be after ob_to_transob()! */
2264                                                 ipokey_to_transdata(ik, td);
2265                                                 
2266                                                 td++;
2267                                                 tx++;
2268                                                 if(ik->next) td->ext= tx;       // prevent corrupting mem!
2269                                         }
2270                                         free_ipokey(&elems);
2271                                         
2272                                         poplast(ob->loc);
2273                                         set_no_parent_ipo(0);
2274                                         
2275                                         CFRA= (short)cfraont;
2276                                         ob->ipoflag= ipoflag;
2277                                         
2278                                         where_is_object(ob);    // restore 
2279                                 }
2280                                 else {
2281                                         ObjectToTransData(td, ob);
2282                                         td->tdi = NULL;
2283                                         td->val = NULL;
2284                                         td++;
2285                                         tx++;
2286                                 }
2287                         }
2288                         else {
2289                                 ObjectToTransData(td, ob);
2290                                 td->tdi = NULL;
2291                                 td->val = NULL;
2292                                 td++;
2293                                 tx++;
2294                         }
2295                 }
2296         }
2297 }
2298
2299 void createTransData(TransInfo *t) 
2300 {
2301         Object *ob= OBACT;
2302         
2303         if (t->context == CTX_TEXTURE) {
2304                 t->flag |= T_TEXTURE;
2305                 createTransTexspace(t);
2306         }
2307         else if (t->context == CTX_EDGE) {
2308                 t->ext = NULL;
2309                 t->flag |= T_EDIT;
2310                 createTransEdge(t);
2311                 if(t->data && t->flag & T_PROP_EDIT) {
2312                         sort_trans_data(t);     // makes selected become first in array
2313                         set_prop_dist(t, 1);
2314                         sort_trans_data_dist(t);
2315                 }
2316         }
2317         else if (t->spacetype == SPACE_IMAGE) {
2318                 t->flag |= T_POINTS|T_2D_EDIT;
2319                 createTransUVs(t);
2320                 if(t->data && (t->flag & T_PROP_EDIT)) {
2321                         sort_trans_data(t);     // makes selected become first in array
2322                         set_prop_dist(t, 1);
2323                         sort_trans_data_dist(t);
2324                 }
2325         }
2326         else if (G.obedit) {
2327                 t->ext = NULL;
2328                 if (G.obedit->type == OB_MESH) {
2329                         createTransEditVerts(t);        
2330                 }
2331                 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
2332                         createTransCurveVerts(t);
2333                 }
2334                 else if (G.obedit->type==OB_LATTICE) {
2335                         createTransLatticeVerts(t);
2336                 }
2337                 else if (G.obedit->type==OB_MBALL) {
2338                         createTransMBallVerts(t);
2339                 }
2340                 else if (G.obedit->type==OB_ARMATURE) {
2341                         createTransArmatureVerts(t);
2342                 }                                                       
2343                 else {
2344                         printf("not done yet! only have mesh surface curve\n");
2345                 }
2346
2347                 if(t->data && t->flag & T_PROP_EDIT) {
2348                         if (ELEM(G.obedit->type, OB_CURVE, OB_MESH)) {
2349                                 sort_trans_data(t);     // makes selected become first in array
2350                                 set_prop_dist(t, 0);
2351                                 sort_trans_data_dist(t);
2352                         }
2353                         else {
2354                                 sort_trans_data(t);     // makes selected become first in array
2355                                 set_prop_dist(t, 1);
2356                                 sort_trans_data_dist(t);
2357                         }
2358                 }
2359
2360                 t->flag |= T_EDIT|T_POINTS;
2361                 
2362                 /* exception... hackish, we want bonesize to use bone orientation matrix (ton) */
2363                 if(t->mode==TFM_BONESIZE) {
2364                         t->flag &= ~(T_EDIT|T_POINTS);
2365                         t->flag |= T_POSE;
2366                         t->poseobj= ob; /* <- tsk tsk, this is going to give issues one day */
2367                 }
2368         }
2369         else if (ob && (ob->flag & OB_POSEMODE)) {
2370                 createTransPose(t, OBACT);
2371         }
2372         else if (G.f & G_WEIGHTPAINT) {
2373                 /* exception, we look for the one selected armature */
2374                 Base *base;
2375                 for(base=FIRSTBASE; base; base= base->next) {
2376                         if(TESTBASELIB(base)) {
2377                                 if(base->object->type==OB_ARMATURE)
2378                                         if(base->object->flag & OB_POSEMODE)
2379                                                 break;
2380                         }
2381                 }
2382                 if(base) {
2383                         createTransPose(t, base->object);
2384                 }
2385         }
2386         else {
2387                 createTransObject(t);
2388                 t->flag |= T_OBJECT;
2389         }
2390
2391         if((t->flag & T_OBJECT) && G.vd->camera==OBACT && G.vd->persp>1) {
2392                 t->flag |= T_CAMERA;
2393         }
2394 }
2395