~ubuntu-branches/ubuntu/gutsy/blender/gutsy-security

« back to all changes in this revision

Viewing changes to source/blender/src/transform_conversions.c

  • Committer: Bazaar Package Importer
  • Author(s): Florian Ernst
  • Date: 2005-11-06 12:40:03 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051106124003-3pgs7tcg5rox96xg
Tags: 2.37a-1.1
* Non-maintainer upload.
* Split out parts of 01_SConstruct_debian.dpatch again: root_build_dir
  really needs to get adjusted before the clean target runs - closes: #333958,
  see #288882 for reference

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * $Id: transform_conversions.c,v 1.16 2005/06/11 16:30:36 jesterking Exp $
 
3
 *
 
4
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU General Public License
 
8
 * as published by the Free Software Foundation; either version 2
 
9
 * of the License, or (at your option) any later version. The Blender
 
10
 * Foundation also sells licenses for use in proprietary software under
 
11
 * the Blender License.  See http://www.blender.org/BL/ for information
 
12
 * about this.
 
13
 *
 
14
 * This program is distributed in the hope that it will be useful,
 
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 * GNU General Public License for more details.
 
18
 *
 
19
 * You should have received a copy of the GNU General Public License
 
20
 * along with this program; if not, write to the Free Software Foundation,
 
21
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
22
 *
 
23
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 
24
 * All rights reserved.
 
25
 *
 
26
 * The Original Code is: all of this file.
 
27
 *
 
28
 * Contributor(s): none yet.
 
29
 *
 
30
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
 
31
 */
 
32
 
 
33
#include <stdlib.h>
 
34
#include <string.h>
 
35
#include <math.h>
 
36
 
 
37
#ifdef HAVE_CONFIG_H
 
38
#include <config.h>
 
39
#endif
 
40
 
 
41
#ifndef WIN32
 
42
#include <unistd.h>
 
43
#else
 
44
#include <io.h>
 
45
#endif
 
46
 
 
47
#include "MEM_guardedalloc.h"
 
48
 
 
49
#include "DNA_action_types.h"
 
50
#include "DNA_armature_types.h"
 
51
#include "DNA_camera_types.h"
 
52
#include "DNA_curve_types.h"
 
53
#include "DNA_effect_types.h"
 
54
#include "DNA_ika_types.h"
 
55
#include "DNA_image_types.h"
 
56
#include "DNA_ipo_types.h"
 
57
#include "DNA_key_types.h"
 
58
#include "DNA_lamp_types.h"
 
59
#include "DNA_lattice_types.h"
 
60
#include "DNA_mesh_types.h"
 
61
#include "DNA_meshdata_types.h"
 
62
#include "DNA_meta_types.h"
 
63
#include "DNA_object_types.h"
 
64
#include "DNA_object_force.h"
 
65
#include "DNA_scene_types.h"
 
66
#include "DNA_screen_types.h"
 
67
#include "DNA_texture_types.h"
 
68
#include "DNA_view3d_types.h"
 
69
#include "DNA_world_types.h"
 
70
#include "DNA_userdef_types.h"
 
71
#include "DNA_property_types.h"
 
72
#include "DNA_vfont_types.h"
 
73
#include "DNA_constraint_types.h"
 
74
 
 
75
#include "BIF_editview.h"
 
76
#include "BIF_resources.h"
 
77
#include "BIF_mywindow.h"
 
78
#include "BIF_gl.h"
 
79
#include "BIF_editlattice.h"
 
80
#include "BIF_editconstraint.h"
 
81
#include "BIF_editarmature.h"
 
82
#include "BIF_editmesh.h"
 
83
#include "BIF_poseobject.h"
 
84
#include "BIF_screen.h"
 
85
#include "BIF_space.h"
 
86
#include "BIF_toolbox.h"
 
87
 
 
88
#include "BKE_action.h"
 
89
#include "BKE_armature.h"
 
90
#include "BKE_blender.h"
 
91
#include "BKE_curve.h"
 
92
#include "BKE_constraint.h"
 
93
#include "BKE_displist.h"
 
94
#include "BKE_effect.h"
 
95
#include "BKE_font.h"
 
96
#include "BKE_global.h"
 
97
#include "BKE_ipo.h"
 
98
#include "BKE_lattice.h"
 
99
#include "BKE_mball.h"
 
100
#include "BKE_object.h"
 
101
#include "BKE_softbody.h"
 
102
#include "BKE_utildefines.h"
 
103
 
 
104
#include "BSE_view.h"
 
105
#include "BSE_edit.h"
 
106
#include "BSE_editaction.h"
 
107
#include "BSE_editipo.h"
 
108
#include "BSE_editipo_types.h"
 
109
#include "BSE_editaction.h"
 
110
 
 
111
#include "BDR_editobject.h"             // reset_slowparents()
 
112
 
 
113
#include "BLI_arithb.h"
 
114
#include "BLI_editVert.h"
 
115
#include "BLI_ghash.h"
 
116
 
 
117
#include "PIL_time.h"
 
118
 
 
119
#include "blendef.h"
 
120
 
 
121
#include "mydevice.h"
 
122
 
 
123
extern ListBase editNurb;
 
124
extern ListBase editelems;
 
125
 
 
126
#include "transform.h"
 
127
 
 
128
/* local protos */
 
129
static void figure_bone_nocalc(Object *ob);
 
130
static void figure_pose_updating(void);
 
131
 
 
132
 
 
133
/* ************************** Functions *************************** */
 
134
 
 
135
static void qsort_trans_data(TransInfo *t, TransData *head, TransData *tail) {
 
136
        TransData pivot = *head;
 
137
        TransData *ihead = head;
 
138
        TransData *itail = tail;
 
139
        short connected = t->flag & T_PROP_CONNECTED;
 
140
 
 
141
        while (head < tail)
 
142
        {
 
143
                if (connected) {
 
144
                        while ((tail->dist >= pivot.dist) && (head < tail))
 
145
                                tail--;
 
146
                }
 
147
                else {
 
148
                        while ((tail->rdist >= pivot.rdist) && (head < tail))
 
149
                                tail--;
 
150
                }
 
151
 
 
152
                if (head != tail)
 
153
                {
 
154
                        *head = *tail;
 
155
                        head++;
 
156
                }
 
157
 
 
158
                if (connected) {
 
159
                        while ((head->dist <= pivot.dist) && (head < tail))
 
160
                                head++;
 
161
                }
 
162
                else {
 
163
                        while ((head->rdist <= pivot.rdist) && (head < tail))
 
164
                                head++;
 
165
                }
 
166
 
 
167
                if (head != tail)
 
168
                {
 
169
                        *tail = *head;
 
170
                        tail--;
 
171
                }
 
172
        }
 
173
 
 
174
        *head = pivot;
 
175
        if (ihead < head) {
 
176
                qsort_trans_data(t, ihead, head-1);
 
177
        }
 
178
        if (itail > head) {
 
179
                qsort_trans_data(t, head+1, itail);
 
180
        }
 
181
}
 
182
 
 
183
void sort_trans_data_dist(TransInfo *t) {
 
184
        TransData *start = t->data;
 
185
        int i = 1;
 
186
 
 
187
        while(i < t->total && start->flag & TD_SELECTED) {
 
188
                start++;
 
189
                i++;
 
190
        }
 
191
        qsort_trans_data(t, start, t->data + t->total - 1);
 
192
}
 
193
 
 
194
static void sort_trans_data(TransInfo *t) 
 
195
{
 
196
        TransData *sel, *unsel;
 
197
        TransData temp;
 
198
        unsel = t->data;
 
199
        sel = t->data;
 
200
        sel += t->total - 1;
 
201
        while (sel > unsel) {
 
202
                while (unsel->flag & TD_SELECTED) {
 
203
                        unsel++;
 
204
                        if (unsel == sel) {
 
205
                                return;
 
206
                        }
 
207
                }
 
208
                while (!(sel->flag & TD_SELECTED)) {
 
209
                        sel--;
 
210
                        if (unsel == sel) {
 
211
                                return;
 
212
                        }
 
213
                }
 
214
                temp = *unsel;
 
215
                *unsel = *sel;
 
216
                *sel = temp;
 
217
                sel--;
 
218
                unsel++;
 
219
        }
 
220
}
 
221
 
 
222
 
 
223
/* distance calculated from not-selected vertex to nearest selected vertex
 
224
   warning; this is loops inside loop, has minor N^2 issues, but by sorting list it is OK */
 
225
static void set_prop_dist(TransInfo *t, short with_dist)
 
226
{
 
227
        TransData *tob;
 
228
        int a;
 
229
        
 
230
        for(a=0, tob= t->data; a<t->total; a++, tob++) {
 
231
                
 
232
                tob->rdist= 0.0f; // init, it was mallocced
 
233
                
 
234
                if((tob->flag & TD_SELECTED)==0) {
 
235
                        TransData *td;
 
236
                        int i;
 
237
                        float dist, vec[3];
 
238
 
 
239
                        tob->rdist = -1.0f; // signal for next loop
 
240
                                
 
241
                        for (i = 0, td= t->data; i < t->total; i++, td++) {
 
242
                                if(td->flag & TD_SELECTED) {
 
243
                                        VecSubf(vec, tob->center, td->center);
 
244
                                        Mat3MulVecfl(tob->mtx, vec);
 
245
                                        dist = Normalise(vec);
 
246
                                        if (tob->rdist == -1.0f) {
 
247
                                                tob->rdist = dist;
 
248
                                        }
 
249
                                        else if (dist < tob->rdist) {
 
250
                                                tob->rdist = dist;
 
251
                                        }
 
252
                                }
 
253
                                else break;     // by definition transdata has selected items in beginning
 
254
                        }
 
255
                        if (with_dist) {
 
256
                                tob->dist = tob->rdist;
 
257
                        }
 
258
                }       
 
259
        }
 
260
}
 
261
 
 
262
/* ************************** CONVERSIONS ************************* */
 
263
 
 
264
/* ********************* texture space ********* */
 
265
 
 
266
static void createTransTexspace(TransInfo *t)
 
267
{
 
268
        TransData *td;
 
269
        Object *ob;
 
270
        ID *id;
 
271
        
 
272
        ob= OBACT;
 
273
        t->total = 1;
 
274
        td= t->data= MEM_callocN(sizeof(TransData), "TransTexspace");
 
275
        td->ext= t->ext= MEM_callocN(sizeof(TransDataExtension), "TransTexspace");
 
276
        
 
277
        td->flag= TD_SELECTED;
 
278
        VECCOPY(td->center, ob->obmat[3]);
 
279
        td->ob = ob;
 
280
        
 
281
        Mat3CpyMat4(td->mtx, ob->obmat);
 
282
        Mat3Inv(td->smtx, td->mtx);
 
283
        
 
284
        id= ob->data;
 
285
        if(id==0);
 
286
        else if( GS(id->name)==ID_ME) {
 
287
                Mesh *me= ob->data;
 
288
                me->texflag &= ~AUTOSPACE;
 
289
                td->loc= me->loc;
 
290
                td->ext->rot= me->rot;
 
291
                td->ext->size= me->size;
 
292
        }
 
293
        else if( GS(id->name)==ID_CU) {
 
294
                Curve *cu= ob->data;
 
295
                cu->texflag &= ~CU_AUTOSPACE;
 
296
                td->loc= cu->loc;
 
297
                td->ext->rot= cu->rot;
 
298
                td->ext->size= cu->size;
 
299
        }
 
300
        else if( GS(id->name)==ID_MB) {
 
301
                MetaBall *mb= ob->data;
 
302
                mb->texflag &= ~MB_AUTOSPACE;
 
303
                td->loc= mb->loc;
 
304
                td->ext->rot= mb->rot;
 
305
                td->ext->size= mb->size;
 
306
        }
 
307
        
 
308
        VECCOPY(td->iloc, td->loc);
 
309
        VECCOPY(td->ext->irot, td->ext->rot);
 
310
        VECCOPY(td->ext->isize, td->ext->size);
 
311
}
 
312
 
 
313
/* ********************* edge (for crease) ***** */
 
314
 
 
315
static void createTransEdge(TransInfo *t) {
 
316
        TransData *td = NULL;
 
317
        EditMesh *em = G.editMesh;
 
318
        EditEdge *eed;
 
319
        Mesh *me = G.obedit->data;
 
320
        float mtx[3][3], smtx[3][3];
 
321
        int count=0, countsel=0;
 
322
        int propmode = t->flag & T_PROP_EDIT;
 
323
 
 
324
        /* THIS IS A REALLY STUPID HACK, MUST BE A BETTER WAY TO DO IT */
 
325
        /* this is sufficient to invoke edges added in mesh, but only in editmode */
 
326
        if(me->medge==NULL) {
 
327
                me->medge= MEM_callocN(sizeof(MEdge), "fake medge");
 
328
                me->totedge= 1;
 
329
                allqueue(REDRAWBUTSEDIT, 0);
 
330
        }
 
331
                                        
 
332
        for(eed= em->edges.first; eed; eed= eed->next) {
 
333
                if(eed->h==0) {
 
334
                        if (eed->f & SELECT) countsel++;
 
335
                        if (propmode) count++;
 
336
                }
 
337
        }
 
338
 
 
339
        if (countsel == 0)
 
340
                return;
 
341
 
 
342
        if(propmode) {
 
343
                t->total = count;
 
344
        }
 
345
        else {
 
346
                t->total = countsel;
 
347
        }
 
348
 
 
349
        td= t->data= MEM_callocN(t->total * sizeof(TransData), "TransCrease");
 
350
 
 
351
        Mat3CpyMat4(mtx, G.obedit->obmat);
 
352
        Mat3Inv(smtx, mtx);
 
353
 
 
354
        for(eed= em->edges.first; eed; eed= eed->next) {
 
355
                if(eed->h==0 && (eed->f & SELECT || propmode)) {
 
356
                        /* need to set center for center calculations */
 
357
                        VecAddf(td->center, eed->v1->co, eed->v2->co);
 
358
                        VecMulf(td->center, 0.5f);
 
359
 
 
360
                        td->loc= NULL;
 
361
                        if (eed->f & SELECT)
 
362
                                td->flag= TD_SELECTED;
 
363
                        else 
 
364
                                td->flag= 0;
 
365
 
 
366
 
 
367
                        Mat3CpyMat3(td->smtx, smtx);
 
368
                        Mat3CpyMat3(td->mtx, mtx);
 
369
 
 
370
                        td->ext = NULL;
 
371
                        td->tdi = NULL;
 
372
                        td->val = &(eed->crease);
 
373
                        td->ival = eed->crease;
 
374
 
 
375
                        td++;
 
376
                }
 
377
        }
 
378
}
 
379
 
 
380
/* ********************* pose mode ************* */
 
381
 
 
382
/* callback, make sure it's identical structured as next one */
 
383
/* also used to count for manipulator */
 
384
void count_bone_select(TransInfo *t, ListBase *lb, int *counter) 
 
385
{
 
386
        Bone *bone;
 
387
        int deeper= 1;
 
388
        
 
389
        for(bone= lb->first; bone; bone= bone->next) {
 
390
                if (bone->flag & BONE_SELECTED) {
 
391
                        /* We don't let IK children get "grabbed" */
 
392
                        /* ALERT! abusive global Trans here */
 
393
                        if ( (t->mode!=TFM_TRANSLATION) || (bone->flag & BONE_IK_TOPARENT)==0 ) {
 
394
                                (*counter)++;
 
395
                                deeper= 0;      // no transform on children if one parent bone is selected
 
396
                        }
 
397
                        else deeper= 1;
 
398
                }
 
399
                if(deeper) count_bone_select(t, &bone->childbase, counter);
 
400
        }
 
401
}
 
402
 
 
403
/* recursive */
 
404
static void add_pose_transdata(TransInfo *t, ListBase *lb, Object *ob, TransData **tdp)
 
405
{
 
406
        Bone *bone;
 
407
        TransData *td;
 
408
        float   parmat[4][4], tempmat[4][4];
 
409
        float tempobmat[4][4];
 
410
        float vec[3];
 
411
        int deeper= 1;
 
412
        
 
413
        for(bone= lb->first; bone; bone= bone->next) {
 
414
                if (bone->flag & BONE_SELECTED) {
 
415
                        /* We don't let IK children get "grabbed" */
 
416
                        /* ALERT! abusive global Trans here */
 
417
                        if ( (t->mode!=TFM_TRANSLATION) || (bone->flag & BONE_IK_TOPARENT)==0 ) {
 
418
                                
 
419
                                td= *tdp;
 
420
                                
 
421
                                get_bone_root_pos (bone, vec, 1);
 
422
                                
 
423
                                //VecAddf (centroid, centroid, vec);
 
424
                                VECCOPY(td->center, vec);
 
425
                                
 
426
                                td->ob = ob;
 
427
                                td->flag= TD_SELECTED|TD_USEQUAT;
 
428
                                td->loc = bone->loc;
 
429
                                VECCOPY(td->iloc, bone->loc);
 
430
                                
 
431
                                td->ext->rot= NULL;
 
432
                                td->ext->quat= bone->quat;
 
433
                                td->ext->size= bone->size;
 
434
                                td->ext->bone= bone; // FIXME: Dangerous
 
435
 
 
436
                                QUATCOPY(td->ext->iquat, bone->quat);
 
437
                                VECCOPY(td->ext->isize, bone->size);
 
438
                                
 
439
                                /* Get the matrix of this bone minus the usertransform */
 
440
                                Mat4CpyMat4 (tempobmat, bone->obmat);
 
441
                                Mat4One (bone->obmat);
 
442
                                get_objectspace_bone_matrix(bone, tempmat, 1, 1);
 
443
                                Mat4CpyMat4 (bone->obmat, tempobmat);
 
444
 
 
445
                                Mat4MulMat4 (parmat, tempmat, ob->obmat);       /* Original */
 
446
                                
 
447
                                Mat3CpyMat4 (td->mtx, parmat);
 
448
                                Mat3Inv (td->smtx, td->mtx);
 
449
 
 
450
                                Mat3CpyMat3(td->axismtx, td->mtx);
 
451
                                Mat3Ortho(td->axismtx);
 
452
                                
 
453
                                (*tdp)++;
 
454
                                deeper= 0;
 
455
                        }
 
456
                        else deeper= 1;
 
457
                }
 
458
                if(deeper) add_pose_transdata(t, &bone->childbase, ob, tdp);
 
459
        }
 
460
}
 
461
 
 
462
static void createTransPose(TransInfo *t)
 
463
{
 
464
        bArmature *arm;
 
465
        TransData *td;
 
466
        TransDataExtension *tdx;
 
467
        int i;
 
468
        
 
469
        /* check validity of state */
 
470
        arm=get_armature (G.obpose);
 
471
        if (arm==NULL) return;
 
472
        
 
473
        if (arm->flag & ARM_RESTPOS){
 
474
                notice ("Transformation not possible while Rest Position is enabled");
 
475
                return;
 
476
        }
 
477
        if (!(G.obpose->lay & G.vd->lay)) return;
 
478
 
 
479
        /* copied from old code, no idea. we let linker solve it for now */
 
480
        {
 
481
                /* figure out which bones need calculating */
 
482
                figure_bone_nocalc(G.obpose);
 
483
                figure_pose_updating();
 
484
        }
 
485
        
 
486
        /* copied from old code, no idea... (ton) */
 
487
        apply_pose_armature(arm, G.obpose->pose, 0);
 
488
        where_is_armature (G.obpose);
 
489
        
 
490
        /* count total */
 
491
        count_bone_select(t, &arm->bonebase, &t->total);
 
492
        
 
493
        if(t->total==0 && t->mode==TFM_TRANSLATION) {
 
494
                t->mode= TFM_ROTATION;
 
495
                count_bone_select(t, &arm->bonebase, &t->total);
 
496
        }               
 
497
        if(t->total==0) return;
 
498
 
 
499
        /* init trans data */
 
500
    td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransPoseBone");
 
501
    tdx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "TransPoseBoneExt");
 
502
        for(i=0; i<t->total; i++, td++, tdx++) {
 
503
                td->ext= tdx;
 
504
                td->tdi = NULL;
 
505
                td->val = NULL;
 
506
        }       
 
507
        /* recursive fill trans data */
 
508
        td= t->data;
 
509
        add_pose_transdata(t, &arm->bonebase, G.obpose, &td);
 
510
        
 
511
}
 
512
 
 
513
/* ********************* armature ************** */
 
514
 
 
515
static void createTransArmatureVerts(TransInfo *t)
 
516
{
 
517
        EditBone *ebo;
 
518
        TransData *td;
 
519
        float mtx[3][3], smtx[3][3];
 
520
 
 
521
        t->total = 0;
 
522
        for (ebo=G.edbo.first;ebo;ebo=ebo->next){
 
523
                if (ebo->flag & BONE_TIPSEL){
 
524
                        t->total++;
 
525
                }
 
526
                if (ebo->flag & BONE_ROOTSEL){
 
527
                        t->total++;
 
528
                }
 
529
        }
 
530
 
 
531
    if (!t->total) return;
 
532
        
 
533
        Mat3CpyMat4(mtx, G.obedit->obmat);
 
534
        Mat3Inv(smtx, mtx);
 
535
 
 
536
    td = t->data = MEM_mallocN(t->total*sizeof(TransData), "TransEditBone");
 
537
        
 
538
        for (ebo=G.edbo.first;ebo;ebo=ebo->next){
 
539
                if (ebo->flag & BONE_TIPSEL){
 
540
                        VECCOPY (td->iloc, ebo->tail);
 
541
                        VECCOPY (td->center, td->iloc);
 
542
                        td->loc= ebo->tail;
 
543
                        td->flag= TD_SELECTED;
 
544
 
 
545
                        Mat3CpyMat3(td->smtx, smtx);
 
546
                        Mat3CpyMat3(td->mtx, mtx);
 
547
 
 
548
                        td->ext = NULL;
 
549
                        td->tdi = NULL;
 
550
                        td->val = NULL;
 
551
 
 
552
                        td++;
 
553
                }
 
554
                if (ebo->flag & BONE_ROOTSEL){
 
555
                        VECCOPY (td->iloc, ebo->head);
 
556
                        VECCOPY (td->center, td->iloc);
 
557
                        td->loc= ebo->head;
 
558
                        td->flag= TD_SELECTED;
 
559
 
 
560
                        Mat3CpyMat3(td->smtx, smtx);
 
561
                        Mat3CpyMat3(td->mtx, mtx);
 
562
 
 
563
                        td->ext = NULL;
 
564
                        td->tdi = NULL;
 
565
                        td->val = NULL;
 
566
 
 
567
                        td++;
 
568
                }
 
569
                        
 
570
        }
 
571
}
 
572
 
 
573
/* ********************* meta elements ********* */
 
574
 
 
575
static void createTransMBallVerts(TransInfo *t)
 
576
{
 
577
        MetaElem *ml;
 
578
        TransData *td;
 
579
        TransDataExtension *tx;
 
580
        float mtx[3][3], smtx[3][3];
 
581
        int count=0, countsel=0;
 
582
        int propmode = t->flag & T_PROP_EDIT;
 
583
 
 
584
        /* count totals */
 
585
        for(ml= editelems.first; ml; ml= ml->next) {
 
586
                if(ml->flag & SELECT) countsel++;
 
587
                if(propmode) count++;
 
588
        }
 
589
 
 
590
        /* note: in prop mode we need at least 1 selected */
 
591
        if (countsel==0) return;
 
592
        
 
593
        if(propmode) t->total = count; 
 
594
        else t->total = countsel;
 
595
        
 
596
        td = t->data= MEM_mallocN(t->total*sizeof(TransData), "TransObData(MBall EditMode)");
 
597
        tx = t->ext = MEM_mallocN(t->total*sizeof(TransDataExtension), "MetaElement_TransExtension");
 
598
 
 
599
        Mat3CpyMat4(mtx, G.obedit->obmat);
 
600
        Mat3Inv(smtx, mtx);
 
601
    
 
602
        for(ml= editelems.first; ml; ml= ml->next) {
 
603
                if(propmode || (ml->flag & SELECT)) {
 
604
                        td->loc= &ml->x;
 
605
                        VECCOPY(td->iloc, td->loc);
 
606
                        VECCOPY(td->center, td->loc);
 
607
 
 
608
                        if(ml->flag & SELECT) td->flag= TD_SELECTED | TD_USEQUAT | TD_SINGLESIZE;
 
609
                        else td->flag= TD_USEQUAT;
 
610
 
 
611
                        Mat3CpyMat3(td->smtx, smtx);
 
612
                        Mat3CpyMat3(td->mtx, mtx);
 
613
 
 
614
                        td->ext = tx;
 
615
                        td->tdi = NULL;
 
616
 
 
617
                        /* Radius of MetaElem (mass of MetaElem influence) */
 
618
                        if(ml->flag & MB_SCALE_RAD){
 
619
                                td->val = &ml->rad;
 
620
                                td->ival = ml->rad;
 
621
                        }
 
622
                        else{
 
623
                                td->val = &ml->s;
 
624
                                td->ival = ml->s;
 
625
                        }
 
626
 
 
627
                        /* expx/expy/expz determine "shape" of some MetaElem types */
 
628
                        tx->size = &ml->expx;
 
629
                        tx->isize[0] = ml->expx;
 
630
                        tx->isize[1] = ml->expy;
 
631
                        tx->isize[2] = ml->expz;
 
632
 
 
633
                        /* quat is used for rotation of MetaElem */
 
634
                        tx->quat = ml->quat;
 
635
                        QUATCOPY(tx->iquat, ml->quat);
 
636
 
 
637
                        tx->rot = NULL;
 
638
 
 
639
                        td++;
 
640
                        tx++;
 
641
                }
 
642
        }
 
643
 
644
 
 
645
/* ********************* curve/surface ********* */
 
646
 
 
647
static void calc_distanceCurveVerts(TransData *head, TransData *tail) {
 
648
        TransData *td, *td_near = NULL;
 
649
        for (td = head; td<=tail; td++) {
 
650
                if (td->flag & TD_SELECTED) {
 
651
                        td_near = td;
 
652
                        td->dist = 0.0f;
 
653
                }
 
654
                else if(td_near) {
 
655
                        float dist;
 
656
                        dist = VecLenf(td_near->center, td->center);
 
657
                        if (dist < (td-1)->dist) {
 
658
                                td->dist = (td-1)->dist;
 
659
                        }
 
660
                        else {
 
661
                                td->dist = dist;
 
662
                        }
 
663
                }
 
664
                else {
 
665
                        td->dist = MAXFLOAT;
 
666
                        td->flag |= TD_NOTCONNECTED;
 
667
                }
 
668
        }
 
669
        td_near = NULL;
 
670
        for (td = tail; td>=head; td--) {
 
671
                if (td->flag & TD_SELECTED) {
 
672
                        td_near = td;
 
673
                        td->dist = 0.0f;
 
674
                }
 
675
                else if(td_near) {
 
676
                        float dist;
 
677
                        dist = VecLenf(td_near->center, td->center);
 
678
                        if (td->flag & TD_NOTCONNECTED || dist < td->dist || (td+1)->dist < td->dist) {
 
679
                                td->flag &= ~TD_NOTCONNECTED;
 
680
                                if (dist < (td+1)->dist) {
 
681
                                        td->dist = (td+1)->dist;
 
682
                                }
 
683
                                else {
 
684
                                        td->dist = dist;
 
685
                                }
 
686
                        }
 
687
                }
 
688
        }
 
689
}
 
690
 
 
691
static void createTransCurveVerts(TransInfo *t)
 
692
{
 
693
        TransData *td = NULL;
 
694
        Nurb *nu;
 
695
        BezTriple *bezt;
 
696
        BPoint *bp;
 
697
        float mtx[3][3], smtx[3][3];
 
698
        int a;
 
699
        int count=0, countsel=0;
 
700
        int propmode = t->flag & T_PROP_EDIT;
 
701
 
 
702
        /* count total of vertices, check identical as in 2nd loop for making transdata! */
 
703
        for(nu= editNurb.first; nu; nu= nu->next) {
 
704
                if((nu->type & 7)==CU_BEZIER) {
 
705
                        for(a=0, bezt= nu->bezt; a<nu->pntsu; a++, bezt++) {
 
706
                                if(bezt->hide==0) {
 
707
                                        if(bezt->f1 & 1) countsel++;
 
708
                                        if(bezt->f2 & 1) countsel++;
 
709
                                        if(bezt->f3 & 1) countsel++;
 
710
                                        if(propmode) count+= 3;
 
711
                                }
 
712
                        }
 
713
                }
 
714
                else {
 
715
                        for(a= nu->pntsu*nu->pntsv, bp= nu->bp; a>0; a--, bp++) {
 
716
                                if(bp->hide==0) {
 
717
                                        if(propmode) count++;
 
718
                                        if(bp->f1 & 1) countsel++;
 
719
                                }
 
720
                        }
 
721
                }
 
722
        }
 
723
        /* note: in prop mode we need at least 1 selected */
 
724
        if (countsel==0) return;
 
725
        
 
726
        if(propmode) t->total = count; 
 
727
        else t->total = countsel;
 
728
        t->data= MEM_mallocN(t->total*sizeof(TransData), "TransObData(Curve EditMode)");
 
729
 
 
730
        Mat3CpyMat4(mtx, G.obedit->obmat);
 
731
        Mat3Inv(smtx, mtx);
 
732
 
 
733
    td = t->data;
 
734
        for(nu= editNurb.first; nu; nu= nu->next) {
 
735
                if((nu->type & 7)==CU_BEZIER) {
 
736
                        TransData *head, *tail;
 
737
                        head = tail = td;
 
738
                        for(a=0, bezt= nu->bezt; a<nu->pntsu; a++, bezt++) {
 
739
                                if(bezt->hide==0) {
 
740
                                        if(propmode || (bezt->f1 & 1)) {
 
741
                                                VECCOPY(td->iloc, bezt->vec[0]);
 
742
                                                td->loc= bezt->vec[0];
 
743
                                                VECCOPY(td->center, bezt->vec[1]);
 
744
                                                if(bezt->f1 & 1) td->flag= TD_SELECTED;
 
745
                                                else td->flag= 0;
 
746
                                                td->ext = NULL;
 
747
                                                td->tdi = NULL;
 
748
                                                td->val = NULL;
 
749
 
 
750
                                                Mat3CpyMat3(td->smtx, smtx);
 
751
                                                Mat3CpyMat3(td->mtx, mtx);
 
752
 
 
753
                                                td++;
 
754
                                                count++;
 
755
                                                tail++;
 
756
                                        }
 
757
                                        /* THIS IS THE CV, the other two are handles */
 
758
                                        if(propmode || (bezt->f2 & 1)) {
 
759
                                                VECCOPY(td->iloc, bezt->vec[1]);
 
760
                                                td->loc= bezt->vec[1];
 
761
                                                VECCOPY(td->center, td->loc);
 
762
                                                if(bezt->f2 & 1) td->flag= TD_SELECTED;
 
763
                                                else td->flag= 0;
 
764
                                                td->ext = NULL;
 
765
                                                td->tdi = NULL;
 
766
                                                td->val = &(bezt->alfa);
 
767
                                                td->ival = bezt->alfa;
 
768
 
 
769
                                                Mat3CpyMat3(td->smtx, smtx);
 
770
                                                Mat3CpyMat3(td->mtx, mtx);
 
771
 
 
772
                                                td++;
 
773
                                                count++;
 
774
                                                tail++;
 
775
                                        }
 
776
                                        if(propmode || (bezt->f3 & 1)) {
 
777
                                                VECCOPY(td->iloc, bezt->vec[2]);
 
778
                                                td->loc= bezt->vec[2];
 
779
                                                VECCOPY(td->center, bezt->vec[1]);
 
780
                                                if(bezt->f3 & 1) td->flag= TD_SELECTED;
 
781
                                                else td->flag= 0;
 
782
                                                td->ext = NULL;
 
783
                                                td->tdi = NULL;
 
784
                                                td->val = NULL;
 
785
 
 
786
                                                Mat3CpyMat3(td->smtx, smtx);
 
787
                                                Mat3CpyMat3(td->mtx, mtx);
 
788
 
 
789
                                                td++;
 
790
                                                count++;
 
791
                                                tail++;
 
792
                                        }
 
793
                                }
 
794
                                else if (propmode && head != tail) {
 
795
                                        calc_distanceCurveVerts(head, tail-1);
 
796
                                        head = tail;
 
797
                                }
 
798
                        }
 
799
                        if (propmode && head != tail)
 
800
                                calc_distanceCurveVerts(head, tail);
 
801
                }
 
802
                else {
 
803
                        TransData *head, *tail;
 
804
                        head = tail = td;
 
805
                        for(a= nu->pntsu*nu->pntsv, bp= nu->bp; a>0; a--, bp++) {
 
806
                                if(bp->hide==0) {
 
807
                                        if(propmode || (bp->f1 & 1)) {
 
808
                                                VECCOPY(td->iloc, bp->vec);
 
809
                                                td->loc= bp->vec;
 
810
                                                VECCOPY(td->center, td->loc);
 
811
                                                if(bp->f1 & 1) td->flag= TD_SELECTED;
 
812
                                                else td->flag= 0;
 
813
                                                td->ext = NULL;
 
814
                                                td->tdi = NULL;
 
815
                                                td->val = &(bp->alfa);
 
816
                                                td->ival = bp->alfa;
 
817
 
 
818
                                                Mat3CpyMat3(td->smtx, smtx);
 
819
                                                Mat3CpyMat3(td->mtx, mtx);
 
820
 
 
821
                                                td++;
 
822
                                                count++;
 
823
                                                tail++;
 
824
                                        }
 
825
                                }
 
826
                                else if (propmode && head != tail) {
 
827
                                        calc_distanceCurveVerts(head, tail-1);
 
828
                                        head = tail;
 
829
                                }
 
830
                        }
 
831
                        if (propmode && head != tail)
 
832
                                calc_distanceCurveVerts(head, tail-1);
 
833
                }
 
834
        }
 
835
}
 
836
 
 
837
/* ********************* lattice *************** */
 
838
 
 
839
static void createTransLatticeVerts(TransInfo *t)
 
840
{
 
841
        TransData *td = NULL;
 
842
        BPoint *bp;
 
843
        float mtx[3][3], smtx[3][3];
 
844
        int a;
 
845
        int count=0, countsel=0;
 
846
        int propmode = t->flag & T_PROP_EDIT;
 
847
 
 
848
        bp= editLatt->def;
 
849
        a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
 
850
        while(a--) {
 
851
                if(bp->f1 & 1) countsel++;
 
852
                if(propmode) count++;
 
853
                bp++;
 
854
        }
 
855
        
 
856
        /* note: in prop mode we need at least 1 selected */
 
857
        if (countsel==0) return;
 
858
        
 
859
        if(propmode) t->total = count; 
 
860
        else t->total = countsel;
 
861
        t->data= MEM_mallocN(t->total*sizeof(TransData), "TransObData(Lattice EditMode)");
 
862
        
 
863
        Mat3CpyMat4(mtx, G.obedit->obmat);
 
864
        Mat3Inv(smtx, mtx);
 
865
 
 
866
        td = t->data;
 
867
        bp= editLatt->def;
 
868
        a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
 
869
        while(a--) {
 
870
                if(propmode || (bp->f1 & 1)) {
 
871
                        if(bp->hide==0) {
 
872
                                VECCOPY(td->iloc, bp->vec);
 
873
                                td->loc= bp->vec;
 
874
                                VECCOPY(td->center, td->loc);
 
875
                                if(bp->f1 & 1) td->flag= TD_SELECTED;
 
876
                                else td->flag= 0;
 
877
                                Mat3CpyMat3(td->smtx, smtx);
 
878
                                Mat3CpyMat3(td->mtx, mtx);
 
879
 
 
880
                                td->ext = NULL;
 
881
                                td->tdi = NULL;
 
882
                                td->val = NULL;
 
883
 
 
884
                                td++;
 
885
                                count++;
 
886
                        }
 
887
                }
 
888
                bp++;
 
889
        }
 
890
 
891
 
 
892
/* ********************* mesh ****************** */
 
893
 
 
894
/* proportional distance based on connectivity  */
 
895
#define E_VEC(a)        (vectors + (3 * (int)(a)->vn))
 
896
#define E_NEAR(a)       (nears[((int)(a)->vn)])
 
897
static void editmesh_set_connectivity_distance(int total, float *vectors, EditVert **nears)
 
898
{
 
899
        EditMesh *em = G.editMesh;
 
900
        EditVert *eve;
 
901
        EditEdge *eed;
 
902
        int i= 0, done= 1;
 
903
 
 
904
        /* f2 flag is used for 'selection' */
 
905
        /* vn is offset on scratch array   */
 
906
        for(eve= em->verts.first; eve; eve= eve->next) {
 
907
                if(eve->h==0) {
 
908
                        eve->vn = (EditVert *)(i++);
 
909
 
 
910
                        if(eve->f & SELECT) {
 
911
                                eve->f2= 2;
 
912
                                E_NEAR(eve) = eve;
 
913
                                E_VEC(eve)[0] = 0.0f;
 
914
                                E_VEC(eve)[1] = 0.0f;
 
915
                                E_VEC(eve)[2] = 0.0f;
 
916
                        }
 
917
                        else {
 
918
                                eve->f2 = 0;
 
919
                        }
 
920
                }
 
921
        }
 
922
 
 
923
 
 
924
        /* Floodfill routine */
 
925
        /*
 
926
        At worst this is n*n of complexity where n is number of edges 
 
927
        Best case would be n if the list is ordered perfectly.
 
928
        Estimate is n log n in average (so not too bad)
 
929
        */
 
930
        while(done) {
 
931
                done= 0;
 
932
                
 
933
                for(eed= em->edges.first; eed; eed= eed->next) {
 
934
                        if(eed->h==0) {
 
935
                                EditVert *v1= eed->v1, *v2= eed->v2;
 
936
                                float *vec2 = E_VEC(v2);
 
937
                                float *vec1 = E_VEC(v1);
 
938
 
 
939
                                if (v1->f2 + v2->f2 == 4)
 
940
                                        continue;
 
941
 
 
942
                                if (v1->f2) {
 
943
                                        if (v2->f2) {
 
944
                                                float nvec[3];
 
945
                                                float len1 = VecLength(vec1);
 
946
                                                float len2 = VecLength(vec2);
 
947
                                                float lenn;
 
948
                                                /* for v2 if not selected */
 
949
                                                if (v2->f2 != 2) {
 
950
                                                        VecSubf(nvec, v2->co, E_NEAR(v1)->co);
 
951
                                                        lenn = VecLength(nvec);
 
952
                                                        if (lenn - len1 > 0.00001f && len2 - lenn > 0.00001f) {
 
953
                                                                VECCOPY(vec2, nvec);
 
954
                                                                E_NEAR(v2) = E_NEAR(v1);
 
955
                                                                done = 1;
 
956
                                                        }
 
957
                                                        else if (len2 - len1 > 0.00001f && len1 - lenn > 0.00001f) {
 
958
                                                                VECCOPY(vec2, vec1);
 
959
                                                                E_NEAR(v2) = E_NEAR(v1);
 
960
                                                                done = 1;
 
961
                                                        }
 
962
                                                }
 
963
                                                /* for v1 if not selected */
 
964
                                                if (v1->f2 != 2) {
 
965
                                                        VecSubf(nvec, v1->co, E_NEAR(v2)->co);
 
966
                                                        lenn = VecLength(nvec);
 
967
                                                        if (lenn - len2 > 0.00001f && len1 - lenn > 0.00001f) {
 
968
                                                                VECCOPY(vec1, nvec);
 
969
                                                                E_NEAR(v1) = E_NEAR(v2);
 
970
                                                                done = 1;
 
971
                                                        }
 
972
                                                        else if (len1 - len2 > 0.00001f && len2 - lenn > 0.00001f) {
 
973
                                                                VECCOPY(vec1, vec2);
 
974
                                                                E_NEAR(v1) = E_NEAR(v2);
 
975
                                                                done = 1;
 
976
                                                        }
 
977
                                                }
 
978
                                        }
 
979
                                        else {
 
980
                                                v2->f2 = 1;
 
981
                                                VecSubf(vec2, v2->co, E_NEAR(v1)->co);
 
982
                                                if (VecLength(vec1) - VecLength(vec2) > 0.00001f) {
 
983
                                                        VECCOPY(vec2, vec1);
 
984
                                                }
 
985
                                                E_NEAR(v2) = E_NEAR(v1);
 
986
                                                done = 1;
 
987
                                        }
 
988
                                }
 
989
                                else if (v2->f2) {
 
990
                                        v1->f2 = 1;
 
991
                                        VecSubf(vec1, v1->co, E_NEAR(v2)->co);
 
992
                                        if (VecLength(vec2) - VecLength(vec1) > 0.00001f) {
 
993
                                                VECCOPY(vec1, vec2);
 
994
                                        }
 
995
                                        E_NEAR(v1) = E_NEAR(v2);
 
996
                                        done = 1;
 
997
                                }
 
998
                        }
 
999
                }
 
1000
        }
 
1001
}
 
1002
 
 
1003
 
 
1004
static void VertsToTransData(TransData *td, EditVert *eve)
 
1005
{
 
1006
        td->flag = 0;
 
1007
        td->loc = eve->co;
 
1008
        VECCOPY(td->center, td->loc);
 
1009
        VECCOPY(td->iloc, td->loc);
 
1010
 
 
1011
        // Setting normals
 
1012
        VECCOPY(td->axismtx[2], eve->no);
 
1013
        td->axismtx[0][0]               =
 
1014
                td->axismtx[0][1]       =
 
1015
                td->axismtx[0][2]       =
 
1016
                td->axismtx[1][0]       =
 
1017
                td->axismtx[1][1]       =
 
1018
                td->axismtx[1][2]       = 0.0f;
 
1019
 
 
1020
        td->ext = NULL;
 
1021
        td->tdi = NULL;
 
1022
        td->val = NULL;
 
1023
}
 
1024
 
 
1025
static void createTransEditVerts(TransInfo *t)
 
1026
{
 
1027
        TransData *tob = NULL;
 
1028
        EditMesh *em = G.editMesh;
 
1029
        EditVert *eve;
 
1030
        EditVert **nears = NULL;
 
1031
        float *vectors = NULL;
 
1032
        float mtx[3][3], smtx[3][3];
 
1033
        int count=0, countsel=0;
 
1034
        int propmode = t->flag & T_PROP_EDIT;
 
1035
                
 
1036
        // transform now requires awareness for select mode, so we tag the f1 flags in verts
 
1037
        if(G.scene->selectmode & SCE_SELECT_VERTEX) {
 
1038
                for(eve= em->verts.first; eve; eve= eve->next) {
 
1039
                        if(eve->h==0 && (eve->f & SELECT)) 
 
1040
                                eve->f1= SELECT;
 
1041
                        else
 
1042
                                eve->f1= 0;
 
1043
                }
 
1044
        }
 
1045
        else if(G.scene->selectmode & SCE_SELECT_EDGE) {
 
1046
                EditEdge *eed;
 
1047
                for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
 
1048
                for(eed= em->edges.first; eed; eed= eed->next) {
 
1049
                        if(eed->h==0 && (eed->f & SELECT))
 
1050
                                eed->v1->f1= eed->v2->f1= SELECT;
 
1051
                }
 
1052
        }
 
1053
        else {
 
1054
                EditFace *efa;
 
1055
                for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
 
1056
                for(efa= em->faces.first; efa; efa= efa->next) {
 
1057
                        if(efa->h==0 && (efa->f & SELECT)) {
 
1058
                                efa->v1->f1= efa->v2->f1= efa->v3->f1= SELECT;
 
1059
                                if(efa->v4) efa->v4->f1= SELECT;
 
1060
                        }
 
1061
                }
 
1062
        }
 
1063
        
 
1064
        /* now we can count */
 
1065
        for(eve= em->verts.first; eve; eve= eve->next) {
 
1066
                if(eve->h==0) {
 
1067
                        if(eve->f1) countsel++;
 
1068
                        if(propmode) count++;
 
1069
                }
 
1070
        }
 
1071
        
 
1072
        /* note: in prop mode we need at least 1 selected */
 
1073
        if (countsel==0) return;
 
1074
        
 
1075
        if(propmode) {
 
1076
                t->total = count; 
 
1077
        
 
1078
                /* allocating scratch arrays */
 
1079
                vectors = (float *)MEM_mallocN(t->total * 3 * sizeof(float), "scratch vectors");
 
1080
                nears = (EditVert**)MEM_mallocN(t->total * sizeof(EditVert*), "scratch nears");
 
1081
        }
 
1082
        else t->total = countsel;
 
1083
        tob= t->data= MEM_mallocN(t->total*sizeof(TransData), "TransObData(Mesh EditMode)");
 
1084
        
 
1085
        Mat3CpyMat4(mtx, G.obedit->obmat);
 
1086
        Mat3Inv(smtx, mtx);
 
1087
 
 
1088
        if(propmode) editmesh_set_connectivity_distance(t->total, vectors, nears);
 
1089
        
 
1090
        for (eve=em->verts.first; eve; eve=eve->next) {
 
1091
                if(eve->h==0) {
 
1092
                        if(propmode || eve->f1) {
 
1093
                                VertsToTransData(tob, eve);
 
1094
 
 
1095
                                if(eve->f1) tob->flag |= TD_SELECTED;
 
1096
                                if(propmode) {
 
1097
                                        if (eve->f2) {
 
1098
                                                float vec[3];
 
1099
                                                VECCOPY(vec, E_VEC(eve));
 
1100
                                                Mat3MulVecfl(mtx, vec);
 
1101
                                                tob->dist= VecLength(vec);
 
1102
                                        }
 
1103
                                        else {
 
1104
                                                tob->flag |= TD_NOTCONNECTED;
 
1105
                                                tob->dist = MAXFLOAT;
 
1106
                                        }
 
1107
                                }
 
1108
                                
 
1109
                                Mat3CpyMat3(tob->smtx, smtx);
 
1110
                                Mat3CpyMat3(tob->mtx, mtx);
 
1111
 
 
1112
                                tob++;
 
1113
                        }
 
1114
                }       
 
1115
        }
 
1116
        if (propmode) {
 
1117
                MEM_freeN(vectors);
 
1118
                MEM_freeN(nears);
 
1119
        }
 
1120
 
 
1121
}
 
1122
 
 
1123
/* **************** IpoKey stuff, for Object TransData ********** */
 
1124
 
 
1125
/* storage of bezier triple. thats why -3 and +3! */
 
1126
static void set_tdi_old(float *old, float *poin)
 
1127
{
 
1128
        old[0]= *(poin);
 
1129
        old[3]= *(poin-3);
 
1130
        old[6]= *(poin+3);
 
1131
}
 
1132
 
 
1133
/* while transforming */
 
1134
void add_tdi_poin(float *poin, float *old, float delta)
 
1135
{
 
1136
        if(poin) {
 
1137
                poin[0]= old[0]+delta;
 
1138
                poin[-3]= old[3]+delta;
 
1139
                poin[3]= old[6]+delta;
 
1140
        }
 
1141
}
 
1142
 
 
1143
/* fill ipokey transdata with old vals and pointers */
 
1144
static void ipokey_to_transdata(IpoKey *ik, TransData *td)
 
1145
{
 
1146
        extern int ob_ar[];             // blenkernel ipo.c
 
1147
        TransDataIpokey *tdi= td->tdi;
 
1148
        BezTriple *bezt;
 
1149
        int a, delta= 0;
 
1150
        
 
1151
        td->val= NULL;  // is read on ESC
 
1152
        
 
1153
        for(a=0; a<OB_TOTIPO; a++) {
 
1154
                if(ik->data[a]) {
 
1155
                        bezt= ik->data[a];
 
1156
                        
 
1157
                        switch( ob_ar[a] ) {
 
1158
                                case OB_LOC_X:
 
1159
                                case OB_DLOC_X:
 
1160
                                        tdi->locx= &(bezt->vec[1][1]); break;
 
1161
                                case OB_LOC_Y:
 
1162
                                case OB_DLOC_Y:
 
1163
                                        tdi->locy= &(bezt->vec[1][1]); break;
 
1164
                                case OB_LOC_Z:
 
1165
                                case OB_DLOC_Z:
 
1166
                                        tdi->locz= &(bezt->vec[1][1]); break;
 
1167
                                        
 
1168
                                case OB_DROT_X:
 
1169
                                        delta= 1;
 
1170
                                case OB_ROT_X:
 
1171
                                        tdi->rotx= &(bezt->vec[1][1]); break;
 
1172
                                case OB_DROT_Y:
 
1173
                                        delta= 1;
 
1174
                                case OB_ROT_Y:
 
1175
                                        tdi->roty= &(bezt->vec[1][1]); break;
 
1176
                                case OB_DROT_Z:
 
1177
                                        delta= 1;
 
1178
                                case OB_ROT_Z:
 
1179
                                        tdi->rotz= &(bezt->vec[1][1]); break;
 
1180
                                        
 
1181
                                case OB_SIZE_X:
 
1182
                                case OB_DSIZE_X:
 
1183
                                        tdi->sizex= &(bezt->vec[1][1]); break;
 
1184
                                case OB_SIZE_Y:
 
1185
                                case OB_DSIZE_Y:
 
1186
                                        tdi->sizey= &(bezt->vec[1][1]); break;
 
1187
                                case OB_SIZE_Z:
 
1188
                                case OB_DSIZE_Z:
 
1189
                                        tdi->sizez= &(bezt->vec[1][1]); break;          
 
1190
                        }       
 
1191
                }
 
1192
        }
 
1193
        
 
1194
        /* oldvals for e.g. undo */
 
1195
        if(tdi->locx) set_tdi_old(tdi->oldloc, tdi->locx);
 
1196
        if(tdi->locy) set_tdi_old(tdi->oldloc+1, tdi->locy);
 
1197
        if(tdi->locz) set_tdi_old(tdi->oldloc+2, tdi->locz);
 
1198
        
 
1199
        /* remember, for mapping curves ('1'=10 degrees)  */
 
1200
        if(tdi->rotx) set_tdi_old(tdi->oldrot, tdi->rotx);
 
1201
        if(tdi->roty) set_tdi_old(tdi->oldrot+1, tdi->roty);
 
1202
        if(tdi->rotz) set_tdi_old(tdi->oldrot+2, tdi->rotz);
 
1203
        
 
1204
        /* this is not allowed to be dsize! */
 
1205
        if(tdi->sizex) set_tdi_old(tdi->oldsize, tdi->sizex);
 
1206
        if(tdi->sizey) set_tdi_old(tdi->oldsize+1, tdi->sizey);
 
1207
        if(tdi->sizez) set_tdi_old(tdi->oldsize+2, tdi->sizez);
 
1208
        
 
1209
        tdi->flag= TOB_IPO;
 
1210
        if(delta) tdi->flag |= TOB_IPODROT;
 
1211
}
 
1212
 
 
1213
 
 
1214
/* *************************** Object Transform data ******************* */
 
1215
 
 
1216
static void ObjectToTransData(TransData *td, Object *ob) 
 
1217
{
 
1218
        float obmtx[3][3];
 
1219
        Object *tr;
 
1220
        void *cfirst, *clast;
 
1221
 
 
1222
        /* set axismtx BEFORE clearing constraints to have the real orientation */
 
1223
        Mat3CpyMat4(td->axismtx, ob->obmat);
 
1224
        Mat3Ortho(td->axismtx);
 
1225
 
 
1226
        cfirst = ob->constraints.first;
 
1227
        clast = ob->constraints.last;
 
1228
        ob->constraints.first=ob->constraints.last=NULL;
 
1229
 
 
1230
        tr= ob->track;
 
1231
        ob->track= NULL;
 
1232
 
 
1233
        where_is_object(ob);
 
1234
 
 
1235
        ob->track= tr;
 
1236
 
 
1237
        ob->constraints.first = cfirst;
 
1238
        ob->constraints.last = clast;
 
1239
 
 
1240
        td->ob = ob;
 
1241
 
 
1242
        td->loc = ob->loc;
 
1243
        VECCOPY(td->iloc, td->loc);
 
1244
        
 
1245
        td->ext->rot = ob->rot;
 
1246
        VECCOPY(td->ext->irot, ob->rot);
 
1247
        VECCOPY(td->ext->drot, ob->drot);
 
1248
        
 
1249
        td->ext->size = ob->size;
 
1250
        VECCOPY(td->ext->isize, ob->size);
 
1251
        VECCOPY(td->ext->dsize, ob->dsize);
 
1252
 
 
1253
        VECCOPY(td->center, ob->obmat[3]);
 
1254
 
 
1255
        if (ob->parent)
 
1256
        {
 
1257
                float totmat[3][3], obinv[3][3];
 
1258
                
 
1259
                /* we calculate smtx without obmat: so a parmat */
 
1260
                object_to_mat3(ob, obmtx);
 
1261
                Mat3CpyMat4(totmat, ob->obmat);
 
1262
                Mat3Inv(obinv, totmat);
 
1263
                Mat3MulMat3(td->smtx, obmtx, obinv);
 
1264
                Mat3Inv(td->mtx, td->smtx);
 
1265
        }
 
1266
        else
 
1267
        {
 
1268
                Mat3One(td->smtx);
 
1269
                Mat3One(td->mtx);
 
1270
        }
 
1271
}
 
1272
 
 
1273
/* only used in function below, stuff to be removed */
 
1274
static Object *is_a_parent_selected_int(Object *startob, Object *ob, GHash *done_hash) 
 
1275
{
 
1276
        if (ob!=startob && TESTBASE(ob))
 
1277
                return ob;
 
1278
        
 
1279
        if (BLI_ghash_haskey(done_hash, ob))
 
1280
                return NULL;
 
1281
        else
 
1282
                BLI_ghash_insert(done_hash, ob, NULL);
 
1283
        
 
1284
        if (ob->parent) {
 
1285
                Object *par= is_a_parent_selected_int(startob, ob->parent, done_hash);
 
1286
                if (par)
 
1287
                        return par;
 
1288
        }
 
1289
        return NULL;
 
1290
}
 
1291
 
 
1292
/* only used in function below, stuff to be removed */
 
1293
static Object *is_a_parent_selected(Object *ob) 
 
1294
{
 
1295
        GHash *gh= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
 
1296
        Object *res= is_a_parent_selected_int(ob, ob, gh);
 
1297
        BLI_ghash_free(gh, NULL, NULL);
 
1298
        
 
1299
        return res;
 
1300
}
 
1301
 
 
1302
 
 
1303
 
 
1304
/* sets flags in Bases to define whether they take part in transform */
 
1305
/* it deselects Bases, so we have to call the clear function always after */
 
1306
static void set_trans_object_base_flags(TransInfo *t)
 
1307
{
 
1308
        /*
 
1309
         if Base selected and has parent selected:
 
1310
         base->flag= BA_WASSEL+BA_PARSEL
 
1311
         if base not selected and parent selected:
 
1312
         base->flag= BA_PARSEL
 
1313
         */
 
1314
        GHash *object_to_base_hash= NULL; 
 
1315
        Base *base;
 
1316
        
 
1317
        /* moved to start of function, it is needed for hooks now too */
 
1318
        if (!object_to_base_hash) {
 
1319
                Base *b;
 
1320
                object_to_base_hash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
 
1321
                
 
1322
                for (b= FIRSTBASE; b; b= b->next)
 
1323
                        BLI_ghash_insert(object_to_base_hash, b->object, b);
 
1324
        }
 
1325
        
 
1326
        /* makes sure base flags and object flags are identical */
 
1327
        copy_baseflags();
 
1328
        
 
1329
        for (base= FIRSTBASE; base; base= base->next) {
 
1330
                base->flag &= ~(BA_PARSEL+BA_WASSEL);
 
1331
                
 
1332
                if( (base->lay & G.vd->lay) && base->object->id.lib==0) {
 
1333
                        Object *ob= base->object;
 
1334
                        Object *parsel= is_a_parent_selected(ob);
 
1335
                        
 
1336
                        /* parentkey here? */
 
1337
                        
 
1338
                        if(parsel) {
 
1339
                                if(base->flag & SELECT) {
 
1340
                                        base->flag &= ~SELECT;
 
1341
                                        base->flag |= (BA_PARSEL+BA_WASSEL);
 
1342
                                }
 
1343
                                else base->flag |= BA_PARSEL;
 
1344
                        }
 
1345
                        
 
1346
                        if(t->mode==TFM_TRANSLATION)  {
 
1347
                                if(ob->track && TESTBASE(ob->track) && (base->flag & SELECT)==0)  
 
1348
                                        base->flag |= BA_PARSEL;
 
1349
                        }
 
1350
                        
 
1351
                        /* updates? */
 
1352
                        if(ob->hooks.first) {
 
1353
                                Base *b;
 
1354
                                ObHook *hook= ob->hooks.first;
 
1355
                                
 
1356
                                while(hook) {
 
1357
                                        if(hook->parent) {
 
1358
                                                Object *parsel= is_a_parent_selected(hook->parent);
 
1359
                                                
 
1360
                                                b= BLI_ghash_lookup(object_to_base_hash, hook->parent);
 
1361
                                                if(parsel || ((base->flag | b->flag) & (SELECT | BA_PARSEL)) ) {
 
1362
                                                        base->flag |= BA_DISP_UPDATE;
 
1363
                                                }
 
1364
                                        }
 
1365
                                        hook= hook->next;
 
1366
                                }
 
1367
                        }
 
1368
                        
 
1369
                        if(ob->parent && ob->parent->type==OB_LATTICE)
 
1370
                                if(ob->parent->hooks.first) base->flag |= BA_DISP_UPDATE;
 
1371
                        
 
1372
                        if(base->flag & (SELECT | BA_PARSEL)) {
 
1373
                                
 
1374
                                base->flag |= BA_WHERE_UPDATE;
 
1375
                                
 
1376
                                if(ob->parent) {
 
1377
                                        if(ob->parent->type==OB_LATTICE) base->flag |= BA_DISP_UPDATE;
 
1378
                                        else if(ob->partype==PARSKEL) {
 
1379
                                                if ELEM3(ob->parent->type, OB_IKA, OB_CURVE, OB_ARMATURE) 
 
1380
                                                        base->flag |= BA_DISP_UPDATE;
 
1381
                                        }
 
1382
                                }
 
1383
                                if(ob->track) {
 
1384
                                        ;
 
1385
                                }
 
1386
                                
 
1387
                                if( give_parteff(ob) ) base->flag |= BA_DISP_UPDATE;
 
1388
                                
 
1389
                                if(ob->type==OB_MBALL) {
 
1390
                                        Base *b;
 
1391
                                        
 
1392
                                        b= BLI_ghash_lookup(object_to_base_hash, find_basis_mball(ob));
 
1393
                                        b->flag |= BA_DISP_UPDATE;
 
1394
                                }
 
1395
                        }
 
1396
                }
 
1397
        }
 
1398
        
 
1399
        if (object_to_base_hash)
 
1400
                BLI_ghash_free(object_to_base_hash, NULL, NULL);
 
1401
        
 
1402
}
 
1403
 
 
1404
void clear_trans_object_base_flags(void)
 
1405
{
 
1406
        Base *base;
 
1407
        
 
1408
        base= FIRSTBASE;
 
1409
        while(base) {
 
1410
                if(base->flag & BA_WASSEL) base->flag |= SELECT;
 
1411
                base->flag &= ~(BA_PARSEL+BA_WASSEL);
 
1412
                
 
1413
                base->flag &= ~(BA_DISP_UPDATE+BA_WHERE_UPDATE+BA_DO_IPO);
 
1414
                
 
1415
                /* pose here? */
 
1416
                if (base->object->pose) {
 
1417
                        Object *ob= base->object;
 
1418
                        bPoseChannel *chan;
 
1419
                        for (chan = ob->pose->chanbase.first; chan; chan=chan->next) {
 
1420
                                chan->flag &= ~PCHAN_TRANS_UPDATE;
 
1421
                        }
 
1422
                }
 
1423
                
 
1424
                base= base->next;
 
1425
        }
 
1426
        copy_baseflags();
 
1427
}
 
1428
 
 
1429
/* ******************************************************************************** */
 
1430
/* ************** TOTALLY #@#! CODE FROM PAST TRANSFORM FOR POSEMODE ************** */
 
1431
/* ******************************************************************************** */
 
1432
 
 
1433
 
 
1434
static int is_ob_constraint_target(Object *ob, ListBase *conlist) {
 
1435
        /* Is this object the target of a constraint in this list? 
 
1436
         */
 
1437
 
 
1438
        bConstraint *con;
 
1439
 
 
1440
        for (con=conlist->first; con; con=con->next)
 
1441
        {
 
1442
                if (get_constraint_target(con) == ob)
 
1443
                        return 1;
 
1444
        }
 
1445
        return 0;
 
1446
 
 
1447
}
 
1448
 
 
1449
static int clear_bone_nocalc(Object *ob, Bone *bone, void *ptr) {
 
1450
        /* When we aren't transform()-ing, we'll want to turn off
 
1451
         * the no calc flag for bone bone in case the frame changes,
 
1452
         * or something
 
1453
         */
 
1454
        bone->flag &= ~BONE_NOCALC;
 
1455
        
 
1456
        return 0;
 
1457
}
 
1458
 
 
1459
 
 
1460
static int set_bone_nocalc(Object *ob, Bone *bone, void *ptr) {
 
1461
        /* Calculating bone transformation makes thins slow ...
 
1462
         * lets set the no calc flag for a bone by default
 
1463
         */
 
1464
        bone->flag |= BONE_NOCALC;
 
1465
        
 
1466
        return 0;
 
1467
}
 
1468
 
 
1469
static int selected_bone_docalc(Object *ob, Bone *bone, void *ptr) {
 
1470
        /* Let's clear the no calc flag for selected bones.
 
1471
         * This function always returns 1 for non-no calc bones
 
1472
         * (a.k.a., the 'do calc' bones) so that the bone_looper 
 
1473
         * will count these
 
1474
         */
 
1475
        if (bone->flag & BONE_NOCALC) {
 
1476
                if ( (bone->flag & BONE_SELECTED) ) {
 
1477
                        bone->flag &= ~BONE_NOCALC;
 
1478
                        return 1;
 
1479
                }
 
1480
                
 
1481
        }
 
1482
        else {
 
1483
                return 1;
 
1484
        }
 
1485
        return 0;
 
1486
}
 
1487
 
 
1488
static Bone *get_parent_bone_docalc(Bone *bone) {
 
1489
        Bone            *parBone;
 
1490
 
 
1491
        for (parBone = bone->parent; parBone; parBone=parBone->parent)
 
1492
                if (~parBone->flag & BONE_NOCALC)
 
1493
                        return parBone;
 
1494
 
 
1495
        return NULL;
 
1496
}
 
1497
 
 
1498
static int is_bone_parent(Bone *childBone, Bone *parBone) {
 
1499
        Bone            *currBone;
 
1500
 
 
1501
        for (currBone = childBone->parent; currBone; currBone=currBone->parent)
 
1502
                if (currBone == parBone)
 
1503
                        return 1;
 
1504
 
 
1505
        return 0;
 
1506
}
 
1507
 
 
1508
static void figure_bone_nocalc_constraint(Bone *conbone, bConstraint *con,
 
1509
                                                                                  Object *ob, bArmature *arm) {
 
1510
        /* If this bone has a constraint with a subtarget that has
 
1511
         * the nocalc flag cleared, then we better clear the no calc flag
 
1512
         * on this bone too (and the whole IK chain if this is an IK
 
1513
         * constraint).
 
1514
         *
 
1515
         * Conversly, if this bone has an IK constraint and the root of
 
1516
         * the chain has the no calc flag cleared, we had best clear that
 
1517
         * flag for the whole chain.
 
1518
         */
 
1519
        Bone *subtarbone;
 
1520
        Bone *parBone;
 
1521
        char *subtar;
 
1522
 
 
1523
        subtar = get_con_subtarget_name(con, ob);
 
1524
 
 
1525
        if (subtar) {
 
1526
                if ( (subtarbone = get_named_bone(arm, subtar)) ) {
 
1527
                        if ( (~subtarbone->flag & BONE_NOCALC) ||
 
1528
                                 (get_parent_bone_docalc(subtarbone)) ) {
 
1529
                                if (con->type == CONSTRAINT_TYPE_KINEMATIC)
 
1530
                                        /* IK target is flaged for updating, so we
 
1531
                                         * must update the whole chain.
 
1532
                                         */
 
1533
                                        ik_chain_looper(ob, conbone, NULL, 
 
1534
                                                                        clear_bone_nocalc);
 
1535
                                else
 
1536
                                        /* Constraint target is flagged for
 
1537
                                         * updating, so we update this bone only
 
1538
                                         */
 
1539
                                        conbone->flag &= ~BONE_NOCALC;
 
1540
                        }
 
1541
                        else {
 
1542
                                if ( (parBone = get_parent_bone_docalc(conbone)) ) {
 
1543
                                        /* a parent is flagged for updating */
 
1544
                                        if (!is_bone_parent(subtarbone, parBone)) {
 
1545
                                                /* if the subtarget is also a child of
 
1546
                                                 * this bone, we needn't worry, other
 
1547
                                                 * wise, we have to update
 
1548
                                                 */
 
1549
                                                if (con->type == CONSTRAINT_TYPE_KINEMATIC)
 
1550
                                                        ik_chain_looper(ob, conbone, NULL, 
 
1551
                                                                                        clear_bone_nocalc);
 
1552
                                                else
 
1553
                                                        conbone->flag &= ~BONE_NOCALC;
 
1554
                                        }
 
1555
                                }
 
1556
 
 
1557
                        }
 
1558
                }
 
1559
        }
 
1560
        else {
 
1561
                /* no subtarget ... target is regular object */
 
1562
                if ( (parBone = get_parent_bone_docalc(conbone)) ) {
 
1563
                        /* parent is flagged for updating ... since
 
1564
                         * the target will never move (not a bone)
 
1565
                         * we had better update this bone/chain
 
1566
                         */
 
1567
                        if (con->type == CONSTRAINT_TYPE_KINEMATIC)
 
1568
                                ik_chain_looper(ob, conbone, NULL, 
 
1569
                                                                clear_bone_nocalc);
 
1570
                        else
 
1571
                                conbone->flag &= ~BONE_NOCALC;
 
1572
                }
 
1573
        }
 
1574
 
 
1575
}
 
1576
 
 
1577
static void figure_bone_nocalc_core(Object *ob, bArmature *arm) {
 
1578
        /* Let's figure out which bones need to be recalculated,
 
1579
         * and which don't. Calculations are based on which bones
 
1580
         * are selected, and the constraints that love them.
 
1581
         */
 
1582
        bPoseChannel *chan;
 
1583
        bConstraint *con;
 
1584
        Bone *conbone;
 
1585
 
 
1586
        int numbones, oldnumbones, iterations;
 
1587
 
 
1588
        oldnumbones = -1;
 
1589
        numbones    =  0;
 
1590
        iterations  =  0;
 
1591
 
 
1592
        /* O.K., lets loop until we don't clear any more no calc bones
 
1593
         */
 
1594
        while (oldnumbones != numbones) {
 
1595
                /* I wonder if this will ever get executed? */
 
1596
                if ( (++iterations) == 1000) {
 
1597
                        printf("figurin' nocalc is talking too long\n");
 
1598
                        break;
 
1599
                }
 
1600
 
 
1601
                oldnumbones = numbones;
 
1602
 
 
1603
                /* clear no calc for selected bones and count */
 
1604
                numbones = bone_looper(ob, arm->bonebase.first, NULL, 
 
1605
                                                           selected_bone_docalc);
 
1606
 
 
1607
                if (ob->pose) {
 
1608
                        for (chan = ob->pose->chanbase.first; chan; chan=chan->next){
 
1609
                                conbone = get_named_bone(arm, chan->name);
 
1610
                                if (conbone) {
 
1611
                                        for (con = chan->constraints.first; con; con=con->next) {
 
1612
                                                figure_bone_nocalc_constraint(conbone, con, ob, arm);
 
1613
                                        }
 
1614
                                }
 
1615
                        }
 
1616
                }
 
1617
        }
 
1618
}
 
1619
 
 
1620
static void figure_bone_nocalc(Object *ob) 
 
1621
{
 
1622
        /* Let's figure out which bones need to be recalculated,
 
1623
         * and which don't. Calculations are based on which bones
 
1624
         * are selected, and the constraints that love them.
 
1625
         */
 
1626
        bArmature *arm;
 
1627
 
 
1628
        arm = get_armature(ob);
 
1629
        if (!arm) return;
 
1630
 
 
1631
        if (arm->flag & ARM_RESTPOS) return;
 
1632
 
 
1633
        /* Set no calc for all bones
 
1634
         */
 
1635
        bone_looper(ob, arm->bonebase.first, NULL, 
 
1636
                                set_bone_nocalc);
 
1637
 
 
1638
        figure_bone_nocalc_core(ob, arm);
 
1639
}
 
1640
 
 
1641
static int bone_nocalc2chan_trans_update(Object *ob, Bone *bone, void *ptr) {
 
1642
        /* Set PCHAN_TRANS_UPDATE for channels with bones that don't have
 
1643
         * the no calc flag set ... I hate this.
 
1644
         */
 
1645
        bPoseChannel *chan;
 
1646
 
 
1647
        if (~bone->flag & BONE_NOCALC) {
 
1648
                chan = get_pose_channel(ob->pose, bone->name);
 
1649
                if (chan) chan->flag |= PCHAN_TRANS_UPDATE;
 
1650
        }
 
1651
        else {
 
1652
                /* reset this thing too */
 
1653
                bone->flag &= ~BONE_NOCALC;
 
1654
        }
 
1655
        
 
1656
        return 0;
 
1657
}
 
1658
 
 
1659
static void clear_gonna_move(void) {
 
1660
        Base *base;
 
1661
 
 
1662
        /* clear the gonna move flag */
 
1663
        for (base= FIRSTBASE; base; base= base->next) {
 
1664
                base->object->flag &= ~OB_GONNA_MOVE;
 
1665
        }
 
1666
}
 
1667
 
 
1668
static int is_parent_gonna_move(Object *ob) {
 
1669
        if ( (ob->parent) &&
 
1670
                 (ob->parent->flag & OB_GONNA_MOVE) ) {
 
1671
                return 1;
 
1672
        }
 
1673
        return 0;
 
1674
}
 
1675
 
 
1676
static int is_constraint_target_gonna_move(Object *ob) {
 
1677
        Object *tarOb;
 
1678
        bConstraint *con;
 
1679
        bPoseChannel *chan;
 
1680
 
 
1681
        for (con = ob->constraints.first; con; con=con->next) {
 
1682
                if ( (tarOb = get_constraint_target(con)) ) {
 
1683
                        if (tarOb->flag & OB_GONNA_MOVE )
 
1684
                                return 1;
 
1685
                }
 
1686
        }
 
1687
 
 
1688
        if (ob->pose) {
 
1689
                for (chan = ob->pose->chanbase.first; chan; chan=chan->next){
 
1690
                        for (con = chan->constraints.first; con; con=con->next) {
 
1691
                                if ( (tarOb = get_constraint_target(con)) ) {
 
1692
                                        if (tarOb->flag & OB_GONNA_MOVE )
 
1693
                                                return 1;
 
1694
                                }
 
1695
                        }
 
1696
                }
 
1697
        }
 
1698
 
 
1699
        return 0;
 
1700
}
 
1701
 
 
1702
static void flag_moving_objects(void) {
 
1703
        Base *base;
 
1704
        int numgonnamove = 0, oldnumgonnamove = -1;
 
1705
 
 
1706
        clear_gonna_move();
 
1707
 
 
1708
        /* the 'well ordering principle' guarantees convergence (honest)
 
1709
         */
 
1710
        while (numgonnamove != oldnumgonnamove) {
 
1711
                oldnumgonnamove = numgonnamove;
 
1712
                numgonnamove = 0;
 
1713
                for (base= FIRSTBASE; base; base= base->next) {
 
1714
                        if (base->object->flag & OB_GONNA_MOVE) {
 
1715
                                ++numgonnamove;
 
1716
                        }
 
1717
                        else if (base->flag & SELECT) {
 
1718
                                base->object->flag |= OB_GONNA_MOVE;
 
1719
                                ++numgonnamove;
 
1720
                        }
 
1721
                        else if (is_parent_gonna_move(base->object)) {
 
1722
                                base->object->flag |= OB_GONNA_MOVE;
 
1723
                                ++numgonnamove;
 
1724
                        }
 
1725
                        else if (is_constraint_target_gonna_move(base->object)) {
 
1726
                                base->object->flag |= OB_GONNA_MOVE;
 
1727
                                ++numgonnamove;
 
1728
                        }
 
1729
                }
 
1730
        }
 
1731
 
 
1732
}
 
1733
 
 
1734
static int pose_do_update_flag(Object *ob) {
 
1735
        /* Figure out which pose channels need constant updating.
 
1736
         * Well use the bone BONE_NOCALC bit to do some temporary
 
1737
         * flagging (so we can reuse code), which will later be
 
1738
         * converted to a value for a channel... I hate this.
 
1739
         */
 
1740
        Base *base;
 
1741
        bPoseChannel *chan;
 
1742
        int do_update = 0;
 
1743
        bArmature *arm;
 
1744
 
 
1745
        arm = get_armature(ob);
 
1746
        if (!arm) return 0;
 
1747
 
 
1748
        /* initialize */
 
1749
        bone_looper(ob, arm->bonebase.first, NULL, 
 
1750
                                set_bone_nocalc);
 
1751
 
 
1752
        if (ob->pose) {
 
1753
                for (chan = ob->pose->chanbase.first; chan; chan=chan->next){
 
1754
                        if (chan->constraints.first) {
 
1755
                                for (base= FIRSTBASE; base; base= base->next) {
 
1756
                                        if (is_ob_constraint_target(base->object, 
 
1757
                                                                                                &chan->constraints)) {
 
1758
                                                if( (base->object->flag & OB_GONNA_MOVE) || 
 
1759
                                                        (ob->flag & OB_GONNA_MOVE)) {
 
1760
                                                        Bone *bone;
 
1761
                                                        /* If this armature is selected, or if the
 
1762
                                                         * object that is the target of a constraint
 
1763
                                                         * is selected, then lets constantly update
 
1764
                                                         * this pose channel.
 
1765
                                                         */
 
1766
                                                        bone = get_named_bone(ob->data, chan->name);
 
1767
                                                        if (bone) {
 
1768
                                                                bone->flag &= ~BONE_NOCALC;
 
1769
                                                                ++do_update;
 
1770
                                                        }
 
1771
                                                }
 
1772
                                        }
 
1773
                                }
 
1774
                        }
 
1775
                }
 
1776
        }
 
1777
 
 
1778
        if (do_update) {
 
1779
                figure_bone_nocalc_core(ob, arm);
 
1780
        }
 
1781
 
 
1782
        bone_looper(ob, arm->bonebase.first, NULL, 
 
1783
                                bone_nocalc2chan_trans_update);
 
1784
 
 
1785
        return do_update;
 
1786
}
 
1787
 
 
1788
/* this is a confusing call, it also does the constraint update flags, but was not used...
 
1789
   hopefully transform refactor will take care better of it (ton) */
 
1790
static void figure_pose_updating(void)
 
1791
{
 
1792
        Base *base;
 
1793
 
 
1794
        flag_moving_objects();
 
1795
 
 
1796
        for (base= FIRSTBASE; base; base= base->next) {
 
1797
                /* Recalculate the pose if necessary, regardless of
 
1798
                 * whether the layer is visible or not.
 
1799
                 */
 
1800
                if (pose_do_update_flag(base->object)) {
 
1801
                        base->flag |= BA_WHERE_UPDATE;
 
1802
                }
 
1803
                else if(base->object->flag & OB_GONNA_MOVE) {
 
1804
                        /* if position updates, deform info could change too */
 
1805
                        if(base->object->hooks.first) base->flag |= BA_DISP_UPDATE;
 
1806
                        else if(base->object->parent) {
 
1807
                                if(base->object->parent->type==OB_LATTICE || base->object->partype==PARSKEL)
 
1808
                                        base->flag |= BA_DISP_UPDATE;
 
1809
                        }
 
1810
                }
 
1811
        }
 
1812
 
 
1813
}
 
1814
 
 
1815
 
 
1816
/* copied from old transform, will be replaced with proper depgraph code (ton) */
 
1817
static void clear_bone_nocalc_ob(Object *ob) {
 
1818
        /* Let's clear no calc for all of the bones in the whole darn armature
 
1819
        */
 
1820
        bArmature *arm;
 
1821
        arm = get_armature(ob);
 
1822
        if (arm) {
 
1823
                bone_looper(ob, arm->bonebase.first, NULL, 
 
1824
                                        clear_bone_nocalc);
 
1825
        }
 
1826
        
 
1827
}
 
1828
 
 
1829
 
 
1830
/* ******************************************************************************** */
 
1831
/* ************ END, TOTALLY #@#! CODE FROM PAST TRANSFORM FOR POSEMODE *********** */
 
1832
/* ******************************************************************************** */
 
1833
 
 
1834
/* copied from old transform, will be replaced with proper depgraph code (ton) */
 
1835
void special_aftertrans_update(char mode, int flip, short canceled, int keyflags)
 
1836
{
 
1837
        Object *ob;
 
1838
        Base *base;
 
1839
        MetaBall *mb;
 
1840
        Curve *cu;
 
1841
        int doit,redrawipo=0;
 
1842
        
 
1843
        
 
1844
        /* displaylists etc. */
 
1845
        
 
1846
        if(G.obedit) {
 
1847
                if(G.obedit->type==OB_MBALL) {
 
1848
                        mb= G.obedit->data;
 
1849
                        if(mb->flag != MB_UPDATE_ALWAYS) makeDispList(G.obedit);
 
1850
                }
 
1851
                else if(G.obedit->type==OB_MESH) {
 
1852
                        if(flip) flip_editnormals();
 
1853
                        
 
1854
                        recalc_editnormals();
 
1855
                }
 
1856
        }
 
1857
        else if (G.obpose){
 
1858
                bAction *act;
 
1859
                bPose   *pose;
 
1860
                bPoseChannel *pchan;
 
1861
                
 
1862
                /* we had better clear the no calc flags on the bones
 
1863
                        * ... else things won't look too good when changing
 
1864
                        * frames, etc.
 
1865
                        */
 
1866
                clear_bone_nocalc_ob(G.obpose);
 
1867
                
 
1868
                if ((G.flags & G_RECORDKEYS) && !canceled){
 
1869
                        act=G.obpose->action;
 
1870
                        pose=G.obpose->pose;
 
1871
                        
 
1872
                        if (!act)
 
1873
                                act=G.obpose->action=add_empty_action();
 
1874
                        
 
1875
                        collect_pose_garbage(G.obpose);
 
1876
                        filter_pose_keys ();
 
1877
                        for (pchan=pose->chanbase.first; pchan; pchan=pchan->next){
 
1878
                                if (pchan->flag & POSE_KEY){
 
1879
                                        if (keyflags){
 
1880
                                                set_action_key(act, pchan, AC_QUAT_X, 1);
 
1881
                                                set_action_key(act, pchan, AC_QUAT_Y, 1);
 
1882
                                                set_action_key(act, pchan, AC_QUAT_Z, 1);
 
1883
                                                set_action_key(act, pchan, AC_QUAT_W, 1);
 
1884
                                        }
 
1885
                                        if (keyflags){
 
1886
                                                set_action_key(act, pchan, AC_SIZE_X, 1);
 
1887
                                                set_action_key(act, pchan, AC_SIZE_Y, 1);
 
1888
                                                set_action_key(act, pchan, AC_SIZE_Z, 1);
 
1889
                                        }
 
1890
                                        if (keyflags){
 
1891
                                                set_action_key(act, pchan, AC_LOC_X, 1);
 
1892
                                                set_action_key(act, pchan, AC_LOC_Y, 1);
 
1893
                                                set_action_key(act, pchan, AC_LOC_Z, 1);
 
1894
                                        }
 
1895
                                }
 
1896
                        }
 
1897
                        
 
1898
                        
 
1899
                        remake_action_ipos (act);
 
1900
                        allspace(REMAKEIPO, 0);
 
1901
                        allqueue(REDRAWACTION, 0);
 
1902
                        allqueue(REDRAWIPO, 0);
 
1903
                        allqueue(REDRAWNLA, 0);
 
1904
                }
 
1905
                if (!canceled && is_delay_deform()){
 
1906
                        clear_pose_constraint_status(G.obpose);
 
1907
                        make_displists_by_armature(G.obpose);
 
1908
                }
 
1909
                
 
1910
        }
 
1911
        else {
 
1912
                base= FIRSTBASE;
 
1913
                while(base) {   
 
1914
                        
 
1915
                        ob= base->object;
 
1916
                        
 
1917
                        if(base->flag & BA_WHERE_UPDATE) {
 
1918
                                
 
1919
                                where_is_object(ob);
 
1920
                                
 
1921
                                if(ob->type==OB_ARMATURE && canceled) {
 
1922
                                        /* Unfortunately, sometimes when you escape
 
1923
                                        * a transform on an object that is the
 
1924
                                        * target of an IK constraint on an armature
 
1925
                                        * bone, the rotations are not restored
 
1926
                                        * correctly on the bones in the IK chain. 
 
1927
                                        * There is probably a nice, elegant way to fix 
 
1928
                                        * this using transdata, but this system is so 
 
1929
                                        * darn confusing that we'll do it this brute
 
1930
                                        * force way instead:
 
1931
                                        */
 
1932
                                        clear_pose_constraint_status(ob);
 
1933
                                        make_displists_by_armature(ob);
 
1934
                                }
 
1935
                        }
 
1936
                        if(base->flag & BA_DISP_UPDATE) {
 
1937
                                if(ob->type==OB_MBALL) {
 
1938
                                        mb= ob->data;
 
1939
                                        if(mb->flag != MB_UPDATE_ALWAYS || G.obedit == NULL) makeDispList(ob);
 
1940
                                }
 
1941
                                if( give_parteff(ob) ) build_particle_system(ob);
 
1942
                        }
 
1943
                        if(base->flag & BA_DO_IPO) redrawipo= 1;
 
1944
                        
 
1945
                        if(mode=='s' && ob->type==OB_FONT) {
 
1946
                                doit= 0;
 
1947
                                cu= ob->data;
 
1948
                                
 
1949
                                if(cu->bevobj && (cu->bevobj->flag & SELECT) ) doit= 1;
 
1950
                                else if(cu->taperobj && (cu->taperobj->flag & SELECT) ) doit= 1;
 
1951
                                else if(cu->textoncurve) {
 
1952
                                        if(cu->textoncurve->flag & SELECT) doit= 1;
 
1953
                                        else if(ob->flag & SELECT) doit= 1;
 
1954
                                }
 
1955
                                
 
1956
                                if(doit) {
 
1957
                                        text_to_curve(ob, 0);
 
1958
                                        makeDispList(ob);
 
1959
                                }
 
1960
                        }
 
1961
                        if(mode=='s' && ob->type==OB_CURVE) {
 
1962
                                doit= 0;
 
1963
                                cu= ob->data;
 
1964
                                
 
1965
                                if(cu->bevobj && (cu->bevobj->flag & SELECT) ) 
 
1966
                                        makeDispList(ob);
 
1967
                                else if(cu->taperobj && (cu->taperobj->flag & SELECT) ) 
 
1968
                                        makeDispList(ob);
 
1969
                        }
 
1970
                        
 
1971
                        if(ob->softflag & OB_SB_ENABLE) sbObjectReset(ob);
 
1972
                        
 
1973
                        where_is_object(ob);    /* always do, for track etc. */
 
1974
                        
 
1975
                        /* Set autokey if necessary */
 
1976
                        if ((G.flags & G_RECORDKEYS) && (!canceled) && (base->flag & SELECT)){
 
1977
                                if (keyflags){
 
1978
                                        insertkey(&base->object->id, OB_ROT_X);
 
1979
                                        insertkey(&base->object->id, OB_ROT_Y);
 
1980
                                        insertkey(&base->object->id, OB_ROT_Z);
 
1981
                                }
 
1982
                                if (keyflags){
 
1983
                                        insertkey(&base->object->id, OB_LOC_X);
 
1984
                                        insertkey(&base->object->id, OB_LOC_Y);
 
1985
                                        insertkey(&base->object->id, OB_LOC_Z);
 
1986
                                }
 
1987
                                if (keyflags){
 
1988
                                        insertkey(&base->object->id, OB_SIZE_X);
 
1989
                                        insertkey(&base->object->id, OB_SIZE_Y);
 
1990
                                        insertkey(&base->object->id, OB_SIZE_Z);
 
1991
                                }
 
1992
                                
 
1993
                                remake_object_ipos (ob);
 
1994
                                allqueue(REDRAWIPO, 0);
 
1995
                                allspace(REMAKEIPO, 0);
 
1996
                                allqueue(REDRAWVIEW3D, 0);
 
1997
                                allqueue(REDRAWNLA, 0);
 
1998
                        }
 
1999
                        
 
2000
                        base= base->next;
 
2001
                }
 
2002
                
 
2003
        }
 
2004
        
 
2005
        if(redrawipo) {
 
2006
                allqueue(REDRAWNLA, 0);
 
2007
                allqueue(REDRAWACTION, 0);
 
2008
                allqueue(REDRAWIPO, 0);
 
2009
        }
 
2010
        
 
2011
        if(G.vd->drawtype == OB_SHADED) reshadeall_displist();
 
2012
        
 
2013
}
 
2014
 
 
2015
 
 
2016
 
 
2017
 
 
2018
 
 
2019
static void createTransObject(TransInfo *t)
 
2020
{
 
2021
        TransData *td = NULL;
 
2022
        TransDataExtension *tx;
 
2023
        Object *ob;
 
2024
        Base *base;
 
2025
        IpoKey *ik;
 
2026
        ListBase elems;
 
2027
        
 
2028
        /* hackish... but we have to do it somewhere */
 
2029
        reset_slowparents();
 
2030
        
 
2031
        set_trans_object_base_flags(t);
 
2032
 
 
2033
        {
 
2034
                /* this has to be done, or else constraints on armature
 
2035
                 * bones that point to objects/bones that are outside
 
2036
                 * of the armature don't work outside of posemode 
 
2037
                 * (and yes, I know it's confusing ...).
 
2038
                 */
 
2039
                figure_pose_updating();
 
2040
        }
 
2041
        
 
2042
        /* count */     
 
2043
        for(base= FIRSTBASE; base; base= base->next) {
 
2044
                if TESTBASELIB(base) {
 
2045
                        ob= base->object;
 
2046
                        
 
2047
                        /* store ipo keys? */
 
2048
                        if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) {
 
2049
                                elems.first= elems.last= NULL;
 
2050
                                make_ipokey_transform(ob, &elems, 1); /* '1' only selected keys */
 
2051
                                
 
2052
                                pushdata(&elems, sizeof(ListBase));
 
2053
                                
 
2054
                                for(ik= elems.first; ik; ik= ik->next) t->total++;
 
2055
 
 
2056
                                if(elems.first==NULL) t->total++;
 
2057
                        }
 
2058
                        else {
 
2059
                                t->total++;
 
2060
                        }
 
2061
                }
 
2062
        }
 
2063
 
 
2064
        if(!t->total) {
 
2065
                /* clear here, main transform function escapes too */
 
2066
                clear_trans_object_base_flags();
 
2067
                return;
 
2068
        }
 
2069
        
 
2070
        td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransOb");
 
2071
        tx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "TransObExtension");
 
2072
 
 
2073
        for(base= FIRSTBASE; base; base= base->next) {
 
2074
                if TESTBASELIB(base) {
 
2075
                        ob= base->object;
 
2076
                        
 
2077
                        td->flag= TD_SELECTED;
 
2078
                        td->ext = tx;
 
2079
 
 
2080
                        /* store ipo keys? */
 
2081
                        if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) {
 
2082
                                
 
2083
                                popfirst(&elems);       // bring back pushed listbase
 
2084
                                
 
2085
                                if(elems.first) {
 
2086
                                        float cfraont;
 
2087
                                        int ipoflag;
 
2088
                                        
 
2089
                                        base->flag |= BA_DO_IPO+BA_WASSEL;
 
2090
                                        base->flag &= ~SELECT;
 
2091
                                        
 
2092
                                        cfraont= CFRA;
 
2093
                                        set_no_parent_ipo(1);
 
2094
                                        ipoflag= ob->ipoflag;
 
2095
                                        ob->ipoflag &= ~OB_OFFS_OB;
 
2096
                                        
 
2097
                                        pushdata(ob->loc, 7*3*4); // tsk! tsk!
 
2098
                                        
 
2099
                                        for(ik= elems.first; ik; ik= ik->next) {
 
2100
                                                
 
2101
                                                /* weak... this doesn't correct for floating values, giving small errors */
 
2102
                                                CFRA= (short)(ik->val/G.scene->r.framelen);
 
2103
                                                
 
2104
                                                do_ob_ipo(ob);
 
2105
                                                ObjectToTransData(td, ob);      // does where_is_object()
 
2106
                                                
 
2107
                                                td->flag= TD_SELECTED;
 
2108
                                                
 
2109
                                                td->tdi= MEM_callocN(sizeof(TransDataIpokey), "TransDataIpokey");
 
2110
                                                /* also does tdi->flag and oldvals, needs to be after ob_to_transob()! */
 
2111
                                                ipokey_to_transdata(ik, td);
 
2112
                                                
 
2113
                                                td++;
 
2114
                                                tx++;
 
2115
                                                if(ik->next) td->ext= tx;       // prevent corrupting mem!
 
2116
                                        }
 
2117
                                        free_ipokey(&elems);
 
2118
                                        
 
2119
                                        poplast(ob->loc);
 
2120
                                        set_no_parent_ipo(0);
 
2121
                                        
 
2122
                                        CFRA= (short)cfraont;
 
2123
                                        ob->ipoflag= ipoflag;
 
2124
                                        
 
2125
                                        where_is_object(ob);    // restore 
 
2126
                                }
 
2127
                                else {
 
2128
                                        ObjectToTransData(td, ob);
 
2129
                                        td->tdi = NULL;
 
2130
                                        td->val = NULL;
 
2131
                                        td++;
 
2132
                                        tx++;
 
2133
                                }
 
2134
                        }
 
2135
                        else {
 
2136
                                ObjectToTransData(td, ob);
 
2137
                                td->tdi = NULL;
 
2138
                                td->val = NULL;
 
2139
                                td++;
 
2140
                                tx++;
 
2141
                        }
 
2142
                }
 
2143
        }
 
2144
}
 
2145
 
 
2146
void createTransData(TransInfo *t) 
 
2147
{
 
2148
        if (t->context == CTX_TEXTURE) {
 
2149
                t->flag |= T_TEXTURE;
 
2150
                createTransTexspace(t);
 
2151
        }
 
2152
        else if (t->context == CTX_EDGE) {
 
2153
                t->ext = NULL;
 
2154
                t->flag |= T_EDIT;
 
2155
                createTransEdge(t);
 
2156
                if(t->data && t->flag & T_PROP_EDIT) {
 
2157
                        sort_trans_data(t);     // makes selected become first in array
 
2158
                        set_prop_dist(t, 1);
 
2159
                        sort_trans_data_dist(t);
 
2160
                }
 
2161
        }
 
2162
        else if (G.obpose) {
 
2163
                t->flag |= T_POSE;
 
2164
                createTransPose(t);
 
2165
        }
 
2166
        else if (G.obedit) {
 
2167
                t->ext = NULL;
 
2168
                if (G.obedit->type == OB_MESH) {
 
2169
                        if(t->mode==TFM_SHRINKFATTEN && (t->context & CTX_NO_NOR_RECALC)==0)
 
2170
                                vertexnormals(0);
 
2171
                        createTransEditVerts(t);        
 
2172
                }
 
2173
                else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
 
2174
                        createTransCurveVerts(t);
 
2175
                }
 
2176
                else if (G.obedit->type==OB_LATTICE) {
 
2177
                        createTransLatticeVerts(t);
 
2178
                }
 
2179
                else if (G.obedit->type==OB_MBALL) {
 
2180
                        createTransMBallVerts(t);
 
2181
                }
 
2182
                else if (G.obedit->type==OB_ARMATURE) {
 
2183
                        createTransArmatureVerts(t);
 
2184
                }                                                       
 
2185
                else {
 
2186
                        printf("not done yet! only have mesh surface curve\n");
 
2187
                }
 
2188
 
 
2189
                if(t->data && t->flag & T_PROP_EDIT) {
 
2190
                        if (ELEM(G.obedit->type, OB_CURVE, OB_MESH)) {
 
2191
                                sort_trans_data(t);     // makes selected become first in array
 
2192
                                set_prop_dist(t, 0);
 
2193
                                sort_trans_data_dist(t);
 
2194
                        }
 
2195
                        else {
 
2196
                                sort_trans_data(t);     // makes selected become first in array
 
2197
                                set_prop_dist(t, 1);
 
2198
                                sort_trans_data_dist(t);
 
2199
                        }
 
2200
                }
 
2201
                t->flag |= T_EDIT;
 
2202
        }
 
2203
        else {
 
2204
                createTransObject(t);
 
2205
                t->flag |= T_OBJECT;
 
2206
        }
 
2207
 
 
2208
        if((t->flag & T_OBJECT) && G.vd->camera==OBACT && G.vd->persp>1) {
 
2209
                t->flag |= T_CAMERA;
 
2210
        }
 
2211
}
 
2212