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