2.5: Curve edit mode. Transform works again, and editcurve.c is
[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         Object *obedit= CTX_data_edit_object(C);
1342         Curve *cu= obedit->data;
1343         TransData *td = NULL;
1344         Nurb *nu;
1345         BezTriple *bezt;
1346         BPoint *bp;
1347         float mtx[3][3], smtx[3][3];
1348         int a;
1349         int count=0, countsel=0;
1350         int propmode = t->flag & T_PROP_EDIT;
1351
1352         /* to be sure */
1353         if(cu->editnurb==NULL) return;
1354         
1355         /* count total of vertices, check identical as in 2nd loop for making transdata! */
1356         for(nu= cu->editnurb->first; nu; nu= nu->next) {
1357                 if((nu->type & 7)==CU_BEZIER) {
1358                         for(a=0, bezt= nu->bezt; a<nu->pntsu; a++, bezt++) {
1359                                 if(bezt->hide==0) {
1360                                         if (G.f & G_HIDDENHANDLES) {
1361                                                 if(bezt->f2 & SELECT) countsel+=3;
1362                                                 if(propmode) count+= 3;
1363                                         } else {
1364                                                 if(bezt->f1 & SELECT) countsel++;
1365                                                 if(bezt->f2 & SELECT) countsel++;
1366                                                 if(bezt->f3 & SELECT) countsel++;
1367                                                 if(propmode) count+= 3;
1368                                         }
1369                                 }
1370                         }
1371                 }
1372                 else {
1373                         for(a= nu->pntsu*nu->pntsv, bp= nu->bp; a>0; a--, bp++) {
1374                                 if(bp->hide==0) {
1375                                         if(propmode) count++;
1376                                         if(bp->f1 & SELECT) countsel++;
1377                                 }
1378                         }
1379                 }
1380         }
1381         /* note: in prop mode we need at least 1 selected */
1382         if (countsel==0) return;
1383         
1384         if(propmode) t->total = count; 
1385         else t->total = countsel;
1386         t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Curve EditMode)");
1387
1388         Mat3CpyMat4(mtx, t->obedit->obmat);
1389         Mat3Inv(smtx, mtx);
1390         
1391     td = t->data;
1392         for(nu= cu->editnurb->first; nu; nu= nu->next) {
1393                 if((nu->type & 7)==CU_BEZIER) {
1394                         TransData *head, *tail;
1395                         head = tail = td;
1396                         for(a=0, bezt= nu->bezt; a<nu->pntsu; a++, bezt++) {
1397                                 if(bezt->hide==0) {
1398                                         TransDataCurveHandleFlags *hdata = NULL;
1399                                         
1400                                         if(             propmode ||
1401                                                         ((bezt->f2 & SELECT) && (G.f & G_HIDDENHANDLES)) ||
1402                                                         ((bezt->f1 & SELECT) && (G.f & G_HIDDENHANDLES)==0)
1403                                           ) {
1404                                                 VECCOPY(td->iloc, bezt->vec[0]);
1405                                                 td->loc= bezt->vec[0];
1406                                                 VECCOPY(td->center, bezt->vec[1]);
1407                                                 if (G.f & G_HIDDENHANDLES) {
1408                                                         if(bezt->f2 & SELECT) td->flag= TD_SELECTED;
1409                                                         else td->flag= 0;
1410                                                 } else {
1411                                                         if(bezt->f1 & SELECT) td->flag= TD_SELECTED;
1412                                                         else td->flag= 0;
1413                                                 }
1414                                                 td->ext = NULL;
1415                                                 td->tdi = NULL;
1416                                                 td->val = NULL;
1417                                                 
1418                                                 hdata = initTransDataCurveHandes(td, bezt);
1419
1420                                                 Mat3CpyMat3(td->smtx, smtx);
1421                                                 Mat3CpyMat3(td->mtx, mtx);
1422
1423                                                 td++;
1424                                                 count++;
1425                                                 tail++;
1426                                         }
1427                                         
1428                                         /* This is the Curve Point, the other two are handles */
1429                                         if(propmode || (bezt->f2 & SELECT)) {
1430                                                 VECCOPY(td->iloc, bezt->vec[1]);
1431                                                 td->loc= bezt->vec[1];
1432                                                 VECCOPY(td->center, td->loc);
1433                                                 if(bezt->f2 & SELECT) td->flag= TD_SELECTED;
1434                                                 else td->flag= 0;
1435                                                 td->ext = NULL;
1436                                                 td->tdi = NULL;
1437                                                 
1438                                                 if (t->mode==TFM_CURVE_SHRINKFATTEN) { /* || t->mode==TFM_RESIZE) {*/ /* TODO - make points scale */
1439                                                         td->val = &(bezt->radius);
1440                                                         td->ival = bezt->radius;
1441                                                 } else if (t->mode==TFM_TILT) {
1442                                                         td->val = &(bezt->alfa);
1443                                                         td->ival = bezt->alfa;
1444                                                 } else {
1445                                                         td->val = NULL;
1446                                                 }
1447
1448                                                 Mat3CpyMat3(td->smtx, smtx);
1449                                                 Mat3CpyMat3(td->mtx, mtx);
1450                                                 
1451                                                 if ((bezt->f1&SELECT)==0 && (bezt->f3&SELECT)==0)
1452                                                 /* If the middle is selected but the sides arnt, this is needed */
1453                                                 if (hdata==NULL) { /* if the handle was not saved by the previous handle */
1454                                                         hdata = initTransDataCurveHandes(td, bezt);
1455                                                 }
1456                                                 
1457                                                 td++;
1458                                                 count++;
1459                                                 tail++;
1460                                         }
1461                                         if(             propmode ||
1462                                                         ((bezt->f2 & SELECT) && (G.f & G_HIDDENHANDLES)) ||
1463                                                         ((bezt->f3 & SELECT) && (G.f & G_HIDDENHANDLES)==0)
1464                                           ) {
1465                                                 VECCOPY(td->iloc, bezt->vec[2]);
1466                                                 td->loc= bezt->vec[2];
1467                                                 VECCOPY(td->center, bezt->vec[1]);
1468                                                 if (G.f & G_HIDDENHANDLES) {
1469                                                         if(bezt->f2 & SELECT) td->flag= TD_SELECTED;
1470                                                         else td->flag= 0;
1471                                                 } else {
1472                                                         if(bezt->f3 & SELECT) td->flag= TD_SELECTED;
1473                                                         else td->flag= 0;
1474                                                 }
1475                                                 td->ext = NULL;
1476                                                 td->tdi = NULL;
1477                                                 td->val = NULL;
1478
1479                                                 if (hdata==NULL) { /* if the handle was not saved by the previous handle */
1480                                                         hdata = initTransDataCurveHandes(td, bezt);
1481                                                 }
1482                                                 
1483                                                 Mat3CpyMat3(td->smtx, smtx);
1484                                                 Mat3CpyMat3(td->mtx, mtx);
1485
1486                                                 td++;
1487                                                 count++;
1488                                                 tail++;
1489                                         }
1490                                 }
1491                                 else if (propmode && head != tail) {
1492                                         calc_distanceCurveVerts(head, tail-1);
1493                                         head = tail;
1494                                 }
1495                         }
1496                         if (propmode && head != tail)
1497                                 calc_distanceCurveVerts(head, tail-1);
1498                         
1499                         /* TODO - in the case of tilt and radius we can also avoid allocating the initTransDataCurveHandes
1500                          * but for now just dont change handle types */
1501                         if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT) == 0)
1502                                 testhandlesNurb(nu); /* sets the handles based on their selection, do this after the data is copied to the TransData */
1503                 }
1504                 else {
1505                         TransData *head, *tail;
1506                         head = tail = td;
1507                         for(a= nu->pntsu*nu->pntsv, bp= nu->bp; a>0; a--, bp++) {
1508                                 if(bp->hide==0) {
1509                                         if(propmode || (bp->f1 & SELECT)) {
1510                                                 VECCOPY(td->iloc, bp->vec);
1511                                                 td->loc= bp->vec;
1512                                                 VECCOPY(td->center, td->loc);
1513                                                 if(bp->f1 & SELECT) td->flag= TD_SELECTED;
1514                                                 else td->flag= 0;
1515                                                 td->ext = NULL;
1516                                                 td->tdi = NULL;
1517                                                 
1518                                                 if (t->mode==TFM_CURVE_SHRINKFATTEN || t->mode==TFM_RESIZE) {
1519                                                         td->val = &(bp->radius);
1520                                                         td->ival = bp->radius;
1521                                                 } else {
1522                                                         td->val = &(bp->alfa);
1523                                                         td->ival = bp->alfa;
1524                                                 }
1525
1526                                                 Mat3CpyMat3(td->smtx, smtx);
1527                                                 Mat3CpyMat3(td->mtx, mtx);
1528
1529                                                 td++;
1530                                                 count++;
1531                                                 tail++;
1532                                         }
1533                                 }
1534                                 else if (propmode && head != tail) {
1535                                         calc_distanceCurveVerts(head, tail-1);
1536                                         head = tail;
1537                                 }
1538                         }
1539                         if (propmode && head != tail)
1540                                 calc_distanceCurveVerts(head, tail-1);
1541                 }
1542         }
1543 }
1544
1545 /* ********************* lattice *************** */
1546
1547 static void createTransLatticeVerts(bContext *C, TransInfo *t)
1548 {
1549         Lattice *latt = ((Lattice*)t->obedit->data)->editlatt;
1550         TransData *td = NULL;
1551         BPoint *bp;
1552         float mtx[3][3], smtx[3][3];
1553         int a;
1554         int count=0, countsel=0;
1555         int propmode = t->flag & T_PROP_EDIT;
1556
1557         bp = latt->def;
1558         a  = latt->pntsu * latt->pntsv * latt->pntsw;
1559         while(a--) {
1560                 if(bp->hide==0) {
1561                         if(bp->f1 & SELECT) countsel++;
1562                         if(propmode) count++;
1563                 }
1564                 bp++;
1565         }
1566         
1567         /* note: in prop mode we need at least 1 selected */
1568         if (countsel==0) return;
1569         
1570         if(propmode) t->total = count; 
1571         else t->total = countsel;
1572         t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Lattice EditMode)");
1573         
1574         Mat3CpyMat4(mtx, t->obedit->obmat);
1575         Mat3Inv(smtx, mtx);
1576
1577         td = t->data;
1578         bp = latt->def;
1579         a  = latt->pntsu * latt->pntsv * latt->pntsw;
1580         while(a--) {
1581                 if(propmode || (bp->f1 & SELECT)) {
1582                         if(bp->hide==0) {
1583                                 VECCOPY(td->iloc, bp->vec);
1584                                 td->loc= bp->vec;
1585                                 VECCOPY(td->center, td->loc);
1586                                 if(bp->f1 & SELECT) td->flag= TD_SELECTED;
1587                                 else td->flag= 0;
1588                                 Mat3CpyMat3(td->smtx, smtx);
1589                                 Mat3CpyMat3(td->mtx, mtx);
1590
1591                                 td->ext = NULL;
1592                                 td->tdi = NULL;
1593                                 td->val = NULL;
1594
1595                                 td++;
1596                                 count++;
1597                         }
1598                 }
1599                 bp++;
1600         }
1601 }
1602
1603 /* ******************* particle edit **************** */
1604 static void createTransParticleVerts(bContext *C, TransInfo *t)
1605 {
1606         // TRANSFORM_FIX_ME
1607 #if 0
1608         TransData *td = NULL;
1609         TransDataExtension *tx;
1610         Base *base = BASACT;
1611         Object *ob = OBACT;
1612         ParticleSystem *psys = PE_get_current(ob);
1613         ParticleSystemModifierData *psmd = NULL;
1614         ParticleEditSettings *pset = PE_settings(t->scene);
1615         ParticleData *pa = NULL;
1616         ParticleEdit *edit;
1617         ParticleEditKey *key;
1618         float mat[4][4];
1619         int i,k, totpart, transformparticle;
1620         int count = 0, hasselected = 0;
1621         int propmode = t->flag & T_PROP_EDIT;
1622
1623         if(psys==NULL || t->scene->selectmode==SCE_SELECT_PATH) return;
1624
1625         psmd = psys_get_modifier(ob,psys);
1626
1627         edit = psys->edit;
1628         totpart = psys->totpart;
1629         base->flag |= BA_HAS_RECALC_DATA;
1630
1631         for(i=0, pa=psys->particles; i<totpart; i++, pa++) {
1632                 pa->flag &= ~PARS_TRANSFORM;
1633                 transformparticle= 0;
1634
1635                 if((pa->flag & PARS_HIDE)==0) {
1636                         for(k=0, key=edit->keys[i]; k<pa->totkey; k++, key++) {
1637                                 if((key->flag&PEK_HIDE)==0) {
1638                                         if(key->flag&PEK_SELECT) {
1639                                                 hasselected= 1;
1640                                                 transformparticle= 1;
1641                                         }
1642                                         else if(propmode)
1643                                                 transformparticle= 1;
1644                                 }
1645                         }
1646                 }
1647
1648                 if(transformparticle) {
1649                         count += pa->totkey;
1650                         pa->flag |= PARS_TRANSFORM;
1651                 }
1652         }
1653         
1654         /* note: in prop mode we need at least 1 selected */
1655         if (hasselected==0) return;
1656         
1657         t->total = count;
1658         td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Particle Mode)");
1659
1660         if(t->mode == TFM_BAKE_TIME)
1661                 tx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), "Particle_TransExtension");
1662         else
1663                 tx = t->ext = NULL;
1664
1665         Mat4One(mat);
1666
1667         Mat4Invert(ob->imat,ob->obmat);
1668
1669         for(i=0, pa=psys->particles; i<totpart; i++, pa++) {
1670                 TransData *head, *tail;
1671                 head = tail = td;
1672
1673                 if(!(pa->flag & PARS_TRANSFORM)) continue;
1674
1675                 psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, mat);
1676
1677                 for(k=0, key=edit->keys[i]; k<pa->totkey; k++, key++) {
1678                         VECCOPY(key->world_co, key->co);
1679                         Mat4MulVecfl(mat, key->world_co);
1680                         td->loc = key->world_co;
1681
1682                         VECCOPY(td->iloc, td->loc);
1683                         VECCOPY(td->center, td->loc);
1684
1685                         if(key->flag & PEK_SELECT)
1686                                 td->flag |= TD_SELECTED;
1687                         else if(!propmode)
1688                                 td->flag |= TD_SKIP;
1689
1690                         Mat3One(td->mtx);
1691                         Mat3One(td->smtx);
1692
1693                         /* don't allow moving roots */
1694                         if(k==0 && pset->flag & PE_LOCK_FIRST)
1695                                 td->protectflag |= OB_LOCK_LOC;
1696
1697                         td->ob = ob;
1698                         td->ext = tx;
1699                         td->tdi = NULL;
1700                         if(t->mode == TFM_BAKE_TIME) {
1701                                 td->val = key->time;
1702                                 td->ival = *(key->time);
1703                                 /* abuse size and quat for min/max values */
1704                                 td->flag |= TD_NO_EXT;
1705                                 if(k==0) tx->size = 0;
1706                                 else tx->size = (key - 1)->time;
1707
1708                                 if(k == pa->totkey - 1) tx->quat = 0;
1709                                 else tx->quat = (key + 1)->time;
1710                         }
1711
1712                         td++;
1713                         if(tx)
1714                                 tx++;
1715                         tail++;
1716                 }
1717                 if (propmode && head != tail)
1718                         calc_distanceCurveVerts(head, tail - 1);
1719         }
1720 #endif
1721 }
1722
1723 void flushTransParticles(TransInfo *t)
1724 {
1725 #if 0 // TRANSFORM_FIX_ME
1726         Scene *scene = t->scene;
1727         Object *ob = OBACT;
1728         ParticleSystem *psys = PE_get_current(ob);
1729         ParticleSystemModifierData *psmd;
1730         ParticleData *pa;
1731         ParticleEditKey *key;
1732         TransData *td;
1733         float mat[4][4], imat[4][4], co[3];
1734         int i, k, propmode = t->flag & T_PROP_EDIT;
1735
1736         psmd = psys_get_modifier(ob, psys);
1737
1738         /* we do transform in world space, so flush world space position
1739          * back to particle local space */
1740         td= t->data;
1741         for(i=0, pa=psys->particles; i<psys->totpart; i++, pa++, td++) {
1742                 if(!(pa->flag & PARS_TRANSFORM)) continue;
1743
1744                 psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, mat);
1745                 Mat4Invert(imat,mat);
1746
1747                 for(k=0, key=psys->edit->keys[i]; k<pa->totkey; k++, key++) {
1748                         VECCOPY(co, key->world_co);
1749                         Mat4MulVecfl(imat, co);
1750
1751                         /* optimization for proportional edit */
1752                         if(!propmode || !FloatCompare(key->co, co, 0.0001f)) {
1753                                 VECCOPY(key->co, co);
1754                                 pa->flag |= PARS_EDIT_RECALC;
1755                         }
1756                 }
1757         }
1758
1759         PE_update_object(scene, OBACT, 1);
1760 #endif
1761 }
1762
1763 /* ********************* mesh ****************** */
1764
1765 /* proportional distance based on connectivity  */
1766 #define E_VEC(a)        (vectors + (3 * (a)->tmp.l))
1767 #define E_NEAR(a)       (nears[((a)->tmp.l)])
1768 #define THRESHOLD       0.0001f
1769 static void editmesh_set_connectivity_distance(EditMesh *em, int total, float *vectors, EditVert **nears)
1770 {
1771         EditVert *eve;
1772         EditEdge *eed;
1773         int i= 0, done= 1;
1774
1775         /* f2 flag is used for 'selection' */
1776         /* tmp.l is offset on scratch array   */
1777         for(eve= em->verts.first; eve; eve= eve->next) {
1778                 if(eve->h==0) {
1779                         eve->tmp.l = i++;
1780
1781                         if(eve->f & SELECT) {
1782                                 eve->f2= 2;
1783                                 E_NEAR(eve) = eve;
1784                                 E_VEC(eve)[0] = 0.0f;
1785                                 E_VEC(eve)[1] = 0.0f;
1786                                 E_VEC(eve)[2] = 0.0f;
1787                         }
1788                         else {
1789                                 eve->f2 = 0;
1790                         }
1791                 }
1792         }
1793
1794
1795         /* Floodfill routine */
1796         /*
1797         At worst this is n*n of complexity where n is number of edges 
1798         Best case would be n if the list is ordered perfectly.
1799         Estimate is n log n in average (so not too bad)
1800         */
1801         while(done) {
1802                 done= 0;
1803                 
1804                 for(eed= em->edges.first; eed; eed= eed->next) {
1805                         if(eed->h==0) {
1806                                 EditVert *v1= eed->v1, *v2= eed->v2;
1807                                 float *vec2 = E_VEC(v2);
1808                                 float *vec1 = E_VEC(v1);
1809
1810                                 if (v1->f2 + v2->f2 == 4)
1811                                         continue;
1812
1813                                 if (v1->f2) {
1814                                         if (v2->f2) {
1815                                                 float nvec[3];
1816                                                 float len1 = VecLength(vec1);
1817                                                 float len2 = VecLength(vec2);
1818                                                 float lenn;
1819                                                 /* for v2 if not selected */
1820                                                 if (v2->f2 != 2) {
1821                                                         VecSubf(nvec, v2->co, E_NEAR(v1)->co);
1822                                                         lenn = VecLength(nvec);
1823                                                         /* 1 < n < 2 */
1824                                                         if (lenn - len1 > THRESHOLD && len2 - lenn > THRESHOLD) {
1825                                                                 VECCOPY(vec2, nvec);
1826                                                                 E_NEAR(v2) = E_NEAR(v1);
1827                                                                 done = 1;
1828                                                         }
1829                                                         /* n < 1 < 2 */
1830                                                         else if (len2 - len1 > THRESHOLD && len1 - lenn > THRESHOLD) {
1831                                                                 VECCOPY(vec2, vec1);
1832                                                                 E_NEAR(v2) = E_NEAR(v1);
1833                                                                 done = 1;
1834                                                         }
1835                                                 }
1836                                                 /* for v1 if not selected */
1837                                                 if (v1->f2 != 2) {
1838                                                         VecSubf(nvec, v1->co, E_NEAR(v2)->co);
1839                                                         lenn = VecLength(nvec);
1840                                                         /* 2 < n < 1 */
1841                                                         if (lenn - len2 > THRESHOLD && len1 - lenn > THRESHOLD) {
1842                                                                 VECCOPY(vec1, nvec);
1843                                                                 E_NEAR(v1) = E_NEAR(v2);
1844                                                                 done = 1;
1845                                                         }
1846                                                         /* n < 2 < 1 */
1847                                                         else if (len1 - len2 > THRESHOLD && len2 - lenn > THRESHOLD) {
1848                                                                 VECCOPY(vec1, vec2);
1849                                                                 E_NEAR(v1) = E_NEAR(v2);
1850                                                                 done = 1;
1851                                                         }
1852                                                 }
1853                                         }
1854                                         else {
1855                                                 v2->f2 = 1;
1856                                                 VecSubf(vec2, v2->co, E_NEAR(v1)->co);
1857                                                 /* 2 < 1 */
1858                                                 if (VecLength(vec1) - VecLength(vec2) > THRESHOLD) {
1859                                                         VECCOPY(vec2, vec1);
1860                                                 }
1861                                                 E_NEAR(v2) = E_NEAR(v1);
1862                                                 done = 1;
1863                                         }
1864                                 }
1865                                 else if (v2->f2) {
1866                                         v1->f2 = 1;
1867                                         VecSubf(vec1, v1->co, E_NEAR(v2)->co);
1868                                         /* 2 < 1 */
1869                                         if (VecLength(vec2) - VecLength(vec1) > THRESHOLD) {
1870                                                 VECCOPY(vec1, vec2);
1871                                         }
1872                                         E_NEAR(v1) = E_NEAR(v2);
1873                                         done = 1;
1874                                 }
1875                         }
1876                 }
1877         }
1878 }
1879
1880 /* loop-in-a-loop I know, but we need it! (ton) */
1881 static void get_face_center(float *cent, EditMesh *em, EditVert *eve)
1882 {
1883         EditFace *efa;
1884         
1885         for(efa= em->faces.first; efa; efa= efa->next)
1886                 if(efa->f & SELECT)
1887                         if(efa->v1==eve || efa->v2==eve || efa->v3==eve || efa->v4==eve)
1888                                 break;
1889         if(efa) {
1890                 VECCOPY(cent, efa->cent);
1891         }
1892 }
1893
1894 //way to overwrite what data is edited with transform
1895 //static void VertsToTransData(TransData *td, EditVert *eve, BakeKey *key)
1896 static void VertsToTransData(TransInfo *t, TransData *td, EditMesh *em, EditVert *eve)
1897 {
1898         td->flag = 0;
1899         //if(key)
1900         //      td->loc = key->co;
1901         //else
1902         td->loc = eve->co;
1903         
1904         VECCOPY(td->center, td->loc);
1905         if(t->around==V3D_LOCAL && (em->selectmode & SCE_SELECT_FACE))
1906                 get_face_center(td->center, em, eve);
1907         VECCOPY(td->iloc, td->loc);
1908
1909         // Setting normals
1910         VECCOPY(td->axismtx[2], eve->no);
1911         td->axismtx[0][0]               =
1912                 td->axismtx[0][1]       =
1913                 td->axismtx[0][2]       =
1914                 td->axismtx[1][0]       =
1915                 td->axismtx[1][1]       =
1916                 td->axismtx[1][2]       = 0.0f;
1917
1918         td->ext = NULL;
1919         td->tdi = NULL;
1920         td->val = NULL;
1921         td->extra = NULL;
1922         if (t->mode == TFM_BWEIGHT) {
1923                 td->val = &(eve->bweight);
1924                 td->ival = eve->bweight;
1925         }
1926 }
1927
1928 /* *********************** CrazySpace correction. Now without doing subsurf optimal ****************** */
1929
1930 static void make_vertexcos__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
1931 {
1932         float *vec = userData;
1933         
1934         vec+= 3*index;
1935         VECCOPY(vec, co);
1936 }
1937
1938 static int modifiers_disable_subsurf_temporary(Object *ob)
1939 {
1940         ModifierData *md;
1941         int disabled = 0;
1942         
1943         for(md=ob->modifiers.first; md; md=md->next)
1944                 if(md->type==eModifierType_Subsurf)
1945                         if(md->mode & eModifierMode_OnCage) {
1946                                 md->mode ^= eModifierMode_DisableTemporary;
1947                                 disabled= 1;
1948                         }
1949         
1950         return disabled;
1951 }
1952
1953 /* disable subsurf temporal, get mapped cos, and enable it */
1954 static float *get_crazy_mapped_editverts(TransInfo *t)
1955 {
1956         Mesh *me= t->obedit->data;
1957         DerivedMesh *dm;
1958         float *vertexcos;
1959
1960         /* disable subsurf temporal, get mapped cos, and enable it */
1961         if(modifiers_disable_subsurf_temporary(t->obedit)) {
1962                 /* need to make new derivemesh */
1963                 makeDerivedMesh(t->scene, t->obedit, me->edit_mesh, CD_MASK_BAREMESH);
1964         }
1965
1966         /* now get the cage */
1967         dm= editmesh_get_derived_cage(t->scene, t->obedit, me->edit_mesh, CD_MASK_BAREMESH);
1968
1969         vertexcos= MEM_mallocN(3*sizeof(float)*me->edit_mesh->totvert, "vertexcos map");
1970         dm->foreachMappedVert(dm, make_vertexcos__mapFunc, vertexcos);
1971         
1972         dm->release(dm);
1973         
1974         /* set back the flag, no new cage needs to be built, transform does it */
1975         modifiers_disable_subsurf_temporary(t->obedit);
1976         
1977         return vertexcos;
1978 }
1979
1980 #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])
1981 static void set_crazy_vertex_quat(float *quat, float *v1, float *v2, float *v3, float *def1, float *def2, float *def3)
1982 {
1983         float vecu[3], vecv[3];
1984         float q1[4], q2[4];
1985         
1986         TAN_MAKE_VEC(vecu, v1, v2);
1987         TAN_MAKE_VEC(vecv, v1, v3);
1988         triatoquat(v1, vecu, vecv, q1);
1989         
1990         TAN_MAKE_VEC(vecu, def1, def2);
1991         TAN_MAKE_VEC(vecv, def1, def3);
1992         triatoquat(def1, vecu, vecv, q2);
1993         
1994         QuatSub(quat, q2, q1);
1995 }
1996 #undef TAN_MAKE_VEC
1997
1998 static void set_crazyspace_quats(EditMesh *em, float *origcos, float *mappedcos, float *quats)
1999 {
2000         EditVert *eve, *prev;
2001         EditFace *efa;
2002         float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4;
2003         intptr_t index= 0;
2004         
2005         /* two abused locations in vertices */
2006         for(eve= em->verts.first; eve; eve= eve->next, index++) {
2007                 eve->tmp.p = NULL;
2008                 eve->prev= (EditVert *)index;
2009         }
2010         
2011         /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */
2012         for(efa= em->faces.first; efa; efa= efa->next) {
2013                 
2014                 /* retrieve mapped coordinates */
2015                 v1= mappedcos + 3*(intptr_t)(efa->v1->prev);
2016                 v2= mappedcos + 3*(intptr_t)(efa->v2->prev);
2017                 v3= mappedcos + 3*(intptr_t)(efa->v3->prev);
2018
2019                 co1= (origcos)? origcos + 3*(intptr_t)(efa->v1->prev): efa->v1->co;
2020                 co2= (origcos)? origcos + 3*(intptr_t)(efa->v2->prev): efa->v2->co;
2021                 co3= (origcos)? origcos + 3*(intptr_t)(efa->v3->prev): efa->v3->co;
2022
2023                 if(efa->v2->tmp.p==NULL && efa->v2->f1) {
2024                         set_crazy_vertex_quat(quats, co2, co3, co1, v2, v3, v1);
2025                         efa->v2->tmp.p= (void*)quats;
2026                         quats+= 4;
2027                 }
2028                 
2029                 if(efa->v4) {
2030                         v4= mappedcos + 3*(intptr_t)(efa->v4->prev);
2031                         co4= (origcos)? origcos + 3*(intptr_t)(efa->v4->prev): efa->v4->co;
2032
2033                         if(efa->v1->tmp.p==NULL && efa->v1->f1) {
2034                                 set_crazy_vertex_quat(quats, co1, co2, co4, v1, v2, v4);
2035                                 efa->v1->tmp.p= (void*)quats;
2036                                 quats+= 4;
2037                         }
2038                         if(efa->v3->tmp.p==NULL && efa->v3->f1) {
2039                                 set_crazy_vertex_quat(quats, co3, co4, co2, v3, v4, v2);
2040                                 efa->v3->tmp.p= (void*)quats;
2041                                 quats+= 4;
2042                         }
2043                         if(efa->v4->tmp.p==NULL && efa->v4->f1) {
2044                                 set_crazy_vertex_quat(quats, co4, co1, co3, v4, v1, v3);
2045                                 efa->v4->tmp.p= (void*)quats;
2046                                 quats+= 4;
2047                         }
2048                 }
2049                 else {
2050                         if(efa->v1->tmp.p==NULL && efa->v1->f1) {
2051                                 set_crazy_vertex_quat(quats, co1, co2, co3, v1, v2, v3);
2052                                 efa->v1->tmp.p= (void*)quats;
2053                                 quats+= 4;
2054                         }
2055                         if(efa->v3->tmp.p==NULL && efa->v3->f1) {
2056                                 set_crazy_vertex_quat(quats, co3, co1, co2, v3, v1, v2);
2057                                 efa->v3->tmp.p= (void*)quats;
2058                                 quats+= 4;
2059                         }
2060                 }
2061         }
2062
2063         /* restore abused prev pointer */
2064         for(prev= NULL, eve= em->verts.first; eve; prev= eve, eve= eve->next)
2065                 eve->prev= prev;
2066
2067 }
2068
2069 void createTransBMeshVerts(TransInfo *t, BME_Mesh *bm, BME_TransData_Head *td) {
2070         BME_Vert *v;
2071         BME_TransData *vtd;
2072         TransData *tob;
2073         int i;
2074
2075         tob = t->data = MEM_callocN(td->len*sizeof(TransData), "TransObData(Bevel tool)");
2076
2077         for (i=0,v=bm->verts.first;v;v=v->next) {
2078                 if ( (vtd = BME_get_transdata(td,v)) ) {
2079                         tob->loc = vtd->loc;
2080                         tob->val = &vtd->factor;
2081                         VECCOPY(tob->iloc,vtd->co);
2082                         VECCOPY(tob->center,vtd->org);
2083                         VECCOPY(tob->axismtx[0],vtd->vec);
2084                         tob->axismtx[1][0] = vtd->max ? *vtd->max : 0;
2085                         tob++;
2086                         i++;
2087                 }
2088         }
2089         /* since td is a memarena, it can hold more transdata than actual elements
2090          * (i.e. we can't depend on td->len to determine the number of actual elements) */
2091         t->total = i;
2092 }
2093
2094 static void createTransEditVerts(bContext *C, TransInfo *t)
2095 {
2096         Scene *scene = CTX_data_scene(C);
2097         TransData *tob = NULL;
2098         EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
2099         EditVert *eve;
2100         EditVert **nears = NULL;
2101         EditVert *eve_act = NULL;
2102         float *vectors = NULL, *mappedcos = NULL, *quats= NULL;
2103         float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL;
2104         int count=0, countsel=0, a, totleft;
2105         int propmode = t->flag & T_PROP_EDIT;
2106         int mirror = 0;
2107         
2108         if ((t->options & CTX_NO_MIRROR) == 0 && (scene->toolsettings->editbutflag & B_MESH_X_MIRROR))
2109         {
2110                 mirror = 1;
2111         }
2112
2113         // transform now requires awareness for select mode, so we tag the f1 flags in verts
2114         if(scene->selectmode & SCE_SELECT_VERTEX) {
2115                 for(eve= em->verts.first; eve; eve= eve->next) {
2116                         if(eve->h==0 && (eve->f & SELECT)) 
2117                                 eve->f1= SELECT;
2118                         else
2119                                 eve->f1= 0;
2120                 }
2121         }
2122         else if(scene->selectmode & SCE_SELECT_EDGE) {
2123                 EditEdge *eed;
2124                 for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
2125                 for(eed= em->edges.first; eed; eed= eed->next) {
2126                         if(eed->h==0 && (eed->f & SELECT))
2127                                 eed->v1->f1= eed->v2->f1= SELECT;
2128                 }
2129         }
2130         else {
2131                 EditFace *efa;
2132                 for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
2133                 for(efa= em->faces.first; efa; efa= efa->next) {
2134                         if(efa->h==0 && (efa->f & SELECT)) {
2135                                 efa->v1->f1= efa->v2->f1= efa->v3->f1= SELECT;
2136                                 if(efa->v4) efa->v4->f1= SELECT;
2137                         }
2138                 }
2139         }
2140         
2141         /* now we can count */
2142         for(eve= em->verts.first; eve; eve= eve->next) {
2143                 if(eve->h==0) {
2144                         if(eve->f1) countsel++;
2145                         if(propmode) count++;
2146                 }
2147         }
2148         
2149         /* note: in prop mode we need at least 1 selected */
2150         if (countsel==0) return;
2151         
2152         /* check active */
2153         if (em->selected.last) {
2154                 EditSelection *ese = em->selected.last;
2155                 if ( ese->type == EDITVERT ) {
2156                         eve_act = (EditVert *)ese->data;
2157                 }
2158         }
2159
2160         
2161         if(propmode) {
2162                 t->total = count; 
2163         
2164                 /* allocating scratch arrays */
2165                 vectors = (float *)MEM_mallocN(t->total * 3 * sizeof(float), "scratch vectors");
2166                 nears = (EditVert**)MEM_mallocN(t->total * sizeof(EditVert*), "scratch nears");
2167         }
2168         else t->total = countsel;
2169         tob= t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Mesh EditMode)");
2170         
2171         Mat3CpyMat4(mtx, t->obedit->obmat);
2172         Mat3Inv(smtx, mtx);
2173
2174         if(propmode) editmesh_set_connectivity_distance(em, t->total, vectors, nears);
2175         
2176         /* detect CrazySpace [tm] */
2177         if(propmode==0) {
2178                 if(modifiers_getCageIndex(t->obedit, NULL)>=0) {
2179                         if(modifiers_isDeformed(t->scene, t->obedit)) {
2180                                 /* check if we can use deform matrices for modifier from the
2181                                    start up to stack, they are more accurate than quats */
2182                                 totleft= editmesh_get_first_deform_matrices(t->obedit, em, &defmats, &defcos);
2183
2184                                 /* if we still have more modifiers, also do crazyspace
2185                                    correction with quats, relative to the coordinates after
2186                                    the modifiers that support deform matrices (defcos) */
2187                                 if(totleft > 0) {
2188                                         mappedcos= get_crazy_mapped_editverts(t);
2189                                         quats= MEM_mallocN( (t->total)*sizeof(float)*4, "crazy quats");
2190                                         set_crazyspace_quats(em, (float*)defcos, mappedcos, quats);
2191                                         if(mappedcos)
2192                                                 MEM_freeN(mappedcos);
2193                                 }
2194
2195                                 if(defcos)
2196                                         MEM_freeN(defcos);
2197                         }
2198                 }
2199         }
2200         
2201         /* find out which half we do */
2202         if(mirror) {
2203                 for (eve=em->verts.first; eve; eve=eve->next) {
2204                         if(eve->h==0 && eve->f1 && eve->co[0]!=0.0f) {
2205                                 if(eve->co[0]<0.0f)
2206                                         mirror = -1;
2207                                 break;
2208                         }
2209                 }
2210         }
2211         
2212         for (a=0, eve=em->verts.first; eve; eve=eve->next, a++) {
2213                 if(eve->h==0) {
2214                         if(propmode || eve->f1) {
2215                                 VertsToTransData(t, tob, em, eve);
2216                                 
2217                                 /* selected */
2218                                 if(eve->f1) tob->flag |= TD_SELECTED;
2219                                 
2220                                 /* active */
2221                                 if(eve == eve_act) tob->flag |= TD_ACTIVE;
2222                                 
2223                                 if(propmode) {
2224                                         if (eve->f2) {
2225                                                 float vec[3];
2226                                                 VECCOPY(vec, E_VEC(eve));
2227                                                 Mat3MulVecfl(mtx, vec);
2228                                                 tob->dist= VecLength(vec);
2229                                         }
2230                                         else {
2231                                                 tob->flag |= TD_NOTCONNECTED;
2232                                                 tob->dist = MAXFLOAT;
2233                                         }
2234                                 }
2235                                 
2236                                 /* CrazySpace */
2237                                 if(defmats || (quats && eve->tmp.p)) {
2238                                         float mat[3][3], imat[3][3], qmat[3][3];
2239                                         
2240                                         /* use both or either quat and defmat correction */
2241                                         if(quats && eve->tmp.f) {
2242                                                 QuatToMat3(eve->tmp.p, qmat);
2243
2244                                                 if(defmats)
2245                                                         Mat3MulSerie(mat, mtx, qmat, defmats[a],
2246                                                                 NULL, NULL, NULL, NULL, NULL);
2247                                                 else
2248                                                         Mat3MulMat3(mat, mtx, qmat);
2249                                         }
2250                                         else
2251                                                 Mat3MulMat3(mat, mtx, defmats[a]);
2252
2253                                         Mat3Inv(imat, mat);
2254                                         
2255                                         Mat3CpyMat3(tob->smtx, imat);
2256                                         Mat3CpyMat3(tob->mtx, mat);
2257                                 }
2258                                 else {
2259                                         Mat3CpyMat3(tob->smtx, smtx);
2260                                         Mat3CpyMat3(tob->mtx, mtx);
2261                                 }
2262                                 
2263                                 /* Mirror? */
2264                                 if( (mirror>0 && tob->iloc[0]>0.0f) || (mirror<0 && tob->iloc[0]<0.0f)) {
2265                                         EditVert *vmir= editmesh_get_x_mirror_vert(t->obedit, em, tob->iloc);   /* initializes octree on first call */
2266                                         if(vmir != eve) tob->extra = vmir;
2267                                 }
2268                                 tob++;
2269                         }
2270                 }       
2271         }
2272         if (propmode) {
2273                 MEM_freeN(vectors);
2274                 MEM_freeN(nears);
2275         }
2276         /* crazy space free */
2277         if(quats)
2278                 MEM_freeN(quats);
2279         if(defmats)
2280                 MEM_freeN(defmats);
2281 }
2282
2283 /* *** NODE EDITOR *** */
2284 void flushTransNodes(TransInfo *t)
2285 {
2286         int a;
2287         TransData2D *td;
2288         
2289         /* flush to 2d vector from internally used 3d vector */
2290         for(a=0, td= t->data2d; a<t->total; a++, td++) {
2291                 td->loc2d[0]= td->loc[0];
2292                 td->loc2d[1]= td->loc[1];
2293         }
2294 }
2295
2296 /* *** SEQUENCE EDITOR *** */
2297 void flushTransSeq(TransInfo *t)
2298 {
2299         ListBase *seqbasep= seq_give_editing(t->scene, FALSE)->seqbasep; /* Editing null check alredy done */
2300         int a, new_frame;
2301         TransData *td= t->data;
2302         TransData2D *td2d= t->data2d;
2303         TransDataSeq *tdsq= NULL;
2304         Sequence *seq;
2305
2306         
2307
2308         /* prevent updating the same seq twice
2309          * if the transdata order is changed this will mess up
2310          * but so will TransDataSeq */
2311         Sequence *seq_prev= NULL;
2312
2313         /* flush to 2d vector from internally used 3d vector */
2314         for(a=0; a<t->total; a++, td++, td2d++) {
2315
2316                 tdsq= (TransDataSeq *)td->extra;
2317                 seq= tdsq->seq;
2318                 new_frame= (int)(td2d->loc[0] + 0.5f);
2319
2320                 switch (tdsq->sel_flag) {
2321                 case SELECT:
2322                         if (seq->type != SEQ_META && seq_tx_test(seq)) /* for meta's, their children move */
2323                                 seq->start= new_frame - tdsq->start_offset;
2324                         
2325                         if (seq->depth==0) {
2326                                 seq->machine= (int)(td2d->loc[1] + 0.5f);
2327                                 CLAMP(seq->machine, 1, MAXSEQ);
2328                         }
2329                         break;
2330                 case SEQ_LEFTSEL: /* no vertical transform  */
2331                         seq_tx_set_final_left(seq, new_frame);
2332                         seq_tx_handle_xlimits(seq, tdsq->flag&SEQ_LEFTSEL, tdsq->flag&SEQ_RIGHTSEL);
2333                         fix_single_seq(seq); /* todo - move this into aftertrans update? - old seq tx needed it anyway */
2334                         break;
2335                 case SEQ_RIGHTSEL: /* no vertical transform  */
2336                         seq_tx_set_final_right(seq, new_frame);
2337                         seq_tx_handle_xlimits(seq, tdsq->flag&SEQ_LEFTSEL, tdsq->flag&SEQ_RIGHTSEL);
2338                         fix_single_seq(seq); /* todo - move this into aftertrans update? - old seq tx needed it anyway */
2339                         break;
2340                 }
2341
2342                 if (seq != seq_prev) {
2343                         if(seq->depth==0) {
2344                                 /* Calculate this strip and all nested strips
2345                                  * children are ALWAYS transformed first
2346                                  * so we dont need to do this in another loop. */
2347                                 calc_sequence(seq);
2348                                 
2349                                 /* test overlap, displayes red outline */
2350                                 seq->flag &= ~SEQ_OVERLAP;
2351                                 if( seq_test_overlap(seqbasep, seq) ) {
2352                                         seq->flag |= SEQ_OVERLAP;
2353                                 }
2354                         }
2355                         else {
2356                                 calc_sequence_disp(seq);
2357                         }
2358                 }
2359                 seq_prev= seq;
2360         }
2361
2362         if (t->mode == TFM_TIME_TRANSLATE) { /* originally TFM_TIME_EXTEND, transform changes */
2363                 /* Special annoying case here, need to calc metas with TFM_TIME_EXTEND only */
2364                 seq= seqbasep->first;
2365
2366                 while(seq) {
2367                         if (seq->type == SEQ_META && seq->flag & SELECT)
2368                                 calc_sequence(seq);
2369                         seq= seq->next;
2370                 }
2371         }
2372 }
2373
2374 /* ********************* UV ****************** */
2375
2376 static void UVsToTransData(SpaceImage *sima, TransData *td, TransData2D *td2d, float *uv, int selected)
2377 {
2378         float aspx, aspy;
2379
2380         ED_space_image_uv_aspect(sima, &aspx, &aspy);
2381
2382         /* uv coords are scaled by aspects. this is needed for rotations and
2383            proportional editing to be consistent with the stretchted uv coords
2384            that are displayed. this also means that for display and numinput,
2385            and when the the uv coords are flushed, these are converted each time */
2386         td2d->loc[0] = uv[0]*aspx;
2387         td2d->loc[1] = uv[1]*aspy;
2388         td2d->loc[2] = 0.0f;
2389         td2d->loc2d = uv;
2390
2391         td->flag = 0;
2392         td->loc = td2d->loc;
2393         VECCOPY(td->center, td->loc);
2394         VECCOPY(td->iloc, td->loc);
2395
2396         memset(td->axismtx, 0, sizeof(td->axismtx));
2397         td->axismtx[2][2] = 1.0f;
2398
2399         td->ext= NULL; td->tdi= NULL; td->val= NULL;
2400
2401         if(selected) {
2402                 td->flag |= TD_SELECTED;
2403                 td->dist= 0.0;
2404         }
2405         else {
2406                 td->dist= MAXFLOAT;
2407         }
2408         Mat3One(td->mtx);
2409         Mat3One(td->smtx);
2410 }
2411
2412 static void createTransUVs(bContext *C, TransInfo *t)
2413 {
2414         SpaceImage *sima = (SpaceImage*)CTX_wm_space_data(C);
2415         Image *ima = CTX_data_edit_image(C);
2416         Scene *scene = CTX_data_scene(C);
2417         TransData *td = NULL;
2418         TransData2D *td2d = NULL;
2419         MTFace *tf;
2420         int count=0, countsel=0;
2421         int propmode = t->flag & T_PROP_EDIT;
2422
2423         EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
2424         EditFace *efa;
2425         
2426         if(!ED_uvedit_test(t->obedit)) return;
2427
2428         /* count */
2429         for (efa= em->faces.first; efa; efa= efa->next) {
2430                 tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
2431
2432                 if(uvedit_face_visible(scene, ima, efa, tf)) {
2433                         efa->tmp.p = tf;
2434                         
2435                         if (uvedit_uv_selected(scene, efa, tf, 0)) countsel++; 
2436                         if (uvedit_uv_selected(scene, efa, tf, 1)) countsel++; 
2437                         if (uvedit_uv_selected(scene, efa, tf, 2)) countsel++; 
2438                         if (efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) countsel++;
2439                         if(propmode)
2440                                 count += (efa->v4)? 4: 3;
2441                 } else {
2442                         efa->tmp.p = NULL;
2443                 }
2444         }
2445         
2446         /* note: in prop mode we need at least 1 selected */
2447         if (countsel==0) return;
2448         
2449         t->total= (propmode)? count: countsel;
2450         t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(UV Editing)");
2451         /* for each 2d uv coord a 3d vector is allocated, so that they can be
2452            treated just as if they were 3d verts */
2453         t->data2d= MEM_callocN(t->total*sizeof(TransData2D), "TransObData2D(UV Editing)");
2454
2455         if(sima->flag & SI_CLIP_UV)
2456                 t->flag |= T_CLIP_UV;
2457
2458         td= t->data;
2459         td2d= t->data2d;
2460         
2461         for (efa= em->faces.first; efa; efa= efa->next) {
2462                 if ((tf=(MTFace *)efa->tmp.p)) {
2463                         if (propmode) {
2464                                 UVsToTransData(sima, td++, td2d++, tf->uv[0], uvedit_uv_selected(scene, efa, tf, 0));
2465                                 UVsToTransData(sima, td++, td2d++, tf->uv[1], uvedit_uv_selected(scene, efa, tf, 1));
2466                                 UVsToTransData(sima, td++, td2d++, tf->uv[2], uvedit_uv_selected(scene, efa, tf, 2));
2467                                 if(efa->v4)
2468                                         UVsToTransData(sima, td++, td2d++, tf->uv[3], uvedit_uv_selected(scene, efa, tf, 3));
2469                         } else {
2470                                 if(uvedit_uv_selected(scene, efa, tf, 0))                               UVsToTransData(sima, td++, td2d++, tf->uv[0], 1);
2471                                 if(uvedit_uv_selected(scene, efa, tf, 1))                               UVsToTransData(sima, td++, td2d++, tf->uv[1], 1);
2472                                 if(uvedit_uv_selected(scene, efa, tf, 2))                               UVsToTransData(sima, td++, td2d++, tf->uv[2], 1);
2473                                 if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3))    UVsToTransData(sima, td++, td2d++, tf->uv[3], 1);
2474                         }
2475                 }
2476         }
2477         
2478         if (sima->flag & SI_LIVE_UNWRAP)
2479                 ED_uvedit_live_unwrap_begin(t->scene, t->obedit);
2480 }
2481
2482 void flushTransUVs(TransInfo *t)
2483 {
2484         SpaceImage *sima = t->sa->spacedata.first;
2485         TransData2D *td;
2486         int a, width, height;
2487         float aspx, aspy, invx, invy;
2488
2489         ED_space_image_uv_aspect(sima, &aspx, &aspy);
2490         ED_space_image_size(sima, &width, &height);
2491         invx= 1.0f/aspx;
2492         invy= 1.0f/aspy;
2493
2494         /* flush to 2d vector from internally used 3d vector */
2495         for(a=0, td= t->data2d; a<t->total; a++, td++) {
2496                 td->loc2d[0]= td->loc[0]*invx;
2497                 td->loc2d[1]= td->loc[1]*invy;
2498                 
2499                 if((sima->flag & SI_PIXELSNAP) && (t->state != TRANS_CANCEL)) {
2500                         td->loc2d[0]= (float)floor(width*td->loc2d[0] + 0.5f)/width;
2501                         td->loc2d[1]= (float)floor(height*td->loc2d[1] + 0.5f)/height;
2502                 }
2503         }
2504 }
2505
2506 int clipUVTransform(TransInfo *t, float *vec, int resize)
2507 {
2508         TransData *td;
2509         int a, clipx=1, clipy=1;
2510         float aspx, aspy, min[2], max[2];
2511
2512         ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy);
2513         min[0]= min[1]= 0.0f;
2514         max[0]= aspx; max[1]= aspy;
2515
2516         for(a=0, td= t->data; a<t->total; a++, td++) {
2517                 DO_MINMAX2(td->loc, min, max);
2518         }
2519
2520         if(resize) {
2521                 if(min[0] < 0.0f && t->center[0] > 0.0f && t->center[0] < aspx*0.5f)
2522                         vec[0] *= t->center[0]/(t->center[0] - min[0]);
2523                 else if(max[0] > aspx && t->center[0] < aspx)
2524                         vec[0] *= (t->center[0] - aspx)/(t->center[0] - max[0]);
2525                 else
2526                         clipx= 0;
2527
2528                 if(min[1] < 0.0f && t->center[1] > 0.0f && t->center[1] < aspy*0.5f)
2529                         vec[1] *= t->center[1]/(t->center[1] - min[1]);
2530                 else if(max[1] > aspy && t->center[1] < aspy)
2531                         vec[1] *= (t->center[1] - aspy)/(t->center[1] - max[1]);
2532                 else
2533                         clipy= 0;
2534         }
2535         else {
2536                 if(min[0] < 0.0f)
2537                         vec[0] -= min[0];
2538                 else if(max[0] > aspx)
2539                         vec[0] -= max[0]-aspx;
2540                 else
2541                         clipx= 0;
2542
2543                 if(min[1] < 0.0f)
2544                         vec[1] -= min[1];
2545                 else if(max[1] > aspy)
2546                         vec[1] -= max[1]-aspy;
2547                 else
2548                         clipy= 0;
2549         }       
2550
2551         return (clipx || clipy);
2552 }
2553
2554 /* ********************* ACTION/NLA EDITOR ****************** */
2555
2556 /* Called by special_aftertrans_update to make sure selected gp-frames replace
2557  * any other gp-frames which may reside on that frame (that are not selected).
2558  * It also makes sure gp-frames are still stored in chronological order after
2559  * transform.
2560  */
2561 static void posttrans_gpd_clean (bGPdata *gpd)
2562 {
2563         bGPDlayer *gpl;
2564         
2565         for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
2566                 ListBase sel_buffer = {NULL, NULL};
2567                 bGPDframe *gpf, *gpfn;
2568                 bGPDframe *gfs, *gfsn;
2569                 
2570                 /* loop 1: loop through and isolate selected gp-frames to buffer 
2571                  * (these need to be sorted as they are isolated)
2572                  */
2573                 for (gpf= gpl->frames.first; gpf; gpf= gpfn) {
2574                         short added= 0;
2575                         gpfn= gpf->next;
2576                         
2577                         if (gpf->flag & GP_FRAME_SELECT) {
2578                                 BLI_remlink(&gpl->frames, gpf);
2579                                 
2580                                 /* find place to add them in buffer
2581                                  * - go backwards as most frames will still be in order,
2582                                  *   so doing it this way will be faster 
2583                                  */
2584                                 for (gfs= sel_buffer.last; gfs; gfs= gfs->prev) {
2585                                         /* if current (gpf) occurs after this one in buffer, add! */
2586                                         if (gfs->framenum < gpf->framenum) {
2587                                                 BLI_insertlinkafter(&sel_buffer, gfs, gpf);
2588                                                 added= 1;
2589                                                 break;
2590                                         }
2591                                 }
2592                                 if (added == 0)
2593                                         BLI_addhead(&sel_buffer, gpf);
2594                         }
2595                 }
2596                 
2597                 /* error checking: it is unlikely, but may be possible to have none selected */
2598                 if (sel_buffer.first == NULL)
2599                         continue;
2600                 
2601                 /* if all were selected (i.e. gpl->frames is empty), then just transfer sel-buf over */
2602                 if (gpl->frames.first == NULL) {
2603                         gpl->frames.first= sel_buffer.first;
2604                         gpl->frames.last= sel_buffer.last;
2605                         
2606                         continue;
2607                 }
2608                 
2609                 /* loop 2: remove duplicates of frames in buffers */
2610                 for (gpf= gpl->frames.first; gpf && sel_buffer.first; gpf= gpfn) {
2611                         gpfn= gpf->next;
2612                         
2613                         /* loop through sel_buffer, emptying stuff from front of buffer if ok */
2614                         for (gfs= sel_buffer.first; gfs && gpf; gfs= gfsn) {
2615                                 gfsn= gfs->next;
2616                                 
2617                                 /* if this buffer frame needs to go before current, add it! */
2618                                 if (gfs->framenum < gpf->framenum) {
2619                                         /* transfer buffer frame to frames list (before current) */
2620                                         BLI_remlink(&sel_buffer, gfs);
2621                                         BLI_insertlinkbefore(&gpl->frames, gpf, gfs);
2622                                 }
2623                                 /* if this buffer frame is on same frame, replace current with it and stop */
2624                                 else if (gfs->framenum == gpf->framenum) {
2625                                         /* transfer buffer frame to frames list (before current) */
2626                                         BLI_remlink(&sel_buffer, gfs);
2627                                         BLI_insertlinkbefore(&gpl->frames, gpf, gfs);
2628                                         
2629                                         /* get rid of current frame */
2630                                         // TRANSFORM_FIX_ME
2631                                         //gpencil_layer_delframe(gpl, gpf);
2632                                 }
2633                         }
2634                 }
2635                 
2636                 /* if anything is still in buffer, append to end */
2637                 for (gfs= sel_buffer.first; gfs; gfs= gfsn) {
2638                         gfsn= gfs->next;
2639                         
2640                         BLI_remlink(&sel_buffer, gfs);
2641                         BLI_addtail(&gpl->frames, gfs);
2642                 }
2643         }
2644 }
2645
2646 /* Called during special_aftertrans_update to make sure selected keyframes replace
2647  * any other keyframes which may reside on that frame (that is not selected).
2648  */
2649 static void posttrans_fcurve_clean (FCurve *fcu)
2650 {
2651         float *selcache;        /* cache for frame numbers of selected frames (icu->totvert*sizeof(float)) */
2652         int len, index, i;      /* number of frames in cache, item index */
2653         
2654         /* allocate memory for the cache */
2655         // TODO: investigate using GHash for this instead?
2656         if (fcu->totvert == 0) 
2657                 return;
2658         selcache= MEM_callocN(sizeof(float)*fcu->totvert, "FCurveSelFrameNums");
2659         len= 0;
2660         index= 0;
2661         
2662         /* We do 2 loops, 1 for marking keyframes for deletion, one for deleting 
2663          * as there is no guarantee what order the keyframes are exactly, even though 
2664          * they have been sorted by time.
2665          */
2666          
2667         /*      Loop 1: find selected keyframes   */
2668         for (i = 0; i < fcu->totvert; i++) {
2669                 BezTriple *bezt= &fcu->bezt[i];
2670                 
2671                 if (BEZSELECTED(bezt)) {
2672                         selcache[index]= bezt->vec[1][0];
2673                         index++;
2674                         len++;
2675                 }
2676         }
2677         
2678         /* Loop 2: delete unselected keyframes on the same frames (if any keyframes were found) */
2679         if (len) {
2680                 for (i = 0; i < fcu->totvert; i++) {
2681                         BezTriple *bezt= &fcu->bezt[i];
2682                         
2683                         if (BEZSELECTED(bezt) == 0) {
2684                                 /* check beztriple should be removed according to cache */
2685                                 for (index= 0; index < len; index++) {
2686                                         if (IS_EQ(bezt->vec[1][0], selcache[index])) {
2687                                                 //delete_icu_key(icu, i, 0);
2688                                                 break;
2689                                         }
2690                                         else if (bezt->vec[1][0] > selcache[index])
2691                                                 break;
2692                                 }
2693                         }
2694                 }
2695                 
2696                 testhandles_fcurve(fcu);
2697         }
2698         
2699         /* free cache */
2700         MEM_freeN(selcache);
2701 }
2702
2703
2704 /* Called by special_aftertrans_update to make sure selected keyframes replace
2705  * any other keyframes which may reside on that frame (that is not selected).
2706  * remake_action_ipos should have already been called 
2707  */
2708 static void posttrans_action_clean (bAnimContext *ac, bAction *act)
2709 {
2710         ListBase anim_data = {NULL, NULL};
2711         bAnimListElem *ale;
2712         int filter;
2713         
2714         /* filter data */
2715         filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
2716         ANIM_animdata_filter(ac, &anim_data, filter, act, ANIMCONT_ACTION);
2717         
2718         /* loop through relevant data, removing keyframes from the ipo-blocks that were attached 
2719          *      - all keyframes are converted in/out of global time 
2720          */
2721         for (ale= anim_data.first; ale; ale= ale->next) {
2722                 Object *nob= ANIM_nla_mapping_get(ac, ale);
2723                 
2724                 if (nob) {
2725                         //ANIM_nla_mapping_apply_ipocurve(nob, ale->key_data, 0, 1); 
2726                         posttrans_fcurve_clean(ale->key_data);
2727                         //ANIM_nla_mapping_apply_ipocurve(nob, ale->key_data, 1, 1);
2728                 }
2729                 else 
2730                         posttrans_fcurve_clean(ale->key_data);
2731         }
2732         
2733         /* free temp data */
2734         BLI_freelistN(&anim_data);
2735 }
2736
2737 /* ----------------------------- */
2738
2739 /* This function tests if a point is on the "mouse" side of the cursor/frame-marking */
2740 static short FrameOnMouseSide(char side, float frame, float cframe)
2741 {
2742         /* both sides, so it doesn't matter */
2743         if (side == 'B') return 1;
2744         
2745         /* only on the named side */
2746         if (side == 'R')
2747                 return (frame >= cframe) ? 1 : 0;
2748         else
2749                 return (frame <= cframe) ? 1 : 0;
2750 }
2751
2752 /* fully select selected beztriples, but only include if it's on the right side of cfra */
2753 static int count_fcurve_keys(FCurve *fcu, char side, float cfra)
2754 {
2755         BezTriple *bezt;
2756         int i, count = 0;
2757         
2758         if (fcu == NULL)
2759                 return count;
2760         
2761         /* only include points that occur on the right side of cfra */
2762         for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) {
2763                 if (bezt->f2 & SELECT) {
2764                         /* fully select the other two keys */
2765                         bezt->f1 |= SELECT;
2766                         bezt->f3 |= SELECT;
2767                         
2768                         /* increment by 3, as there are 3 points (3 * x-coordinates) that need transform */
2769                         if (FrameOnMouseSide(side, bezt->vec[1][0], cfra))
2770                                 count += 3;
2771                 }
2772         }