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