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