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