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