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