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