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