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