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