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