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