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