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