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