- add BM_NGON_STACK_SIZE define to use wherever ngon stack arrays are used.
[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         BMEditMesh *em = ((Mesh *)t->obedit->data)->edit_btmesh;
303         TransData *td = NULL;
304         BMEdge *eed;
305         BMIter iter;
306         float mtx[3][3], smtx[3][3];
307         int count=0, countsel=0;
308         int propmode = t->flag & T_PROP_EDIT;
309
310         BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
311                 if (BM_TestHFlag(eed, BM_HIDDEN))
312                         continue;
313
314                 if (BM_TestHFlag(eed, BM_SELECT)) countsel++;
315                 if (propmode) count++;
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         efa = BMIter_New(&iter, bm, BM_FACES_OF_VERT, eve);
1921         if (efa) {
1922                 BM_Compute_Face_CenterMean(bm, efa, cent_r);
1923         }
1924         else {
1925                 zero_v3(cent_r);
1926         }
1927
1928         if (is_zero_v3(cent_r)) cent_r[2] = 1.0f;
1929 }
1930
1931 #define VertsToTransData(t, td, em, eve, bweight) \
1932         td->flag = 0;\
1933         td->loc = eve->co;\
1934         copy_v3_v3(td->center, td->loc);\
1935         if(t->around==V3D_LOCAL && (em->selectmode & SCE_SELECT_FACE))\
1936                 get_face_center(td->center, em, eve);\
1937         copy_v3_v3(td->iloc, td->loc);\
1938         copy_v3_v3(td->axismtx[2], eve->no);\
1939         td->axismtx[0][0]               =\
1940                 td->axismtx[0][1]       =\
1941                 td->axismtx[0][2]       =\
1942                 td->axismtx[1][0]       =\
1943                 td->axismtx[1][1]       =\
1944                 td->axismtx[1][2]       = 0.0f;\
1945         td->ext = NULL;\
1946         td->val = NULL;\
1947         td->extra = NULL;\
1948         if (t->mode == TFM_BWEIGHT) {\
1949                 td->val = bweight;\
1950                 td->ival = bweight ? *(bweight) : 1.0f;\
1951         }
1952
1953 #if 0
1954 //way to overwrite what data is edited with transform
1955 //static void VertsToTransData(TransData *td, EditVert *eve, BakeKey *key)
1956 inline void VertsToTransData(TransInfo *t, TransData *td, BMesh *em, BMVert *eve)
1957 {
1958         td->flag = 0;
1959         //if(key)
1960         //      td->loc = key->co;
1961         //else
1962         td->loc = eve->co;
1963
1964         copy_v3_v3(td->center, td->loc);
1965         if(t->around==V3D_LOCAL && (em->selectmode & SCE_SELECT_FACE))
1966                 get_face_center(td->center, em, eve);
1967         copy_v3_v3(td->iloc, td->loc);
1968
1969         // Setting normals
1970         copy_v3_v3(td->axismtx[2], eve->no);
1971         td->axismtx[0][0]               =
1972                 td->axismtx[0][1]       =
1973                 td->axismtx[0][2]       =
1974                 td->axismtx[1][0]       =
1975                 td->axismtx[1][1]       =
1976                 td->axismtx[1][2]       = 0.0f;
1977
1978         td->ext = NULL;
1979         td->val = NULL;
1980         td->extra = NULL;
1981         if (t->mode == TFM_BWEIGHT) {
1982                 td->val = &(eve->bweight);
1983                 td->ival = eve->bweight;
1984         }
1985 }
1986 #endif
1987
1988 /* *********************** CrazySpace correction. Now without doing subsurf optimal ****************** */
1989
1990 static void make_vertexcos__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
1991 {
1992         float *vec = userData;
1993
1994         vec+= 3*index;
1995         VECCOPY(vec, co);
1996 }
1997
1998 static int modifiers_disable_subsurf_temporary(Object *ob)
1999 {
2000         ModifierData *md;
2001         int disabled = 0;
2002
2003         for(md=ob->modifiers.first; md; md=md->next)
2004                 if(md->type==eModifierType_Subsurf)
2005                         if(md->mode & eModifierMode_OnCage) {
2006                                 md->mode ^= eModifierMode_DisableTemporary;
2007                                 disabled= 1;
2008                         }
2009
2010         return disabled;
2011 }
2012
2013 /* disable subsurf temporal, get mapped cos, and enable it */
2014 static float *get_crazy_mapped_editverts(TransInfo *t)
2015 {
2016         Mesh *me= t->obedit->data;
2017         DerivedMesh *dm;
2018         float *vertexcos;
2019
2020         /* disable subsurf temporal, get mapped cos, and enable it */
2021         if(modifiers_disable_subsurf_temporary(t->obedit)) {
2022                 /* need to make new derivemesh */
2023                 makeDerivedMesh(t->scene, t->obedit, me->edit_btmesh, CD_MASK_BAREMESH, 0);
2024         }
2025
2026         /* now get the cage */
2027         dm= editbmesh_get_derived_cage(t->scene, t->obedit, me->edit_btmesh, CD_MASK_BAREMESH);
2028
2029         vertexcos= MEM_mallocN(3*sizeof(float)*me->edit_btmesh->bm->totvert, "vertexcos map");
2030         dm->foreachMappedVert(dm, make_vertexcos__mapFunc, vertexcos);
2031
2032         dm->release(dm);
2033
2034         /* set back the flag, no new cage needs to be built, transform does it */
2035         modifiers_disable_subsurf_temporary(t->obedit);
2036
2037         return vertexcos;
2038 }
2039
2040 #define TAN_MAKE_VEC(a, b, c)   a[0]= b[0] + 0.2f*(b[0]-c[0]); a[1]= b[1] + 0.2f*(b[1]-c[1]); a[2]= b[2] + 0.2f*(b[2]-c[2])
2041 static void set_crazy_vertex_quat(float *quat, float *v1, float *v2, float *v3, float *def1, float *def2, float *def3)
2042 {
2043         float vecu[3], vecv[3];
2044         float q1[4], q2[4];
2045
2046         TAN_MAKE_VEC(vecu, v1, v2);
2047         TAN_MAKE_VEC(vecv, v1, v3);
2048         tri_to_quat( q1,v1, vecu, vecv);
2049
2050         TAN_MAKE_VEC(vecu, def1, def2);
2051         TAN_MAKE_VEC(vecv, def1, def3);
2052         tri_to_quat( q2,def1, vecu, vecv);
2053
2054         sub_qt_qtqt(quat, q2, q1);
2055 }
2056 #undef TAN_MAKE_VEC
2057
2058 static void createTransEditVerts(bContext *C, TransInfo *t)
2059 {
2060         ToolSettings *ts = CTX_data_tool_settings(C);
2061         TransData *tob = NULL;
2062         BMEditMesh *em = ((Mesh *)t->obedit->data)->edit_btmesh;
2063         BMesh *bm = em->bm;
2064         BMVert *eve;
2065         BMIter iter;
2066         BMVert *eve_act = NULL;
2067         float *mappedcos = NULL, *quats= NULL;
2068         float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL;
2069         float *dists=NULL;
2070         int count=0, countsel=0, a, totleft, *selstate = NULL;
2071         BLI_array_declare(selstate);
2072         int propmode = (t->flag & T_PROP_EDIT) ? (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) : 0;
2073         int mirror = 0;
2074         short selectmode = ts->selectmode;
2075
2076         if (t->flag & T_MIRROR)
2077         {
2078                 EDBM_CacheMirrorVerts(em, TRUE);
2079                 mirror = 1;
2080         }
2081
2082         /* edge slide forces edge select */
2083         if (t->mode == TFM_EDGE_SLIDE) {
2084                 selectmode = SCE_SELECT_EDGE;
2085         }
2086
2087         /* BMESH_TODO, writing into the index values is BAD!, means we cant
2088          * use the values for vertex mirror - campbell */
2089
2090         // transform now requires awareness for select mode, so we tag the f1 flags in verts
2091         if(selectmode & SCE_SELECT_VERTEX) {
2092                 BM_ITER(eve, &iter, bm, BM_VERTS_OF_MESH, NULL) {
2093                         if (BM_Selected(bm, eve)) {
2094                                 BM_SetHFlag(eve, BM_TMP_TAG);
2095                         }
2096                         else {
2097                                 BM_ClearHFlag(eve, BM_TMP_TAG);
2098                         }
2099                 }
2100         }
2101         else if(selectmode & SCE_SELECT_EDGE) {
2102                 BMEdge *eed;
2103
2104                 eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
2105                 for( ; eve; eve=BMIter_Step(&iter)) BM_ClearHFlag(eve, BM_TMP_TAG);
2106
2107                 eed = BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL);
2108                 for( ; eed; eed=BMIter_Step(&iter)) {
2109                         if (BM_Selected(bm, eed)) {
2110                                 BM_SetHFlag(eed->v1, BM_TMP_TAG);
2111                                 BM_SetHFlag(eed->v2, BM_TMP_TAG);
2112                         }
2113                 }
2114         }
2115         else {
2116                 BMFace *efa;
2117                 eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
2118                 for( ; eve; eve=BMIter_Step(&iter)) BM_ClearHFlag(eve, BM_TMP_TAG);
2119
2120                 efa = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
2121                 for( ; efa; efa=BMIter_Step(&iter)) {
2122                         if (BM_Selected(bm, efa)) {
2123                                 BMIter liter;
2124                                 BMLoop *l;
2125
2126                                 l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, efa);
2127                                 for (; l; l=BMIter_Step(&liter)) {
2128                                         BM_SetHFlag(l->v, BM_TMP_TAG);
2129                                 }
2130                         }
2131                 }
2132         }
2133
2134         /* now we can count. we store selection state in selstate, since
2135            get_crazy_mapped_editverts messes up the index state of the
2136            verts*/
2137         eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
2138         for(a=0; eve; eve=BMIter_Step(&iter), a++) {
2139                 BLI_array_growone(selstate);
2140
2141                 if (BM_TestHFlag(eve, BM_TMP_TAG)) {
2142                         selstate[a] = 1;
2143                         countsel++;
2144                 }
2145                 if(propmode) count++;
2146         }
2147
2148         /* note: in prop mode we need at least 1 selected */
2149         if (countsel == 0) {
2150                 goto cleanup;
2151         }
2152
2153         /* check active */
2154         if (em->bm->selected.last) {
2155                 BMEditSelection *ese = em->bm->selected.last;
2156                 if (ese->htype == BM_VERT) {
2157                         eve_act = (BMVert *)ese->data;
2158                 }
2159         }
2160
2161
2162         if(propmode) {
2163                 t->total = count;
2164
2165                 /* allocating scratch arrays */
2166                 if (propmode & T_PROP_CONNECTED)
2167                         dists = MEM_mallocN(em->bm->totvert * sizeof(float), "scratch nears");
2168         }
2169         else t->total = countsel;
2170
2171         tob= t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Mesh EditMode)");
2172
2173         copy_m3_m4(mtx, t->obedit->obmat);
2174         invert_m3_m3(smtx, mtx);
2175
2176         if(propmode & T_PROP_CONNECTED)
2177                 editmesh_set_connectivity_distance(em, mtx, dists);
2178
2179         /* detect CrazySpace [tm] */
2180         if(modifiers_getCageIndex(t->scene, t->obedit, NULL, 1)>=0) {
2181                 if(modifiers_isCorrectableDeformed(t->obedit)) {
2182                         /* check if we can use deform matrices for modifier from the
2183                            start up to stack, they are more accurate than quats */
2184                         totleft= editbmesh_get_first_deform_matrices(t->scene, t->obedit, em, &defmats, &defcos);
2185
2186                         /* if we still have more modifiers, also do crazyspace
2187                            correction with quats, relative to the coordinates after
2188                            the modifiers that support deform matrices (defcos) */
2189                         if(totleft > 0) {
2190                                 mappedcos= crazyspace_get_mapped_editverts(t->scene, t->obedit);
2191                                 quats= MEM_mallocN( (t->total)*sizeof(float)*4, "crazy quats");
2192                                 crazyspace_set_quats_editmesh(em, (float*)defcos, mappedcos, quats); /* BMESH_TODO, abuses vertex index, should use an int array */
2193                                 if(mappedcos)
2194                                         MEM_freeN(mappedcos);
2195                         }
2196
2197                         if(defcos)
2198                                 MEM_freeN(defcos);
2199                 }
2200         }
2201
2202         /* find out which half we do */
2203         if(mirror) {
2204                 eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
2205                 for(a=0; eve; eve=BMIter_Step(&iter), a++) {
2206                         if(!BM_TestHFlag(eve, BM_HIDDEN) && selstate[a] && eve->co[0]!=0.0f) {
2207                                 if(eve->co[0]<0.0f)
2208                                 {
2209                                         t->mirror = -1;
2210                                         mirror = -1;
2211                                 }
2212                                 break;
2213                         }
2214                 }
2215         }
2216
2217         eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
2218         for(a=0; eve; eve=BMIter_Step(&iter), a++) {
2219                 if(!BM_TestHFlag(eve, BM_HIDDEN)) {
2220                         if(propmode || selstate[a]) {
2221                                 float *bweight = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_BWEIGHT);
2222                                 
2223                                 VertsToTransData(t, tob, bm, eve, bweight);
2224
2225                                 /* selected */
2226                                 if(selstate[a]) tob->flag |= TD_SELECTED;
2227
2228                                 /* active */
2229                                 if(eve == eve_act) tob->flag |= TD_ACTIVE;
2230
2231                                 if(propmode) {
2232                                         if (propmode & T_PROP_CONNECTED) {
2233                                                 tob->dist = dists[a];
2234                                         } else {
2235                                                 tob->flag |= TD_NOTCONNECTED;
2236                                                 tob->dist = MAXFLOAT;
2237                                         }
2238                                 }
2239
2240                                 /* CrazySpace */
2241                                 if(defmats || (quats && BM_GetIndex(eve) != -1)) {
2242                                         float mat[3][3], qmat[3][3], imat[3][3];
2243
2244                                         /* use both or either quat and defmat correction */
2245                                         if(quats && BM_GetIndex(eve) != -1) {
2246                                                 quat_to_mat3(qmat, quats + 4*BM_GetIndex(eve));
2247
2248                                                 if(defmats)
2249                                                         mul_serie_m3(mat, mtx, qmat, defmats[a],
2250                                                                 NULL, NULL, NULL, NULL, NULL);
2251                                                 else
2252                                                         mul_m3_m3m3(mat, mtx, qmat);
2253                                         }
2254                                         else
2255                                                 mul_m3_m3m3(mat, mtx, defmats[a]);
2256
2257                                         invert_m3_m3(imat, mat);
2258
2259                                         copy_m3_m3(tob->smtx, imat);
2260                                         copy_m3_m3(tob->mtx, mat);
2261                                 }
2262                                 else {
2263                                         copy_m3_m3(tob->smtx, smtx);
2264                                         copy_m3_m3(tob->mtx, mtx);
2265                                 }
2266
2267                                 /* Mirror? */
2268                                 if( (mirror>0 && tob->iloc[0]>0.0f) || (mirror<0 && tob->iloc[0]<0.0f)) {
2269                                         BMVert *vmir= EDBM_GetMirrorVert(em, eve); //t->obedit, em, eve, tob->iloc, a);
2270                                         if(vmir && vmir != eve) {
2271                                                 tob->extra = vmir;
2272                                         }
2273                                 }
2274                                 tob++;
2275                         }
2276                 }
2277         }
2278         
2279         if (mirror != 0)
2280         {
2281                 tob = t->data;
2282                 for( a = 0; a < t->total; a++, tob++ )
2283                 {
2284                         if (ABS(tob->loc[0]) <= 0.00001f)
2285                         {
2286                                 tob->flag |= TD_MIRROR_EDGE;
2287                         }
2288                 }
2289         }
2290
2291 cleanup:
2292         /* crazy space free */
2293         if(quats)
2294                 MEM_freeN(quats);
2295         if(defmats)
2296                 MEM_freeN(defmats);
2297         if (dists)
2298                 MEM_freeN(dists);
2299         
2300         BLI_array_free(selstate);
2301
2302         if (t->flag & T_MIRROR)
2303         {
2304                 EDBM_EndMirrorCache(em);
2305                 mirror = 1;
2306         }
2307 }
2308
2309 /* *** NODE EDITOR *** */
2310 void flushTransNodes(TransInfo *t)
2311 {
2312         int a;
2313         TransData2D *td;
2314
2315         /* flush to 2d vector from internally used 3d vector */
2316         for(a=0, td= t->data2d; a<t->total; a++, td++) {
2317                 td->loc2d[0]= td->loc[0];
2318                 td->loc2d[1]= td->loc[1];
2319         }
2320         
2321         /* handle intersection with noodles */
2322         if(t->total==1) {
2323                 ED_node_link_intersect_test(t->sa, 1);
2324         }
2325         
2326 }
2327
2328 /* *** SEQUENCE EDITOR *** */
2329
2330 /* commented _only_ because the meta may have animaion data which
2331  * needs moving too [#28158] */
2332
2333 #define SEQ_TX_NESTED_METAS
2334
2335 void flushTransSeq(TransInfo *t)
2336 {
2337         ListBase *seqbasep= seq_give_editing(t->scene, FALSE)->seqbasep; /* Editing null check already done */
2338         int a, new_frame, old_start;
2339         TransData *td= NULL;
2340         TransData2D *td2d= NULL;
2341         TransDataSeq *tdsq= NULL;
2342         Sequence *seq;
2343
2344
2345
2346         /* prevent updating the same seq twice
2347          * if the transdata order is changed this will mess up
2348          * but so will TransDataSeq */
2349         Sequence *seq_prev= NULL;
2350
2351         /* flush to 2d vector from internally used 3d vector */
2352         for(a=0, td= t->data, td2d= t->data2d; a<t->total; a++, td++, td2d++) {
2353                 tdsq= (TransDataSeq *)td->extra;
2354                 seq= tdsq->seq;
2355                 old_start = seq->start;
2356                 new_frame= (int)floor(td2d->loc[0] + 0.5f);
2357
2358                 switch (tdsq->sel_flag) {
2359                 case SELECT:
2360 #ifdef SEQ_TX_NESTED_METAS
2361                         if ((seq->depth != 0 || seq_tx_test(seq))) /* for meta's, their children move */
2362                                 seq->start= new_frame - tdsq->start_offset;
2363 #else
2364                         if (seq->type != SEQ_META && (seq->depth != 0 || seq_tx_test(seq))) /* for meta's, their children move */
2365                                 seq->start= new_frame - tdsq->start_offset;
2366 #endif
2367                         if (seq->depth==0) {
2368                                 seq->machine= (int)floor(td2d->loc[1] + 0.5f);
2369                                 CLAMP(seq->machine, 1, MAXSEQ);
2370                         }
2371                         break;
2372                 case SEQ_LEFTSEL: /* no vertical transform  */
2373                         seq_tx_set_final_left(seq, new_frame);
2374                         seq_tx_handle_xlimits(seq, tdsq->flag&SEQ_LEFTSEL, tdsq->flag&SEQ_RIGHTSEL);
2375                         seq_single_fix(seq); /* todo - move this into aftertrans update? - old seq tx needed it anyway */
2376                         break;
2377                 case SEQ_RIGHTSEL: /* no vertical transform  */
2378                         seq_tx_set_final_right(seq, new_frame);
2379                         seq_tx_handle_xlimits(seq, tdsq->flag&SEQ_LEFTSEL, tdsq->flag&SEQ_RIGHTSEL);
2380                         seq_single_fix(seq); /* todo - move this into aftertrans update? - old seq tx needed it anyway */
2381                         break;
2382                 }
2383
2384                 if (seq != seq_prev) {
2385                         if(seq->depth==0) {
2386                                 /* Calculate this strip and all nested strips
2387                                  * children are ALWAYS transformed first
2388                                  * so we dont need to do this in another loop. */
2389                                 calc_sequence(t->scene, seq);
2390                         }
2391                         else {
2392                                 calc_sequence_disp(t->scene, seq);
2393                         }
2394
2395                         if(tdsq->sel_flag == SELECT)
2396                                 seq_offset_animdata(t->scene, seq, seq->start - old_start);
2397                 }
2398                 seq_prev= seq;
2399         }
2400
2401         /* need to do the overlap check in a new loop otherwise adjacent strips
2402          * will not be updated and we'll get false positives */
2403         seq_prev= NULL;
2404         for(a=0, td= t->data, td2d= t->data2d; a<t->total; a++, td++, td2d++) {
2405
2406                 tdsq= (TransDataSeq *)td->extra;
2407                 seq= tdsq->seq;
2408
2409                 if (seq != seq_prev) {
2410                         if(seq->depth==0) {
2411                                 /* test overlap, displayes red outline */
2412                                 seq->flag &= ~SEQ_OVERLAP;
2413                                 if( seq_test_overlap(seqbasep, seq) ) {
2414                                         seq->flag |= SEQ_OVERLAP;
2415                                 }
2416                         }
2417                 }
2418                 seq_prev= seq;
2419         }
2420
2421         if (t->mode == TFM_SEQ_SLIDE) { /* originally TFM_TIME_EXTEND, transform changes */
2422                 /* Special annoying case here, need to calc metas with TFM_TIME_EXTEND only */
2423                 seq= seqbasep->first;
2424
2425                 while(seq) {
2426                         if (seq->type == SEQ_META && seq->flag & SELECT)
2427                                 calc_sequence(t->scene, seq);
2428                         seq= seq->next;
2429                 }
2430         }
2431 }
2432
2433 /* ********************* UV ****************** */
2434
2435 static void UVsToTransData(SpaceImage *sima, TransData *td, TransData2D *td2d, float *uv, int selected)
2436 {
2437         float aspx, aspy;
2438
2439         ED_space_image_uv_aspect(sima, &aspx, &aspy);
2440
2441         /* uv coords are scaled by aspects. this is needed for rotations and
2442            proportional editing to be consistent with the stretchted uv coords
2443            that are displayed. this also means that for display and numinput,
2444            and when the the uv coords are flushed, these are converted each time */
2445         td2d->loc[0] = uv[0]*aspx;
2446         td2d->loc[1] = uv[1]*aspy;
2447         td2d->loc[2] = 0.0f;
2448         td2d->loc2d = uv;
2449
2450         td->flag = 0;
2451         td->loc = td2d->loc;
2452         copy_v3_v3(td->center, td->loc);
2453         copy_v3_v3(td->iloc, td->loc);
2454
2455         memset(td->axismtx, 0, sizeof(td->axismtx));
2456         td->axismtx[2][2] = 1.0f;
2457
2458         td->ext= NULL; td->val= NULL;
2459
2460         if(selected) {
2461                 td->flag |= TD_SELECTED;
2462                 td->dist= 0.0;
2463         }
2464         else {
2465                 td->dist= MAXFLOAT;
2466         }
2467         unit_m3(td->mtx);
2468         unit_m3(td->smtx);
2469 }
2470
2471 static void createTransUVs(bContext *C, TransInfo *t)
2472 {
2473         SpaceImage *sima = CTX_wm_space_image(C);
2474         Image *ima = CTX_data_edit_image(C);
2475         Scene *scene = t->scene;
2476         TransData *td = NULL;
2477         TransData2D *td2d = NULL;
2478         MTexPoly *tf;
2479         MLoopUV *luv;
2480         BMEditMesh *em = ((Mesh *)t->obedit->data)->edit_btmesh;
2481         BMFace *efa;
2482         BMLoop *l;
2483         BMIter iter, liter;
2484         int count=0, countsel=0;
2485         int propmode = t->flag & T_PROP_EDIT;
2486
2487         if(!ED_space_image_show_uvedit(sima, t->obedit)) return;
2488
2489         /* count */
2490         BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
2491                 tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
2492
2493                 if(!uvedit_face_visible(scene, ima, efa, tf)) {
2494                         BM_ClearHFlag(efa, BM_TMP_TAG);
2495                         continue;
2496                 }
2497                 
2498                 BM_SetHFlag(efa, BM_TMP_TAG);
2499                 BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
2500                         if (uvedit_uv_selected(em, scene, l)) 
2501                                 countsel++;
2502
2503                         if(propmode)
2504                                 count++;
2505                 }
2506         }
2507
2508          /* note: in prop mode we need at least 1 selected */
2509         if (countsel==0) return;
2510
2511         t->total= (propmode)? count: countsel;
2512         t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(UV Editing)");
2513         /* for each 2d uv coord a 3d vector is allocated, so that they can be
2514            treated just as if they were 3d verts */
2515         t->data2d= MEM_callocN(t->total*sizeof(TransData2D), "TransObData2D(UV Editing)");
2516
2517         if(sima->flag & SI_CLIP_UV)
2518                 t->flag |= T_CLIP_UV;
2519
2520         td= t->data;
2521         td2d= t->data2d;
2522
2523         BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
2524                 if (!BM_TestHFlag(efa, BM_TMP_TAG))
2525                         continue;
2526
2527                 tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
2528                 BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
2529                         if (!propmode && !uvedit_uv_selected(em, scene, l))
2530                                 continue;
2531                         
2532                         luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
2533                         UVsToTransData(sima, td++, td2d++, luv->uv, uvedit_uv_selected(em, scene, l));
2534                 }
2535         }
2536
2537         if (sima->flag & SI_LIVE_UNWRAP)
2538                 ED_uvedit_live_unwrap_begin(t->scene, t->obedit);
2539 }
2540
2541 void flushTransUVs(TransInfo *t)
2542 {
2543         SpaceImage *sima = t->sa->spacedata.first;
2544         TransData2D *td;
2545         int a, width, height;
2546         float aspx, aspy, invx, invy;
2547
2548         ED_space_image_uv_aspect(sima, &aspx, &aspy);
2549         ED_space_image_size(sima, &width, &height);
2550         invx= 1.0f/aspx;
2551         invy= 1.0f/aspy;
2552
2553         /* flush to 2d vector from internally used 3d vector */
2554         for(a=0, td= t->data2d; a<t->total; a++, td++) {
2555                 if (!td->loc2d) continue;
2556                 
2557                 td->loc2d[0]= td->loc[0]*invx;
2558                 td->loc2d[1]= td->loc[1]*invy;
2559
2560                 if((sima->flag & SI_PIXELSNAP) && (t->state != TRANS_CANCEL)) {
2561                         td->loc2d[0]= (float)floor(width*td->loc2d[0] + 0.5f)/width;
2562                         td->loc2d[1]= (float)floor(height*td->loc2d[1] + 0.5f)/height;
2563                 }
2564         }
2565 }
2566
2567 int clipUVTransform(TransInfo *t, float *vec, int resize)
2568 {
2569         TransData *td;
2570         int a, clipx=1, clipy=1;
2571         float aspx, aspy, min[2], max[2];
2572
2573         ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy);
2574         min[0]= min[1]= 0.0f;
2575         max[0]= aspx; max[1]= aspy;
2576
2577         for(a=0, td= t->data; a<t->total; a++, td++) {
2578                 DO_MINMAX2(td->loc, min, max);
2579         }
2580
2581         if(resize) {
2582                 if(min[0] < 0.0f && t->center[0] > 0.0f && t->center[0] < aspx*0.5f)
2583                         vec[0] *= t->center[0]/(t->center[0] - min[0]);
2584                 else if(max[0] > aspx && t->center[0] < aspx)
2585                         vec[0] *= (t->center[0] - aspx)/(t->center[0] - max[0]);
2586                 else
2587                         clipx= 0;
2588
2589                 if(min[1] < 0.0f && t->center[1] > 0.0f && t->center[1] < aspy*0.5f)
2590                         vec[1] *= t->center[1]/(t->center[1] - min[1]);
2591                 else if(max[1] > aspy && t->center[1] < aspy)
2592                         vec[1] *= (t->center[1] - aspy)/(t->center[1] - max[1]);
2593                 else
2594                         clipy= 0;
2595         }
2596         else {
2597                 if(min[0] < 0.0f)
2598                         vec[0] -= min[0];
2599                 else if(max[0] > aspx)
2600                         vec[0] -= max[0]-aspx;
2601                 else
2602                         clipx= 0;
2603
2604                 if(min[1] < 0.0f)
2605                         vec[1] -= min[1];
2606                 else if(max[1] > aspy)
2607                         vec[1] -= max[1]-aspy;
2608                 else
2609                         clipy= 0;
2610         }
2611
2612         return (clipx || clipy);
2613 }
2614
2615 /* ********************* ANIMATION EDITORS (GENERAL) ************************* */
2616
2617 /* This function tests if a point is on the "mouse" side of the cursor/frame-marking */
2618 static short FrameOnMouseSide(char side, float frame, float cframe)
2619 {
2620         /* both sides, so it doesn't matter */
2621         if (side == 'B') return 1;
2622
2623         /* only on the named side */
2624         if (side == 'R')
2625                 return (frame >= cframe) ? 1 : 0;
2626         else
2627                 return (frame <= cframe) ? 1 : 0;
2628 }
2629
2630 /* ********************* NLA EDITOR ************************* */
2631
2632 static void createTransNlaData(bContext *C, TransInfo *t)
2633 {
2634         Scene *scene= t->scene;
2635         SpaceNla *snla = NULL;
2636         TransData *td = NULL;
2637         TransDataNla *tdn = NULL;
2638         
2639         bAnimContext ac;
2640         ListBase anim_data = {NULL, NULL};
2641         bAnimListElem *ale;
2642         int filter;
2643         
2644         int count=0;
2645         
2646         /* determine what type of data we are operating on */
2647         if (ANIM_animdata_get_context(C, &ac) == 0)
2648                 return;
2649         snla = (SpaceNla *)ac.sl;
2650         
2651         /* filter data */
2652         filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
2653         ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
2654         
2655         /* which side of the current frame should be allowed */
2656         if (t->mode == TFM_TIME_EXTEND) {
2657                 /* only side on which mouse is gets transformed */
2658                 float xmouse, ymouse;
2659                 
2660                 UI_view2d_region_to_view(&ac.ar->v2d, t->imval[0], t->imval[1], &xmouse, &ymouse);
2661                 t->frame_side= (xmouse > CFRA) ? 'R' : 'L';
2662         }
2663         else {
2664                 /* normal transform - both sides of current frame are considered */
2665                 t->frame_side = 'B';
2666         }
2667         
2668         /* loop 1: count how many strips are selected (consider each strip as 2 points) */
2669         for (ale= anim_data.first; ale; ale= ale->next) {
2670                 NlaTrack *nlt= (NlaTrack *)ale->data;
2671                 NlaStrip *strip;
2672                 
2673                 /* make some meta-strips for chains of selected strips */
2674                 BKE_nlastrips_make_metas(&nlt->strips, 1);
2675                 
2676                 /* only consider selected strips */
2677                 for (strip= nlt->strips.first; strip; strip= strip->next) {
2678                         // TODO: we can make strips have handles later on...
2679                         /* transition strips can't get directly transformed */
2680                         if (strip->type != NLASTRIP_TYPE_TRANSITION) {
2681                                 if (strip->flag & NLASTRIP_FLAG_SELECT) {
2682                                         if (FrameOnMouseSide(t->frame_side, strip->start, (float)CFRA)) count++;
2683                                         if (FrameOnMouseSide(t->frame_side, strip->end, (float)CFRA)) count++;
2684                                 }
2685                         }
2686                 }
2687         }
2688         
2689         /* stop if trying to build list if nothing selected */
2690         if (count == 0) {
2691                 /* cleanup temp list */
2692                 BLI_freelistN(&anim_data);
2693                 return;
2694         }
2695         
2696         /* allocate memory for data */
2697         t->total= count;
2698         
2699         t->data= MEM_callocN(t->total*sizeof(TransData), "TransData(NLA Editor)");
2700         td= t->data;
2701         t->customData= MEM_callocN(t->total*sizeof(TransDataNla), "TransDataNla (NLA Editor)");
2702         tdn= t->customData;
2703         
2704         /* loop 2: build transdata array */
2705         for (ale= anim_data.first; ale; ale= ale->next) {
2706                 /* only if a real NLA-track */
2707                 if (ale->type == ANIMTYPE_NLATRACK) {
2708                         AnimData *adt = ale->adt;
2709                         NlaTrack *nlt= (NlaTrack *)ale->data;
2710                         NlaStrip *strip;
2711                         
2712                         /* only consider selected strips */
2713                         for (strip= nlt->strips.first; strip; strip= strip->next) {
2714                                 // TODO: we can make strips have handles later on...
2715                                 /* transition strips can't get directly transformed */
2716                                 if (strip->type != NLASTRIP_TYPE_TRANSITION) {
2717                                         if (strip->flag & NLASTRIP_FLAG_SELECT) {
2718                                                 /* our transform data is constructed as follows:
2719                                                  *      - only the handles on the right side of the current-frame get included
2720                                                  *      - td structs are transform-elements operated on by the transform system
2721                                                  *        and represent a single handle. The storage/pointer used (val or loc) depends on
2722                                                  *        whether we're scaling or transforming. Ultimately though, the handles
2723                                                  *        the td writes to will simply be a dummy in tdn
2724                                                  *      - for each strip being transformed, a single tdn struct is used, so in some
2725                                                  *        cases, there will need to be 1 of these tdn elements in the array skipped...
2726                                                  */
2727                                                 float center[3], yval;
2728                                                 
2729                                                 /* firstly, init tdn settings */
2730                                                 tdn->id= ale->id;
2731                                                 tdn->oldTrack= tdn->nlt= nlt;
2732                                                 tdn->strip= strip;
2733                                                 tdn->trackIndex= BLI_findindex(&adt->nla_tracks, nlt);
2734                                                 
2735                                                 yval= (float)(tdn->trackIndex * NLACHANNEL_STEP(snla));
2736                                                 
2737                                                 tdn->h1[0]= strip->start;
2738                                                 tdn->h1[1]= yval;
2739                                                 tdn->h2[0]= strip->end;
2740                                                 tdn->h2[1]= yval;
2741                                                 
2742                                                 center[0]= (float)CFRA;
2743                                                 center[1]= yval;
2744                                                 center[2]= 0.0f;
2745                                                 
2746                                                 /* set td's based on which handles are applicable */
2747                                                 if (FrameOnMouseSide(t->frame_side, strip->start, (float)CFRA))
2748                                                 {
2749                                                         /* just set tdn to assume that it only has one handle for now */
2750                                                         tdn->handle= -1;
2751                                                         
2752                                                         /* now, link the transform data up to this data */
2753                                                         if (ELEM(t->mode, TFM_TRANSLATION, TFM_TIME_EXTEND)) {
2754                                                                 td->loc= tdn->h1;
2755                                                                 copy_v3_v3(td->iloc, tdn->h1);
2756                                                                 
2757                                                                 /* store all the other gunk that is required by transform */
2758                                                                 copy_v3_v3(td->center, center);
2759                                                                 memset(td->axismtx, 0, sizeof(td->axismtx));
2760                                                                 td->axismtx[2][2] = 1.0f;
2761                                                                 
2762                                                                 td->ext= NULL; td->val= NULL;
2763                                                                 
2764                                                                 td->flag |= TD_SELECTED;
2765                                                                 td->dist= 0.0f;
2766                                                                 
2767                                                                 unit_m3(td->mtx);
2768                                                                 unit_m3(td->smtx);
2769                                                         }
2770                                                         else {
2771                                                                 /* time scaling only needs single value */
2772                                                                 td->val= &tdn->h1[0];
2773                                                                 td->ival= tdn->h1[0];
2774                                                         }
2775                                                         
2776                                                         td->extra= tdn;
2777                                                         td++;
2778                                                 }
2779                                                 if (FrameOnMouseSide(t->frame_side, strip->end, (float)CFRA))
2780                                                 {
2781                                                         /* if tdn is already holding the start handle, then we're doing both, otherwise, only end */
2782                                                         tdn->handle= (tdn->handle) ? 2 : 1;
2783                                                         
2784                                                         /* now, link the transform data up to this data */
2785                                                         if (ELEM(t->mode, TFM_TRANSLATION, TFM_TIME_EXTEND)) {
2786                                                                 td->loc= tdn->h2;
2787                                                                 copy_v3_v3(td->iloc, tdn->h2);
2788                                                                 
2789                                                                 /* store all the other gunk that is required by transform */
2790                                                                 copy_v3_v3(td->center, center);
2791                                                                 memset(td->axismtx, 0, sizeof(td->axismtx));
2792                                                                 td->axismtx[2][2] = 1.0f;
2793                                                                 
2794                                                                 td->ext= NULL; td->val= NULL;
2795                                                                 
2796                                                                 td->flag |= TD_SELECTED;
2797                                                                 td->dist= 0.0f;
2798                                                                 
2799