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