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