diff options
-rw-r--r-- | source/blender/include/BDR_editobject.h | 29 | ||||
-rwxr-xr-x | source/blender/include/BIF_transform.h | 2 | ||||
-rwxr-xr-x | source/blender/include/transform.h | 1 | ||||
-rw-r--r-- | source/blender/src/drawimage.c | 27 | ||||
-rw-r--r-- | source/blender/src/edit.c | 442 | ||||
-rw-r--r-- | source/blender/src/editarmature.c | 148 | ||||
-rw-r--r-- | source/blender/src/editobject.c | 1595 | ||||
-rwxr-xr-x | source/blender/src/transform.c | 1 | ||||
-rwxr-xr-x | source/blender/src/transform_conversions.c | 607 | ||||
-rwxr-xr-x | source/blender/src/transform_generics.c | 21 |
10 files changed, 1084 insertions, 1789 deletions
diff --git a/source/blender/include/BDR_editobject.h b/source/blender/include/BDR_editobject.h index 45ebaff1d62..4ac93f1899c 100644 --- a/source/blender/include/BDR_editobject.h +++ b/source/blender/include/BDR_editobject.h @@ -33,9 +33,7 @@ #ifndef BDR_EDITOBJECT_H #define BDR_EDITOBJECT_H -struct TransVert; struct Object; -struct TransOb; struct Tex; struct Material; struct Base; @@ -56,8 +54,11 @@ int test_parent_loop(struct Object *par, struct Object *ob); void make_parent(void); void make_displists_by_parent(struct Object *ob); + void exit_editmode(int freedata); void check_editmode(int type); +void enter_editmode(void); + void docentre(int centremode); void docentre_new(void); void docentre_cursor(void); @@ -72,26 +73,18 @@ void make_links_menu(void); void make_links(short event); void make_duplilist_real(void); void apply_object(void); -void ob_to_transob(struct Object *ob, struct TransOb *tob); -void ob_to_tex_transob(struct Object *ob, struct TransOb *tob); -void make_trans_objects(void); -void enter_editmode(void); + void copymenu_logicbricks(struct Object *ob); -void clearbaseflags_for_editing(void); -void make_trans_verts(float *min, float *max, int mode); -void draw_prop_circle(void); -void set_proportional_weight(struct TransVert *tv, float *min, float *max); -void special_trans_update(int keyflags); -void special_aftertrans_update(char mode, int flip, short canceled, int keyflags); -void calc_trans_verts(void); + + +/* old transform */ void apply_keyb_grid(float *val, float fac1, float fac2, float fac3, int invert); void compatible_eul(float *eul, float *oldrot); void headerprint(char *str); -void add_ipo_tob_poin(float *poin, float *old, float delta); -void restore_tob(struct TransOb *tob); +/* used for old game engine collision optimize */ int cylinder_intersect_test(void); int sphere_intersect_test(void); -int my_clock(void); + void std_rmouse_transform(void (*xf_func)(int, int)); void rightmouse_transform(void); @@ -117,8 +110,8 @@ void first_base(void); void make_displists_by_obdata(void *obdata); void flip_subdivison(struct Object *ob, int); void mirrormenu(void); -void Mirror(short mode); -void flag_edge_crease(void); + + void add_hook(void); #endif /* BDR_EDITOBJECT_H */ diff --git a/source/blender/include/BIF_transform.h b/source/blender/include/BIF_transform.h index 6c7efcbc133..680b324d917 100755 --- a/source/blender/include/BIF_transform.h +++ b/source/blender/include/BIF_transform.h @@ -61,7 +61,7 @@ void Transform(int mode, int context); - +void Mirror(short mode); struct TransInfo; struct ScrArea; diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h index 23c816053ff..f87d4768dcd 100755 --- a/source/blender/include/transform.h +++ b/source/blender/include/transform.h @@ -246,6 +246,7 @@ void createTransData(TransInfo *t); void sort_trans_data_dist(TransInfo *t); void clear_trans_object_base_flags(void); void add_tdi_poin(float *poin, float *old, float delta); +void special_aftertrans_update(char mode, int flip, short canceled, int keyflags); /*********************** Constraints *****************************/ void getConstraintMatrix(TransInfo *t); diff --git a/source/blender/src/drawimage.c b/source/blender/src/drawimage.c index d7a7c53b74e..f1991f52a6f 100644 --- a/source/blender/src/drawimage.c +++ b/source/blender/src/drawimage.c @@ -44,6 +44,7 @@ #endif #include "MEM_guardedalloc.h" +#include "BLI_arithb.h" #include "BLI_blenlib.h" #include "IMB_imbuf_types.h" @@ -63,19 +64,18 @@ #include "BKE_image.h" #include "BDR_editface.h" -#include "BDR_editobject.h" +#include "BDR_drawobject.h" #include "BDR_drawmesh.h" - #include "BIF_gl.h" -#include "BIF_space.h" -#include "BIF_screen.h" #include "BIF_mywindow.h" #include "BIF_drawimage.h" #include "BIF_resources.h" #include "BIF_interface.h" #include "BIF_editsima.h" #include "BIF_glutil.h" +#include "BIF_space.h" +#include "BIF_screen.h" #include "BSE_trans_types.h" @@ -84,6 +84,7 @@ #include "blendef.h" #include "butspace.h" // event codes +float prop_cent[3]= {0.0, 0.0, 0.0}, prop_size= 0.1; /** * Sets up the fields of the View2D member of the SpaceImage struct @@ -494,10 +495,26 @@ static unsigned int *get_part_from_ibuf(ImBuf *ibuf, short startx, short starty, return rectmain; } +/* now only in use by drawimage.c */ +static void draw_prop_circle() +{ + if (G.scene->proportional) { + float tmat[4][4], imat[4][4]; + + if(G.moving) { + BIF_ThemeColor(TH_GRID); + + mygetmatrix(tmat); + Mat4Invert(imat, tmat); + + drawcircball(GL_LINE_LOOP, prop_cent, prop_size, imat); + } + } +} + static void draw_image_prop_circle(ImBuf *ibuf) { float aspx, aspy; - extern float prop_cent[3]; if(G.moving && G.scene->proportional) { diff --git a/source/blender/src/edit.c b/source/blender/src/edit.c index 2c7443c9298..003b4b10365 100644 --- a/source/blender/src/edit.c +++ b/source/blender/src/edit.c @@ -31,6 +31,7 @@ */ #include <math.h> +#include <string.h> #ifdef HAVE_CONFIG_H #include <config.h> @@ -41,14 +42,17 @@ #else #include <io.h> #endif + #include "MEM_guardedalloc.h" #include "BMF_Api.h" #include "PIL_time.h" +#include "DNA_action_types.h" #include "DNA_armature_types.h" #include "DNA_curve_types.h" +#include "DNA_ipo_types.h" #include "DNA_lattice_types.h" #include "DNA_meta_types.h" #include "DNA_mesh_types.h" @@ -62,13 +66,17 @@ #include "BLI_arithb.h" #include "BLI_editVert.h" -#include "BKE_utildefines.h" +#include "BKE_action.h" +#include "BKE_armature.h" #include "BKE_anim.h" -#include "BKE_object.h" +#include "BKE_curve.h" #include "BKE_displist.h" #include "BKE_global.h" +#include "BKE_ipo.h" #include "BKE_lattice.h" #include "BKE_mesh.h" +#include "BKE_object.h" +#include "BKE_utildefines.h" #include "BIF_editmesh.h" #include "BIF_editview.h" @@ -105,9 +113,6 @@ #endif -/* from editobject */ -extern void make_trans_verts(float *min, float *max, int mode); - /* circle selection callback */ typedef void (*select_CBfunc)(short selecting, Object *editobj, short *mval, float rad); @@ -548,9 +553,7 @@ void count_object(Object *ob, int sel) /* is called on most actions, like select/add/delete/layermove */ void countall() { -/* extern Lattice *editLatt; in BKE_lattice.h*/ extern ListBase editNurb; - /* extern ListBase bpbase; */ Base *base; Object *ob; Mesh *me; @@ -558,7 +561,6 @@ void countall() BezTriple *bezt; BPoint *bp; MetaElem *ml; - /* struct BodyPoint *bop; */ struct EditVert *eve; struct EditFace *efa; struct EditBone *ebo; @@ -708,6 +710,13 @@ void countall() allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */ } +/* ************************************************** */ +/* ********************* old transform stuff ******** */ +/* ************************************************** */ + +static TransVert *transvmain=NULL; +static int tottrans= 0; + /* selected things moved, and might need update in displists */ static void update_select_dependency(void) { @@ -726,10 +735,407 @@ static void update_select_dependency(void) } +static void calc_trans_verts(void) +{ + extern ListBase editNurb; + + if (ELEM(G.obedit->type, OB_MESH, OB_MBALL)) + makeDispList(G.obedit); + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { + Nurb *nu= editNurb.first; + while(nu) { + test2DNurb(nu); + testhandlesNurb(nu); /* test for bezier too */ + nu= nu->next; + } + makeDispList(G.obedit); + } +} + +static int pose_flags_reset_done(Object *ob) { + /* Clear the constraint done status for every pose channe; + * that has been flagged as needing constant updating + */ + bPoseChannel *chan; + int numreset = 0; + + if (ob->pose) { + for (chan = ob->pose->chanbase.first; chan; chan=chan->next){ + if (chan->flag & PCHAN_TRANS_UPDATE) { + chan->flag &= ~PCHAN_DONE; + numreset++; + } + + } + } + return numreset; +} + + +/* copied from editobject.c, should be replaced with proper depgraph */ +static void special_trans_update(void) +{ + Base *base; + Curve *cu; + IpoCurve *icu; + + if(G.obedit) { + if(G.obedit->type==OB_MESH) { + recalc_editnormals(); // does face centers too + } + if(G.obedit->type==OB_CURVE) { + cu= G.obedit->data; + + makeBevelList(G.obedit); // might be needed for deform + calc_curvepath(G.obedit); + + base= FIRSTBASE; + while(base) { + if(base->lay & G.vd->lay) { + if(base->object->parent==G.obedit && base->object->partype==PARSKEL) + makeDispList(base->object); + else if(base->object->type==OB_CURVE) { + Curve *cu= base->object->data; + if(G.obedit==cu->bevobj || G.obedit==cu->taperobj) + makeDispList(base->object); + } + } + base= base->next; + } + } + else if(G.obedit->type==OB_ARMATURE){ + EditBone *ebo; + + /* Ensure all bones are correctly adjusted */ + for (ebo=G.edbo.first; ebo; ebo=ebo->next){ + + if ((ebo->flag & BONE_IK_TOPARENT) && ebo->parent){ + /* If this bone has a parent tip that has been moved */ + if (ebo->parent->flag & BONE_TIPSEL){ + VECCOPY (ebo->head, ebo->parent->tail); + } + /* If this bone has a parent tip that has NOT been moved */ + else{ + VECCOPY (ebo->parent->tail, ebo->head); + } + } + } + } + else if(G.obedit->type==OB_LATTICE) { + + if(editLatt->flag & LT_OUTSIDE) outside_lattice(editLatt); + + base= FIRSTBASE; + while(base) { + if(base->lay & G.vd->lay) { + if(base->object->parent==G.obedit) { + makeDispList(base->object); + } + } + base= base->next; + } + } + } + else { + base= FIRSTBASE; + while(base) { + if(base->flag & BA_DO_IPO) { + + base->object->ctime= -1234567.0; + + icu= base->object->ipo->curve.first; + while(icu) { + calchandles_ipocurve(icu); + icu= icu->next; + } + + } + if(base->object->partype & PARSLOW) { + base->object->partype -= PARSLOW; + where_is_object(base->object); + base->object->partype |= PARSLOW; + } + else if(base->flag & BA_WHERE_UPDATE) { + where_is_object(base->object); + } + + base= base->next; + } + + base= FIRSTBASE; + while(base) { + + if(base->flag & BA_DISP_UPDATE) makeDispList(base->object); + + base= base->next; + } + + } + + base= FIRSTBASE; + while(base) { + if (pose_flags_reset_done(base->object)) { + if (!is_delay_deform()) + make_displists_by_armature(base->object); + } + + base= base->next; + } + +#if 1 + if (G.obpose && G.obpose->type == OB_ARMATURE) + clear_pose_constraint_status(G.obpose); + + if (!is_delay_deform()) make_displists_by_armature(G.obpose); +#endif + + if(G.vd->drawtype == OB_SHADED) reshadeall_displist(); + +} + +/* copied from editobject.c, needs to be replaced with new transform code still */ +/* mode: 1 = proportional */ +static void make_trans_verts(float *min, float *max, int mode) +{ + extern ListBase editNurb; + EditMesh *em = G.editMesh; + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + TransVert *tv=NULL; + MetaElem *ml; + EditVert *eve; + EditBone *ebo; + float total, centre[3], centroid[3]; + int a; + + tottrans= 0; // global! + + INIT_MINMAX(min, max); + centroid[0]=centroid[1]=centroid[2]= 0.0; + + /* note for transform refactor: dont rely on countall anymore... its ancient */ + /* I skip it for editmesh now (ton) */ + if(G.obedit->type!=OB_MESH) { + countall(); + if(mode) tottrans= G.totvert; + else tottrans= G.totvertsel; + + if(G.totvertsel==0) { + tottrans= 0; + return; + } + tv=transvmain= MEM_callocN(tottrans*sizeof(TransVert), "maketransverts"); + } + + /* we count again because of hide (old, not for mesh!) */ + tottrans= 0; + + if(G.obedit->type==OB_MESH) { + int proptrans= 0; + + // transform now requires awareness for select mode, so we tag the f1 flags in verts + tottrans= 0; + if(G.scene->selectmode & SCE_SELECT_VERTEX) { + for(eve= em->verts.first; eve; eve= eve->next) { + if(eve->h==0 && (eve->f & SELECT)) { + eve->f1= SELECT; + tottrans++; + } + else eve->f1= 0; + } + } + else if(G.scene->selectmode & SCE_SELECT_EDGE) { + EditEdge *eed; + for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0; + for(eed= em->edges.first; eed; eed= eed->next) { + if(eed->h==0 && (eed->f & SELECT)) eed->v1->f1= eed->v2->f1= SELECT; + } + for(eve= em->verts.first; eve; eve= eve->next) if(eve->f1) tottrans++; + } + else { + EditFace *efa; + for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0; + for(efa= em->faces.first; efa; efa= efa->next) { + if(efa->h==0 && (efa->f & SELECT)) { + efa->v1->f1= efa->v2->f1= efa->v3->f1= SELECT; + if(efa->v4) efa->v4->f1= SELECT; + } + } + for(eve= em->verts.first; eve; eve= eve->next) if(eve->f1) tottrans++; + } + + /* proportional edit exception... */ + if(mode==1 && tottrans) { + for(eve= em->verts.first; eve; eve= eve->next) { + if(eve->h==0) { + eve->f1 |= 2; + proptrans++; + } + } + if(proptrans>tottrans) tottrans= proptrans; + } + + /* and now make transverts */ + if(tottrans) { + tv=transvmain= MEM_callocN(tottrans*sizeof(TransVert), "maketransverts"); + + for(eve= em->verts.first; eve; eve= eve->next) { + if(eve->f1) { + VECCOPY(tv->oldloc, eve->co); + tv->loc= eve->co; + if(eve->no[0]!=0.0 || eve->no[1]!=0.0 ||eve->no[2]!=0.0) + tv->nor= eve->no; // note this is a hackish signal (ton) + tv->flag= eve->f1 & SELECT; + tv++; + } + } + } + } + else if (G.obedit->type==OB_ARMATURE){ + for (ebo=G.edbo.first;ebo;ebo=ebo->next){ + if (ebo->flag & BONE_TIPSEL){ + VECCOPY (tv->oldloc, ebo->tail); + tv->loc= ebo->tail; + tv->nor= NULL; + tv->flag= 1; + tv++; + tottrans++; + } + + /* Only add the root if there is no selected IK parent */ + if (ebo->flag & BONE_ROOTSEL){ + if (!(ebo->parent && (ebo->flag & BONE_IK_TOPARENT) && ebo->parent->flag & BONE_TIPSEL)){ + VECCOPY (tv->oldloc, ebo->head); + tv->loc= ebo->head; + tv->nor= NULL; + tv->flag= 1; + tv++; + tottrans++; + } + } + + } + } + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { + nu= editNurb.first; + while(nu) { + if((nu->type & 7)==CU_BEZIER) { + a= nu->pntsu; + bezt= nu->bezt; + while(a--) { + if(bezt->hide==0) { + if(mode==1 || (bezt->f1 & 1)) { + VECCOPY(tv->oldloc, bezt->vec[0]); + tv->loc= bezt->vec[0]; + tv->flag= bezt->f1 & 1; + tv++; + tottrans++; + } + if(mode==1 || (bezt->f2 & 1)) { + VECCOPY(tv->oldloc, bezt->vec[1]); + tv->loc= bezt->vec[1]; + tv->val= &(bezt->alfa); + tv->oldval= bezt->alfa; + tv->flag= bezt->f2 & 1; + tv++; + tottrans++; + } + if(mode==1 || (bezt->f3 & 1)) { + VECCOPY(tv->oldloc, bezt->vec[2]); + tv->loc= bezt->vec[2]; + tv->flag= bezt->f3 & 1; + tv++; + tottrans++; + } + } + bezt++; + } + } + else { + a= nu->pntsu*nu->pntsv; + bp= nu->bp; + while(a--) { + if(bp->hide==0) { + if(mode==1 || (bp->f1 & 1)) { + VECCOPY(tv->oldloc, bp->vec); + tv->loc= bp->vec; + tv->val= &(bp->alfa); + tv->oldval= bp->alfa; + tv->flag= bp->f1 & 1; + tv++; + tottrans++; + } + } + bp++; + } + } + nu= nu->next; + } + } + else if(G.obedit->type==OB_MBALL) { + extern ListBase editelems; /* go away ! */ + ml= editelems.first; + while(ml) { + if(ml->flag & SELECT) { + tv->loc= &ml->x; + VECCOPY(tv->oldloc, tv->loc); + tv->val= &(ml->rad); + tv->oldval= ml->rad; + tv->flag= 1; + tv++; + tottrans++; + } + ml= ml->next; + } + } + else if(G.obedit->type==OB_LATTICE) { + bp= editLatt->def; + + a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; + + while(a--) { + if(mode==1 || (bp->f1 & 1)) { + if(bp->hide==0) { + VECCOPY(tv->oldloc, bp->vec); + tv->loc= bp->vec; + tv->flag= bp->f1 & 1; + tv++; + tottrans++; + } + } + bp++; + } + } + + /* cent etc */ + tv= transvmain; + total= 0.0; + for(a=0; a<tottrans; a++, tv++) { + if(tv->flag & SELECT) { + centroid[0]+= tv->oldloc[0]; + centroid[1]+= tv->oldloc[1]; + centroid[2]+= tv->oldloc[2]; + total+= 1.0; + DO_MINMAX(tv->oldloc, min, max); + } + } + if(total!=0.0) { + centroid[0]/= total; + centroid[1]/= total; + centroid[2]/= total; + } + + centre[0]= (min[0]+max[0])/2.0; + centre[1]= (min[1]+max[1])/2.0; + centre[2]= (min[2]+max[2])/2.0; + +} + + + void snap_sel_to_grid() { - extern TransVert *transvmain; - extern int tottrans; extern float originmat[3][3]; /* object.c */ TransVert *tv; Base *base; @@ -774,7 +1180,7 @@ void snap_sel_to_grid() calc_trans_verts(); // does test2d, makedisplist too */ - special_trans_update(0); + special_trans_update(); allqueue(REDRAWVIEW3D, 0); return; @@ -818,8 +1224,6 @@ void snap_sel_to_grid() void snap_sel_to_curs() { - extern TransVert *transvmain; - extern int tottrans; extern float originmat[3][3]; /* object.c */ TransVert *tv; Base *base; @@ -859,7 +1263,7 @@ void snap_sel_to_curs() calc_trans_verts(); // does test2d, makedisplist too */ - special_trans_update(0); + special_trans_update(); allqueue(REDRAWVIEW3D, 0); return; @@ -919,8 +1323,6 @@ void snap_curs_to_grid() void snap_curs_to_sel() { - extern TransVert *transvmain; - extern int tottrans; TransVert *tv; Base *base; float *curs, bmat[3][3], vec[3], min[3], max[3], centroid[3]; @@ -992,8 +1394,6 @@ void snap_curs_to_sel() void snap_curs_to_firstsel() { - extern TransVert *transvmain; - extern int tottrans; TransVert *tv; Base *base; float *curs, bmat[3][3], vec[3], min[3], max[3], centroid[3]; @@ -1063,8 +1463,6 @@ void snap_curs_to_firstsel() void snap_to_center() { - extern TransVert *transvmain; - extern int tottrans; extern float originmat[3][3]; TransVert *tv; Base *base; @@ -1170,7 +1568,7 @@ void snap_to_center() if ELEM4(G.obedit->type, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) makeDispList(G.obedit); - special_trans_update(0); + special_trans_update(); allqueue(REDRAWVIEW3D, 0); return; @@ -1310,8 +1708,6 @@ void toggle_shading(void) void minmax_verts(float *min, float *max) { - extern TransVert *transvmain; - extern int tottrans; TransVert *tv; float centroid[3], vec[3], bmat[3][3]; int a; diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c index 2c5dfd08ce7..0dc6f5e44b7 100644 --- a/source/blender/src/editarmature.c +++ b/source/blender/src/editarmature.c @@ -103,8 +103,6 @@ #define B_CYAN 0xFFFF00 #define B_AQUA 0xFFBB55 /* 0xFF8833*/ -extern int tottrans; /* Originally defined in editobject.c */ -extern struct TransOb *transmain; /* Originally defined in editobject.c */ extern float centre[3], centroid[3]; /* Originally defined in editobject.c */ /* Macros */ @@ -126,9 +124,8 @@ static void delete_bone(struct EditBone* exBone); static void clear_armature_children (struct Bone *bone, struct bPose *pose, char mode); static int count_bones (struct bArmature *arm, int flagmask, int allbones); - static int count_bonechildren (struct Bone *bone, int incount, int flagmask, int allbones); -static int add_trans_bonechildren (struct Object* ob, struct Bone* bone, struct TransOb* buffer, int index, char mode); + static void deselect_bonechildren (Object *ob, struct Bone *bone, int mode); static void selectconnected_posebonechildren (struct Bone *bone); @@ -2268,62 +2265,6 @@ void mousepose_armature(void) } -void make_trans_bones (char mode) -/* Used in pose mode */ -{ - bArmature *arm; - Bone *curBone; - int count=0; - - transmain=NULL; - - arm=get_armature (G.obpose); - if (!arm) - return; - - if (arm->flag & ARM_RESTPOS){ - notice ("Transformation not possible while Rest Position is enabled"); - return; - } - - - if (!(G.obpose->lay & G.vd->lay)) - return; - - - centroid[0]=centroid[1]=centroid[2]=0; - - apply_pose_armature(arm, G.obpose->pose, 0); - where_is_armature (G.obpose); - - /* Allocate memory for the transformation record */ - tottrans= count_bones (arm, BONE_SELECTED, 1); - - if (!tottrans) - return; - - transmain= MEM_callocN(tottrans*sizeof(TransOb), "bonetransmain"); - - for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){ - count = add_trans_bonechildren (G.obpose, curBone, transmain, count, mode); - } - - tottrans=count; - - if (tottrans){ - centroid[0]/=tottrans; - centroid[1]/=tottrans; - centroid[2]/=tottrans; - Mat4MulVecfl (G.obpose->obmat, centroid); - } - else{ - MEM_freeN (transmain); - transmain = NULL; - } - return; - -} - static int count_bones (bArmature *arm, int flagmask, int allbones) { int count=0; @@ -2361,93 +2302,6 @@ static int count_bonechildren (Bone *bone, int incount, int flagmask, int allbon } -static int add_trans_bonechildren (Object* ob, Bone* bone, TransOb* buffer, int index, char mode) -{ - Bone *curBone; - TransOb *curOb; - float parmat[4][4], tempmat[4][4]; - float tempobmat[4][4]; - float vec[3]; - if (!bone) - return index; - - - - /* We don't let IK children get "grabbed" */ - if (bone->flag & BONE_SELECTED){ - if (!((mode=='g' || mode=='G') && (bone->flag & BONE_IK_TOPARENT))){ - - get_bone_root_pos (bone, vec, 1); - - VecAddf (centroid, centroid, vec); - - curOb=&buffer[index]; - - curOb->ob = ob; - curOb->rot=NULL; - - curOb->quat= bone->quat; - curOb->size= bone->size; - curOb->loc = bone->loc; - - curOb->data = bone; // FIXME: Dangerous - - memcpy (curOb->oldquat, bone->quat, sizeof (bone->quat)); - memcpy (curOb->oldsize, bone->size, sizeof (bone->size)); - memcpy (curOb->oldloc, bone->loc, sizeof (bone->loc)); - -#if 0 - if (bone->parent) - get_objectspace_bone_matrix(bone->parent, tempmat, 1, 1); - else - Mat4One (tempmat); -#else - /* Get the matrix of this bone minus the usertransform */ - Mat4CpyMat4 (tempobmat, bone->obmat); - Mat4One (bone->obmat); - get_objectspace_bone_matrix(bone, tempmat, 1, 1); - Mat4CpyMat4 (bone->obmat, tempobmat); - - -#endif - -#if 1 - Mat4MulMat4 (parmat, tempmat, ob->obmat); /* Original */ - - /* Get world transform */ - get_objectspace_bone_matrix(bone, tempmat, 1, 1); - if (ob->parent){ - where_is_object(ob->parent); - Mat4MulSerie (tempobmat, ob->parent->obmat, ob->obmat, tempmat, NULL, NULL, NULL, NULL, NULL); - } - else - Mat4MulSerie (tempobmat, ob->obmat, tempmat, NULL, NULL, NULL, NULL, NULL, NULL); - Mat3CpyMat4 (curOb->axismat, tempobmat); - Mat3Ortho(curOb->axismat); - -#else - Mat4MulMat4 (parmat, ob->obmat, tempmat); -#endif - Mat3CpyMat4 (curOb->parmat, parmat); - Mat3Inv (curOb->parinv, curOb->parmat); - - Mat3CpyMat4 (curOb->obmat, bone->obmat); - Mat3Inv (curOb->obinv, curOb->obmat); - - index++; - return index; - } - - } - - /* Recursively search */ - for (curBone = bone->childbase.first; curBone; curBone=curBone->next){ - index=add_trans_bonechildren (ob, curBone, buffer, index, mode); - } - - return index; -} - static void deselect_bonechildren (Object *ob, Bone *bone, int mode) { Bone *curBone; diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 8fd95ec22e2..f06f55f387d 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -166,35 +166,11 @@ #include "BIF_poseobject.h" -/* extern Lattice *copy_lattice(Lattice *lt); */ -extern ListBase editNurb; -extern ListBase editelems; - -TransOb *transmain= 0; -TransVert *transvmain= 0; -int tottrans=0, transmode=0; /* 1: texspace */ - -float prop_size= 1.0; -float prop_cent[3]; - /* used in editipo, editcurve and here */ #define BEZSELECTED(bezt) (((bezt)->f1 & 1) || ((bezt)->f2 & 1) || ((bezt)->f3 & 1)) -#define TRANS_TEX 1 - -#define KEYFLAG_ROT 0x00000001 -#define KEYFLAG_LOC 0x00000002 -#define KEYFLAG_SIZE 0x00000004 - -float centre[3], centroid[3]; - -void mirrormenu(void); - /* local prototypes -------------*/ -int pose_flags_reset_done(Object *); /* used in transform_generic.c */ -void figure_bone_nocalc(Object *); /* used in transform.c */ -void figure_pose_updating(void); /* used in transform.c */ -void constline_callback(void); /* used in drawview.c */ + /* --------------------------------- */ void add_object_draw(int type) /* for toolbox or menus, only non-editmode stuff */ @@ -1023,6 +999,7 @@ void make_vertex_parent(void) } } else if ELEM(G.obedit->type, OB_SURF, OB_CURVE) { + extern ListBase editNurb; nu= editNurb.first; while(nu) { if((nu->type & 7)==CU_BEZIER) { @@ -1517,6 +1494,7 @@ void exit_editmode(int freedata) /* freedata==0 at render, 1= freedata, 2= do un if (freedata) free_editArmature(); } else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { + extern ListBase editNurb; load_editNurb(); if(freedata) freeNurblist(&editNurb); } @@ -1528,6 +1506,7 @@ void exit_editmode(int freedata) /* freedata==0 at render, 1= freedata, 2= do un if(freedata) free_editLatt(); } else if(G.obedit->type==OB_MBALL) { + extern ListBase editelems; load_editMball(); if(freedata) BLI_freelistN(&editelems); } @@ -1743,6 +1722,7 @@ void docentre(int centremode) else if ELEM(base->object->type, OB_CURVE, OB_SURF) { if(G.obedit) { + extern ListBase editNurb; nu1= editNurb.first; } else { @@ -3065,1518 +3045,8 @@ void apply_object() /* ************ GENERAL *************** */ -static Object *is_a_parent_selected_int(Object *startob, Object *ob, GHash *done_hash) { - if (ob!=startob && TESTBASE(ob)) - return ob; - - if (BLI_ghash_haskey(done_hash, ob)) - return NULL; - else - BLI_ghash_insert(done_hash, ob, NULL); - - if (ob->parent) { - Object *par= is_a_parent_selected_int(startob, ob->parent, done_hash); - if (par) - return par; - } - - /* IK is more complex in parents... */ - - /* XXX, should we be handling armatures or constraints here? - zr */ - - if(ob->type==OB_IKA) { - Ika *ika= ob->data; - - if (ika->def) { - int i; - - for (i=0; i<ika->totdef; i++) { - Deform *def= &ika->def[i]; - - if (def->ob && ob!=def->ob && def->ob!=startob) { - Object *par= is_a_parent_selected_int(startob, def->ob, done_hash); - if (par) - return par; - } - } - } - - if (ika->parent) { - Object *par= is_a_parent_selected_int(startob, ika->parent, done_hash); - if (par) - return par; - } - } - - return NULL; -} - -static Object *is_a_parent_selected(Object *ob) { - GHash *gh= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); - Object *res= is_a_parent_selected_int(ob, ob, gh); - BLI_ghash_free(gh, NULL, NULL); - - return res; -} - -/*** POSE FIGURIN' -- START ***/ - -static void clear_pose_update_flag(Object *ob) { - /* Clear the flag for each pose channel that indicates that - * pose should be updated on every redraw - */ - bPoseChannel *chan; - - if (ob->pose) { - for (chan = ob->pose->chanbase.first; chan; - chan=chan->next){ - chan->flag &= ~PCHAN_TRANS_UPDATE; - } - } -} - -/* exposed in transform.c */ -int pose_flags_reset_done(Object *ob) { - /* Clear the constraint done status for every pose channe; - * that has been flagged as needing constant updating - */ - bPoseChannel *chan; - int numreset = 0; - - if (ob->pose) { - for (chan = ob->pose->chanbase.first; chan; chan=chan->next){ - if (chan->flag & PCHAN_TRANS_UPDATE) { - chan->flag &= ~PCHAN_DONE; - numreset++; - } - - } - } - return numreset; -} - -static int is_ob_constraint_target(Object *ob, ListBase *conlist) { - /* Is this object the target of a constraint in this list? - */ - - bConstraint *con; - - for (con=conlist->first; con; con=con->next) - { - if (get_constraint_target(con) == ob) - return 1; - } - return 0; - -} - -static int clear_bone_nocalc(Object *ob, Bone *bone, void *ptr) { - /* When we aren't transform()-ing, we'll want to turn off - * the no calc flag for bone bone in case the frame changes, - * or something - */ - bone->flag &= ~BONE_NOCALC; - - return 0; -} - - -static void clear_bone_nocalc_ob(Object *ob) { - /* Let's clear no calc for all of the bones in the whole darn armature - */ - bArmature *arm; - arm = get_armature(ob); - if (arm) { - bone_looper(ob, arm->bonebase.first, NULL, - clear_bone_nocalc); - } - -} - -static int set_bone_nocalc(Object *ob, Bone *bone, void *ptr) { - /* Calculating bone transformation makes thins slow ... - * lets set the no calc flag for a bone by default - */ - bone->flag |= BONE_NOCALC; - - return 0; -} - -static int selected_bone_docalc(Object *ob, Bone *bone, void *ptr) { - /* Let's clear the no calc flag for selected bones. - * This function always returns 1 for non-no calc bones - * (a.k.a., the 'do calc' bones) so that the bone_looper - * will count these - */ - if (bone->flag & BONE_NOCALC) { - if ( (bone->flag & BONE_SELECTED) ) { - bone->flag &= ~BONE_NOCALC; - return 1; - } - - } - else { - return 1; - } - return 0; -} - -static Bone *get_parent_bone_docalc(Bone *bone) { - Bone *parBone; - - for (parBone = bone->parent; parBone; parBone=parBone->parent) - if (~parBone->flag & BONE_NOCALC) - return parBone; - - return NULL; -} - -static int is_bone_parent(Bone *childBone, Bone *parBone) { - Bone *currBone; - - for (currBone = childBone->parent; currBone; currBone=currBone->parent) - if (currBone == parBone) - return 1; - - return 0; -} - -static void figure_bone_nocalc_constraint(Bone *conbone, bConstraint *con, - Object *ob, bArmature *arm) { - /* If this bone has a constraint with a subtarget that has - * the nocalc flag cleared, then we better clear the no calc flag - * on this bone too (and the whole IK chain if this is an IK - * constraint). - * - * Conversly, if this bone has an IK constraint and the root of - * the chain has the no calc flag cleared, we had best clear that - * flag for the whole chain. - */ - Bone *subtarbone; - Bone *parBone; - char *subtar; - - subtar = get_con_subtarget_name(con, ob); - - if (subtar) { - if ( (subtarbone = get_named_bone(arm, subtar)) ) { - if ( (~subtarbone->flag & BONE_NOCALC) || - (get_parent_bone_docalc(subtarbone)) ) { - if (con->type == CONSTRAINT_TYPE_KINEMATIC) - /* IK target is flaged for updating, so we - * must update the whole chain. - */ - ik_chain_looper(ob, conbone, NULL, - clear_bone_nocalc); - else - /* Constraint target is flagged for - * updating, so we update this bone only - */ - conbone->flag &= ~BONE_NOCALC; - } - else { - if ( (parBone = get_parent_bone_docalc(conbone)) ) { - /* a parent is flagged for updating */ - if (!is_bone_parent(subtarbone, parBone)) { - /* if the subtarget is also a child of - * this bone, we needn't worry, other - * wise, we have to update - */ - if (con->type == CONSTRAINT_TYPE_KINEMATIC) - ik_chain_looper(ob, conbone, NULL, - clear_bone_nocalc); - else - conbone->flag &= ~BONE_NOCALC; - } - } - - } - } - } - else { - /* no subtarget ... target is regular object */ - if ( (parBone = get_parent_bone_docalc(conbone)) ) { - /* parent is flagged for updating ... since - * the target will never move (not a bone) - * we had better update this bone/chain - */ - if (con->type == CONSTRAINT_TYPE_KINEMATIC) - ik_chain_looper(ob, conbone, NULL, - clear_bone_nocalc); - else - conbone->flag &= ~BONE_NOCALC; - } - } - -} - -static void figure_bone_nocalc_core(Object *ob, bArmature *arm) { - /* Let's figure out which bones need to be recalculated, - * and which don't. Calculations are based on which bones - * are selected, and the constraints that love them. - */ - bPoseChannel *chan; - bConstraint *con; - Bone *conbone; - - int numbones, oldnumbones, iterations; - - oldnumbones = -1; - numbones = 0; - iterations = 0; - - /* O.K., lets loop until we don't clear any more no calc bones - */ - while (oldnumbones != numbones) { - /* I wonder if this will ever get executed? */ - if ( (++iterations) == 1000) { - printf("figurin' nocalc is talking too long\n"); - break; - } - - oldnumbones = numbones; - - /* clear no calc for selected bones and count */ - numbones = bone_looper(ob, arm->bonebase.first, NULL, - selected_bone_docalc); - - if (ob->pose) { - for (chan = ob->pose->chanbase.first; chan; chan=chan->next){ - conbone = get_named_bone(arm, chan->name); - if (conbone) { - for (con = chan->constraints.first; con; con=con->next) { - figure_bone_nocalc_constraint(conbone, con, ob, arm); - } - } - } - } - } -} - -/* exposed in transform.c */ -void figure_bone_nocalc(Object *ob) { - /* Let's figure out which bones need to be recalculated, - * and which don't. Calculations are based on which bones - * are selected, and the constraints that love them. - */ - bArmature *arm; - - arm = get_armature(ob); - if (!arm) return; - - if (arm->flag & ARM_RESTPOS) return; - - /* Set no calc for all bones - */ - bone_looper(ob, arm->bonebase.first, NULL, - set_bone_nocalc); - - figure_bone_nocalc_core(ob, arm); -} - -static int bone_nocalc2chan_trans_update(Object *ob, Bone *bone, void *ptr) { - /* Set PCHAN_TRANS_UPDATE for channels with bones that don't have - * the no calc flag set ... I hate this. - */ - bPoseChannel *chan; - - if (~bone->flag & BONE_NOCALC) { - chan = get_pose_channel(ob->pose, bone->name); - if (chan) chan->flag |= PCHAN_TRANS_UPDATE; - } - else { - /* reset this thing too */ - bone->flag &= ~BONE_NOCALC; - } - - return 0; -} - -static void clear_gonna_move(void) { - Base *base; - - /* clear the gonna move flag */ - for (base= FIRSTBASE; base; base= base->next) { - base->object->flag &= ~OB_GONNA_MOVE; - } -} - -static int is_parent_gonna_move(Object *ob) { - if ( (ob->parent) && - (ob->parent->flag & OB_GONNA_MOVE) ) { - return 1; - } - return 0; -} - -static int is_constraint_target_gonna_move(Object *ob) { - Object *tarOb; - bConstraint *con; - bPoseChannel *chan; - - for (con = ob->constraints.first; con; con=con->next) { - if ( (tarOb = get_constraint_target(con)) ) { - if (tarOb->flag & OB_GONNA_MOVE ) - return 1; - } - } - - if (ob->pose) { - for (chan = ob->pose->chanbase.first; chan; chan=chan->next){ - for (con = chan->constraints.first; con; con=con->next) { - if ( (tarOb = get_constraint_target(con)) ) { - if (tarOb->flag & OB_GONNA_MOVE ) - return 1; - } - } - } - } - - return 0; -} - -static void flag_moving_objects(void) { - Base *base; - int numgonnamove = 0, oldnumgonnamove = -1; - - clear_gonna_move(); - - /* the 'well ordering principle' guarantees convergence (honest) - */ - while (numgonnamove != oldnumgonnamove) { - oldnumgonnamove = numgonnamove; - numgonnamove = 0; - for (base= FIRSTBASE; base; base= base->next) { - if (base->object->flag & OB_GONNA_MOVE) { - ++numgonnamove; - } - else if (base->flag & SELECT) { - base->object->flag |= OB_GONNA_MOVE; - ++numgonnamove; - } - else if (is_parent_gonna_move(base->object)) { - base->object->flag |= OB_GONNA_MOVE; - ++numgonnamove; - } - else if (is_constraint_target_gonna_move(base->object)) { - base->object->flag |= OB_GONNA_MOVE; - ++numgonnamove; - } - } - } - -} - -static int pose_do_update_flag(Object *ob) { - /* Figure out which pose channels need constant updating. - * Well use the bone BONE_NOCALC bit to do some temporary - * flagging (so we can reuse code), which will later be - * converted to a value for a channel... I hate this. - */ - Base *base; - bPoseChannel *chan; - int do_update = 0; - bArmature *arm; - - arm = get_armature(ob); - if (!arm) return 0; - - /* initialize */ - bone_looper(ob, arm->bonebase.first, NULL, - set_bone_nocalc); - - if (ob->pose) { - for (chan = ob->pose->chanbase.first; chan; chan=chan->next){ - if (chan->constraints.first) { - for (base= FIRSTBASE; base; base= base->next) { - if (is_ob_constraint_target(base->object, - &chan->constraints)) { - if( (base->object->flag & OB_GONNA_MOVE) || - (ob->flag & OB_GONNA_MOVE)) { - Bone *bone; - /* If this armature is selected, or if the - * object that is the target of a constraint - * is selected, then lets constantly update - * this pose channel. - */ - bone = get_named_bone(ob->data, chan->name); - if (bone) { - bone->flag &= ~BONE_NOCALC; - ++do_update; - } - } - } - } - } - } - } - - if (do_update) { - figure_bone_nocalc_core(ob, arm); - } - - bone_looper(ob, arm->bonebase.first, NULL, - bone_nocalc2chan_trans_update); - - return do_update; -} - -/* this is a confusing call, it also does the constraint update flags, but was not used... - hopefully transform refactor will take care better of it (ton) */ -/* exposed int transform.c */ -void figure_pose_updating(void) -{ - Base *base; - - flag_moving_objects(); - - for (base= FIRSTBASE; base; base= base->next) { - /* Recalculate the pose if necessary, regardless of - * whether the layer is visible or not. - */ - if (pose_do_update_flag(base->object)) { - base->flag |= BA_WHERE_UPDATE; - } - else if(base->object->flag & OB_GONNA_MOVE) { - /* if position updates, deform info could change too */ - if(base->object->hooks.first) base->flag |= BA_DISP_UPDATE; - else if(base->object->parent) { - if(base->object->parent->type==OB_LATTICE || base->object->partype==PARSKEL) - base->flag |= BA_DISP_UPDATE; - } - } - } - -} - -/*** POSE FIGURIN' -- END ***/ - - -static void setbaseflags_for_editing(int mode) /* 0,'g','r','s' */ -{ - /* - if base selected and has parent selected: - base->flag= BA_WASSEL+BA_PARSEL - if base not selected and parent selected: - base->flag= BA_PARSEL - - */ - GHash *object_to_base_hash= NULL; - Base *base; - - /* moved to start of function, it is needed for hooks now too */ - if (!object_to_base_hash) { - Base *b; - object_to_base_hash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); - - for (b= FIRSTBASE; b; b= b->next) - BLI_ghash_insert(object_to_base_hash, b->object, b); - } - - - copy_baseflags(); - - for (base= FIRSTBASE; base; base= base->next) { - base->flag &= ~(BA_PARSEL+BA_WASSEL); - - if( (base->lay & G.vd->lay) && base->object->id.lib==0) { - Object *ob= base->object; - Object *parsel= is_a_parent_selected(ob); - - /* parentkey here? */ - - if(parsel) { - if(base->flag & SELECT) { - base->flag &= ~SELECT; - base->flag |= (BA_PARSEL+BA_WASSEL); - } - else base->flag |= BA_PARSEL; - } - - if(mode=='g') { - if(ob->track && TESTBASE(ob->track) && (base->flag & SELECT)==0) - base->flag |= BA_PARSEL; - } - - /* updates? */ - if(ob->type==OB_IKA) { - Ika *ika= ob->data; - if(ika->parent && parsel) base->flag |= BA_WHERE_UPDATE; - } - - if(ob->hooks.first) { - Base *b; - ObHook *hook= ob->hooks.first; - - while(hook) { - if(hook->parent) { - Object *parsel= is_a_parent_selected(hook->parent); - - b= BLI_ghash_lookup(object_to_base_hash, hook->parent); - if(parsel || ((base->flag | b->flag) & (SELECT | BA_PARSEL)) ) { - base->flag |= BA_DISP_UPDATE; - } - } - hook= hook->next; - } - } - - if(ob->parent && ob->parent->type==OB_LATTICE) - if(ob->parent->hooks.first) base->flag |= BA_DISP_UPDATE; - - if(base->flag & (SELECT | BA_PARSEL)) { - - base->flag |= BA_WHERE_UPDATE; - - if(ob->parent) { - if(ob->parent->type==OB_LATTICE) base->flag |= BA_DISP_UPDATE; - else if(ob->partype==PARSKEL) { - if ELEM3(ob->parent->type, OB_IKA, OB_CURVE, OB_ARMATURE) - base->flag |= BA_DISP_UPDATE; - } - } - if(ob->track) { - ; - } - - if( give_parteff(ob) ) base->flag |= BA_DISP_UPDATE; - - if(ob->type==OB_MBALL) { - Base *b; - - b= BLI_ghash_lookup(object_to_base_hash, find_basis_mball(ob)); - b->flag |= BA_DISP_UPDATE; - } - } - } - } - - if (object_to_base_hash) - BLI_ghash_free(object_to_base_hash, NULL, NULL); -} - - -void clearbaseflags_for_editing() -{ - Base *base; - - base= FIRSTBASE; - while(base) { - if(base->flag & BA_WASSEL) base->flag |= SELECT; - base->flag &= ~(BA_PARSEL+BA_WASSEL); - - base->flag &= ~(BA_DISP_UPDATE+BA_WHERE_UPDATE+BA_DO_IPO); - - clear_pose_update_flag(base->object); - - base= base->next; - } - copy_baseflags(); -} - -void ob_to_transob(Object *ob, TransOb *tob) -{ - float totmat[3][3]; - Object *tr; - void *cfirst, *clast; - - tob->ob= ob; - - cfirst = ob->constraints.first; - clast = ob->constraints.last; - - ob->constraints.first=ob->constraints.last=NULL; - - tr= ob->track; - ob->track= 0; - where_is_object(ob); - ob->track= tr; - ob->constraints.first = cfirst; - ob->constraints.last = clast; - - - - tob->loc= ob->loc; - VECCOPY(tob->oldloc, tob->loc); - - tob->rot= ob->rot; - VECCOPY(tob->oldrot, ob->rot); - VECCOPY(tob->olddrot, ob->drot); - - tob->quat= ob->quat; - QUATCOPY(tob->oldquat, ob->quat); - QUATCOPY(tob->olddquat, ob->dquat); - - tob->size= ob->size; - VECCOPY(tob->oldsize, ob->size); - - VECCOPY(tob->olddsize, ob->dsize); - - /* only object, not parent */ - object_to_mat3(ob, tob->obmat); - Mat3Inv(tob->obinv, tob->obmat); - - Mat3CpyMat4(totmat, ob->obmat); - - /* this is totmat without obmat: so a parmat */ - Mat3MulMat3(tob->parmat, totmat, tob->obinv); - Mat3Inv(tob->parinv, tob->parmat); - - Mat3MulMat3(tob->axismat, tob->parmat, tob->obmat); // New! - Mat3Ortho(tob->axismat); - - VECCOPY(tob->obvec, ob->obmat[3]); - - centroid[0]+= tob->obvec[0]; - centroid[1]+= tob->obvec[1]; - centroid[2]+= tob->obvec[2]; - - tob->eff= 0; - - if(ob->type==OB_IKA) { - Ika *ika=ob->data; - - calc_ika(ika, 0); - - ika->effn[0]= ika->eff[0]; - ika->effn[1]= ika->eff[1]; - ika->effn[2]= 0.0; - - VecMat4MulVecfl(ika->effg, ob->obmat, ika->effn); - - if(ika->flag & IK_GRABEFF) { - - tob->eff= ika->effg; - VECCOPY(tob->oldeff, tob->eff); - tob->flag |= TOB_IKA; - - tob->loc= 0; - } - - } -} - -void ob_to_tex_transob(Object *ob, TransOb *tob) -{ - Mesh *me; - Curve *cu; - MetaBall *mb; - ID *id; - - ob_to_transob(ob, tob); - - id= ob->data; - if(id==0); - else if( GS(id->name)==ID_ME) { - me= ob->data; - me->texflag &= ~AUTOSPACE; - tob->loc= me->loc; - tob->rot= me->rot; - tob->size= me->size; - } - else if( GS(id->name)==ID_CU) { - cu= ob->data; - cu->texflag &= ~CU_AUTOSPACE; - tob->loc= cu->loc; - tob->rot= cu->rot; - tob->size= cu->size; - } - else if( GS(id->name)==ID_MB) { - mb= ob->data; - mb->texflag &= ~MB_AUTOSPACE; - tob->loc= mb->loc; - tob->rot= mb->rot; - tob->size= mb->size; - } - - VECCOPY(tob->oldloc, tob->loc); - VECCOPY(tob->oldrot, tob->rot); - VECCOPY(tob->oldsize, tob->size); -} - -void make_trans_objects() -{ - Base *base; - Object *ob; - TransOb *tob = NULL; - ListBase elems; - IpoKey *ik; - float cfraont, min[3], max[3]; - int ipoflag; - - tottrans= 0; - - INIT_MINMAX(min, max); - centroid[0]=centroid[1]=centroid[2]= 0.0; - - /* count */ - base= FIRSTBASE; - while(base) { - if TESTBASELIB(base) { - ob= base->object; - - if(transmode==TRANS_TEX) { - if(ob->dtx & OB_TEXSPACE) tottrans++; - } - else { - if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) { - elems.first= elems.last= 0; - make_ipokey_transform(ob, &elems, 1); /* '1' only selected keys */ - - pushdata(&elems, sizeof(ListBase)); - - ik= elems.first; - while(ik) { - tottrans++; - ik= ik->next; - } - if(elems.first==0) tottrans++; - } - else tottrans++; - } - } - base= base->next; - } - - if(tottrans) tob= transmain= MEM_mallocN(tottrans*sizeof(TransOb), "transmain"); - - reset_slowparents(); - - - /*also do this below when tottrans==0, because of freeing pushpop and ipokeys */ - - base= FIRSTBASE; - while(base) { - if TESTBASELIB(base) { - ob= base->object; - - if(transmode==TRANS_TEX) { - if(ob->dtx & OB_TEXSPACE) { - tob->flag= 0; - - ob_to_tex_transob(ob, tob); - DO_MINMAX(tob->obvec, min, max); - - tob++; - } - } - else { - - /* is needed! (bevobj) */ - if(base->flag & SELECT) ob->flag|= SELECT; else ob->flag &= ~SELECT; - - if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) { - - popfirst(&elems); - - if(elems.first) { - base->flag |= BA_DO_IPO+BA_WASSEL; - base->flag &= ~SELECT; - - cfraont= CFRA; - set_no_parent_ipo(1); - ipoflag= ob->ipoflag; - ob->ipoflag &= ~OB_OFFS_OB; - - pushdata(ob->loc, 7*3*4); - - ik= elems.first; - while(ik) { - - CFRA= ik->val/G.scene->r.framelen; - - do_ob_ipo(ob); - where_is_object(ob); - - ob_to_transob(ob, tob); - DO_MINMAX(tob->obvec, min, max); - - /* also does tob->flag and oldvals, needs to be after ob_to_transob()! */ - set_ipo_pointers_transob(ik, tob); - - tob++; - ik= ik->next; - } - free_ipokey(&elems); - - poplast(ob->loc); - set_no_parent_ipo(0); - - CFRA= cfraont; - ob->ipoflag= ipoflag; - } - else { - tob->flag= 0; - - ob_to_transob(ob, tob); - DO_MINMAX(tob->obvec, min, max); - - tob++; - } - } - else { - tob->flag= 0; - - ob_to_transob(ob, tob); - DO_MINMAX(tob->obvec, min, max); - - tob++; - } - } - - } - base= base->next; - } - - pushpop_test(); /* only for debug & to be sure */ - - if(tottrans==0) return; - - centroid[0]/= tottrans; - centroid[1]/= tottrans; - centroid[2]/= tottrans; - - centre[0]= (min[0]+max[0])/2.0; - centre[1]= (min[1]+max[1])/2.0; - centre[2]= (min[2]+max[2])/2.0; -} - -/* mode: 1 = proportional */ -void make_trans_verts(float *min, float *max, int mode) -{ - EditMesh *em = G.editMesh; -/* extern Lattice *editLatt; already in BKE_lattice.h */ - Nurb *nu; - BezTriple *bezt; - BPoint *bp; - TransVert *tv=NULL; - MetaElem *ml; - EditVert *eve; - EditBone *ebo; - float total; - int a; - - tottrans= 0; // global! - - INIT_MINMAX(min, max); - centroid[0]=centroid[1]=centroid[2]= 0.0; - - /* note for transform refactor: dont rely on countall anymore... its ancient */ - /* I skip it for editmesh now (ton) */ - if(G.obedit->type!=OB_MESH) { - countall(); - if(mode) tottrans= G.totvert; - else tottrans= G.totvertsel; - - if(G.totvertsel==0) { - tottrans= 0; - return; - } - tv=transvmain= MEM_callocN(tottrans*sizeof(TransVert), "maketransverts"); - } - - /* we count again because of hide (old, not for mesh!) */ - tottrans= 0; - - if(G.obedit->type==OB_MESH) { - int proptrans= 0; - - // transform now requires awareness for select mode, so we tag the f1 flags in verts - tottrans= 0; - if(G.scene->selectmode & SCE_SELECT_VERTEX) { - for(eve= em->verts.first; eve; eve= eve->next) { - if(eve->h==0 && (eve->f & SELECT)) { - eve->f1= SELECT; - tottrans++; - } - else eve->f1= 0; - } - } - else if(G.scene->selectmode & SCE_SELECT_EDGE) { - EditEdge *eed; - for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0; - for(eed= em->edges.first; eed; eed= eed->next) { - if(eed->h==0 && (eed->f & SELECT)) eed->v1->f1= eed->v2->f1= SELECT; - } - for(eve= em->verts.first; eve; eve= eve->next) if(eve->f1) tottrans++; - } - else { - EditFace *efa; - for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0; - for(efa= em->faces.first; efa; efa= efa->next) { - if(efa->h==0 && (efa->f & SELECT)) { - efa->v1->f1= efa->v2->f1= efa->v3->f1= SELECT; - if(efa->v4) efa->v4->f1= SELECT; - } - } - for(eve= em->verts.first; eve; eve= eve->next) if(eve->f1) tottrans++; - } - - /* proportional edit exception... */ - if(mode==1 && tottrans) { - for(eve= em->verts.first; eve; eve= eve->next) { - if(eve->h==0) { - eve->f1 |= 2; - proptrans++; - } - } - if(proptrans>tottrans) tottrans= proptrans; - } - - /* and now make transverts */ - if(tottrans) { - tv=transvmain= MEM_callocN(tottrans*sizeof(TransVert), "maketransverts"); - - for(eve= em->verts.first; eve; eve= eve->next) { - if(eve->f1) { - VECCOPY(tv->oldloc, eve->co); - tv->loc= eve->co; - if(eve->no[0]!=0.0 || eve->no[1]!=0.0 ||eve->no[2]!=0.0) - tv->nor= eve->no; // note this is a hackish signal (ton) - tv->flag= eve->f1 & SELECT; - tv++; - } - } - } - } - else if (G.obedit->type==OB_ARMATURE){ - for (ebo=G.edbo.first;ebo;ebo=ebo->next){ - if (ebo->flag & BONE_TIPSEL){ - VECCOPY (tv->oldloc, ebo->tail); - tv->loc= ebo->tail; - tv->nor= NULL; - tv->flag= 1; - tv++; - tottrans++; - } - - /* Only add the root if there is no selected IK parent */ - if (ebo->flag & BONE_ROOTSEL){ - if (!(ebo->parent && (ebo->flag & BONE_IK_TOPARENT) && ebo->parent->flag & BONE_TIPSEL)){ - VECCOPY (tv->oldloc, ebo->head); - tv->loc= ebo->head; - tv->nor= NULL; - tv->flag= 1; - tv++; - tottrans++; - } - } - - } - } - else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { - nu= editNurb.first; - while(nu) { - if((nu->type & 7)==CU_BEZIER) { - a= nu->pntsu; - bezt= nu->bezt; - while(a--) { - if(bezt->hide==0) { - if(mode==1 || (bezt->f1 & 1)) { - VECCOPY(tv->oldloc, bezt->vec[0]); - tv->loc= bezt->vec[0]; - tv->flag= bezt->f1 & 1; - tv++; - tottrans++; - } - if(mode==1 || (bezt->f2 & 1)) { - VECCOPY(tv->oldloc, bezt->vec[1]); - tv->loc= bezt->vec[1]; - tv->val= &(bezt->alfa); - tv->oldval= bezt->alfa; - tv->flag= bezt->f2 & 1; - tv++; - tottrans++; - } - if(mode==1 || (bezt->f3 & 1)) { - VECCOPY(tv->oldloc, bezt->vec[2]); - tv->loc= bezt->vec[2]; - tv->flag= bezt->f3 & 1; - tv++; - tottrans++; - } - } - bezt++; - } - } - else { - a= nu->pntsu*nu->pntsv; - bp= nu->bp; - while(a--) { - if(bp->hide==0) { - if(mode==1 || (bp->f1 & 1)) { - VECCOPY(tv->oldloc, bp->vec); - tv->loc= bp->vec; - tv->val= &(bp->alfa); - tv->oldval= bp->alfa; - tv->flag= bp->f1 & 1; - tv++; - tottrans++; - } - } - bp++; - } - } - nu= nu->next; - } - } - else if(G.obedit->type==OB_MBALL) { - ml= editelems.first; - while(ml) { - if(ml->flag & SELECT) { - tv->loc= &ml->x; - VECCOPY(tv->oldloc, tv->loc); - tv->val= &(ml->rad); - tv->oldval= ml->rad; - tv->flag= 1; - tv++; - tottrans++; - } - ml= ml->next; - } - } - else if(G.obedit->type==OB_LATTICE) { - bp= editLatt->def; - - a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; - - while(a--) { - if(mode==1 || (bp->f1 & 1)) { - if(bp->hide==0) { - VECCOPY(tv->oldloc, bp->vec); - tv->loc= bp->vec; - tv->flag= bp->f1 & 1; - tv++; - tottrans++; - } - } - bp++; - } - } - - /* cent etc */ - tv= transvmain; - total= 0.0; - for(a=0; a<tottrans; a++, tv++) { - if(tv->flag & SELECT) { - centroid[0]+= tv->oldloc[0]; - centroid[1]+= tv->oldloc[1]; - centroid[2]+= tv->oldloc[2]; - total+= 1.0; - DO_MINMAX(tv->oldloc, min, max); - } - } - if(total!=0.0) { - centroid[0]/= total; - centroid[1]/= total; - centroid[2]/= total; - } - - centre[0]= (min[0]+max[0])/2.0; - centre[1]= (min[1]+max[1])/2.0; - centre[2]= (min[2]+max[2])/2.0; - -} - -/* now only in use by drawimage.c */ -void draw_prop_circle() -{ - if (G.scene->proportional) { - float tmat[4][4], imat[4][4]; - - if(G.moving) { - BIF_ThemeColor(TH_GRID); - - mygetmatrix(tmat); - Mat4Invert(imat, tmat); - - drawcircball(GL_LINE_LOOP, prop_cent, prop_size, imat); - } - } -} - -void set_proportional_weight(TransVert *tv, float *min, float *max) -{ - float dist, xdist, ydist, zdist; - - if(tv->oldloc[0]<min[0]) xdist= tv->oldloc[0]-min[0]; - else if(tv->oldloc[0]>max[0]) xdist= tv->oldloc[0]-max[0]; - else xdist= 0.0; - - if(tv->oldloc[1]<min[1]) ydist= tv->oldloc[1]-min[1]; - else if(tv->oldloc[1]>max[1]) ydist= tv->oldloc[1]-max[1]; - else ydist= 0.0; - - if(tv->oldloc[2]<min[2]) zdist= tv->oldloc[2]-min[2]; - else if(tv->oldloc[2]>max[2]) zdist= tv->oldloc[2]-max[2]; - else zdist= 0.0; - - dist= sqrt(xdist*xdist + ydist*ydist + zdist*zdist); - if(dist==0.0) tv->fac= 1.0; - else if(dist > prop_size) tv->fac= 0.0; - else { - dist= (prop_size-dist)/prop_size; - if(G.scene->prop_mode==1) tv->fac= 3.0*dist*dist - 2.0*dist*dist*dist; - else tv->fac= dist*dist; - } -} - -void special_trans_update(int keyflags) -{ -/* extern Lattice *editLatt; already in BKE_lattice.h */ - Base *base; - Curve *cu; - IpoCurve *icu; - - if(G.obedit) { - if(G.obedit->type==OB_MESH) { - recalc_editnormals(); // does face centers too - } - if(G.obedit->type==OB_CURVE) { - cu= G.obedit->data; - - makeBevelList(G.obedit); // might be needed for deform - calc_curvepath(G.obedit); - - base= FIRSTBASE; - while(base) { - if(base->lay & G.vd->lay) { - if(base->object->parent==G.obedit && base->object->partype==PARSKEL) - makeDispList(base->object); - else if(base->object->type==OB_CURVE) { - Curve *cu= base->object->data; - if(G.obedit==cu->bevobj || G.obedit==cu->taperobj) - makeDispList(base->object); - } - } - base= base->next; - } - } - else if(G.obedit->type==OB_ARMATURE){ - EditBone *ebo; - - /* Ensure all bones are correctly adjusted */ - for (ebo=G.edbo.first; ebo; ebo=ebo->next){ - - if ((ebo->flag & BONE_IK_TOPARENT) && ebo->parent){ - /* If this bone has a parent tip that has been moved */ - if (ebo->parent->flag & BONE_TIPSEL){ - VECCOPY (ebo->head, ebo->parent->tail); - } - /* If this bone has a parent tip that has NOT been moved */ - else{ - VECCOPY (ebo->parent->tail, ebo->head); - } - } - } - } - else if(G.obedit->type==OB_LATTICE) { - - if(editLatt->flag & LT_OUTSIDE) outside_lattice(editLatt); - - base= FIRSTBASE; - while(base) { - if(base->lay & G.vd->lay) { - if(base->object->parent==G.obedit) { - makeDispList(base->object); - } - } - base= base->next; - } - } - } - else if(G.obpose){ - int i; - bPoseChannel *chan; - - if (!G.obpose->pose) G.obpose->pose= MEM_callocN(sizeof(bPose), "pose"); - - switch (G.obpose->type){ - case OB_ARMATURE: - - /* Make channels for the transforming bones (in posemode) */ - for (i=0; i< tottrans; i++){ - chan = MEM_callocN (sizeof (bPoseChannel), "transPoseChannel"); - - if (keyflags & KEYFLAG_ROT){ - chan->flag |= POSE_ROT; - memcpy (chan->quat, transmain[i].quat, sizeof (chan->quat)); - } - if (keyflags & KEYFLAG_LOC){ - chan->flag |= POSE_LOC; - memcpy (chan->loc, transmain[i].loc, sizeof (chan->loc)); - } - if (keyflags & KEYFLAG_SIZE){ - chan->flag |= POSE_SIZE; - memcpy (chan->size, transmain[i].size, sizeof (chan->size)); - } - - strcpy (chan->name, ((Bone*) transmain[i].data)->name); - - set_pose_channel (G.obpose->pose, chan); - } - break; - } - } - else { - base= FIRSTBASE; - while(base) { - if(base->flag & BA_DO_IPO) { - - base->object->ctime= -1234567.0; - - icu= base->object->ipo->curve.first; - while(icu) { - calchandles_ipocurve(icu); - icu= icu->next; - } - - } - if(base->object->partype & PARSLOW) { - base->object->partype -= PARSLOW; - where_is_object(base->object); - base->object->partype |= PARSLOW; - } - else if(base->flag & BA_WHERE_UPDATE) { - where_is_object(base->object); - if(base->object->type==OB_IKA) { - itterate_ika(base->object); - } - - } - - base= base->next; - } - - base= FIRSTBASE; - while(base) { - - if(base->flag & BA_DISP_UPDATE) makeDispList(base->object); - - base= base->next; - } - - } - - base= FIRSTBASE; - while(base) { - if (pose_flags_reset_done(base->object)) { - if (!is_delay_deform()) - make_displists_by_armature(base->object); - } - - base= base->next; - } - -#if 1 - if (G.obpose && G.obpose->type == OB_ARMATURE) - clear_pose_constraint_status(G.obpose); - - if (!is_delay_deform()) make_displists_by_armature(G.obpose); -#endif - - if(G.vd->drawtype == OB_SHADED) reshadeall_displist(); - -} - - -void special_aftertrans_update(char mode, int flip, short canceled, int keyflags) -{ - Object *ob; - Base *base; - MetaBall *mb; - Curve *cu; - int doit,redrawipo=0; - - - /* displaylists etc. */ - - if(G.obedit) { - if(G.obedit->type==OB_MBALL) { - mb= G.obedit->data; - if(mb->flag != MB_UPDATE_ALWAYS) makeDispList(G.obedit); - } - else if(G.obedit->type==OB_MESH) { - if(flip) flip_editnormals(); - - recalc_editnormals(); - } - } - else if (G.obpose){ - bAction *act; - bPose *pose; - bPoseChannel *pchan; - - /* we had better clear the no calc flags on the bones - * ... else things won't look too good when changing - * frames, etc. - */ - clear_bone_nocalc_ob(G.obpose); - - if (U.uiflag & USER_KEYINSERTACT && !canceled){ - act=G.obpose->action; - pose=G.obpose->pose; - - if (!act) - act=G.obpose->action=add_empty_action(); - - collect_pose_garbage(G.obpose); - filter_pose_keys (); - for (pchan=pose->chanbase.first; pchan; pchan=pchan->next){ - if (pchan->flag & POSE_KEY){ - if (keyflags & KEYFLAG_ROT){ - set_action_key(act, pchan, AC_QUAT_X, 1); - set_action_key(act, pchan, AC_QUAT_Y, 1); - set_action_key(act, pchan, AC_QUAT_Z, 1); - set_action_key(act, pchan, AC_QUAT_W, 1); - } - if (keyflags & KEYFLAG_SIZE){ - set_action_key(act, pchan, AC_SIZE_X, 1); - set_action_key(act, pchan, AC_SIZE_Y, 1); - set_action_key(act, pchan, AC_SIZE_Z, 1); - } - if (keyflags & KEYFLAG_LOC){ - set_action_key(act, pchan, AC_LOC_X, 1); - set_action_key(act, pchan, AC_LOC_Y, 1); - set_action_key(act, pchan, AC_LOC_Z, 1); - } - } - } - - - remake_action_ipos (act); - allspace(REMAKEIPO, 0); - allqueue(REDRAWACTION, 0); - allqueue(REDRAWIPO, 0); - allqueue(REDRAWNLA, 0); - } - if (!canceled && is_delay_deform()){ - clear_pose_constraint_status(G.obpose); - make_displists_by_armature(G.obpose); - } - - } - else { - base= FIRSTBASE; - while(base) { - - ob= base->object; - - if(base->flag & BA_WHERE_UPDATE) { - - where_is_object(ob); - - if(ob->type==OB_ARMATURE && canceled) { - /* Unfortunately, sometimes when you escape - * a transform on an object that is the - * target of an IK constraint on an armature - * bone, the rotations are not restored - * correctly on the bones in the IK chain. - * There is probably a nice, elegant way to fix - * this using transdata, but this system is so - * darn confusing that we'll do it this brute - * force way instead: - */ - clear_pose_constraint_status(ob); - make_displists_by_armature(ob); - } - } - if(base->flag & BA_DISP_UPDATE) { - if(ob->type==OB_MBALL) { - mb= ob->data; - if(mb->flag != MB_UPDATE_ALWAYS || G.obedit == NULL) makeDispList(ob); - } - if( give_parteff(ob) ) build_particle_system(ob); - } - if(base->flag & BA_DO_IPO) redrawipo= 1; - - if(mode=='s' && ob->type==OB_FONT) { - doit= 0; - cu= ob->data; - - if(cu->bevobj && (cu->bevobj->flag & SELECT) ) doit= 1; - else if(cu->taperobj && (cu->taperobj->flag & SELECT) ) doit= 1; - else if(cu->textoncurve) { - if(cu->textoncurve->flag & SELECT) doit= 1; - else if(ob->flag & SELECT) doit= 1; - } - - if(doit) { - text_to_curve(ob, 0); - makeDispList(ob); - } - } - if(mode=='s' && ob->type==OB_CURVE) { - doit= 0; - cu= ob->data; - - if(cu->bevobj && (cu->bevobj->flag & SELECT) ) - makeDispList(ob); - else if(cu->taperobj && (cu->taperobj->flag & SELECT) ) - makeDispList(ob); - } - - if(ob->softflag & OB_SB_ENABLE) sbObjectReset(ob); - - where_is_object(ob); /* always do, for track etc. */ - - /* Set autokey if necessary */ - if ((U.uiflag & USER_KEYINSERTOBJ) && (!canceled) && (base->flag & SELECT)){ - if (keyflags & KEYFLAG_ROT){ - insertkey(&base->object->id, OB_ROT_X); - insertkey(&base->object->id, OB_ROT_Y); - insertkey(&base->object->id, OB_ROT_Z); - } - if (keyflags & KEYFLAG_LOC){ - insertkey(&base->object->id, OB_LOC_X); - insertkey(&base->object->id, OB_LOC_Y); - insertkey(&base->object->id, OB_LOC_Z); - } - if (keyflags & KEYFLAG_SIZE){ - insertkey(&base->object->id, OB_SIZE_X); - insertkey(&base->object->id, OB_SIZE_Y); - insertkey(&base->object->id, OB_SIZE_Z); - } - - remake_object_ipos (ob); - allqueue(REDRAWIPO, 0); - allspace(REMAKEIPO, 0); - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWNLA, 0); - } - - base= base->next; - } - - } - - if(redrawipo) { - allqueue(REDRAWNLA, 0); - allqueue(REDRAWACTION, 0); - allqueue(REDRAWIPO, 0); - } - - if(G.vd->drawtype == OB_SHADED) reshadeall_displist(); - -} - - - -void calc_trans_verts(void) -{ - if (ELEM(G.obedit->type, OB_MESH, OB_MBALL)) - makeDispList(G.obedit); - else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { - Nurb *nu= editNurb.first; - while(nu) { - test2DNurb(nu); - testhandlesNurb(nu); /* test for bezier too */ - nu= nu->next; - } - makeDispList(G.obedit); - } -} +/* now only used in 2d spaces, like ipo, nla, sima... */ void apply_keyb_grid(float *val, float fac1, float fac2, float fac3, int invert) { /* fac1 is for 'nothing', fac2 for CTRL, fac3 for SHIFT */ @@ -4662,41 +3132,6 @@ void compatible_eul(float *eul, float *oldrot) } -void add_ipo_tob_poin(float *poin, float *old, float delta) -{ - if(poin) { - poin[0]= old[0]+delta; - poin[-3]= old[3]+delta; - poin[3]= old[6]+delta; - } -} - -void restore_tob(TransOb *tob) -{ - - if(tob->flag & TOB_IPO) { - add_ipo_tob_poin(tob->locx, tob->oldloc, 0.0); - add_ipo_tob_poin(tob->locy, tob->oldloc+1, 0.0); - add_ipo_tob_poin(tob->locz, tob->oldloc+2, 0.0); -/* QUAT! */ - add_ipo_tob_poin(tob->rotx, tob->oldrot+3, 0.0); - add_ipo_tob_poin(tob->roty, tob->oldrot+4, 0.0); - add_ipo_tob_poin(tob->rotz, tob->oldrot+5, 0.0); - - add_ipo_tob_poin(tob->sizex, tob->oldsize, 0.0); - add_ipo_tob_poin(tob->sizey, tob->oldsize+1, 0.0); - add_ipo_tob_poin(tob->sizez, tob->oldsize+2, 0.0); - - } - else { - if(tob->eff) VECCOPY(tob->eff, tob->oldeff); - if(tob->loc) VECCOPY(tob->loc, tob->oldloc); - if(tob->rot) VECCOPY(tob->rot, tob->oldrot); - - QUATCOPY(tob->quat, tob->oldquat); - VECCOPY(tob->size, tob->oldsize); - } -} int cylinder_intersect_test(void) { @@ -4804,20 +3239,6 @@ int sphere_intersect_test(void) return 1; } -#ifndef CLOCKS_PER_SEC -#define CLOCKS_PER_SEC 1000000 -#endif - -int my_clock(void) -{ - float ftime; - - ftime= (float)clock(); - ftime*= 100.0/CLOCKS_PER_SEC; - - return (int)ftime; -} - void std_rmouse_transform(void (*xf_func)(int, int)) { @@ -6050,13 +4471,9 @@ void texspace_edit(void) } - //transmode= TRANS_TEX; - if(nr==1) Transform(TFM_TRANSLATION, CTX_TEXTURE); else if(nr==2) Transform(TFM_RESIZE, CTX_TEXTURE); else if(nr==3) Transform(TFM_ROTATION, CTX_TEXTURE); - - //transmode= 0; } void first_base(void) diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c index 53097a2a25e..db209780492 100755 --- a/source/blender/src/transform.c +++ b/source/blender/src/transform.c @@ -188,7 +188,6 @@ static void view_editmove(unsigned short event) } } - void Transform(int mode, int context) { int ret_val = 0; diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index d95c84330b4..e14cec6a131 100755 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -61,6 +61,7 @@ #include "DNA_meshdata_types.h" #include "DNA_meta_types.h" #include "DNA_object_types.h" +#include "DNA_object_force.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_texture_types.h" @@ -76,8 +77,10 @@ #include "BIF_mywindow.h" #include "BIF_gl.h" #include "BIF_editlattice.h" +#include "BIF_editconstraint.h" #include "BIF_editarmature.h" #include "BIF_editmesh.h" +#include "BIF_poseobject.h" #include "BIF_screen.h" #include "BIF_space.h" #include "BIF_toolbox.h" @@ -86,19 +89,25 @@ #include "BKE_armature.h" #include "BKE_blender.h" #include "BKE_curve.h" +#include "BKE_constraint.h" #include "BKE_displist.h" #include "BKE_effect.h" +#include "BKE_font.h" #include "BKE_global.h" #include "BKE_ipo.h" #include "BKE_lattice.h" #include "BKE_mball.h" #include "BKE_object.h" +#include "BKE_softbody.h" #include "BKE_utildefines.h" #include "BSE_view.h" #include "BSE_edit.h" +#include "BSE_editaction.h" #include "BSE_editipo.h" #include "BSE_editipo_types.h" +#include "BSE_editaction.h" + #include "BDR_editobject.h" // reset_slowparents() #include "BLI_arithb.h" @@ -116,6 +125,11 @@ extern ListBase editelems; #include "transform.h" +/* local protos */ +static void figure_bone_nocalc(Object *ob); +static void figure_pose_updating(void); + + /* ************************** Functions *************************** */ static void qsort_trans_data(TransInfo *t, TransData *head, TransData *tail) { @@ -464,9 +478,6 @@ static void createTransPose(TransInfo *t) /* copied from old code, no idea. we let linker solve it for now */ { - extern void figure_bone_nocalc(Object *ob); - extern void figure_pose_updating(void); - /* figure out which bones need calculating */ figure_bone_nocalc(G.obpose); figure_pose_updating(); @@ -1396,6 +1407,595 @@ void clear_trans_object_base_flags(void) copy_baseflags(); } +/* ******************************************************************************** */ +/* ************** TOTALLY #@#! CODE FROM PAST TRANSFORM FOR POSEMODE ************** */ +/* ******************************************************************************** */ + + +static int is_ob_constraint_target(Object *ob, ListBase *conlist) { + /* Is this object the target of a constraint in this list? + */ + + bConstraint *con; + + for (con=conlist->first; con; con=con->next) + { + if (get_constraint_target(con) == ob) + return 1; + } + return 0; + +} + +static int clear_bone_nocalc(Object *ob, Bone *bone, void *ptr) { + /* When we aren't transform()-ing, we'll want to turn off + * the no calc flag for bone bone in case the frame changes, + * or something + */ + bone->flag &= ~BONE_NOCALC; + + return 0; +} + + +static int set_bone_nocalc(Object *ob, Bone *bone, void *ptr) { + /* Calculating bone transformation makes thins slow ... + * lets set the no calc flag for a bone by default + */ + bone->flag |= BONE_NOCALC; + + return 0; +} + +static int selected_bone_docalc(Object *ob, Bone *bone, void *ptr) { + /* Let's clear the no calc flag for selected bones. + * This function always returns 1 for non-no calc bones + * (a.k.a., the 'do calc' bones) so that the bone_looper + * will count these + */ + if (bone->flag & BONE_NOCALC) { + if ( (bone->flag & BONE_SELECTED) ) { + bone->flag &= ~BONE_NOCALC; + return 1; + } + + } + else { + return 1; + } + return 0; +} + +static Bone *get_parent_bone_docalc(Bone *bone) { + Bone *parBone; + + for (parBone = bone->parent; parBone; parBone=parBone->parent) + if (~parBone->flag & BONE_NOCALC) + return parBone; + + return NULL; +} + +static int is_bone_parent(Bone *childBone, Bone *parBone) { + Bone *currBone; + + for (currBone = childBone->parent; currBone; currBone=currBone->parent) + if (currBone == parBone) + return 1; + + return 0; +} + +static void figure_bone_nocalc_constraint(Bone *conbone, bConstraint *con, + Object *ob, bArmature *arm) { + /* If this bone has a constraint with a subtarget that has + * the nocalc flag cleared, then we better clear the no calc flag + * on this bone too (and the whole IK chain if this is an IK + * constraint). + * + * Conversly, if this bone has an IK constraint and the root of + * the chain has the no calc flag cleared, we had best clear that + * flag for the whole chain. + */ + Bone *subtarbone; + Bone *parBone; + char *subtar; + + subtar = get_con_subtarget_name(con, ob); + + if (subtar) { + if ( (subtarbone = get_named_bone(arm, subtar)) ) { + if ( (~subtarbone->flag & BONE_NOCALC) || + (get_parent_bone_docalc(subtarbone)) ) { + if (con->type == CONSTRAINT_TYPE_KINEMATIC) + /* IK target is flaged for updating, so we + * must update the whole chain. + */ + ik_chain_looper(ob, conbone, NULL, + clear_bone_nocalc); + else + /* Constraint target is flagged for + * updating, so we update this bone only + */ + conbone->flag &= ~BONE_NOCALC; + } + else { + if ( (parBone = get_parent_bone_docalc(conbone)) ) { + /* a parent is flagged for updating */ + if (!is_bone_parent(subtarbone, parBone)) { + /* if the subtarget is also a child of + * this bone, we needn't worry, other + * wise, we have to update + */ + if (con->type == CONSTRAINT_TYPE_KINEMATIC) + ik_chain_looper(ob, conbone, NULL, + clear_bone_nocalc); + else + conbone->flag &= ~BONE_NOCALC; + } + } + + } + } + } + else { + /* no subtarget ... target is regular object */ + if ( (parBone = get_parent_bone_docalc(conbone)) ) { + /* parent is flagged for updating ... since + * the target will never move (not a bone) + * we had better update this bone/chain + */ + if (con->type == CONSTRAINT_TYPE_KINEMATIC) + ik_chain_looper(ob, conbone, NULL, + clear_bone_nocalc); + else + conbone->flag &= ~BONE_NOCALC; + } + } + +} + +static void figure_bone_nocalc_core(Object *ob, bArmature *arm) { + /* Let's figure out which bones need to be recalculated, + * and which don't. Calculations are based on which bones + * are selected, and the constraints that love them. + */ + bPoseChannel *chan; + bConstraint *con; + Bone *conbone; + + int numbones, oldnumbones, iterations; + + oldnumbones = -1; + numbones = 0; + iterations = 0; + + /* O.K., lets loop until we don't clear any more no calc bones + */ + while (oldnumbones != numbones) { + /* I wonder if this will ever get executed? */ + if ( (++iterations) == 1000) { + printf("figurin' nocalc is talking too long\n"); + break; + } + + oldnumbones = numbones; + + /* clear no calc for selected bones and count */ + numbones = bone_looper(ob, arm->bonebase.first, NULL, + selected_bone_docalc); + + if (ob->pose) { + for (chan = ob->pose->chanbase.first; chan; chan=chan->next){ + conbone = get_named_bone(arm, chan->name); + if (conbone) { + for (con = chan->constraints.first; con; con=con->next) { + figure_bone_nocalc_constraint(conbone, con, ob, arm); + } + } + } + } + } +} + +static void figure_bone_nocalc(Object *ob) +{ + /* Let's figure out which bones need to be recalculated, + * and which don't. Calculations are based on which bones + * are selected, and the constraints that love them. + */ + bArmature *arm; + + arm = get_armature(ob); + if (!arm) return; + + if (arm->flag & ARM_RESTPOS) return; + + /* Set no calc for all bones + */ + bone_looper(ob, arm->bonebase.first, NULL, + set_bone_nocalc); + + figure_bone_nocalc_core(ob, arm); +} + +static int bone_nocalc2chan_trans_update(Object *ob, Bone *bone, void *ptr) { + /* Set PCHAN_TRANS_UPDATE for channels with bones that don't have + * the no calc flag set ... I hate this. + */ + bPoseChannel *chan; + + if (~bone->flag & BONE_NOCALC) { + chan = get_pose_channel(ob->pose, bone->name); + if (chan) chan->flag |= PCHAN_TRANS_UPDATE; + } + else { + /* reset this thing too */ + bone->flag &= ~BONE_NOCALC; + } + + return 0; +} + +static void clear_gonna_move(void) { + Base *base; + + /* clear the gonna move flag */ + for (base= FIRSTBASE; base; base= base->next) { + base->object->flag &= ~OB_GONNA_MOVE; + } +} + +static int is_parent_gonna_move(Object *ob) { + if ( (ob->parent) && + (ob->parent->flag & OB_GONNA_MOVE) ) { + return 1; + } + return 0; +} + +static int is_constraint_target_gonna_move(Object *ob) { + Object *tarOb; + bConstraint *con; + bPoseChannel *chan; + + for (con = ob->constraints.first; con; con=con->next) { + if ( (tarOb = get_constraint_target(con)) ) { + if (tarOb->flag & OB_GONNA_MOVE ) + return 1; + } + } + + if (ob->pose) { + for (chan = ob->pose->chanbase.first; chan; chan=chan->next){ + for (con = chan->constraints.first; con; con=con->next) { + if ( (tarOb = get_constraint_target(con)) ) { + if (tarOb->flag & OB_GONNA_MOVE ) + return 1; + } + } + } + } + + return 0; +} + +static void flag_moving_objects(void) { + Base *base; + int numgonnamove = 0, oldnumgonnamove = -1; + + clear_gonna_move(); + + /* the 'well ordering principle' guarantees convergence (honest) + */ + while (numgonnamove != oldnumgonnamove) { + oldnumgonnamove = numgonnamove; + numgonnamove = 0; + for (base= FIRSTBASE; base; base= base->next) { + if (base->object->flag & OB_GONNA_MOVE) { + ++numgonnamove; + } + else if (base->flag & SELECT) { + base->object->flag |= OB_GONNA_MOVE; + ++numgonnamove; + } + else if (is_parent_gonna_move(base->object)) { + base->object->flag |= OB_GONNA_MOVE; + ++numgonnamove; + } + else if (is_constraint_target_gonna_move(base->object)) { + base->object->flag |= OB_GONNA_MOVE; + ++numgonnamove; + } + } + } + +} + +static int pose_do_update_flag(Object *ob) { + /* Figure out which pose channels need constant updating. + * Well use the bone BONE_NOCALC bit to do some temporary + * flagging (so we can reuse code), which will later be + * converted to a value for a channel... I hate this. + */ + Base *base; + bPoseChannel *chan; + int do_update = 0; + bArmature *arm; + + arm = get_armature(ob); + if (!arm) return 0; + + /* initialize */ + bone_looper(ob, arm->bonebase.first, NULL, + set_bone_nocalc); + + if (ob->pose) { + for (chan = ob->pose->chanbase.first; chan; chan=chan->next){ + if (chan->constraints.first) { + for (base= FIRSTBASE; base; base= base->next) { + if (is_ob_constraint_target(base->object, + &chan->constraints)) { + if( (base->object->flag & OB_GONNA_MOVE) || + (ob->flag & OB_GONNA_MOVE)) { + Bone *bone; + /* If this armature is selected, or if the + * object that is the target of a constraint + * is selected, then lets constantly update + * this pose channel. + */ + bone = get_named_bone(ob->data, chan->name); + if (bone) { + bone->flag &= ~BONE_NOCALC; + ++do_update; + } + } + } + } + } + } + } + + if (do_update) { + figure_bone_nocalc_core(ob, arm); + } + + bone_looper(ob, arm->bonebase.first, NULL, + bone_nocalc2chan_trans_update); + + return do_update; +} + +/* this is a confusing call, it also does the constraint update flags, but was not used... + hopefully transform refactor will take care better of it (ton) */ +static void figure_pose_updating(void) +{ + Base *base; + + flag_moving_objects(); + + for (base= FIRSTBASE; base; base= base->next) { + /* Recalculate the pose if necessary, regardless of + * whether the layer is visible or not. + */ + if (pose_do_update_flag(base->object)) { + base->flag |= BA_WHERE_UPDATE; + } + else if(base->object->flag & OB_GONNA_MOVE) { + /* if position updates, deform info could change too */ + if(base->object->hooks.first) base->flag |= BA_DISP_UPDATE; + else if(base->object->parent) { + if(base->object->parent->type==OB_LATTICE || base->object->partype==PARSKEL) + base->flag |= BA_DISP_UPDATE; + } + } + } + +} + + +/* copied from old transform, will be replaced with proper depgraph code (ton) */ +static void clear_bone_nocalc_ob(Object *ob) { + /* Let's clear no calc for all of the bones in the whole darn armature + */ + bArmature *arm; + arm = get_armature(ob); + if (arm) { + bone_looper(ob, arm->bonebase.first, NULL, + clear_bone_nocalc); + } + +} + + +/* ******************************************************************************** */ +/* ************ END, TOTALLY #@#! CODE FROM PAST TRANSFORM FOR POSEMODE *********** */ +/* ******************************************************************************** */ + +/* copied from old transform, will be replaced with proper depgraph code (ton) */ +void special_aftertrans_update(char mode, int flip, short canceled, int keyflags) +{ + Object *ob; + Base *base; + MetaBall *mb; + Curve *cu; + int doit,redrawipo=0; + + + /* displaylists etc. */ + + if(G.obedit) { + if(G.obedit->type==OB_MBALL) { + mb= G.obedit->data; + if(mb->flag != MB_UPDATE_ALWAYS) makeDispList(G.obedit); + } + else if(G.obedit->type==OB_MESH) { + if(flip) flip_editnormals(); + + recalc_editnormals(); + } + } + else if (G.obpose){ + bAction *act; + bPose *pose; + bPoseChannel *pchan; + + /* we had better clear the no calc flags on the bones + * ... else things won't look too good when changing + * frames, etc. + */ + clear_bone_nocalc_ob(G.obpose); + + if (U.uiflag & USER_KEYINSERTACT && !canceled){ + act=G.obpose->action; + pose=G.obpose->pose; + + if (!act) + act=G.obpose->action=add_empty_action(); + + collect_pose_garbage(G.obpose); + filter_pose_keys (); + for (pchan=pose->chanbase.first; pchan; pchan=pchan->next){ + if (pchan->flag & POSE_KEY){ + if (keyflags){ + set_action_key(act, pchan, AC_QUAT_X, 1); + set_action_key(act, pchan, AC_QUAT_Y, 1); + set_action_key(act, pchan, AC_QUAT_Z, 1); + set_action_key(act, pchan, AC_QUAT_W, 1); + } + if (keyflags){ + set_action_key(act, pchan, AC_SIZE_X, 1); + set_action_key(act, pchan, AC_SIZE_Y, 1); + set_action_key(act, pchan, AC_SIZE_Z, 1); + } + if (keyflags){ + set_action_key(act, pchan, AC_LOC_X, 1); + set_action_key(act, pchan, AC_LOC_Y, 1); + set_action_key(act, pchan, AC_LOC_Z, 1); + } + } + } + + + remake_action_ipos (act); + allspace(REMAKEIPO, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWIPO, 0); + allqueue(REDRAWNLA, 0); + } + if (!canceled && is_delay_deform()){ + clear_pose_constraint_status(G.obpose); + make_displists_by_armature(G.obpose); + } + + } + else { + base= FIRSTBASE; + while(base) { + + ob= base->object; + + if(base->flag & BA_WHERE_UPDATE) { + + where_is_object(ob); + + if(ob->type==OB_ARMATURE && canceled) { + /* Unfortunately, sometimes when you escape + * a transform on an object that is the + * target of an IK constraint on an armature + * bone, the rotations are not restored + * correctly on the bones in the IK chain. + * There is probably a nice, elegant way to fix + * this using transdata, but this system is so + * darn confusing that we'll do it this brute + * force way instead: + */ + clear_pose_constraint_status(ob); + make_displists_by_armature(ob); + } + } + if(base->flag & BA_DISP_UPDATE) { + if(ob->type==OB_MBALL) { + mb= ob->data; + if(mb->flag != MB_UPDATE_ALWAYS || G.obedit == NULL) makeDispList(ob); + } + if( give_parteff(ob) ) build_particle_system(ob); + } + if(base->flag & BA_DO_IPO) redrawipo= 1; + + if(mode=='s' && ob->type==OB_FONT) { + doit= 0; + cu= ob->data; + + if(cu->bevobj && (cu->bevobj->flag & SELECT) ) doit= 1; + else if(cu->taperobj && (cu->taperobj->flag & SELECT) ) doit= 1; + else if(cu->textoncurve) { + if(cu->textoncurve->flag & SELECT) doit= 1; + else if(ob->flag & SELECT) doit= 1; + } + + if(doit) { + text_to_curve(ob, 0); + makeDispList(ob); + } + } + if(mode=='s' && ob->type==OB_CURVE) { + doit= 0; + cu= ob->data; + + if(cu->bevobj && (cu->bevobj->flag & SELECT) ) + makeDispList(ob); + else if(cu->taperobj && (cu->taperobj->flag & SELECT) ) + makeDispList(ob); + } + + if(ob->softflag & OB_SB_ENABLE) sbObjectReset(ob); + + where_is_object(ob); /* always do, for track etc. */ + + /* Set autokey if necessary */ + if ((U.uiflag & USER_KEYINSERTOBJ) && (!canceled) && (base->flag & SELECT)){ + if (keyflags){ + insertkey(&base->object->id, OB_ROT_X); + insertkey(&base->object->id, OB_ROT_Y); + insertkey(&base->object->id, OB_ROT_Z); + } + if (keyflags){ + insertkey(&base->object->id, OB_LOC_X); + insertkey(&base->object->id, OB_LOC_Y); + insertkey(&base->object->id, OB_LOC_Z); + } + if (keyflags){ + insertkey(&base->object->id, OB_SIZE_X); + insertkey(&base->object->id, OB_SIZE_Y); + insertkey(&base->object->id, OB_SIZE_Z); + } + + remake_object_ipos (ob); + allqueue(REDRAWIPO, 0); + allspace(REMAKEIPO, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWNLA, 0); + } + + base= base->next; + } + + } + + if(redrawipo) { + allqueue(REDRAWNLA, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWIPO, 0); + } + + if(G.vd->drawtype == OB_SHADED) reshadeall_displist(); + +} + + + + static void createTransObject(TransInfo *t) { @@ -1412,7 +2012,6 @@ static void createTransObject(TransInfo *t) set_trans_object_base_flags(t); { - extern void figure_pose_updating(void); /* this has to be done, or else constraints on armature * bones that point to objects/bones that are outside * of the armature don't work outside of posemode diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c index 9f90b3ed785..049f0ca2241 100755 --- a/source/blender/src/transform_generics.c +++ b/source/blender/src/transform_generics.c @@ -140,6 +140,26 @@ void getViewVector(float coord[3], float vec[3]) { /* ************************** GENERICS **************************** */ +static int pose_flags_reset_done(Object *ob) { + /* Clear the constraint done status for every pose channe; + * that has been flagged as needing constant updating + */ + bPoseChannel *chan; + int numreset = 0; + + if (ob->pose) { + for (chan = ob->pose->chanbase.first; chan; chan=chan->next){ + if (chan->flag & PCHAN_TRANS_UPDATE) { + chan->flag &= ~PCHAN_DONE; + numreset++; + } + + } + } + return numreset; +} + + /* called for objects updating while transform acts, once per redraw */ void recalcData(TransInfo *t) { @@ -289,7 +309,6 @@ void recalcData(TransInfo *t) /* ugly stuff for posemode, copied from old system */ base= FIRSTBASE; while(base) { - extern int pose_flags_reset_done(Object *ob); // linker solves if (pose_flags_reset_done(base->object)) { if (!is_delay_deform()) |