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