From 3ad55e1541c8e901b57451206f73c4753aa2f4ee Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 26 Sep 2008 19:00:49 +0000 Subject: nurbs surface resolution is now per segment rather then being distributed over the whole surface. This is what 2D do alredy and makes resolution settings more like subsurf level. - This makes it impossible to have a lower resolution output then the nurbs cage, however this dosnt seem a very useful feature. - Using the do-versions from recent curve interpolation fix. Tested with these files. http://digilander.libero.it/pafurijaz/Files/Blender/Libellula.zip http://digilander.libero.it/pafurijaz/Files/Blender/Martello.zip http://digilander.libero.it/pafurijaz/Files/Blender/Punta.zip http://digilander.libero.it/pafurijaz/Files/Blender/Phones.zip http://digilander.libero.it/pafurijaz/Files/Blender/Tubo.zip http://digilander.libero.it/pafurijaz/Files/Blender/Pipe.zip http://digilander.libero.it/pafurijaz/Files/Blender/Tire.zip http://digilander.libero.it/pafurijaz/Files/Blender/Cotton.zip --- source/blender/blenkernel/intern/curve.c | 46 ++++++++++++++++------------- source/blender/blenkernel/intern/displist.c | 8 ++--- source/blender/blenloader/intern/readfile.c | 9 ++++++ source/blender/src/editcurve.c | 21 +++++-------- 4 files changed, 46 insertions(+), 38 deletions(-) diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 457bfe20915..06c1dd4ffe6 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -658,23 +658,23 @@ void makeNurbfaces(Nurb *nu, float *coord_array, int rowstride) float u, v, ustart, uend, ustep, vstart, vend, vstep, sumdiv; int i, j, iofs, jofs, cycl, len, resolu, resolv; int istart, iend, jsta, jen, *jstart, *jend, ratcomp; - + + int totu = nu->pntsu*nu->resolu, totv = nu->pntsv*nu->resolv; + if(nu->knotsu==NULL || nu->knotsv==NULL) return; if(nu->orderu>nu->pntsu) return; if(nu->orderv>nu->pntsv) return; if(coord_array==NULL) return; - + /* allocate and initialize */ - len= nu->pntsu*nu->pntsv; + len = totu * totv; if(len==0) return; sum= (float *)MEM_callocN(sizeof(float)*len, "makeNurbfaces1"); - - resolu= nu->resolu; - resolv= nu->resolv; - len= resolu*resolv; + + len= totu*totv; if(len==0) { MEM_freeN(sum); return; @@ -690,12 +690,13 @@ void makeNurbfaces(Nurb *nu, float *coord_array, int rowstride) } bp++; } - + fp= nu->knotsu; ustart= fp[nu->orderu-1]; if(nu->flagu & CU_CYCLIC) uend= fp[nu->pntsu+nu->orderu-1]; else uend= fp[nu->pntsu]; - ustep= (uend-ustart)/(resolu-1+(nu->flagu & CU_CYCLIC)); + ustep= (uend-ustart)/((nu->flagu & CU_CYCLIC) ? totu : totu - 1); + basisu= (float *)MEM_mallocN(sizeof(float)*KNOTSU(nu), "makeNurbfaces3"); fp= nu->knotsv; @@ -703,17 +704,19 @@ void makeNurbfaces(Nurb *nu, float *coord_array, int rowstride) if(nu->flagv & CU_CYCLIC) vend= fp[nu->pntsv+nu->orderv-1]; else vend= fp[nu->pntsv]; - vstep= (vend-vstart)/(resolv-1+(nu->flagv & CU_CYCLIC)); + vstep= (vend-vstart)/((nu->flagv & CU_CYCLIC) ? totv : totv - 1); + len= KNOTSV(nu); - basisv= (float *)MEM_mallocN(sizeof(float)*len*resolv, "makeNurbfaces3"); - jstart= (int *)MEM_mallocN(sizeof(float)*resolv, "makeNurbfaces4"); - jend= (int *)MEM_mallocN(sizeof(float)*resolv, "makeNurbfaces5"); + basisv= (float *)MEM_mallocN(sizeof(float)*len*totv, "makeNurbfaces3"); + jstart= (int *)MEM_mallocN(sizeof(float)*totv, "makeNurbfaces4"); + jend= (int *)MEM_mallocN(sizeof(float)*totv, "makeNurbfaces5"); /* precalculation of basisv and jstart,jend */ if(nu->flagv & CU_CYCLIC) cycl= nu->orderv-1; else cycl= 0; v= vstart; basis= basisv; + resolv= totv; while(resolv--) { basisNurb(v, nu->orderv, (short)(nu->pntsv+cycl), nu->knotsv, basis, jstart+resolv, jend+resolv); basis+= KNOTSV(nu); @@ -724,12 +727,13 @@ void makeNurbfaces(Nurb *nu, float *coord_array, int rowstride) else cycl= 0; in= coord_array; u= ustart; + resolu= totu; while(resolu--) { basisNurb(u, nu->orderu, (short)(nu->pntsu+cycl), nu->knotsu, basisu, &istart, &iend); basis= basisv; - resolv= nu->resolv; + resolv= totv; while(resolv--) { jsta= jstart[resolv]; @@ -798,7 +802,7 @@ void makeNurbfaces(Nurb *nu, float *coord_array, int rowstride) basis+= KNOTSV(nu); } u+= ustep; - if (rowstride!=0) in = (float*) (((unsigned char*) in) + (rowstride - 3*nu->resolv*sizeof(*in))); + if (rowstride!=0) in = (float*) (((unsigned char*) in) + (rowstride - 3*totv*sizeof(*in))); } /* free */ @@ -954,8 +958,8 @@ float *make_orco_surf(Object *ob) See also convertblender.c: init_render_surf() */ - sizeu = nu->resolu; - sizev = nu->resolv; + sizeu = nu->pntsu*nu->resolu; + sizev = nu->pntsv*nu->resolv; if (nu->flagu & CU_CYCLIC) sizeu++; if (nu->flagv & CU_CYCLIC) sizev++; if(nu->pntsv>1) tot+= sizeu * sizev; @@ -968,8 +972,8 @@ float *make_orco_surf(Object *ob) nu= cu->nurb.first; while(nu) { if(nu->pntsv>1) { - sizeu = nu->resolu; - sizev = nu->resolv; + sizeu = nu->pntsu*nu->resolu; + sizev = nu->pntsv*nu->resolv; if (nu->flagu & CU_CYCLIC) sizeu++; if (nu->flagv & CU_CYCLIC) sizev++; @@ -990,7 +994,7 @@ float *make_orco_surf(Object *ob) } } else { - float *_tdata= MEM_callocN(nu->resolu*nu->resolv*3*sizeof(float), "temp data"); + float *_tdata= MEM_callocN((nu->pntsu*nu->resolu) * (nu->pntsv*nu->resolv) *3*sizeof(float), "temp data"); float *tdata= _tdata; makeNurbfaces(nu, tdata, 0); @@ -1005,7 +1009,7 @@ float *make_orco_surf(Object *ob) if (a==sizev-1 && (nu->flagv & CU_CYCLIC)) use_a= 0; - tdata = _tdata + 3 * (use_b * nu->resolv + use_a); + tdata = _tdata + 3 * (use_b * (nu->pntsv*nu->resolv) + use_a); fp[0]= (tdata[0]-cu->loc[0])/cu->size[0]; fp[1]= (tdata[1]-cu->loc[1])/cu->size[1]; diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 598973d6974..f67fcd7a1b7 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1342,7 +1342,7 @@ void makeDispListSurf(Object *ob, ListBase *dispbase, int forRender) makeNurbcurve(nu, data, NULL, NULL, nu->resolu); } else { - len= nu->resolu*nu->resolv; + len= (nu->pntsu*nu->resolu) * (nu->pntsv*nu->resolv); dl= MEM_callocN(sizeof(DispList), "makeDispListsurf"); dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts"); @@ -1354,9 +1354,9 @@ void makeDispListSurf(Object *ob, ListBase *dispbase, int forRender) data= dl->verts; dl->type= DL_SURF; - - dl->parts= nu->resolu; /* in reverse, because makeNurbfaces works that way */ - dl->nr= nu->resolv; + + dl->parts= (nu->pntsu*nu->resolu); /* in reverse, because makeNurbfaces works that way */ + dl->nr= (nu->pntsv*nu->resolv); if(nu->flagv & CU_CYCLIC) dl->flag|= DL_CYCL_U; /* reverse too! */ if(nu->flagu & CU_CYCLIC) dl->flag|= DL_CYCL_V; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 85e45e87994..d38eed4d094 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7879,6 +7879,15 @@ static void do_versions(FileData *fd, Library *lib, Main *main) for(nu= cu->nurb.first; nu; nu= nu->next) { if (nu) { nu->radius_interp = 3; + + /* resolu and resolv are now used differently for surfaces + * rather then using the resolution to define the entire number of divisions, + * use it for the number of divisions per segment + */ + if (nu->pntsv > 1) { + nu->resolu = MAX2( 1, (int)(((float)nu->resolu / (float)nu->pntsu)+0.5f) ); + nu->resolv = MAX2( 1, (int)(((float)nu->resolv / (float)nu->pntsv)+0.5f) ); + } } } } diff --git a/source/blender/src/editcurve.c b/source/blender/src/editcurve.c index 1dee0837445..76a4e1028f0 100644 --- a/source/blender/src/editcurve.c +++ b/source/blender/src/editcurve.c @@ -828,7 +828,6 @@ short extrudeflagNurb(int flag) MEM_freeN(nu->bp); nu->bp= newbp; nu->pntsv++; - if(nu->resolv<3) nu->resolv++; makeknots(nu, 2, nu->flagv>>1); } else if(v==0 || v== nu->pntsu-1) { /* collumn in v-direction selected */ @@ -856,7 +855,6 @@ short extrudeflagNurb(int flag) MEM_freeN(nu->bp); nu->bp= newbp; nu->pntsu++; - if(nu->resolu<3) nu->resolu++; makeknots(nu, 1, nu->flagu>>1); } } @@ -2470,8 +2468,6 @@ void merge_2_nurb(Nurb *nu1, Nurb *nu2) /* merge */ origu= nu1->pntsu; nu1->pntsu+= nu2->pntsu; - nu1->resolu+= nu2->pntsu; - if(nu1->resolv < nu2->resolv) nu1->resolv= nu2->resolv; if(nu1->orderu<3) nu1->orderu++; if(nu1->orderv<3) nu1->orderv++; temp= nu1->bp; @@ -2997,7 +2993,6 @@ void addvert_Nurb(int mode) if(bp) { nu->pntsu++; - if(nu->resolu<3) nu->resolu++; makeknots(nu, 1, nu->flagu>>1); if(mode=='e') { @@ -4120,8 +4115,8 @@ Nurb *addNurbprim(int type, int stype, int newname) if ELEM5(stype, 0, 1, 2, 4, 6) { nu = (Nurb*)MEM_callocN(sizeof(Nurb), "addNurbprim"); nu->type= type; - nu->resolu= 12; - nu->resolv= 12; + nu->resolu= 4; + nu->resolv= 4; } switch(stype) { @@ -4203,7 +4198,7 @@ Nurb *addNurbprim(int type, int stype, int newname) nu->pntsv= 1; nu->orderu= 5; nu->flagu= 2; /* endpoint */ - nu->resolu= 32; + nu->resolu= 8; nu->bp= callocstructN(BPoint, 5, "addNurbprim3"); bp= nu->bp; @@ -4361,7 +4356,7 @@ Nurb *addNurbprim(int type, int stype, int newname) } nu= addNurbprim(4, 1, newname); /* circle */ - nu->resolu= 32; + nu->resolu= 4; nu->flag= CU_SMOOTH; BLI_addtail(&editNurb, nu); /* temporal for extrude and translate */ vec[0]=vec[1]= 0.0; @@ -4394,8 +4389,8 @@ Nurb *addNurbprim(int type, int stype, int newname) nu->pntsu= 5; nu->pntsv= 1; nu->orderu= 3; - nu->resolu= 24; - nu->resolv= 32; + nu->resolu= 4; + nu->resolv= 4; nu->flag= CU_SMOOTH; nu->bp= callocstructN(BPoint, 5, "addNurbprim6"); nu->flagu= 0; @@ -4441,8 +4436,8 @@ Nurb *addNurbprim(int type, int stype, int newname) xzproj= 1; nu= addNurbprim(4, 1, newname); /* circle */ xzproj= 0; - nu->resolu= 24; - nu->resolv= 32; + nu->resolu= 4; + nu->resolv= 4; nu->flag= CU_SMOOTH; BLI_addtail(&editNurb, nu); /* temporal for extrude and translate */ if(newname && (U.flag & USER_ADD_VIEWALIGNED) == 0) -- cgit v1.2.3