2
* $Id: transform_conversions.c,v 1.16 2005/06/11 16:30:36 jesterking Exp $
4
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
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
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.
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.
23
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24
* All rights reserved.
26
* The Original Code is: all of this file.
28
* Contributor(s): none yet.
30
* ***** END GPL/BL DUAL LICENSE BLOCK *****
47
#include "MEM_guardedalloc.h"
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"
75
#include "BIF_editview.h"
76
#include "BIF_resources.h"
77
#include "BIF_mywindow.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"
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"
96
#include "BKE_global.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"
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"
111
#include "BDR_editobject.h" // reset_slowparents()
113
#include "BLI_arithb.h"
114
#include "BLI_editVert.h"
115
#include "BLI_ghash.h"
117
#include "PIL_time.h"
121
#include "mydevice.h"
123
extern ListBase editNurb;
124
extern ListBase editelems;
126
#include "transform.h"
129
static void figure_bone_nocalc(Object *ob);
130
static void figure_pose_updating(void);
133
/* ************************** Functions *************************** */
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;
144
while ((tail->dist >= pivot.dist) && (head < tail))
148
while ((tail->rdist >= pivot.rdist) && (head < tail))
159
while ((head->dist <= pivot.dist) && (head < tail))
163
while ((head->rdist <= pivot.rdist) && (head < tail))
176
qsort_trans_data(t, ihead, head-1);
179
qsort_trans_data(t, head+1, itail);
183
void sort_trans_data_dist(TransInfo *t) {
184
TransData *start = t->data;
187
while(i < t->total && start->flag & TD_SELECTED) {
191
qsort_trans_data(t, start, t->data + t->total - 1);
194
static void sort_trans_data(TransInfo *t)
196
TransData *sel, *unsel;
201
while (sel > unsel) {
202
while (unsel->flag & TD_SELECTED) {
208
while (!(sel->flag & TD_SELECTED)) {
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)
230
for(a=0, tob= t->data; a<t->total; a++, tob++) {
232
tob->rdist= 0.0f; // init, it was mallocced
234
if((tob->flag & TD_SELECTED)==0) {
239
tob->rdist = -1.0f; // signal for next loop
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) {
249
else if (dist < tob->rdist) {
253
else break; // by definition transdata has selected items in beginning
256
tob->dist = tob->rdist;
262
/* ************************** CONVERSIONS ************************* */
264
/* ********************* texture space ********* */
266
static void createTransTexspace(TransInfo *t)
274
td= t->data= MEM_callocN(sizeof(TransData), "TransTexspace");
275
td->ext= t->ext= MEM_callocN(sizeof(TransDataExtension), "TransTexspace");
277
td->flag= TD_SELECTED;
278
VECCOPY(td->center, ob->obmat[3]);
281
Mat3CpyMat4(td->mtx, ob->obmat);
282
Mat3Inv(td->smtx, td->mtx);
286
else if( GS(id->name)==ID_ME) {
288
me->texflag &= ~AUTOSPACE;
290
td->ext->rot= me->rot;
291
td->ext->size= me->size;
293
else if( GS(id->name)==ID_CU) {
295
cu->texflag &= ~CU_AUTOSPACE;
297
td->ext->rot= cu->rot;
298
td->ext->size= cu->size;
300
else if( GS(id->name)==ID_MB) {
301
MetaBall *mb= ob->data;
302
mb->texflag &= ~MB_AUTOSPACE;
304
td->ext->rot= mb->rot;
305
td->ext->size= mb->size;
308
VECCOPY(td->iloc, td->loc);
309
VECCOPY(td->ext->irot, td->ext->rot);
310
VECCOPY(td->ext->isize, td->ext->size);
313
/* ********************* edge (for crease) ***** */
315
static void createTransEdge(TransInfo *t) {
316
TransData *td = NULL;
317
EditMesh *em = G.editMesh;
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;
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");
329
allqueue(REDRAWBUTSEDIT, 0);
332
for(eed= em->edges.first; eed; eed= eed->next) {
334
if (eed->f & SELECT) countsel++;
335
if (propmode) count++;
349
td= t->data= MEM_callocN(t->total * sizeof(TransData), "TransCrease");
351
Mat3CpyMat4(mtx, G.obedit->obmat);
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);
362
td->flag= TD_SELECTED;
367
Mat3CpyMat3(td->smtx, smtx);
368
Mat3CpyMat3(td->mtx, mtx);
372
td->val = &(eed->crease);
373
td->ival = eed->crease;
380
/* ********************* pose mode ************* */
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)
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 ) {
395
deeper= 0; // no transform on children if one parent bone is selected
399
if(deeper) count_bone_select(t, &bone->childbase, counter);
404
static void add_pose_transdata(TransInfo *t, ListBase *lb, Object *ob, TransData **tdp)
408
float parmat[4][4], tempmat[4][4];
409
float tempobmat[4][4];
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 ) {
421
get_bone_root_pos (bone, vec, 1);
423
//VecAddf (centroid, centroid, vec);
424
VECCOPY(td->center, vec);
427
td->flag= TD_SELECTED|TD_USEQUAT;
429
VECCOPY(td->iloc, bone->loc);
432
td->ext->quat= bone->quat;
433
td->ext->size= bone->size;
434
td->ext->bone= bone; // FIXME: Dangerous
436
QUATCOPY(td->ext->iquat, bone->quat);
437
VECCOPY(td->ext->isize, bone->size);
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);
445
Mat4MulMat4 (parmat, tempmat, ob->obmat); /* Original */
447
Mat3CpyMat4 (td->mtx, parmat);
448
Mat3Inv (td->smtx, td->mtx);
450
Mat3CpyMat3(td->axismtx, td->mtx);
451
Mat3Ortho(td->axismtx);
458
if(deeper) add_pose_transdata(t, &bone->childbase, ob, tdp);
462
static void createTransPose(TransInfo *t)
466
TransDataExtension *tdx;
469
/* check validity of state */
470
arm=get_armature (G.obpose);
471
if (arm==NULL) return;
473
if (arm->flag & ARM_RESTPOS){
474
notice ("Transformation not possible while Rest Position is enabled");
477
if (!(G.obpose->lay & G.vd->lay)) return;
479
/* copied from old code, no idea. we let linker solve it for now */
481
/* figure out which bones need calculating */
482
figure_bone_nocalc(G.obpose);
483
figure_pose_updating();
486
/* copied from old code, no idea... (ton) */
487
apply_pose_armature(arm, G.obpose->pose, 0);
488
where_is_armature (G.obpose);
491
count_bone_select(t, &arm->bonebase, &t->total);
493
if(t->total==0 && t->mode==TFM_TRANSLATION) {
494
t->mode= TFM_ROTATION;
495
count_bone_select(t, &arm->bonebase, &t->total);
497
if(t->total==0) return;
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++) {
507
/* recursive fill trans data */
509
add_pose_transdata(t, &arm->bonebase, G.obpose, &td);
513
/* ********************* armature ************** */
515
static void createTransArmatureVerts(TransInfo *t)
519
float mtx[3][3], smtx[3][3];
522
for (ebo=G.edbo.first;ebo;ebo=ebo->next){
523
if (ebo->flag & BONE_TIPSEL){
526
if (ebo->flag & BONE_ROOTSEL){
531
if (!t->total) return;
533
Mat3CpyMat4(mtx, G.obedit->obmat);
536
td = t->data = MEM_mallocN(t->total*sizeof(TransData), "TransEditBone");
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);
543
td->flag= TD_SELECTED;
545
Mat3CpyMat3(td->smtx, smtx);
546
Mat3CpyMat3(td->mtx, mtx);
554
if (ebo->flag & BONE_ROOTSEL){
555
VECCOPY (td->iloc, ebo->head);
556
VECCOPY (td->center, td->iloc);
558
td->flag= TD_SELECTED;
560
Mat3CpyMat3(td->smtx, smtx);
561
Mat3CpyMat3(td->mtx, mtx);
573
/* ********************* meta elements ********* */
575
static void createTransMBallVerts(TransInfo *t)
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;
585
for(ml= editelems.first; ml; ml= ml->next) {
586
if(ml->flag & SELECT) countsel++;
587
if(propmode) count++;
590
/* note: in prop mode we need at least 1 selected */
591
if (countsel==0) return;
593
if(propmode) t->total = count;
594
else t->total = countsel;
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");
599
Mat3CpyMat4(mtx, G.obedit->obmat);
602
for(ml= editelems.first; ml; ml= ml->next) {
603
if(propmode || (ml->flag & SELECT)) {
605
VECCOPY(td->iloc, td->loc);
606
VECCOPY(td->center, td->loc);
608
if(ml->flag & SELECT) td->flag= TD_SELECTED | TD_USEQUAT | TD_SINGLESIZE;
609
else td->flag= TD_USEQUAT;
611
Mat3CpyMat3(td->smtx, smtx);
612
Mat3CpyMat3(td->mtx, mtx);
617
/* Radius of MetaElem (mass of MetaElem influence) */
618
if(ml->flag & MB_SCALE_RAD){
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;
633
/* quat is used for rotation of MetaElem */
635
QUATCOPY(tx->iquat, ml->quat);
645
/* ********************* curve/surface ********* */
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) {
656
dist = VecLenf(td_near->center, td->center);
657
if (dist < (td-1)->dist) {
658
td->dist = (td-1)->dist;
666
td->flag |= TD_NOTCONNECTED;
670
for (td = tail; td>=head; td--) {
671
if (td->flag & TD_SELECTED) {
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;
691
static void createTransCurveVerts(TransInfo *t)
693
TransData *td = NULL;
697
float mtx[3][3], smtx[3][3];
699
int count=0, countsel=0;
700
int propmode = t->flag & T_PROP_EDIT;
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++) {
707
if(bezt->f1 & 1) countsel++;
708
if(bezt->f2 & 1) countsel++;
709
if(bezt->f3 & 1) countsel++;
710
if(propmode) count+= 3;
715
for(a= nu->pntsu*nu->pntsv, bp= nu->bp; a>0; a--, bp++) {
717
if(propmode) count++;
718
if(bp->f1 & 1) countsel++;
723
/* note: in prop mode we need at least 1 selected */
724
if (countsel==0) return;
726
if(propmode) t->total = count;
727
else t->total = countsel;
728
t->data= MEM_mallocN(t->total*sizeof(TransData), "TransObData(Curve EditMode)");
730
Mat3CpyMat4(mtx, G.obedit->obmat);
734
for(nu= editNurb.first; nu; nu= nu->next) {
735
if((nu->type & 7)==CU_BEZIER) {
736
TransData *head, *tail;
738
for(a=0, bezt= nu->bezt; a<nu->pntsu; a++, bezt++) {
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;
750
Mat3CpyMat3(td->smtx, smtx);
751
Mat3CpyMat3(td->mtx, mtx);
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;
766
td->val = &(bezt->alfa);
767
td->ival = bezt->alfa;
769
Mat3CpyMat3(td->smtx, smtx);
770
Mat3CpyMat3(td->mtx, mtx);
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;
786
Mat3CpyMat3(td->smtx, smtx);
787
Mat3CpyMat3(td->mtx, mtx);
794
else if (propmode && head != tail) {
795
calc_distanceCurveVerts(head, tail-1);
799
if (propmode && head != tail)
800
calc_distanceCurveVerts(head, tail);
803
TransData *head, *tail;
805
for(a= nu->pntsu*nu->pntsv, bp= nu->bp; a>0; a--, bp++) {
807
if(propmode || (bp->f1 & 1)) {
808
VECCOPY(td->iloc, bp->vec);
810
VECCOPY(td->center, td->loc);
811
if(bp->f1 & 1) td->flag= TD_SELECTED;
815
td->val = &(bp->alfa);
818
Mat3CpyMat3(td->smtx, smtx);
819
Mat3CpyMat3(td->mtx, mtx);
826
else if (propmode && head != tail) {
827
calc_distanceCurveVerts(head, tail-1);
831
if (propmode && head != tail)
832
calc_distanceCurveVerts(head, tail-1);
837
/* ********************* lattice *************** */
839
static void createTransLatticeVerts(TransInfo *t)
841
TransData *td = NULL;
843
float mtx[3][3], smtx[3][3];
845
int count=0, countsel=0;
846
int propmode = t->flag & T_PROP_EDIT;
849
a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
851
if(bp->f1 & 1) countsel++;
852
if(propmode) count++;
856
/* note: in prop mode we need at least 1 selected */
857
if (countsel==0) return;
859
if(propmode) t->total = count;
860
else t->total = countsel;
861
t->data= MEM_mallocN(t->total*sizeof(TransData), "TransObData(Lattice EditMode)");
863
Mat3CpyMat4(mtx, G.obedit->obmat);
868
a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
870
if(propmode || (bp->f1 & 1)) {
872
VECCOPY(td->iloc, bp->vec);
874
VECCOPY(td->center, td->loc);
875
if(bp->f1 & 1) td->flag= TD_SELECTED;
877
Mat3CpyMat3(td->smtx, smtx);
878
Mat3CpyMat3(td->mtx, mtx);
892
/* ********************* mesh ****************** */
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)
899
EditMesh *em = G.editMesh;
904
/* f2 flag is used for 'selection' */
905
/* vn is offset on scratch array */
906
for(eve= em->verts.first; eve; eve= eve->next) {
908
eve->vn = (EditVert *)(i++);
910
if(eve->f & SELECT) {
913
E_VEC(eve)[0] = 0.0f;
914
E_VEC(eve)[1] = 0.0f;
915
E_VEC(eve)[2] = 0.0f;
924
/* Floodfill routine */
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)
933
for(eed= em->edges.first; eed; eed= eed->next) {
935
EditVert *v1= eed->v1, *v2= eed->v2;
936
float *vec2 = E_VEC(v2);
937
float *vec1 = E_VEC(v1);
939
if (v1->f2 + v2->f2 == 4)
945
float len1 = VecLength(vec1);
946
float len2 = VecLength(vec2);
948
/* for v2 if not selected */
950
VecSubf(nvec, v2->co, E_NEAR(v1)->co);
951
lenn = VecLength(nvec);
952
if (lenn - len1 > 0.00001f && len2 - lenn > 0.00001f) {
954
E_NEAR(v2) = E_NEAR(v1);
957
else if (len2 - len1 > 0.00001f && len1 - lenn > 0.00001f) {
959
E_NEAR(v2) = E_NEAR(v1);
963
/* for v1 if not selected */
965
VecSubf(nvec, v1->co, E_NEAR(v2)->co);
966
lenn = VecLength(nvec);
967
if (lenn - len2 > 0.00001f && len1 - lenn > 0.00001f) {
969
E_NEAR(v1) = E_NEAR(v2);
972
else if (len1 - len2 > 0.00001f && len2 - lenn > 0.00001f) {
974
E_NEAR(v1) = E_NEAR(v2);
981
VecSubf(vec2, v2->co, E_NEAR(v1)->co);
982
if (VecLength(vec1) - VecLength(vec2) > 0.00001f) {
985
E_NEAR(v2) = E_NEAR(v1);
991
VecSubf(vec1, v1->co, E_NEAR(v2)->co);
992
if (VecLength(vec2) - VecLength(vec1) > 0.00001f) {
995
E_NEAR(v1) = E_NEAR(v2);
1004
static void VertsToTransData(TransData *td, EditVert *eve)
1008
VECCOPY(td->center, td->loc);
1009
VECCOPY(td->iloc, td->loc);
1012
VECCOPY(td->axismtx[2], eve->no);
1018
td->axismtx[1][2] = 0.0f;
1025
static void createTransEditVerts(TransInfo *t)
1027
TransData *tob = NULL;
1028
EditMesh *em = G.editMesh;
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;
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))
1045
else if(G.scene->selectmode & SCE_SELECT_EDGE) {
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;
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;
1064
/* now we can count */
1065
for(eve= em->verts.first; eve; eve= eve->next) {
1067
if(eve->f1) countsel++;
1068
if(propmode) count++;
1072
/* note: in prop mode we need at least 1 selected */
1073
if (countsel==0) return;
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");
1082
else t->total = countsel;
1083
tob= t->data= MEM_mallocN(t->total*sizeof(TransData), "TransObData(Mesh EditMode)");
1085
Mat3CpyMat4(mtx, G.obedit->obmat);
1088
if(propmode) editmesh_set_connectivity_distance(t->total, vectors, nears);
1090
for (eve=em->verts.first; eve; eve=eve->next) {
1092
if(propmode || eve->f1) {
1093
VertsToTransData(tob, eve);
1095
if(eve->f1) tob->flag |= TD_SELECTED;
1099
VECCOPY(vec, E_VEC(eve));
1100
Mat3MulVecfl(mtx, vec);
1101
tob->dist= VecLength(vec);
1104
tob->flag |= TD_NOTCONNECTED;
1105
tob->dist = MAXFLOAT;
1109
Mat3CpyMat3(tob->smtx, smtx);
1110
Mat3CpyMat3(tob->mtx, mtx);
1123
/* **************** IpoKey stuff, for Object TransData ********** */
1125
/* storage of bezier triple. thats why -3 and +3! */
1126
static void set_tdi_old(float *old, float *poin)
1133
/* while transforming */
1134
void add_tdi_poin(float *poin, float *old, float delta)
1137
poin[0]= old[0]+delta;
1138
poin[-3]= old[3]+delta;
1139
poin[3]= old[6]+delta;
1143
/* fill ipokey transdata with old vals and pointers */
1144
static void ipokey_to_transdata(IpoKey *ik, TransData *td)
1146
extern int ob_ar[]; // blenkernel ipo.c
1147
TransDataIpokey *tdi= td->tdi;
1151
td->val= NULL; // is read on ESC
1153
for(a=0; a<OB_TOTIPO; a++) {
1157
switch( ob_ar[a] ) {
1160
tdi->locx= &(bezt->vec[1][1]); break;
1163
tdi->locy= &(bezt->vec[1][1]); break;
1166
tdi->locz= &(bezt->vec[1][1]); break;
1171
tdi->rotx= &(bezt->vec[1][1]); break;
1175
tdi->roty= &(bezt->vec[1][1]); break;
1179
tdi->rotz= &(bezt->vec[1][1]); break;
1183
tdi->sizex= &(bezt->vec[1][1]); break;
1186
tdi->sizey= &(bezt->vec[1][1]); break;
1189
tdi->sizez= &(bezt->vec[1][1]); break;
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);
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);
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);
1210
if(delta) tdi->flag |= TOB_IPODROT;
1214
/* *************************** Object Transform data ******************* */
1216
static void ObjectToTransData(TransData *td, Object *ob)
1220
void *cfirst, *clast;
1222
/* set axismtx BEFORE clearing constraints to have the real orientation */
1223
Mat3CpyMat4(td->axismtx, ob->obmat);
1224
Mat3Ortho(td->axismtx);
1226
cfirst = ob->constraints.first;
1227
clast = ob->constraints.last;
1228
ob->constraints.first=ob->constraints.last=NULL;
1233
where_is_object(ob);
1237
ob->constraints.first = cfirst;
1238
ob->constraints.last = clast;
1243
VECCOPY(td->iloc, td->loc);
1245
td->ext->rot = ob->rot;
1246
VECCOPY(td->ext->irot, ob->rot);
1247
VECCOPY(td->ext->drot, ob->drot);
1249
td->ext->size = ob->size;
1250
VECCOPY(td->ext->isize, ob->size);
1251
VECCOPY(td->ext->dsize, ob->dsize);
1253
VECCOPY(td->center, ob->obmat[3]);
1257
float totmat[3][3], obinv[3][3];
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);
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)
1276
if (ob!=startob && TESTBASE(ob))
1279
if (BLI_ghash_haskey(done_hash, ob))
1282
BLI_ghash_insert(done_hash, ob, NULL);
1285
Object *par= is_a_parent_selected_int(startob, ob->parent, done_hash);
1292
/* only used in function below, stuff to be removed */
1293
static Object *is_a_parent_selected(Object *ob)
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);
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)
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
1314
GHash *object_to_base_hash= NULL;
1317
/* moved to start of function, it is needed for hooks now too */
1318
if (!object_to_base_hash) {
1320
object_to_base_hash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
1322
for (b= FIRSTBASE; b; b= b->next)
1323
BLI_ghash_insert(object_to_base_hash, b->object, b);
1326
/* makes sure base flags and object flags are identical */
1329
for (base= FIRSTBASE; base; base= base->next) {
1330
base->flag &= ~(BA_PARSEL+BA_WASSEL);
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);
1336
/* parentkey here? */
1339
if(base->flag & SELECT) {
1340
base->flag &= ~SELECT;
1341
base->flag |= (BA_PARSEL+BA_WASSEL);
1343
else base->flag |= BA_PARSEL;
1346
if(t->mode==TFM_TRANSLATION) {
1347
if(ob->track && TESTBASE(ob->track) && (base->flag & SELECT)==0)
1348
base->flag |= BA_PARSEL;
1352
if(ob->hooks.first) {
1354
ObHook *hook= ob->hooks.first;
1358
Object *parsel= is_a_parent_selected(hook->parent);
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;
1369
if(ob->parent && ob->parent->type==OB_LATTICE)
1370
if(ob->parent->hooks.first) base->flag |= BA_DISP_UPDATE;
1372
if(base->flag & (SELECT | BA_PARSEL)) {
1374
base->flag |= BA_WHERE_UPDATE;
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;
1387
if( give_parteff(ob) ) base->flag |= BA_DISP_UPDATE;
1389
if(ob->type==OB_MBALL) {
1392
b= BLI_ghash_lookup(object_to_base_hash, find_basis_mball(ob));
1393
b->flag |= BA_DISP_UPDATE;
1399
if (object_to_base_hash)
1400
BLI_ghash_free(object_to_base_hash, NULL, NULL);
1404
void clear_trans_object_base_flags(void)
1410
if(base->flag & BA_WASSEL) base->flag |= SELECT;
1411
base->flag &= ~(BA_PARSEL+BA_WASSEL);
1413
base->flag &= ~(BA_DISP_UPDATE+BA_WHERE_UPDATE+BA_DO_IPO);
1416
if (base->object->pose) {
1417
Object *ob= base->object;
1419
for (chan = ob->pose->chanbase.first; chan; chan=chan->next) {
1420
chan->flag &= ~PCHAN_TRANS_UPDATE;
1429
/* ******************************************************************************** */
1430
/* ************** TOTALLY #@#! CODE FROM PAST TRANSFORM FOR POSEMODE ************** */
1431
/* ******************************************************************************** */
1434
static int is_ob_constraint_target(Object *ob, ListBase *conlist) {
1435
/* Is this object the target of a constraint in this list?
1440
for (con=conlist->first; con; con=con->next)
1442
if (get_constraint_target(con) == ob)
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,
1454
bone->flag &= ~BONE_NOCALC;
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
1464
bone->flag |= BONE_NOCALC;
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
1475
if (bone->flag & BONE_NOCALC) {
1476
if ( (bone->flag & BONE_SELECTED) ) {
1477
bone->flag &= ~BONE_NOCALC;
1488
static Bone *get_parent_bone_docalc(Bone *bone) {
1491
for (parBone = bone->parent; parBone; parBone=parBone->parent)
1492
if (~parBone->flag & BONE_NOCALC)
1498
static int is_bone_parent(Bone *childBone, Bone *parBone) {
1501
for (currBone = childBone->parent; currBone; currBone=currBone->parent)
1502
if (currBone == parBone)
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
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.
1523
subtar = get_con_subtarget_name(con, ob);
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.
1533
ik_chain_looper(ob, conbone, NULL,
1536
/* Constraint target is flagged for
1537
* updating, so we update this bone only
1539
conbone->flag &= ~BONE_NOCALC;
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
1549
if (con->type == CONSTRAINT_TYPE_KINEMATIC)
1550
ik_chain_looper(ob, conbone, NULL,
1553
conbone->flag &= ~BONE_NOCALC;
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
1567
if (con->type == CONSTRAINT_TYPE_KINEMATIC)
1568
ik_chain_looper(ob, conbone, NULL,
1571
conbone->flag &= ~BONE_NOCALC;
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.
1586
int numbones, oldnumbones, iterations;
1592
/* O.K., lets loop until we don't clear any more no calc bones
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");
1601
oldnumbones = numbones;
1603
/* clear no calc for selected bones and count */
1604
numbones = bone_looper(ob, arm->bonebase.first, NULL,
1605
selected_bone_docalc);
1608
for (chan = ob->pose->chanbase.first; chan; chan=chan->next){
1609
conbone = get_named_bone(arm, chan->name);
1611
for (con = chan->constraints.first; con; con=con->next) {
1612
figure_bone_nocalc_constraint(conbone, con, ob, arm);
1620
static void figure_bone_nocalc(Object *ob)
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.
1628
arm = get_armature(ob);
1631
if (arm->flag & ARM_RESTPOS) return;
1633
/* Set no calc for all bones
1635
bone_looper(ob, arm->bonebase.first, NULL,
1638
figure_bone_nocalc_core(ob, arm);
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.
1647
if (~bone->flag & BONE_NOCALC) {
1648
chan = get_pose_channel(ob->pose, bone->name);
1649
if (chan) chan->flag |= PCHAN_TRANS_UPDATE;
1652
/* reset this thing too */
1653
bone->flag &= ~BONE_NOCALC;
1659
static void clear_gonna_move(void) {
1662
/* clear the gonna move flag */
1663
for (base= FIRSTBASE; base; base= base->next) {
1664
base->object->flag &= ~OB_GONNA_MOVE;
1668
static int is_parent_gonna_move(Object *ob) {
1669
if ( (ob->parent) &&
1670
(ob->parent->flag & OB_GONNA_MOVE) ) {
1676
static int is_constraint_target_gonna_move(Object *ob) {
1681
for (con = ob->constraints.first; con; con=con->next) {
1682
if ( (tarOb = get_constraint_target(con)) ) {
1683
if (tarOb->flag & OB_GONNA_MOVE )
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 )
1702
static void flag_moving_objects(void) {
1704
int numgonnamove = 0, oldnumgonnamove = -1;
1708
/* the 'well ordering principle' guarantees convergence (honest)
1710
while (numgonnamove != oldnumgonnamove) {
1711
oldnumgonnamove = numgonnamove;
1713
for (base= FIRSTBASE; base; base= base->next) {
1714
if (base->object->flag & OB_GONNA_MOVE) {
1717
else if (base->flag & SELECT) {
1718
base->object->flag |= OB_GONNA_MOVE;
1721
else if (is_parent_gonna_move(base->object)) {
1722
base->object->flag |= OB_GONNA_MOVE;
1725
else if (is_constraint_target_gonna_move(base->object)) {
1726
base->object->flag |= OB_GONNA_MOVE;
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.
1745
arm = get_armature(ob);
1749
bone_looper(ob, arm->bonebase.first, NULL,
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)) {
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.
1766
bone = get_named_bone(ob->data, chan->name);
1768
bone->flag &= ~BONE_NOCALC;
1779
figure_bone_nocalc_core(ob, arm);
1782
bone_looper(ob, arm->bonebase.first, NULL,
1783
bone_nocalc2chan_trans_update);
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)
1794
flag_moving_objects();
1796
for (base= FIRSTBASE; base; base= base->next) {
1797
/* Recalculate the pose if necessary, regardless of
1798
* whether the layer is visible or not.
1800
if (pose_do_update_flag(base->object)) {
1801
base->flag |= BA_WHERE_UPDATE;
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;
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
1821
arm = get_armature(ob);
1823
bone_looper(ob, arm->bonebase.first, NULL,
1830
/* ******************************************************************************** */
1831
/* ************ END, TOTALLY #@#! CODE FROM PAST TRANSFORM FOR POSEMODE *********** */
1832
/* ******************************************************************************** */
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)
1841
int doit,redrawipo=0;
1844
/* displaylists etc. */
1847
if(G.obedit->type==OB_MBALL) {
1849
if(mb->flag != MB_UPDATE_ALWAYS) makeDispList(G.obedit);
1851
else if(G.obedit->type==OB_MESH) {
1852
if(flip) flip_editnormals();
1854
recalc_editnormals();
1860
bPoseChannel *pchan;
1862
/* we had better clear the no calc flags on the bones
1863
* ... else things won't look too good when changing
1866
clear_bone_nocalc_ob(G.obpose);
1868
if ((G.flags & G_RECORDKEYS) && !canceled){
1869
act=G.obpose->action;
1870
pose=G.obpose->pose;
1873
act=G.obpose->action=add_empty_action();
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){
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);
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);
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);
1899
remake_action_ipos (act);
1900
allspace(REMAKEIPO, 0);
1901
allqueue(REDRAWACTION, 0);
1902
allqueue(REDRAWIPO, 0);
1903
allqueue(REDRAWNLA, 0);
1905
if (!canceled && is_delay_deform()){
1906
clear_pose_constraint_status(G.obpose);
1907
make_displists_by_armature(G.obpose);
1917
if(base->flag & BA_WHERE_UPDATE) {
1919
where_is_object(ob);
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:
1932
clear_pose_constraint_status(ob);
1933
make_displists_by_armature(ob);
1936
if(base->flag & BA_DISP_UPDATE) {
1937
if(ob->type==OB_MBALL) {
1939
if(mb->flag != MB_UPDATE_ALWAYS || G.obedit == NULL) makeDispList(ob);
1941
if( give_parteff(ob) ) build_particle_system(ob);
1943
if(base->flag & BA_DO_IPO) redrawipo= 1;
1945
if(mode=='s' && ob->type==OB_FONT) {
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;
1957
text_to_curve(ob, 0);
1961
if(mode=='s' && ob->type==OB_CURVE) {
1965
if(cu->bevobj && (cu->bevobj->flag & SELECT) )
1967
else if(cu->taperobj && (cu->taperobj->flag & SELECT) )
1971
if(ob->softflag & OB_SB_ENABLE) sbObjectReset(ob);
1973
where_is_object(ob); /* always do, for track etc. */
1975
/* Set autokey if necessary */
1976
if ((G.flags & G_RECORDKEYS) && (!canceled) && (base->flag & SELECT)){
1978
insertkey(&base->object->id, OB_ROT_X);
1979
insertkey(&base->object->id, OB_ROT_Y);
1980
insertkey(&base->object->id, OB_ROT_Z);
1983
insertkey(&base->object->id, OB_LOC_X);
1984
insertkey(&base->object->id, OB_LOC_Y);
1985
insertkey(&base->object->id, OB_LOC_Z);
1988
insertkey(&base->object->id, OB_SIZE_X);
1989
insertkey(&base->object->id, OB_SIZE_Y);
1990
insertkey(&base->object->id, OB_SIZE_Z);
1993
remake_object_ipos (ob);
1994
allqueue(REDRAWIPO, 0);
1995
allspace(REMAKEIPO, 0);
1996
allqueue(REDRAWVIEW3D, 0);
1997
allqueue(REDRAWNLA, 0);
2006
allqueue(REDRAWNLA, 0);
2007
allqueue(REDRAWACTION, 0);
2008
allqueue(REDRAWIPO, 0);
2011
if(G.vd->drawtype == OB_SHADED) reshadeall_displist();
2019
static void createTransObject(TransInfo *t)
2021
TransData *td = NULL;
2022
TransDataExtension *tx;
2028
/* hackish... but we have to do it somewhere */
2029
reset_slowparents();
2031
set_trans_object_base_flags(t);
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 ...).
2039
figure_pose_updating();
2043
for(base= FIRSTBASE; base; base= base->next) {
2044
if TESTBASELIB(base) {
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 */
2052
pushdata(&elems, sizeof(ListBase));
2054
for(ik= elems.first; ik; ik= ik->next) t->total++;
2056
if(elems.first==NULL) t->total++;
2065
/* clear here, main transform function escapes too */
2066
clear_trans_object_base_flags();
2070
td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransOb");
2071
tx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "TransObExtension");
2073
for(base= FIRSTBASE; base; base= base->next) {
2074
if TESTBASELIB(base) {
2077
td->flag= TD_SELECTED;
2080
/* store ipo keys? */
2081
if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) {
2083
popfirst(&elems); // bring back pushed listbase
2089
base->flag |= BA_DO_IPO+BA_WASSEL;
2090
base->flag &= ~SELECT;
2093
set_no_parent_ipo(1);
2094
ipoflag= ob->ipoflag;
2095
ob->ipoflag &= ~OB_OFFS_OB;
2097
pushdata(ob->loc, 7*3*4); // tsk! tsk!
2099
for(ik= elems.first; ik; ik= ik->next) {
2101
/* weak... this doesn't correct for floating values, giving small errors */
2102
CFRA= (short)(ik->val/G.scene->r.framelen);
2105
ObjectToTransData(td, ob); // does where_is_object()
2107
td->flag= TD_SELECTED;
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);
2115
if(ik->next) td->ext= tx; // prevent corrupting mem!
2117
free_ipokey(&elems);
2120
set_no_parent_ipo(0);
2122
CFRA= (short)cfraont;
2123
ob->ipoflag= ipoflag;
2125
where_is_object(ob); // restore
2128
ObjectToTransData(td, ob);
2136
ObjectToTransData(td, ob);
2146
void createTransData(TransInfo *t)
2148
if (t->context == CTX_TEXTURE) {
2149
t->flag |= T_TEXTURE;
2150
createTransTexspace(t);
2152
else if (t->context == CTX_EDGE) {
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);
2162
else if (G.obpose) {
2166
else if (G.obedit) {
2168
if (G.obedit->type == OB_MESH) {
2169
if(t->mode==TFM_SHRINKFATTEN && (t->context & CTX_NO_NOR_RECALC)==0)
2171
createTransEditVerts(t);
2173
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
2174
createTransCurveVerts(t);
2176
else if (G.obedit->type==OB_LATTICE) {
2177
createTransLatticeVerts(t);
2179
else if (G.obedit->type==OB_MBALL) {
2180
createTransMBallVerts(t);
2182
else if (G.obedit->type==OB_ARMATURE) {
2183
createTransArmatureVerts(t);
2186
printf("not done yet! only have mesh surface curve\n");
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);
2196
sort_trans_data(t); // makes selected become first in array
2197
set_prop_dist(t, 1);
2198
sort_trans_data_dist(t);
2204
createTransObject(t);
2205
t->flag |= T_OBJECT;
2208
if((t->flag & T_OBJECT) && G.vd->camera==OBACT && G.vd->persp>1) {
2209
t->flag |= T_CAMERA;