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