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