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