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