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