diff options
21 files changed, 547 insertions, 617 deletions
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 4effdb6af8a..03a7cfe0096 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -86,5 +86,8 @@ void sethandlesNurb(short code); void swapdata(void *adr1, void *adr2, int len); void switchdirectionNurb( struct Nurb *nu); +float (*curve_getVertexCos(struct Curve *cu, struct ListBase *lb, int *numVerts_r))[3]; +void curve_applyVertexCos(struct Curve *cu, struct ListBase *lb, float (*vertexCos)[3]); + #endif diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h index 434f9fb1ef9..021b584036f 100644 --- a/source/blender/blenkernel/BKE_displist.h +++ b/source/blender/blenkernel/BKE_displist.h @@ -42,6 +42,7 @@ #define DL_INDEX3 4 #define DL_INDEX4 5 #define DL_VERTCOL 6 +#define DL_VERTS 7 /* dl->flag */ #define DL_CYCL_U 1 diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h index 48e8f9fb8b3..073810fd37b 100644 --- a/source/blender/blenkernel/BKE_lattice.h +++ b/source/blender/blenkernel/BKE_lattice.h @@ -41,7 +41,7 @@ struct BPoint; extern struct Lattice *editLatt; -void resizelattice(struct Lattice *lt); +void resizelattice(struct Lattice *lt, int u, int v, int w, struct Object *ltOb); struct Lattice *add_lattice(void); struct Lattice *copy_lattice(struct Lattice *lt); void free_lattice(struct Lattice *lt); @@ -51,11 +51,13 @@ void init_latt_deform(struct Object *oblatt, struct Object *ob); void calc_latt_deform(float *co); void end_latt_deform(void); int object_deform_mball(struct Object *ob); -struct BPoint *latt_bp(struct Lattice *lt, int u, int v, int w); void outside_lattice(struct Lattice *lt); void curve_deform_verts(struct Object *cuOb, struct Object *target, float (*vertexCos)[3], int numVerts); void lattice_deform_verts(struct Object *laOb, struct Object *target, float (*vertexCos)[3], int numVerts); void armature_deform_verts(struct Object *armOb, struct Object *target, float (*vertexCos)[3], int numVerts); +float (*lattice_getVertexCos(struct Object *ob, int *numVerts_r))[3]; +void lattice_applyVertexCos(struct Object *ob, float (*vertexCos)[3]); +void lattice_calc_modifiers(struct Object *ob); #endif diff --git a/source/blender/blenkernel/BKE_softbody.h b/source/blender/blenkernel/BKE_softbody.h index f47cb1b51e3..3ead7445c03 100644 --- a/source/blender/blenkernel/BKE_softbody.h +++ b/source/blender/blenkernel/BKE_softbody.h @@ -34,19 +34,6 @@ #ifndef BKE_SOFTBODY_H #define BKE_SOFTBODY_H -typedef struct BodyPoint { - float origS[3], origE[3], origT[3], pos[3], vec[3], force[3]; - float weight, goal; - float prevpos[3], prevvec[3], prevdx[3], prevdv[3]; /* used for Heun integration */ - int nofsprings; int *springs; - float contactfrict; -} BodyPoint; - -typedef struct BodySpring { - int v1, v2; - float len, strength; -} BodySpring; - struct Object; struct SoftBody; @@ -56,16 +43,11 @@ extern struct SoftBody *sbNew(void); /* frees internal data and softbody itself */ extern void sbFree(struct SoftBody *sb); -/* go one step in simulation, copy result in vertexCos for meshes, or - * directly for lattices. - */ -extern void sbObjectStep(struct Object *ob, float framnr, float (*vertexCos)[3]); +/* do one simul step, reading and writing vertex locs from given array */ +extern void sbObjectStep(struct Object *ob, float framnr, float (*vertexCos)[3], int numVerts); /* makes totally fresh start situation, resets time */ -extern void sbObjectToSoftbody(struct Object *ob, float (*vertexCos)[3]); - -/* resets all motion and time */ -extern void sbObjectReset(struct Object *ob, float (*vertexCos)[3]); +extern void sbObjectToSoftbody(struct Object *ob); #endif diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 150f5eddd41..b1f8fcca6bf 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -2411,3 +2411,57 @@ void switchdirectionNurb(Nurb *nu) } } } + + +float (*curve_getVertexCos(Curve *cu, ListBase *lb, int *numVerts_r))[3] +{ + int i, numVerts = *numVerts_r = count_curveverts(lb); + float *co, (*cos)[3] = MEM_mallocN(sizeof(*cos)*numVerts, "cu_vcos"); + Nurb *nu; + + co = cos[0]; + for (nu=lb->first; nu; nu=nu->next) { + if ((nu->type & 7)==CU_BEZIER) { + BezTriple *bezt = nu->bezt; + + for (i=0; i<nu->pntsu; i++,bezt++) { + VECCOPY(co, bezt->vec[0]); co+=3; + VECCOPY(co, bezt->vec[1]); co+=3; + VECCOPY(co, bezt->vec[2]); co+=3; + } + } else { + BPoint *bp = nu->bp; + + for (i=0; i<nu->pntsu*nu->pntsv; i++,bp++) { + VECCOPY(co, bp->vec); co+=3; + } + } + } + + return cos; +} + +void curve_applyVertexCos(Curve *cu, ListBase *lb, float (*vertexCos)[3]) +{ + float *co = vertexCos[0]; + Nurb *nu; + int i; + + for (nu=lb->first; nu; nu=nu->next) { + if ((nu->type & 7)==CU_BEZIER) { + BezTriple *bezt = nu->bezt; + + for (i=0; i<nu->pntsu; i++,bezt++) { + VECCOPY(bezt->vec[0], co); co+=3; + VECCOPY(bezt->vec[1], co); co+=3; + VECCOPY(bezt->vec[2], co); co+=3; + } + } else { + BPoint *bp = nu->bp; + + for (i=0; i<nu->pntsu*nu->pntsv; i++,bp++) { + VECCOPY(bp->vec, co); co+=3; + } + } + } +} diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index e9c0a1ee252..4ee8fc2640f 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1417,65 +1417,13 @@ void makeDispListMBall(Object *ob) boundbox_displist(ob); } -float (*curve_getVertexCos(Curve *cu, ListBase *lb, int *numVerts_r))[3] -{ - int i, numVerts = *numVerts_r = count_curveverts(lb); - float *co, (*cos)[3] = MEM_mallocN(sizeof(*cos)*numVerts, "cu_vcos"); - Nurb *nu; - - co = cos[0]; - for (nu=lb->first; nu; nu=nu->next) { - if ((nu->type & 7)==CU_BEZIER) { - BezTriple *bezt = nu->bezt; - - for (i=0; i<nu->pntsu; i++,bezt++) { - VECCOPY(co, bezt->vec[0]); co+=3; - VECCOPY(co, bezt->vec[1]); co+=3; - VECCOPY(co, bezt->vec[2]); co+=3; - } - } else { - BPoint *bp = nu->bp; - - for (i=0; i<nu->pntsu*nu->pntsv; i++,bp++) { - VECCOPY(co, bp->vec); co+=3; - } - } - } - - return cos; -} - -void curve_applyVertexCos(Curve *cu, ListBase *lb, float (*vertexCos)[3]) -{ - float *co = vertexCos[0]; - Nurb *nu; - int i; - - for (nu=lb->first; nu; nu=nu->next) { - if ((nu->type & 7)==CU_BEZIER) { - BezTriple *bezt = nu->bezt; - - for (i=0; i<nu->pntsu; i++,bezt++) { - VECCOPY(bezt->vec[0], co); co+=3; - VECCOPY(bezt->vec[1], co); co+=3; - VECCOPY(bezt->vec[2], co); co+=3; - } - } else { - BPoint *bp = nu->bp; - - for (i=0; i<nu->pntsu*nu->pntsv; i++,bp++) { - VECCOPY(bp->vec, co); co+=3; - } - } - } -} - static ModifierData *curve_get_tesselate_point(Object *ob, int forRender, int editmode) { - ModifierData *md, *preTesselatePoint; + ModifierData *md = modifiers_getVirtualModifierList(ob); + ModifierData *preTesselatePoint; preTesselatePoint = NULL; - for (md=ob->modifiers.first; md; md=md->next) { + for (; md; md=md->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); if (!(md->mode&(1<<forRender))) continue; @@ -1493,13 +1441,14 @@ static ModifierData *curve_get_tesselate_point(Object *ob, int forRender, int ed void curve_calc_modifiers_pre(Object *ob, ListBase *nurb, int forRender, float (**originalVerts_r)[3], float (**deformedVerts_r)[3], int *numVerts_r) { int editmode = (!forRender && ob==G.obedit); - ModifierData *md, *preTesselatePoint = curve_get_tesselate_point(ob, forRender, editmode); + ModifierData *md = modifiers_getVirtualModifierList(ob); + ModifierData *preTesselatePoint = curve_get_tesselate_point(ob, forRender, editmode); int numVerts = 0; float (*originalVerts)[3] = NULL; float (*deformedVerts)[3] = NULL; if (preTesselatePoint) { - for (md=ob->modifiers.first; md; md=md->next) { + for (; md; md=md->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); if (!(md->mode&(1<<forRender))) continue; @@ -1516,8 +1465,6 @@ void curve_calc_modifiers_pre(Object *ob, ListBase *nurb, int forRender, float ( if (md==preTesselatePoint) break; } - } else { - md = ob->modifiers.first; } if (deformedVerts) { @@ -1532,13 +1479,12 @@ void curve_calc_modifiers_pre(Object *ob, ListBase *nurb, int forRender, float ( void curve_calc_modifiers_post(Object *ob, ListBase *nurb, ListBase *dispbase, int forRender, float (*originalVerts)[3], float (*deformedVerts)[3]) { int editmode = (!forRender && ob==G.obedit); - ModifierData *md, *preTesselatePoint = curve_get_tesselate_point(ob, forRender, editmode); + ModifierData *md = modifiers_getVirtualModifierList(ob); + ModifierData *preTesselatePoint = curve_get_tesselate_point(ob, forRender, editmode); DispList *dl; if (preTesselatePoint) { md = preTesselatePoint->next; - } else { - md = ob->modifiers.first; } for (; md; md=md->next) { diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 8f463886b3f..df0f9e7d8f8 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -46,6 +46,7 @@ #include "DNA_armature_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_lattice_types.h" @@ -62,6 +63,7 @@ #include "BKE_lattice.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_modifier.h" #include "BKE_object.h" #include "BKE_screen.h" #include "BKE_utildefines.h" @@ -74,45 +76,120 @@ #include "blendef.h" -Lattice *editLatt=0, *deformLatt=0; +Lattice *editLatt=0; +static Lattice *deformLatt=0; -float *latticedata=0, latmat[4][4]; +static float *latticedata=0, latmat[4][4]; -void resizelattice(Lattice *lt) +void calc_lat_fudu(int flag, int res, float *fu, float *du) +{ + if(res==1) { + *fu= 0.0; + *du= 0.0; + } + else if(flag & LT_GRID) { + *fu= -0.5f*(res-1); + *du= 1.0f; + } + else { + *fu= -1.0f; + *du= 2.0f/(res-1); + } +} + +void resizelattice(Lattice *lt, int uNew, int vNew, int wNew, Object *ltOb) { BPoint *bp; - int u, v, w; - float vec[3], fu, fv, fw, du=0.0, dv=0.0, dw=0.0; + int i, u, v, w; + float fu, fv, fw, uc, vc, wc, du=0.0, dv=0.0, dw=0.0; + float *co, (*vertexCos)[3] = NULL; + + while(uNew*vNew*wNew > 32000) { + if( uNew>=vNew && uNew>=wNew) uNew--; + else if( vNew>=uNew && vNew>=wNew) vNew--; + else wNew--; + } + + vertexCos = MEM_mallocN(sizeof(*vertexCos)*uNew*vNew*wNew, "tmp_vcos"); + + calc_lat_fudu(lt->flag, uNew, &fu, &du); + calc_lat_fudu(lt->flag, vNew, &fv, &dv); + calc_lat_fudu(lt->flag, wNew, &fw, &dw); + + /* If old size is different then resolution changed in interface, + * try to do clever reinit of points. Pretty simply idea, we just + * deform new verts by old lattice, but scaling them to match old + * size first. + */ + if (ltOb) { + if (uNew!=1 && lt->pntsu!=1) { + fu = lt->fu; + du = (lt->pntsu-1)*lt->du/(uNew-1); + } + + if (vNew!=1 && lt->pntsv!=1) { + fv = lt->fv; + dv = (lt->pntsv-1)*lt->dv/(vNew-1); + } + + if (wNew!=1 && lt->pntsw!=1) { + fw = lt->fw; + dw = (lt->pntsw-1)*lt->dw/(wNew-1); + } + } + + co = vertexCos[0]; + for(w=0,wc=fw; w<wNew; w++,wc+=dw) { + for(v=0,vc=fv; v<vNew; v++,vc+=dv) { + for(u=0,uc=fu; u<uNew; u++,co+=3,uc+=du) { + co[0] = uc; + co[1] = vc; + co[2] = wc; + } + } + } + if (ltOb) { + float mat[4][4]; + int typeu = lt->typeu, typev = lt->typev, typew = lt->typew; + + /* works best if we force to linear type (endpoints match) */ + lt->typeu = lt->typev = lt->typew = KEY_LINEAR; + + /* prevent using deformed locations */ + freedisplist(<Ob->disp); + + Mat4CpyMat4(mat, ltOb->obmat); + Mat4One(ltOb->obmat); + lattice_deform_verts(ltOb, NULL, vertexCos, uNew*vNew*wNew); + Mat4CpyMat4(ltOb->obmat, mat); + + lt->typeu = typeu; + lt->typev = typev; + lt->typew = typew; + } + + lt->fu = fu; + lt->fv = fv; + lt->fw = fw; + lt->du = du; + lt->dv = dv; + lt->dw = dw; + + lt->pntsu = uNew; + lt->pntsv = vNew; + lt->pntsw = wNew; MEM_freeN(lt->def); lt->def= MEM_callocN(lt->pntsu*lt->pntsv*lt->pntsw*sizeof(BPoint), "lattice bp"); bp= lt->def; - while(lt->pntsu*lt->pntsv*lt->pntsw > 32000) { - if( lt->pntsu>=lt->pntsv && lt->pntsu>=lt->pntsw) lt->pntsu--; - else if( lt->pntsv>=lt->pntsu && lt->pntsv>=lt->pntsw) lt->pntsv--; - else lt->pntsw--; - } - - calc_lat_fudu(lt->flag, lt->pntsu, &fu, &du); - calc_lat_fudu(lt->flag, lt->pntsv, &fv, &dv); - calc_lat_fudu(lt->flag, lt->pntsw, &fw, &dw); - - vec[2]= fw; - for(w=0; w<lt->pntsw; w++) { - vec[1]= fv; - for(v=0; v<lt->pntsv; v++) { - vec[0]= fu; - for(u=0; u<lt->pntsu; u++, bp++) { - VECCOPY(bp->vec, vec); - vec[0]+= du; - } - vec[1]+= dv; - } - vec[2]+= dw; + for (i=0; i<lt->pntsu*lt->pntsv*lt->pntsw; i++,bp++) { + VECCOPY(bp->vec, vertexCos[i]); } + + MEM_freeN(vertexCos); } Lattice *add_lattice() @@ -121,15 +198,12 @@ Lattice *add_lattice() lt= alloc_libblock(&G.main->latt, ID_LT, "Lattice"); - lt->pntsu=lt->pntsv=lt->pntsw= 2; lt->flag= LT_GRID; lt->typeu= lt->typev= lt->typew= KEY_BSPLINE; - /* temporally */ - lt->def= MEM_callocN(sizeof(BPoint), "lattvert"); - - resizelattice(lt); /* creates a uniform lattice */ + lt->def= MEM_callocN(sizeof(BPoint), "lattvert"); /* temporary */ + resizelattice(lt, 2, 2, 2, NULL); /* creates a uniform lattice */ return lt; } @@ -207,45 +281,20 @@ void make_local_lattice(Lattice *lt) } } - - -void calc_lat_fudu(int flag, int res, float *fu, float *du) -{ - - if(res==1) { - *fu= 0.0; - *du= 0.0; - } - else if(flag & LT_GRID) { - *fu= -0.5f*(res-1); - *du= 1.0f; - } - else { - *fu= -1.0f; - *du= 2.0f/(res-1); - } - -} - void init_latt_deform(Object *oblatt, Object *ob) { - /* we make an array with all differences */ - BPoint *bp; + /* we make an array with all differences */ + Lattice *lt = deformLatt = (oblatt==G.obedit)?editLatt:oblatt->data; + BPoint *bp = lt->def; + DispList *dl = find_displist(&oblatt->disp, DL_VERTS); + float *co = dl?dl->verts:NULL; float *fp, imat[4][4]; - float vec[3], fu, fv, fw, du=0.0, dv=0.0, dw=0.0; + float fu, fv, fw; int u, v, w; - - if(oblatt==G.obedit) deformLatt= editLatt; - else deformLatt= oblatt->data; - + fp= latticedata= MEM_mallocN(sizeof(float)*3*deformLatt->pntsu*deformLatt->pntsv*deformLatt->pntsw, "latticedata"); - do_latt_key(oblatt->data); - bp= deformLatt->def; - - //if(ob) where_is_object(ob); causes lag here, but why! (ton) - - /* for example with a particle system: ob==0 */ + /* for example with a particle system: ob==0 */ if(ob==0) { /* in deformspace, calc matrix */ Mat4Invert(latmat, oblatt->obmat); @@ -261,35 +310,30 @@ void init_latt_deform(Object *oblatt, Object *ob) /* back: put in deform array */ Mat4Invert(imat, latmat); } - calc_lat_fudu(deformLatt->flag, deformLatt->pntsu, &fu, &du); - calc_lat_fudu(deformLatt->flag, deformLatt->pntsv, &fv, &dv); - calc_lat_fudu(deformLatt->flag, deformLatt->pntsw, &fw, &dw); - - /* we keep calculating the u v w lattice coordinates, not enough reason to store that */ - vec[2]= fw; - for(w=0; w<deformLatt->pntsw; w++) { - vec[1]= fv; - for(v=0; v<deformLatt->pntsv; v++) { - vec[0]= fu; - for(u=0; u<deformLatt->pntsu; u++, bp++) { - - VecSubf(fp, bp->vec, vec); + for(w=0,fw=lt->fw; w<lt->pntsw; w++,fw+=lt->dw) { + for(v=0,fv=lt->fv; v<lt->pntsv; v++, fv+=lt->dv) { + for(u=0,fu=lt->fu; u<lt->pntsu; u++, bp++, co+=3, fp+=3, fu+=lt->du) { + if (dl) { + fp[0] = co[0] - fu; + fp[1] = co[1] - fv; + fp[2] = co[2] - fw; + } else { + fp[0] = bp->vec[0] - fu; + fp[1] = bp->vec[1] - fv; + fp[2] = bp->vec[2] - fw; + } + Mat4Mul3Vecfl(imat, fp); - - vec[0]+= du; - fp+= 3; } - vec[1]+= dv; } - vec[2]+= dw; } } void calc_latt_deform(float *co) { Lattice *lt; - float fu, du, u, v, w, tu[4], tv[4], tw[4]; + float u, v, w, tu[4], tv[4], tw[4]; float *fpw, *fpv, *fpu, vec[3]; int ui, vi, wi, uu, vv, ww; @@ -305,8 +349,7 @@ void calc_latt_deform(float *co) /* u v w coords */ if(lt->pntsu>1) { - calc_lat_fudu(lt->flag, lt->pntsu, &fu, &du); - u= (vec[0]-fu)/du; + u= (vec[0]-lt->fu)/lt->du; ui= (int)floor(u); u -= ui; set_four_ipo(u, tu, lt->typeu); @@ -317,8 +360,7 @@ void calc_latt_deform(float *co) } if(lt->pntsv>1) { - calc_lat_fudu(lt->flag, lt->pntsv, &fu, &du); - v= (vec[1]-fu)/du; + v= (vec[1]-lt->fv)/lt->dv; vi= (int)floor(v); v -= vi; set_four_ipo(v, tv, lt->typev); @@ -329,8 +371,7 @@ void calc_latt_deform(float *co) } if(lt->pntsw>1) { - calc_lat_fudu(lt->flag, lt->pntsw, &fu, &du); - w= (vec[2]-fu)/du; + w= (vec[2]-lt->fw)/lt->dw; wi= (int)floor(w); w -= wi; set_four_ipo(w, tw, lt->typew); @@ -568,7 +609,7 @@ int object_deform_mball(Object *ob) } } -BPoint *latt_bp(Lattice *lt, int u, int v, int w) +static BPoint *latt_bp(Lattice *lt, int u, int v, int w) { return lt->def+ u + v*lt->pntsu + w*lt->pntsu*lt->pntsv; } @@ -633,3 +674,61 @@ void outside_lattice(Lattice *lt) } } + +float (*lattice_getVertexCos(struct Object *ob, int *numVerts_r))[3] +{ + Lattice *lt = (G.obedit==ob)?editLatt:ob->data; + int i, numVerts = *numVerts_r = lt->pntsu*lt->pntsv*lt->pntsw; + float (*vertexCos)[3] = MEM_mallocN(sizeof(*vertexCos)*numVerts,"lt_vcos"); + + for (i=0; i<numVerts; i++) { + VECCOPY(vertexCos[i], lt->def[i].vec); + } + + return vertexCos; +} + +void lattice_applyVertexCos(struct Object *ob, float (*vertexCos)[3]) +{ + Lattice *lt = ob->data; + int i, numVerts = lt->pntsu*lt->pntsv*lt->pntsw; + + for (i=0; i<numVerts; i++) { + VECCOPY(lt->def[i].vec, vertexCos[i]); + } +} + +void lattice_calc_modifiers(Object *ob) +{ + float (*vertexCos)[3] = NULL; + ModifierData *md = modifiers_getVirtualModifierList(ob); + int numVerts, editmode = G.obedit==ob; + + freedisplist(&ob->disp); + + if (!editmode) { + do_latt_key(ob->data); + } + + for (; md; md=md->next) { + ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + if (!(md->mode&(1<<0))) continue; + if (editmode && !(md->mode&eModifierMode_Editmode)) continue; + if (mti->isDisabled && mti->isDisabled(md)) continue; + if (mti->type!=eModifierTypeType_OnlyDeform) continue; + + if (!vertexCos) vertexCos = lattice_getVertexCos(ob, &numVerts); + mti->deformVerts(md, ob, NULL, vertexCos, numVerts); + } + + if (vertexCos) { + DispList *dl = MEM_callocN(sizeof(*dl), "lt_dl"); + dl->type = DL_VERTS; + dl->parts = 1; + dl->nr = numVerts; + dl->verts = (float*) vertexCos; + + BLI_addtail(&ob->disp, dl); + } +} diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 8c5354b47e8..55f62446bfd 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -1172,7 +1172,7 @@ static void softbodyModifier_deformVerts(ModifierData *md, Object *ob, void *der { SoftbodyModifierData *hmd = (SoftbodyModifierData*) md; - sbObjectStep(ob, (float)G.scene->r.cfra, vertexCos); + sbObjectStep(ob, (float)G.scene->r.cfra, vertexCos, numVerts); } /***/ diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index a43ae4e2978..68f75234c3d 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1762,6 +1762,9 @@ void object_handle_update(Object *ob) else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { makeDispListCurveTypes(ob, 0); } + else if(ob->type==OB_LATTICE) { + lattice_calc_modifiers(ob); + } else if(ob->type==OB_ARMATURE) { /* this actually only happens for reading old files... */ if(ob->pose==NULL || (ob->pose->flag & POSE_RECALC)) diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 86ec2cc0705..7833f968c76 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -85,6 +85,21 @@ extern int get_defgroup_num (Object *ob, bDeformGroup *dg); /* ********** soft body engine ******* */ + +typedef struct BodyPoint { + float origS[3], origE[3], origT[3], pos[3], vec[3], force[3]; + float weight, goal; + float prevpos[3], prevvec[3], prevdx[3], prevdv[3]; /* used for Heun integration */ + int nofsprings; int *springs; + float contactfrict; +} BodyPoint; + +typedef struct BodySpring { + int v1, v2; + float len, strength; +} BodySpring; + + #define SOFTGOALSNAP 0.999f // if bp-> goal is above make it a *forced follow original* and skip all ODE stuff for this bp // removes *unnecessary* stiffnes from ODE system @@ -179,12 +194,10 @@ static void add_mesh_quad_diag_springs(Object *ob) bs->v1= mface->v1; bs->v2= mface->v3; bs->strength= 1.0; - bs->len= VecLenf( (bp+bs->v1)->origS, (bp+bs->v2)->origS); bs++; bs->v1= mface->v2; bs->v2= mface->v4; bs->strength= 1.0; - bs->len= VecLenf( (bp+bs->v1)->origS, (bp+bs->v2)->origS); bs++; } @@ -245,10 +258,10 @@ static void build_bps_springlist(Object *ob) /* creates new softbody if didn't exist yet, makes new points and springs arrays */ -/* called in mesh_to_softbody */ static void renew_softbody(Object *ob, int totpoint, int totspring) { SoftBody *sb; + int i; if(ob->soft==NULL) ob->soft= sbNew(); else free_softbody_intern(ob->soft); @@ -261,6 +274,24 @@ static void renew_softbody(Object *ob, int totpoint, int totspring) sb->bpoint= MEM_mallocN( totpoint*sizeof(BodyPoint), "bodypoint"); if(totspring) sb->bspring= MEM_mallocN( totspring*sizeof(BodySpring), "bodyspring"); + + /* initialise BodyPoint array */ + for (i=0; i<totpoint; i++) { + BodyPoint *bp = &sb->bpoint[i]; + + bp->weight= 1.0; + if(ob->softflag & OB_SB_GOAL) { + bp->goal= ob->soft->defgoal; + } + else { + bp->goal= 0.0f; + /* so this will definily be below SOFTGOALSNAP */ + } + + bp->nofsprings= 0; + bp->springs= NULL; + bp->contactfrict = 0.0f; + } } } @@ -723,94 +754,9 @@ static void interpolate_exciter(Object *ob, int timescale, int time) /* ************ convertors ********** */ /* for each object type we need; - - xxxx_to_softbody(Object *ob) : a full (new) copy - - xxxx_update_softbody(Object *ob) : update refreshes current positions - - softbody_to_xxxx(Object *ob) : after simulation, copy vertex locations back + - xxxx_to_softbody(Object *ob) : a full (new) copy, creates SB geometry */ -/* helper call */ -static int object_has_edges(Object *ob) -{ - if(ob->type==OB_MESH) { - Mesh *me= ob->data; - if(me->medge) return 1; - } - else if(ob->type==OB_LATTICE) { - ; - } - - return 0; -} - -/* helper call */ -static void set_body_point(Object *ob, BodyPoint *bp, float *vec) -{ - VECCOPY(bp->pos, vec); - Mat4MulVecfl(ob->obmat, bp->pos); // yep, sofbody is global coords - VECCOPY(bp->origS, bp->pos); - VECCOPY(bp->origE, bp->pos); - VECCOPY(bp->origT, bp->pos); - - bp->vec[0]= bp->vec[1]= bp->vec[2]= 0.0; - bp->weight= 1.0; - if(ob->softflag & OB_SB_GOAL) { - bp->goal= ob->soft->defgoal; - } - else { - bp->goal= 0.0f; - /* so this will definily be below SOFTGOALSNAP */ - } - - bp->nofsprings= 0; - bp->springs= NULL; - bp->contactfrict = 0.0f; -} - - -/* copy original (new) situation in softbody, as result of matrices or deform */ -/* is assumed to enter function with ob->soft, but can be without points */ -static void mesh_update_softbody(Object *ob, float (*vertexCos)[3]) -{ - Mesh *me= ob->data; - BodyPoint *bp; - int a; - - /* possible after a file read... */ - if(ob->soft->bpoint==NULL) sbObjectToSoftbody(ob, NULL); - - if(me->totvert) { - bp= ob->soft->bpoint; - for(a=0; a<me->totvert; a++, bp++) { - VECCOPY(bp->origS, bp->origE); - if (vertexCos) { - VECCOPY(bp->origE, vertexCos[a]); - } else { - VECCOPY(bp->origE, me->mvert[a].co); - } - Mat4MulVecfl(ob->obmat, bp->origE); - VECCOPY(bp->origT, bp->origE); - } - - if(ob->softflag & OB_SB_EDGES) { - - /* happens when in UI edges was set */ - if(ob->soft->bspring==NULL) - if(object_has_edges(ob)) sbObjectToSoftbody(ob, NULL); - - /* hrms .. do springs alter their lenght ? (yes, mesh keys would (ton)) - if(medge) { - bs= ob->soft->bspring; - bp= ob->soft->bpoint; - for(a=0; (a<me->totedge && a < ob->soft->totspring ); a++, medge++, bs++) { - bs->len= VecLenf( (bp+bs->v1)->origE, (bp+bs->v2)->origE); - } - } - */ - } - } -} - - static void get_scalar_from_vertexgroup(Object *ob, int vertID, short groupindex, float *target) /* result 0 on success, else indicates error number -- kind of *inverse* result defintion, @@ -837,7 +783,7 @@ static void get_scalar_from_vertexgroup(Object *ob, int vertID, short groupindex } /* makes totally fresh start situation */ -static void mesh_to_softbody(Object *ob, float (*vertexCos)[3]) +static void mesh_to_softbody(Object *ob) { SoftBody *sb; Mesh *me= ob->data; @@ -859,12 +805,6 @@ static void mesh_to_softbody(Object *ob, float (*vertexCos)[3]) goalfac= ABS(sb->maxgoal - sb->mingoal); for(a=0; a<me->totvert; a++, bp++) { - if (vertexCos) { - set_body_point(ob, bp, vertexCos[a]); - } else { - set_body_point(ob, bp, me->mvert[a].co); - } - /* get scalar values needed *per vertex* from vertex group functions, so we can *paint* them nicly .. they are normalized [0.0..1.0] so may be we need amplitude for scale @@ -891,12 +831,10 @@ static void mesh_to_softbody(Object *ob, float (*vertexCos)[3]) if (ob->softflag & OB_SB_EDGES) { if(medge) { bs= sb->bspring; - bp= sb->bpoint; for(a=me->totedge; a>0; a--, medge++, bs++) { bs->v1= medge->v1; bs->v2= medge->v2; bs->strength= 1.0; - bs->len= VecLenf( (bp+bs->v1)->origS, (bp+bs->v2)->origS); } @@ -911,19 +849,6 @@ static void mesh_to_softbody(Object *ob, float (*vertexCos)[3]) } -/* copies current sofbody position in mesh, so do this within modifier stacks! */ -static void softbody_to_mesh(Object *ob, float (*vertexCos)[3]) -{ - Mesh *me= ob->data; - BodyPoint *bp= ob->soft->bpoint; - int a; - - for(a=me->totvert; a>0; a--, bp++, vertexCos++) { - VECCOPY(vertexCos[0], bp->pos); - Mat4MulVecfl(ob->imat, vertexCos[0]); // softbody is in global coords - } -} - static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff) { @@ -1021,23 +946,17 @@ static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff) /* makes totally fresh start situation */ static void lattice_to_softbody(Object *ob) { - SoftBody *sb; - BodySpring *bs; Lattice *lt= ob->data; - BodyPoint *bop; - BPoint *bp; - int a, totvert, totspring = 0; + int totvert, totspring = 0; totvert= lt->pntsu*lt->pntsv*lt->pntsw; if (ob->softflag & OB_SB_EDGES){ - totspring = ((lt->pntsu -1) * lt->pntsv + (lt->pntsv -1) * lt->pntsu) * lt->pntsw +lt->pntsu*lt->pntsv*(lt->pntsw -1); if (ob->softflag & OB_SB_QUADS){ - totspring += 4*(lt->pntsu -1) * (lt->pntsv -1) * (lt->pntsw-1); - + totspring += 4*(lt->pntsu -1) * (lt->pntsv -1) * (lt->pntsw-1); } } @@ -1045,110 +964,31 @@ static void lattice_to_softbody(Object *ob) /* renew ends with ob->soft with points and edges, also checks & makes ob->soft */ renew_softbody(ob, totvert, totspring); - /* we always make body points */ - sb= ob->soft; - - for(a= totvert, bp= lt->def, bop= sb->bpoint; a>0; a--, bp++, bop++) { - set_body_point(ob, bop, bp->vec); - } - /* create some helper edges to enable SB lattice to be usefull at all */ if (ob->softflag & OB_SB_EDGES){ - bs = sb->bspring; - makelatticesprings(lt,bs,ob->softflag & OB_SB_QUADS); + makelatticesprings(lt,ob->soft->bspring,ob->softflag & OB_SB_QUADS); build_bps_springlist(ob); /* link bps to springs */ - - /* recalculate lenght since BPoint and Bodypoint obviously can differ */ - bs= ob->soft->bspring; - bop= ob->soft->bpoint; - for(a=0; a < totspring ; a++, bs++) { - bs->len= VecLenf( (bop+bs->v1)->origE, (bop+bs->v2)->origE); - } - - } - -} - -/* copies current sofbody position */ -static void softbody_to_lattice(Object *ob) -{ - SoftBody *sb; - Lattice *lt= ob->data; - BodyPoint *bop; - BPoint *bp; - int a, totvert; - - totvert= lt->pntsu*lt->pntsv*lt->pntsw; - sb= ob->soft; - - for(a= totvert, bp= lt->def, bop= sb->bpoint; a>0; a--, bp++, bop++) { - VECCOPY(bp->vec, bop->pos); - Mat4MulVecfl(ob->imat, bp->vec); // softbody is in global coords } } -/* copy original (new) situation in softbody, as result of matrices or deform */ -/* is assumed to enter function with ob->soft, but can be without points */ -static void lattice_update_softbody(Object *ob) -{ - Lattice *lt= ob->data; - BodyPoint *bop; - BPoint *bp; - int a, totvert; - - totvert= lt->pntsu*lt->pntsv*lt->pntsw; - - /* possible after a file read... */ - if(ob->soft->bpoint==NULL) sbObjectToSoftbody(ob, NULL); - - for(a= totvert, bp= lt->def, bop= ob->soft->bpoint; a>0; a--, bp++, bop++) { - VECCOPY(bop->origS, bop->origE); - VECCOPY(bop->origE, bp->vec); - Mat4MulVecfl(ob->obmat, bop->origE); - VECCOPY(bop->origT, bop->origE); - } -} - /* copies softbody result back in object */ -/* only used in sbObjectStep() */ -static void softbody_to_object(Object *ob, float (*vertexCos)[3]) +static void softbody_to_object(Object *ob, float (*vertexCos)[3], int numVerts) { - - if(ob->soft==NULL) return; - + BodyPoint *bp= ob->soft->bpoint; + int a; + /* inverse matrix is not uptodate... */ Mat4Invert(ob->imat, ob->obmat); - switch(ob->type) { - case OB_MESH: - softbody_to_mesh(ob, vertexCos); - break; - case OB_LATTICE: - softbody_to_lattice(ob); - break; - } -} - -/* copy original (new) situation in softbody, as result of matrices or deform */ -/* used in sbObjectStep() and sbObjectReset() */ -/* assumes to have ob->soft, but can be entered without points */ -static void object_update_softbody(Object *ob, float (*vertexCos)[3]) -{ - - switch(ob->type) { - case OB_MESH: - mesh_update_softbody(ob, vertexCos); - break; - case OB_LATTICE: - lattice_update_softbody(ob); - break; + for(a=0; a<numVerts; a++, bp++) { + VECCOPY(vertexCos[a], bp->pos); + Mat4MulVecfl(ob->imat, vertexCos[a]); // softbody is in global coords } - } /* return 1 if succesfully baked and applied step */ -static int softbody_baked_step(Object *ob, float framenr, float (*vertexCos)[3]) +static int softbody_baked_step(Object *ob, float framenr, float (*vertexCos)[3], int numVerts) { SoftBody *sb= ob->soft; SBVertex *key0, *key1, *key2, *key3; @@ -1200,7 +1040,7 @@ static int softbody_baked_step(Object *ob, float framenr, float (*vertexCos)[3]) bp->pos[2]= data[0]*key0->vec[2] + data[1]*key1->vec[2] + data[2]*key2->vec[2] + data[3]*key3->vec[2]; } - softbody_to_object(ob, vertexCos); + softbody_to_object(ob, vertexCos, numVerts); return 1; } @@ -1293,79 +1133,68 @@ void sbFree(SoftBody *sb) /* makes totally fresh start situation */ -void sbObjectToSoftbody(Object *ob, float (*vertexCos)[3]) +void sbObjectToSoftbody(Object *ob) { + ob->softflag |= OB_SB_REDO; +} +static void convert_object_to_sb(Object *ob, int numVerts) +{ switch(ob->type) { case OB_MESH: - mesh_to_softbody(ob, vertexCos); + mesh_to_softbody(ob); break; case OB_LATTICE: lattice_to_softbody(ob); break; + default: + renew_softbody(ob, numVerts, 0); + break; } - if(ob->soft) ob->soft->ctime= bsystem_time(ob, NULL, (float)G.scene->r.cfra, 0.0); ob->softflag &= ~OB_SB_REDO; + + /* still need to update to correct vertex locations, happens on next step */ + ob->softflag |= OB_SB_RESET; } -/* reset all motion */ -void sbObjectReset(Object *ob, float (*vertexCos)[3]) +static int object_has_edges(Object *ob) { - SoftBody *sb= ob->soft; - BodyPoint *bp; - int a; - - if(sb==NULL) return; - if(sb->keys && sb->totkey) return; // only as cpu time saver - - sb->ctime= bsystem_time(ob, NULL, (float)G.scene->r.cfra, 0.0); - - object_update_softbody(ob, vertexCos); - - for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) { - // origS is previous timestep - VECCOPY(bp->origS, bp->origE); - VECCOPY(bp->pos, bp->origE); - VECCOPY(bp->origT, bp->origE); - bp->vec[0]= bp->vec[1]= bp->vec[2]= 0.0f; - - // no idea about the Heun stuff! (ton) - VECCOPY(bp->prevpos, bp->pos); - VECCOPY(bp->prevvec, bp->vec); - VECCOPY(bp->prevdx, bp->vec); - VECCOPY(bp->prevdv, bp->vec); + if(ob->type==OB_MESH) { + Mesh *me= ob->data; + return (me->medge && me->totedge); + } + else if(ob->type==OB_LATTICE) { + return 1; + } + else { + return 0; } } - /* simulates one step. framenr is in frames */ -/* copies result back to object, displist */ -void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3]) +void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts) { SoftBody *sb; Base *base; + BodyPoint *bp; float dtime; - int timescale,t; + int a,timescale,t; float ctime, forcetime; float err; - - /* this variable is set while transform(). with lattices also having a softbody, - it calls lattice_modifier() all the time... has no displist yet. Is temporal - hack which should be resolved with proper depgraph usage + storage of deformed - vertices in lattice (ton) */ - if(G.moving) return; /* baking works with global time */ if(!(ob->softflag & OB_SB_BAKEDO) ) - if(softbody_baked_step(ob, framenr, vertexCos) ) return; - - /* remake softbody if: */ - if( (ob->softflag & OB_SB_REDO) || // signal after weightpainting - (ob->soft==NULL) || // just to be nice we allow full init - (ob->soft->bpoint==NULL) ) // after reading new file, or acceptable as signal to refresh - sbObjectToSoftbody(ob, vertexCos); + if(softbody_baked_step(ob, framenr, vertexCos, numVerts) ) return; + /* remake softbody if: */ + if( (ob->softflag & OB_SB_REDO) || // signal after weightpainting + (ob->soft==NULL) || // just to be nice we allow full init + (ob->soft->bpoint==NULL) || // after reading new file, or acceptable as signal to refresh + (numVerts!=ob->soft->totpoint) || // should never happen, just to be safe + ((ob->softflag & OB_SB_EDGES) && !ob->soft->bspring && object_has_edges(ob))) // happens when in UI edges was set + convert_object_to_sb(ob, numVerts); + sb= ob->soft; /* still no points? go away */ @@ -1377,23 +1206,53 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3]) } /* checking time: */ + ctime= bsystem_time(ob, NULL, framenr, 0.0); - dtime= ctime - sb->ctime; - // bail out for negative or for large steps - if(dtime<0.0 || dtime >= 9.9*G.scene->r.framelen) { // G.scene->r.framelen corrects for frame-mapping, so this is actually 10 frames for UI - sbObjectReset(ob, vertexCos); - return; + + if (ob->softflag&OB_SB_RESET) { + dtime = 0.0; + } else { + dtime= ctime - sb->ctime; } - + /* the simulator */ - - if(dtime > 0.0) { // note: what does this mean now? (ton) - //answer (BM) : - //dtime is still in [frames] - //we made sure dtime is >= 0.0 - //but still need to handle dtime == 0.0 -> just return sb as is, just to be nice - object_update_softbody(ob, vertexCos); - + + /* update the vertex locations */ + if (dtime!=0.0) { + for(a=0,bp=sb->bpoint; a<numVerts; a++, bp++) { + VECCOPY(bp->origS, bp->origE); + VECCOPY(bp->origE, vertexCos[a]); + Mat4MulVecfl(ob->obmat, bp->origE); + VECCOPY(bp->origT, bp->origE); + } + } + + // G.scene->r.framelen corrects for frame-mapping, so this is actually 10 frames for UI + if((ob->softflag&OB_SB_RESET) || dtime<0.0 || dtime>=9.9*G.scene->r.framelen) { + for(a=0,bp=sb->bpoint; a<numVerts; a++, bp++) { + VECCOPY(bp->pos, vertexCos[a]); + Mat4MulVecfl(ob->obmat, bp->pos); // yep, sofbody is global coords + VECCOPY(bp->origS, bp->pos); + VECCOPY(bp->origE, bp->pos); + VECCOPY(bp->origT, bp->pos); + bp->vec[0]= bp->vec[1]= bp->vec[2]= 0.0f; + + // no idea about the Heun stuff! (ton) + VECCOPY(bp->prevpos, bp->pos); + VECCOPY(bp->prevvec, bp->vec); + VECCOPY(bp->prevdx, bp->vec); + VECCOPY(bp->prevdv, bp->vec); + } + + for(a=0; a<sb->totspring; a++) { + BodySpring *bs = &sb->bspring[a]; + + bs->len= VecLenf(sb->bpoint[bs->v1].origS, sb->bpoint[bs->v2].origS); + } + + ob->softflag &= ~OB_SB_RESET; + } + else if(dtime>0.0) { if (TRUE) { // RSOL1 always true now (ton) /* special case of 2nd order Runge-Kutta type AKA Heun */ float timedone =0.0; // how far did we get without violating error condition @@ -1486,20 +1345,11 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3]) } } } - - /* and apply to vertices */ - softbody_to_object(ob, vertexCos); - - sb->ctime= ctime; - } // if(ABS(dtime) > 0.0) - else { - // rule : you have asked for the current state of the softobject - // since dtime= ctime - ob->soft->ctime== 0.0; - // and we were not notifified about any other time changes - // so here it is ! - softbody_to_object(ob, vertexCos); } + softbody_to_object(ob, vertexCos, numVerts); + sb->ctime= ctime; + /* reset deflector cache */ for(base= G.scene->base.first; base; base= base->next) { if(base->object->sumohandle) { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 7a6928dadb4..8075cdc9dc1 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -119,6 +119,7 @@ #include "BKE_effect.h" // for give_parteff #include "BKE_global.h" // for G #include "BKE_property.h" // for get_property +#include "BKE_lattice.h" #include "BKE_library.h" // for wich_libbase #include "BKE_main.h" // for Main #include "BKE_mesh.h" // for ME_ defines (patching) @@ -4863,7 +4864,18 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } } - } + } + if(main->versionfile <= 238) { + Lattice *lt; + + for (lt=main->latt.first; lt; lt=lt->id.next) { + if (lt->fu==0.0 && lt->fv==0.0 && lt->fw==0.0) { + calc_lat_fudu(lt->flag, lt->pntsu, <->fu, <->du); + calc_lat_fudu(lt->flag, lt->pntsv, <->fv, <->dv); + calc_lat_fudu(lt->flag, lt->pntsw, <->fw, <->dw); + } + } + } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */ diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index e849cdbf114..66914c07ed0 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -422,6 +422,7 @@ enum { #define B_RESIZELAT 2601 #define B_DRAWLAT 2602 #define B_LATTCHANGED 2603 +#define B_REGULARLAT 2604 /* *********************** */ #define B_GAMEBUTS 2800 diff --git a/source/blender/makesdna/DNA_lattice_types.h b/source/blender/makesdna/DNA_lattice_types.h index fc71982fb0e..3d77e7feb02 100644 --- a/source/blender/makesdna/DNA_lattice_types.h +++ b/source/blender/makesdna/DNA_lattice_types.h @@ -42,14 +42,16 @@ typedef struct Lattice { ID id; short pntsu, pntsv, pntsw, flag; + short opntsu, opntsv, opntsw, pad2; char typeu, typev, typew, type; int pad; + float fu, fv, fw, du, dv, dw; + struct BPoint *def; struct Ipo *ipo; struct Key *key; - } Lattice; /* ***************** LATTICE ********************* */ diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index 334d4b44aa6..3396c59a53a 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -118,6 +118,7 @@ typedef struct SoftBody { #define OB_SB_REDO 32 #define OB_SB_BAKESET 64 #define OB_SB_BAKEDO 128 +#define OB_SB_RESET 256 #ifdef __cplusplus } diff --git a/source/blender/python/api2_2x/Lattice.c b/source/blender/python/api2_2x/Lattice.c index 87e0c3ae168..7110944fd31 100644 --- a/source/blender/python/api2_2x/Lattice.c +++ b/source/blender/python/api2_2x/Lattice.c @@ -423,10 +423,7 @@ static PyObject *Lattice_setPartitions( BPy_Lattice * self, PyObject * args ) return ( EXPP_ReturnPyObjError( PyExc_RuntimeError, "partition values must be 2 or greater" ) ); - bl_Lattice->pntsu = ( short ) x; - bl_Lattice->pntsv = ( short ) y; - bl_Lattice->pntsw = ( short ) z; - resizelattice( bl_Lattice ); + resizelattice(bl_Lattice, x, y, z, NULL); Py_INCREF( Py_None ); return Py_None; diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 9f9515d5202..6f805a89a7e 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -75,6 +75,7 @@ #include "BKE_depsgraph.h" #include "BKE_global.h" +#include "BKE_curve.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_modifier.h" @@ -511,6 +512,7 @@ void do_modifier_panels(unsigned short event) break; case B_MODIFIER_RECALC: + ob->softflag |= OB_SB_RESET; allqueue(REDRAWBUTSEDIT, 0); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWOOPS, 0); @@ -700,8 +702,8 @@ static void modifiers_applyModifier(void *obv, void *mdv) if (G.obedit) { error("Modifiers cannot be applied in editmode"); return; - } else if (me->id.us>1) { - error("Modifiers cannot be applied to a multi-user mesh"); + } else if (((ID*) ob->data)->us>1) { + error("Modifiers cannot be applied to multi-user data"); return; } @@ -710,29 +712,54 @@ static void modifiers_applyModifier(void *obv, void *mdv) return; } - // XXX, only for mesh - - dm = mesh_create_derived_for_modifier(ob, md); - if (!dm) { - error("Modifier is disabled or returned error, skipping apply"); - return; - } + if (ob->type==OB_MESH) { + dm = mesh_create_derived_for_modifier(ob, md); + if (!dm) { + error("Modifier is disabled or returned error, skipping apply"); + return; + } - dlm= dm->convertToDispListMesh(dm, 0); + dlm= dm->convertToDispListMesh(dm, 0); - if ((!me->tface || dlm->tface) || okee("Applying will delete mesh UVs and vertex colors")) { - if ((!me->mcol || dlm->mcol) || okee("Applying will delete mesh vertex colors")) { - if (dlm->totvert==me->totvert || okee("Applying will delete mesh sticky, keys, and vertex groups")) { - displistmesh_to_mesh(dlm, me); - converted = 1; + if ((!me->tface || dlm->tface) || okee("Applying will delete mesh UVs and vertex colors")) { + if ((!me->mcol || dlm->mcol) || okee("Applying will delete mesh vertex colors")) { + if (dlm->totvert==me->totvert || okee("Applying will delete mesh sticky, keys, and vertex groups")) { + displistmesh_to_mesh(dlm, me); + converted = 1; + } } } - } - if (!converted) { - displistmesh_free(dlm); + if (!converted) { + displistmesh_free(dlm); + } + dm->release(dm); + } + else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { + ModifierTypeInfo *mti = modifierType_getInfo(md->type); + Curve *cu = ob->data; + int numVerts; + float (*vertexCos)[3]; + + if (!okee("Apply will only change CV points, not tesselated/bevel vertices")) + return; + + if (!(md->mode&eModifierMode_Realtime) || (mti->isDisabled && mti->isDisabled(md))) { + error("Modifier is disabled, skipping apply"); + return; + } + + vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts); + mti->deformVerts(md, ob, NULL, vertexCos, numVerts); + curve_applyVertexCos(cu, &cu->nurb, vertexCos); + MEM_freeN(vertexCos); + + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + } + else { + error("Cannot apply modifier for this object type"); + return; } - dm->release(dm); BLI_remlink(&ob->modifiers, md); modifier_free(md); @@ -1972,13 +1999,23 @@ void do_latticebuts(unsigned short event) if(ob->type!=OB_LATTICE) return; switch(event) { + case B_REGULARLAT: + if(ob) { + lt = ob->data; + if(ob==G.obedit) resizelattice(editLatt, lt->opntsu, lt->opntsv, lt->opntsw, NULL); + else resizelattice(ob->data, lt->opntsu, lt->opntsv, lt->opntsw, NULL); + ob->softflag |= OB_SB_REDO; + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + allqueue(REDRAWVIEW3D, 0); + } case B_RESIZELAT: if(ob) { - if(ob==G.obedit) resizelattice(editLatt); - else resizelattice(ob->data); + lt = ob->data; + resizelattice(ob->data, lt->opntsu, lt->opntsv, lt->opntsw, ob); ob->softflag |= OB_SB_REDO; + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + allqueue(REDRAWVIEW3D, 0); } - allqueue(REDRAWVIEW3D, 0); break; case B_DRAWLAT: allqueue(REDRAWVIEW3D, 0); @@ -2009,24 +2046,28 @@ static void editing_panel_lattice_type(Object *ob, Lattice *lt) uiBlockBeginAlign(block); - uiDefButS(block, NUM, B_RESIZELAT, "U:", 469, 178,100,19, <->pntsu, 1.0, 64.0, 0, 0, "Points in U direction"); + lt->opntsu = lt->pntsu; + lt->opntsv = lt->pntsv; + lt->opntsw = lt->pntsw; + + uiDefButS(block, NUM, B_RESIZELAT, "U:", 469, 178,100,19, <->opntsu, 1.0, 64.0, 0, 0, "Points in U direction"); uiDefButC(block, ROW, B_LATTCHANGED, "Lin", 572, 178, 40, 19, <->typeu, 1.0, (float)KEY_LINEAR, 0, 0, "Set Linear interpolation"); uiDefButC(block, ROW, B_LATTCHANGED, "Card", 613, 178, 40, 19, <->typeu, 1.0, (float)KEY_CARDINAL, 0, 0, "Set Cardinal interpolation"); uiDefButC(block, ROW, B_LATTCHANGED, "B", 652, 178, 40, 19, <->typeu, 1.0, (float)KEY_BSPLINE, 0, 0, "Set B-spline interpolation"); - uiDefButS(block, NUM, B_RESIZELAT, "V:", 469, 156,100,19, <->pntsv, 1.0, 64.0, 0, 0, "Points in V direction"); + uiDefButS(block, NUM, B_RESIZELAT, "V:", 469, 156,100,19, <->opntsv, 1.0, 64.0, 0, 0, "Points in V direction"); uiDefButC(block, ROW, B_LATTCHANGED, "Lin", 572, 156, 40, 19, <->typev, 2.0, (float)KEY_LINEAR, 0, 0, "Set Linear interpolation"); uiDefButC(block, ROW, B_LATTCHANGED, "Card", 613, 156, 40, 19, <->typev, 2.0, (float)KEY_CARDINAL, 0, 0, "Set Cardinal interpolation"); uiDefButC(block, ROW, B_LATTCHANGED, "B", 652, 156, 40, 19, <->typev, 2.0, (float)KEY_BSPLINE, 0, 0, "Set B-spline interpolation"); - uiDefButS(block, NUM, B_RESIZELAT, "W:", 469, 134,100,19, <->pntsw, 1.0, 64.0, 0, 0, "Points in W direction"); + uiDefButS(block, NUM, B_RESIZELAT, "W:", 469, 134,100,19, <->opntsw, 1.0, 64.0, 0, 0, "Points in W direction"); uiDefButC(block, ROW, B_LATTCHANGED, "Lin", 572, 134, 40, 19, <->typew, 3.0, (float)KEY_LINEAR, 0, 0, "Set Linear interpolation"); uiDefButC(block, ROW, B_LATTCHANGED, "Card", 613, 134, 40, 19, <->typew, 3.0, (float)KEY_CARDINAL, 0, 0, "Set Cardinal interpolation"); uiDefButC(block, ROW, B_LATTCHANGED, "B", 652, 134, 40, 19, <->typew, 3.0, (float)KEY_BSPLINE, 0, 0, "Set B-spline interpolation"); uiBlockEndAlign(block); - uiDefBut(block, BUT, B_RESIZELAT, "Make Regular", 469,98,102,31, 0, 0, 0, 0, 0, "Make Lattice regular"); + uiDefBut(block, BUT, B_REGULARLAT, "Make Regular", 469,98,102,31, 0, 0, 0, 0, 0, "Make Lattice regular"); uiClearButLock(); uiDefButBitS(block, TOG, LT_OUTSIDE, B_LATTCHANGED, "Outside", 571,98,122,31, <->flag, 0, 0, 0, 0, "Only draw, and take into account, the outer vertices"); @@ -3229,6 +3270,7 @@ void editing_panels() lt= ob->data; editing_panel_links(ob); // no editmode! editing_panel_lattice_type(ob, lt); + editing_panel_modifiers(ob); break; case OB_LAMP: diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 608867efa9b..a057da29531 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -1044,7 +1044,7 @@ static void softbody_bake(Object *ob) G.scene->r.framelen= 1.0; // baking has to be in uncorrected time CFRA= sb->sfra; update_for_newframe_muted(); // put everything on this frame - sbObjectToSoftbody(ob, NULL); // put softbody in restposition + sbObjectToSoftbody(ob); // put softbody in restposition ob->softflag |= OB_SB_BAKEDO; curarea->win_swap= 0; // clean swapbuffers @@ -1069,7 +1069,7 @@ static void softbody_bake(Object *ob) if(event==ESCKEY) break; } - if(event==ESCKEY) sbObjectToSoftbody(ob, NULL); // clears all + if(event==ESCKEY) sbObjectToSoftbody(ob); // clears all /* restore */ waitcursor(0); @@ -1157,7 +1157,7 @@ void do_object_panels(unsigned short event) break; case B_SOFTBODY_BAKE_FREE: ob= OBACT; - if(ob && ob->soft) sbObjectToSoftbody(ob, NULL); + if(ob && ob->soft) sbObjectToSoftbody(ob); allqueue(REDRAWBUTSOBJECT, 0); allqueue(REDRAWVIEW3D, 0); break; diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 41881e0a296..ab68351f997 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -786,51 +786,32 @@ void drawcamera(Object *ob) } } -static void tekenvertslatt(short sel) +static void lattice_draw_verts(Lattice *lt, DispList *dl, short sel) { - Lattice *lt; - BPoint *bp; - float size; - int a, u, v, w; - - size= BIF_GetThemeValuef(TH_VERTEX_SIZE); - glPointSize(size); - - if(sel) BIF_ThemeColor(TH_VERTEX_SELECT); - else BIF_ThemeColor(TH_VERTEX); + BPoint *bp = lt->def; + float *co = dl?dl->verts:NULL; + int u, v, w; + BIF_ThemeColor(sel?TH_VERTEX_SELECT:TH_VERTEX); + glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE)); bglBegin(GL_POINTS); - bp= editLatt->def; - lt= editLatt; - - if(lt->flag & LT_OUTSIDE) { - - for(w=0; w<lt->pntsw; w++) { - int wxt = (w==0 || w==lt->pntsw-1); - for(v=0; v<lt->pntsv; v++) { - int vxt = (v==0 || v==lt->pntsv-1); - for(u=0; u<lt->pntsu; u++, bp++) { - int uxt = (u==0 || u==lt->pntsu-1); - if(uxt || vxt || wxt) { - if(bp->hide==0) { - if((bp->f1 & 1)==sel) bglVertex3fv(bp->vec); + for(w=0; w<lt->pntsw; w++) { + int wxt = (w==0 || w==lt->pntsw-1); + for(v=0; v<lt->pntsv; v++) { + int vxt = (v==0 || v==lt->pntsv-1); + for(u=0; u<lt->pntsu; u++, bp++, co+=3) { + int uxt = (u==0 || u==lt->pntsu-1); + if(!(lt->flag & LT_OUTSIDE) || uxt || vxt || wxt) { + if(bp->hide==0) { + if((bp->f1 & 1)==sel) { + bglVertex3fv(dl?co:bp->vec); } } } } } } - else { - - a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; - while(a--) { - if(bp->hide==0) { - if((bp->f1 & 1)==sel) bglVertex3fv(bp->vec); - } - bp++; - } - } glPointSize(1.0); bglEnd(); @@ -839,119 +820,74 @@ static void tekenvertslatt(short sel) void lattice_foreachScreenVert(void (*func)(void *userData, BPoint *bp, int x, int y), void *userData) { int i, N = editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; + DispList *dl = find_displist(&G.obedit->disp, DL_VERTS); + float *co = dl?dl->verts:NULL; + BPoint *bp = editLatt->def; float mat[4][4]; short s[2]; view3d_get_object_project_mat(curarea, G.obedit, mat); - for (i=0; i<N; i++) { - BPoint *bp = &editLatt->def[i]; - + for (i=0; i<N; i++, bp++, co+=3) { if (bp->hide==0) { - view3d_project_short(curarea, bp->vec, s, mat); + view3d_project_short(curarea, dl?co:bp->vec, s, mat); func(userData, bp, s[0], s[1]); } } } +static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w) +{ + int index = ((w*lt->pntsv + v)*lt->pntsu) + u; + if (dl) { + glVertex3fv(&dl->verts[index*3]); + } else { + glVertex3fv(lt->def[index].vec); + } +} static void drawlattice(Object *ob) { Lattice *lt; - BPoint *bp, *bpu; - int u, v, w, dv, dw, uxt, vxt, wxt; + DispList *dl; + int u, v, w; - lt= ob->data; + lt= (ob==G.obedit)?editLatt:ob->data; + dl= find_displist(&ob->disp, DL_VERTS); if(ob==G.obedit) { - bp= editLatt->def; - cpack(0x004000); } - else { - do_latt_key(lt); - bp= lt->def; - } - - dv= lt->pntsu; - dw= dv*lt->pntsv; - if(lt->flag & LT_OUTSIDE) { - - for(w=0; w<lt->pntsw; w++) { - - if(w==0 || w==lt->pntsw-1) wxt= 1; else wxt= 0; - - for(v=0; v<lt->pntsv; v++) { - - if(v==0 || v==lt->pntsv-1) vxt= 1; else vxt= 0; - - for(u=0, bpu=0; u<lt->pntsu; u++, bp++) { - - if(u==0 || u==lt->pntsu-1) uxt= 1; else uxt= 0; - - if(uxt || vxt || wxt) { - - if(w && (uxt || vxt)) { - - glBegin(GL_LINE_STRIP); - glVertex3fv( (bp-dw)->vec ); glVertex3fv(bp->vec); - glEnd(); - } - if(v && (uxt || wxt)) { - - glBegin(GL_LINES); - glVertex3fv( (bp-dv)->vec ); glVertex3fv(bp->vec); - glEnd(); - } - if(u && (vxt || wxt)) { - - glBegin(GL_LINES); - glVertex3fv(bpu->vec); glVertex3fv(bp->vec); - glEnd(); - } - } - - bpu= bp; + glBegin(GL_LINES); + for(w=0; w<lt->pntsw; w++) { + int wxt = (w==0 || w==lt->pntsw-1); + for(v=0; v<lt->pntsv; v++) { + int vxt = (v==0 || v==lt->pntsv-1); + for(u=0; u<lt->pntsu; u++) { + int uxt = (u==0 || u==lt->pntsu-1); + + if(w && ((uxt || vxt) || !(lt->flag & LT_OUTSIDE))) { + drawlattice__point(lt, dl, u, v, w-1); + drawlattice__point(lt, dl, u, v, w); } - } - } - } - else { - for(w=0; w<lt->pntsw; w++) { - - for(v=0; v<lt->pntsv; v++) { - - for(u=0, bpu=0; u<lt->pntsu; u++, bp++) { - - if(w) { - - glBegin(GL_LINES); - glVertex3fv( (bp-dw)->vec ); glVertex3fv(bp->vec); - glEnd(); - } - if(v) { - - glBegin(GL_LINES); - glVertex3fv( (bp-dv)->vec ); glVertex3fv(bp->vec); - glEnd(); - } - if(u) { - - glBegin(GL_LINES); - glVertex3fv(bpu->vec); glVertex3fv(bp->vec); - glEnd(); - } - bpu= bp; + if(v && ((uxt || wxt) || !(lt->flag & LT_OUTSIDE))) { + drawlattice__point(lt, dl, u, v-1, w); + drawlattice__point(lt, dl, u, v, w); + } + if(u && ((vxt || wxt) || !(lt->flag & LT_OUTSIDE))) { + drawlattice__point(lt, dl, u-1, v, w); + drawlattice__point(lt, dl, u, v, w); } } } - } + } + glEnd(); if(ob==G.obedit) { if(G.vd->zbuf) glDisable(GL_DEPTH_TEST); - tekenvertslatt(0); - tekenvertslatt(1); + lattice_draw_verts(lt, dl, 0); + lattice_draw_verts(lt, dl, 1); if(G.vd->zbuf) glEnable(GL_DEPTH_TEST); } diff --git a/source/blender/src/editmesh_loop.c b/source/blender/src/editmesh_loop.c index 2191cc94afd..a7d90639414 100644 --- a/source/blender/src/editmesh_loop.c +++ b/source/blender/src/editmesh_loop.c @@ -607,7 +607,7 @@ static CutCurve *get_mouse_trail(int *len, char mode) */ /* prototype */ -short seg_intersect(struct EditEdge * e, CutCurve *c, int len); +static short seg_intersect(struct EditEdge * e, CutCurve *c, int len); void KnifeSubdivide(char mode) { diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 38b795326c4..aee687b1ca6 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -1311,7 +1311,7 @@ void make_parent(void) } else { - base->object->recalc |= OB_RECALC_OB; + base->object->recalc |= OB_RECALC_OB|OB_RECALC_DATA; /* the ifs below are horrible code (ton) */ @@ -1363,7 +1363,6 @@ void make_parent(void) if(par->type==OB_ARMATURE && mode == PARSKEL){ verify_defgroups(base->object); - base->object->recalc |= OB_RECALC_DATA; } } } @@ -1523,9 +1522,9 @@ void exit_editmode(int freedata) /* freedata==0 at render, 1= freedata, 2= do un if(sb->keys) { if( okee("Erase Baked SoftBody") ) - sbObjectToSoftbody(ob, NULL); + sbObjectToSoftbody(ob); } - else sbObjectToSoftbody(ob, NULL); + else sbObjectToSoftbody(ob); } DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index 8d709db03f8..149a9fe6d7f 100755 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -1417,7 +1417,7 @@ void special_aftertrans_update(short cancelled) ob= base->object; - if(modifiers_isSoftbodyEnabled(ob)) sbObjectReset(ob, NULL); + if(modifiers_isSoftbodyEnabled(ob)) ob->softflag |= OB_SB_RESET; /* Set autokey if necessary */ if ((G.flags & G_RECORDKEYS) && (!cancelled) && (base->flag & SELECT)){ |