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