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