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