diff options
-rw-r--r-- | source/blender/blenkernel/intern/displist.c | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/softbody.c | 101 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_curve_types.h | 6 | ||||
-rw-r--r-- | source/blender/src/buttons_object.c | 14 | ||||
-rw-r--r-- | source/blender/src/drawipo.c | 36 | ||||
-rw-r--r-- | source/blender/src/drawview.c | 55 | ||||
-rw-r--r-- | source/blender/src/editipo.c | 16 | ||||
-rw-r--r-- | source/blender/src/editobject.c | 31 |
8 files changed, 173 insertions, 89 deletions
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index f668aa507b4..34500bfeea9 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1429,7 +1429,7 @@ static ModifierData *curve_get_tesselate_point(Object *ob, int forRender, int ed if (editmode && !(md->mode&eModifierMode_Editmode)) continue; if (mti->isDisabled && mti->isDisabled(md)) continue; - if (md->type==eModifierType_Hook) { + if (md->type==eModifierType_Hook || md->type==eModifierType_Softbody) { preTesselatePoint = md; } } @@ -1464,6 +1464,7 @@ void curve_calc_modifiers_pre(Object *ob, ListBase *nurb, int forRender, float ( deformedVerts = curve_getVertexCos(ob->data, nurb, &numVerts); originalVerts = MEM_dupallocN(deformedVerts); } + mti->deformVerts(md, ob, NULL, deformedVerts, numVerts); if (md==preTesselatePoint) diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 7f3dda44255..11bacfd8683 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -70,6 +70,7 @@ variables on the UI for now #include "BLI_blenlib.h" #include "BLI_arithb.h" +#include "BKE_curve.h" #include "BKE_displist.h" #include "BKE_effect.h" #include "BKE_global.h" @@ -1043,7 +1044,7 @@ static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff) static void lattice_to_softbody(Object *ob,int *rcs) { Lattice *lt= ob->data; - SoftBody *sb= ob->soft; + SoftBody *sb; int totvert, totspring = 0; totvert= lt->pntsu*lt->pntsv*lt->pntsw; @@ -1059,7 +1060,8 @@ static void lattice_to_softbody(Object *ob,int *rcs) /* renew ends with ob->soft with points and edges, also checks & makes ob->soft */ - renew_softbody(ob, totvert, totspring,rcs); + renew_softbody(ob, totvert, totspring, rcs); + sb= ob->soft; /* can be created in renew_softbody() */ /* weights from bpoints, same code used as for mesh vertices */ if((ob->softflag & OB_SB_GOAL) && sb->vertgroup) { @@ -1069,9 +1071,7 @@ static void lattice_to_softbody(Object *ob,int *rcs) int a; for(a=0; a<totvert; a++, bp++, bpnt++) { - - bp->goal= sb->mingoal + bpnt->vec[3]*goalfac; - + bp->goal= sb->mingoal + bpnt->weight*goalfac; /* a little ad hoc changing the goal control to be less *sharp* */ bp->goal = (float)pow(bp->goal, 4.0f); } @@ -1084,6 +1084,87 @@ static void lattice_to_softbody(Object *ob,int *rcs) } } +/* makes totally fresh start situation */ +static void curve_surf_to_softbody(Object *ob, int *rcs) +{ + Curve *cu= ob->data; + SoftBody *sb; + int totvert, totspring = 0; + + totvert= count_curveverts(&cu->nurb); + + if (ob->softflag & OB_SB_EDGES){ + if(ob->type==OB_CURVE) { + totspring= totvert - BLI_countlist(&cu->nurb); + } + } + + /* renew ends with ob->soft with points and edges, also checks & makes ob->soft */ + renew_softbody(ob, totvert, totspring, rcs); + sb= ob->soft; /* can be created in renew_softbody() */ + + /* weights from bpoints, same code used as for mesh vertices */ + if((ob->softflag & OB_SB_GOAL) && sb->vertgroup) { + BodyPoint *bp= sb->bpoint; + BodySpring *bs= sb->bspring; + Nurb *nu; + BezTriple *bezt; + BPoint *bpnt; + float goalfac= ABS(sb->maxgoal - sb->mingoal); + int a, curindex=0; + + for(nu= cu->nurb.first; nu; nu= nu->next) { + if(nu->bezt) { + for(bezt=nu->bezt, a=0; a<nu->pntsu; a++, bezt++, bp++, curindex+=3) { + bp->goal= sb->mingoal + bezt->weight*goalfac; + /* a little ad hoc changing the goal control to be less *sharp* */ + bp->goal = (float)pow(bp->goal, 4.0f); + /* all three triples */ + bp++; + bp->goal= (bp-1)->goal; + bp++; + bp->goal= (bp-1)->goal; + + if(totspring) { + if(a>0) { + bs->v1= curindex-1; + bs->v2= curindex; + bs->strength= 1.0; + bs++; + } + bs->v1= curindex; + bs->v2= curindex+1; + bs->strength= 1.0; + bs++; + + bs->v1= curindex+1; + bs->v2= curindex+2; + bs->strength= 1.0; + bs++; + } + } + } + else { + for(bpnt=nu->bp, a=0; a<nu->pntsu*nu->pntsv; a++, bpnt++, bp++, curindex++) { + bp->goal= sb->mingoal + bpnt->weight*goalfac; + /* a little ad hoc changing the goal control to be less *sharp* */ + bp->goal = (float)pow(bp->goal, 4.0f); + + if(totspring && a>0) { + bs->v1= curindex-1; + bs->v2= curindex; + bs->strength= 1.0; + bs++; + } + } + } + } + } + + if(totspring) + build_bps_springlist(ob); /* link bps to springs */ +} + /* copies softbody result back in object */ static void softbody_to_object(Object *ob, float (*vertexCos)[3], int numVerts) @@ -1288,13 +1369,17 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts { switch(ob->type) { case OB_MESH: - mesh_to_softbody(ob,&rcs); + mesh_to_softbody(ob, &rcs); break; case OB_LATTICE: - lattice_to_softbody(ob,&rcs); + lattice_to_softbody(ob, &rcs); + break; + case OB_CURVE: + case OB_SURF: + curve_surf_to_softbody(ob, &rcs); break; default: - renew_softbody(ob, numVerts, 0,&rcs); + renew_softbody(ob, numVerts, 0, &rcs); break; } diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 18237c2f964..ff88e8b1c48 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -75,8 +75,7 @@ typedef struct BevPoint { /* note; alfa location in struct is abused by Key system */ typedef struct BezTriple { float vec[3][3]; - float alfa; - short s[3][2]; /* screen coordinates */ + float alfa, weight, pad; short h1, h2; char f1, f2, f3, hide; } BezTriple; @@ -84,8 +83,7 @@ typedef struct BezTriple { /* note; alfa location in struct is abused by Key system */ typedef struct BPoint { float vec[4]; - float alfa; - short s[2]; + float alfa, weight; short f1, hide; } BPoint; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 6f0d225239a..58d10f9dcf3 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -1907,12 +1907,14 @@ static void object_softbodies(Object *ob) uiBlockEndAlign(block); /* EDGE SPRING STUFF */ - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, OB_SB_EDGES, B_SOFTBODY_CHANGE, "Use Edges", 10,30,150,20, &ob->softflag, 0, 0, 0, 0, "Use Edges as springs"); - uiDefButBitS(block, TOG, OB_SB_QUADS, B_SOFTBODY_CHANGE, "Stiff Quads", 160,30,150,20, &ob->softflag, 0, 0, 0, 0, "Adds diagonal springs on 4-gons"); - uiDefButF(block, NUM, B_DIFF, "E Stiff:", 10,10,150,20, &sb->inspring, 0.0, 0.999, 10, 0, "Edge spring stiffness"); - uiDefButF(block, NUM, B_DIFF, "E Damp:", 160,10,150,20, &sb->infrict, 0.0, 10.0, 10, 0, "Edge spring friction"); - uiBlockEndAlign(block); + if(ob->type!=OB_SURF) { + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, OB_SB_EDGES, B_SOFTBODY_CHANGE, "Use Edges", 10,30,150,20, &ob->softflag, 0, 0, 0, 0, "Use Edges as springs"); + uiDefButBitS(block, TOG, OB_SB_QUADS, B_SOFTBODY_CHANGE, "Stiff Quads", 160,30,150,20, &ob->softflag, 0, 0, 0, 0, "Adds diagonal springs on 4-gons"); + uiDefButF(block, NUM, B_DIFF, "E Stiff:", 10,10,150,20, &sb->inspring, 0.0, 0.999, 10, 0, "Edge spring stiffness"); + uiDefButF(block, NUM, B_DIFF, "E Damp:", 160,10,150,20, &sb->infrict, 0.0, 10.0, 10, 0, "Edge spring friction"); + uiBlockEndAlign(block); + } } } uiBlockEndAlign(block); diff --git a/source/blender/src/drawipo.c b/source/blender/src/drawipo.c index 66bd92cfa1a..f2f8fa6f062 100644 --- a/source/blender/src/drawipo.c +++ b/source/blender/src/drawipo.c @@ -1004,40 +1004,6 @@ static void draw_ipobuts(SpaceIpo *sipo) uiDrawBlock(block); } -static void calc_ipoverts(SpaceIpo *sipo) -{ - View2D *v2d= &sipo->v2d; - EditIpo *ei; - BezTriple *bezt; - BPoint *bp; - int a, b; - - ei= G.sipo->editipo; - for(a=0; a<sipo->totipo; a++, ei++) { - if ISPOIN(ei, flag & IPO_VISIBLE, icu) { - if(ei->icu->bezt) { - bezt= ei->icu->bezt; - b= ei->icu->totvert; - while(b--) { - ipoco_to_areaco(v2d, bezt->vec[0], bezt->s[0]); - ipoco_to_areaco(v2d, bezt->vec[1], bezt->s[1]); - ipoco_to_areaco(v2d, bezt->vec[2], bezt->s[2]); - bezt++; - } - } - else if(ei->icu->bp) { - bp= ei->icu->bp; - b= ei->icu->totvert; - while(b--) { - ipoco_to_areaco(v2d, bp->vec, bp->s); - bp++; - } - } - } - } -} - - static void draw_ipovertices(int sel) { EditIpo *ei; @@ -2022,8 +1988,6 @@ void drawipospace(ScrArea *sa, void *spacedata) calc_ipogrid(); draw_ipogrid(); - calc_ipoverts(sipo); - draw_cfra(sipo); /* ipokeys */ diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 1963e6ae31a..1bc6fdf6d80 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -1184,7 +1184,7 @@ static void load_bgpic_image(char *name) /* this one assumes there is only one global active object in blender... (for object panel) */ static float ob_eul[4]; // used for quat too.... /* this one assumes there is only one editmode in blender... (for object panel) */ -static float ve_median[4]; +static float ve_median[5]; /* is used for both read and write... */ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim) @@ -1194,12 +1194,12 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim) EditMesh *em = G.editMesh; EditVert *eve, *evedef=NULL; EditEdge *eed; - float median[4]; - int tot, totw, totedge; + float median[5]; + int tot, totw, totweight, totedge; char defstr[320]; - median[0]= median[1]= median[2]= median[3]= 0.0; - tot= totw= totedge= 0; + median[0]= median[1]= median[2]= median[3]= median[4]= 0.0; + tot= totw= totweight= totedge= 0; defstr[0]= 0; if(ob->type==OB_MESH) { @@ -1259,6 +1259,8 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim) if(bezt->f2 & 1) { VecAddf(median, median, bezt->vec[1]); tot++; + median[4]+= bezt->weight; + totweight++; } else { if(bezt->f1 & 1) { @@ -1282,6 +1284,8 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim) median[3]+= bp->vec[3]; totw++; tot++; + median[4]+= bp->weight; + totweight++; } bp++; } @@ -1298,9 +1302,9 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim) while(a--) { if(bp->f1 & SELECT) { VecAddf(median, median, bp->vec); - median[3]+= bp->vec[3]; tot++; - totw++; + median[4]+= bp->weight; + totweight++; } bp++; } @@ -1312,51 +1316,51 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim) median[1] /= (float)tot; median[2] /= (float)tot; if(totedge) median[3] /= (float)totedge; - else median[3] /= (float)tot; + else if(totw) median[3] /= (float)totw; + if(totweight) median[4] /= (float)totweight; if(G.vd->flag & V3D_GLOBAL_STATS) Mat4MulVecfl(ob->obmat, median); if(block) { // buttons - uiBlockBeginAlign(block); uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, REDRAWVIEW3D, "Global", 160, 150, 70, 19, &G.vd->flag, 0, 0, 0, 0, "Displays global values"); uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, REDRAWVIEW3D, "Local", 230, 150, 70, 19, &G.vd->flag, 0, 0, 0, 0, "Displays local values"); - QUATCOPY(ve_median, median); + memcpy(ve_median, median, sizeof(ve_median)); uiBlockBeginAlign(block); if(tot==1) { uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex X:", 10, 110, 290, 19, &(ve_median[0]), -lim, lim, 10, 3, ""); uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex Y:", 10, 90, 290, 19, &(ve_median[1]), -lim, lim, 10, 3, ""); uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex Z:", 10, 70, 290, 19, &(ve_median[2]), -lim, lim, 10, 3, ""); - if(totw==1) { - if(ob->type==OB_LATTICE) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex W:", 10, 50, 290, 19, &(ve_median[3]), 0.0, 1.0, 10, 3, ""); - else - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex W:", 10, 50, 290, 19, &(ve_median[3]), 0.01, 100.0, 10, 3, ""); - } + if(totw==1) + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex W:", 10, 50, 290, 19, &(ve_median[3]), 0.01, 100.0, 10, 3, ""); + uiBlockEndAlign(block); + if(defstr[0]) { uiDefBut(block, LABEL, 1, "Vertex Deform Groups", 10, 40, 290, 20, NULL, 0.0, 0.0, 0, 0, ""); uiBlockBeginAlign(block); uiDefButF(block, NUM, B_NOP, "Weight:", 10, 20, 150, 19, defweightp, 0.0f, 1.0f, 10, 3, "Weight value"); uiDefButI(block, MENU, REDRAWVIEW3D, defstr, 160, 20, 140, 19, &curdef, 0.0, 0.0, 0, 0, "Current Vertex Group"); + uiBlockEndAlign(block); } + else if(totweight) + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 10, 20, 290, 19, &(ve_median[4]), 0.0, 1.0, 10, 3, ""); + } else { uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median X:", 10, 110, 290, 19, &(ve_median[0]), -lim, lim, 10, 3, ""); uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Y:", 10, 90, 290, 19, &(ve_median[1]), -lim, lim, 10, 3, ""); uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Z:", 10, 70, 290, 19, &(ve_median[2]), -lim, lim, 10, 3, ""); - if(totw==tot) { - if(ob->type==OB_LATTICE) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median W:", 10, 50, 290, 19, &(ve_median[3]), 0.0, 1.0, 10, 3, ""); - else - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median W:", 10, 50, 290, 19, &(ve_median[3]), 0.01, 100.0, 10, 3, ""); - } + if(totw==tot) + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median W:", 10, 50, 290, 19, &(ve_median[3]), 0.01, 100.0, 10, 3, ""); + uiBlockEndAlign(block); + if(totweight) + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 10, 20, 290, 19, &(ve_median[4]), 0.0, 1.0, 10, 3, "Weight is used for SoftBody Goal"); } - uiBlockEndAlign(block); if(totedge==1) uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Crease W:", 10, 30, 290, 19, &(ve_median[3]), 0.0, 1.0, 10, 3, ""); @@ -1373,6 +1377,7 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim) } VecSubf(median, ve_median, median); median[3]= ve_median[3]-median[3]; + median[4]= ve_median[4]-median[4]; if(ob->type==OB_MESH) { float diffac= 1.0; @@ -1429,6 +1434,7 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim) VecAddf(bezt->vec[0], bezt->vec[0], median); VecAddf(bezt->vec[1], bezt->vec[1], median); VecAddf(bezt->vec[2], bezt->vec[2], median); + bezt->weight+= median[4]; } else { if(bezt->f1 & 1) { @@ -1448,6 +1454,7 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim) if(bp->f1 & 1) { VecAddf(bp->vec, bp->vec, median); bp->vec[3]+= median[3]; + bp->weight+= median[4]; } bp++; } @@ -1467,7 +1474,7 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim) while(a--) { if(bp->f1 & SELECT) { VecAddf(bp->vec, bp->vec, median); - bp->vec[3]+= median[3]; + bp->weight+= median[4]; } bp++; } diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index b26c89fc91f..67f2b4eca0d 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -1241,7 +1241,7 @@ static short findnearest_ipovert(IpoCurve **icu, BezTriple **bezt) EditIpo *ei; BezTriple *bezt1; int dist= 100, temp, a, b; - short mval[2], hpoint=0; + short mval[2], hpoint=0, sco[3][2]; *icu= 0; *bezt= 0; @@ -1257,14 +1257,14 @@ static short findnearest_ipovert(IpoCurve **icu, BezTriple **bezt) b= ei->icu->totvert; while(b--) { - ipoco_to_areaco_noclip(G.v2d, bezt1->vec[0], bezt1->s[0]); - ipoco_to_areaco_noclip(G.v2d, bezt1->vec[1], bezt1->s[1]); - ipoco_to_areaco_noclip(G.v2d, bezt1->vec[2], bezt1->s[2]); + ipoco_to_areaco_noclip(G.v2d, bezt1->vec[0], sco[0]); + ipoco_to_areaco_noclip(G.v2d, bezt1->vec[1], sco[1]); + ipoco_to_areaco_noclip(G.v2d, bezt1->vec[2], sco[2]); if(ei->disptype==IPO_DISPBITS) { - temp= abs(mval[0]- bezt1->s[1][0]); + temp= abs(mval[0]- sco[1][0]); } - else temp= abs(mval[0]- bezt1->s[1][0])+ abs(mval[1]- bezt1->s[1][1]); + else temp= abs(mval[0]- sco[1][0])+ abs(mval[1]- sco[1][1]); if( bezt1->f2 & 1) temp+=5; if(temp<dist) { @@ -1276,7 +1276,7 @@ static short findnearest_ipovert(IpoCurve **icu, BezTriple **bezt) if(ei->disptype!=IPO_DISPBITS && ei->icu->ipo==IPO_BEZ) { /* middle points get an advantage */ - temp= -3+abs(mval[0]- bezt1->s[0][0])+ abs(mval[1]- bezt1->s[0][1]); + temp= -3+abs(mval[0]- sco[0][0])+ abs(mval[1]- sco[0][1]); if( bezt1->f1 & 1) temp+=5; if(temp<dist) { hpoint= 0; @@ -1285,7 +1285,7 @@ static short findnearest_ipovert(IpoCurve **icu, BezTriple **bezt) *icu= ei->icu; } - temp= abs(mval[0]- bezt1->s[2][0])+ abs(mval[1]- bezt1->s[2][1]); + temp= abs(mval[0]- sco[2][0])+ abs(mval[1]- sco[2][1]); if( bezt1->f3 & 1) temp+=5; if(temp<dist) { hpoint= 2; diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 863073ed575..088a66f378a 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -2138,7 +2138,7 @@ void special_editmenu(void) } else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { - nr= pupmenu("Specials%t|Subdivide%x1|Switch Direction%x2"); + nr= pupmenu("Specials%t|Subdivide%x1|Switch Direction%x2|Set Goal Weight %x3"); switch(nr) { case 1: @@ -2147,6 +2147,33 @@ void special_editmenu(void) case 2: switchdirectionNurb2(); break; + case 3: + { + static float weight= 1.0f; + extern ListBase editNurb; + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + int a; + + if(fbutton(&weight, 0.0f, 1.0f, 10, 10, "Set Weight")) { + for(nu= editNurb.first; nu; nu= nu->next) { + if(nu->bezt) { + for(bezt=nu->bezt, a=0; a<nu->pntsu; a++, bezt++) { + if(bezt->f2 & SELECT) + bezt->weight= weight; + } + } + else if(nu->bp) { + for(bp=nu->bp, a=0; a<nu->pntsu*nu->pntsv; a++, bp++) { + if(bp->f1 & SELECT) + bp->weight= weight; + } + } + } + } + } + break; } DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); @@ -2166,7 +2193,7 @@ void special_editmenu(void) while(a--) { if(bp->f1 & SELECT) - bp->vec[3]= weight; + bp->weight= weight; bp++; } } |