diff options
author | Ton Roosendaal <ton@blender.org> | 2006-02-07 22:59:02 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2006-02-07 22:59:02 +0300 |
commit | 78c87abeeda4a366daf23e5b9ef81ba29e329e3f (patch) | |
tree | 00c07b3ec4342e4018c1d5fd9a1bc2ca80875ac6 | |
parent | 0b1cf0a01f60414f5e9cda3ecac4b4ee439f891b (diff) |
Wanted feature for curves: a render-time resolution. This option is
located under the 'def resolu' button. If not zero, it assigns this
resolution to a curve on render.
Also copies with ctrl+c menu.
-rw-r--r-- | source/blender/blenkernel/BKE_curve.h | 16 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/curve.c | 188 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/displist.c | 24 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_curve_types.h | 2 | ||||
-rw-r--r-- | source/blender/render/intern/source/convertblender.c | 17 | ||||
-rw-r--r-- | source/blender/src/buttons_editing.c | 8 | ||||
-rw-r--r-- | source/blender/src/editobject.c | 1 |
7 files changed, 71 insertions, 185 deletions
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 03a7cfe0096..c05e1e729f3 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -60,22 +60,16 @@ struct Nurb *duplicateNurb( struct Nurb *nu); void duplicateNurblist( struct ListBase *lb1, struct ListBase *lb2); void test2DNurb( struct Nurb *nu); void minmaxNurb( struct Nurb *nu, float *min, float *max); -void extend_spline(float * pnts, int in, int out); -void calcknots(float *knots, short aantal, short order, short type); -void makecyclicknots(float *knots, short pnts, short order); + void makeknots( struct Nurb *nu, short uv, short type); -void basisNurb(float t, short order, short pnts, float *knots, float *basis, int *start, int *end); + void makeNurbfaces( struct Nurb *nu, float *data, int rowstride); -void makeNurbcurve_forw(struct Nurb *nu, float *data); -void makeNurbcurve( struct Nurb *nu, float *data, int dim); +void makeNurbcurve( struct Nurb *nu, float *data, int resolu, int dim); void forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride); float *make_orco_curve( struct Object *ob); float *make_orco_surf( struct Object *ob); void makebevelcurve( struct Object *ob, struct ListBase *disp); -short bevelinside(struct BevList *bl1,struct BevList *bl2); -int vergxcobev(const void *a1, const void *a2); -void calc_bevel_sin_cos(float x1, float y1, float x2, float y2, float *sina, float *cosa); -void alfa_bezpart( struct BezTriple *prevbezt, struct BezTriple *bezt, struct Nurb *nu, float *data_a); + void makeBevelList( struct Object *ob); void calchandleNurb( struct BezTriple *bezt, struct BezTriple *prev, struct BezTriple *next, int mode); void calchandlesNurb( struct Nurb *nu); @@ -83,7 +77,7 @@ void testhandlesNurb( struct Nurb *nu); void autocalchandlesNurb( struct Nurb *nu, int flag); void autocalchandlesNurb_all(int flag); 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]; diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index f0bf3672a35..9646ab3718e 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -483,52 +483,7 @@ void minmaxNurb(Nurb *nu, float *min, float *max) /* ~~~~~~~~~~~~~~~~~~~~Non Uniform Rational B Spline calculations ~~~~~~~~~~~ */ -/* actually, doubles should be used here as much as possible */ - -void extend_spline(float * pnts, int in, int out) -{ - float *_pnts; - double * add; - int i, j, k, in2; - - _pnts = pnts; - add = (double*)MEM_mallocN((in)* sizeof(double), "extend_spline"); - - in2 = in -1; - - for (k = 3; k > 0; k--){ - pnts = _pnts; - - /* copy points to 'add' */ - for (i = 0; i < in; i++){ - add[i] = *pnts; - pnts += 3; - } - - /* inverse forward differencing */ - for (i = 0; i < in2; i++){ - for (j = in2; j > i; j--){ - add[j] -= add[j - 1]; - } - } - - pnts = _pnts; - for (i = out; i > 0; i--){ - *pnts = (float)(add[0]); - pnts += 3; - for (j = 0; j < in2; j++){ - add[j] += add[j+1]; - } - } - - _pnts++; - } - - MEM_freeN(add); -} - - -void calcknots(float *knots, short aantal, short order, short type) +static void calcknots(float *knots, short aantal, short order, short type) /* knots: number of pnts NOT corrected for cyclic */ /* type; 0: uniform, 1: endpoints, 2: bezier */ { @@ -567,7 +522,7 @@ void calcknots(float *knots, short aantal, short order, short type) } } -void makecyclicknots(float *knots, short pnts, short order) +static void makecyclicknots(float *knots, short pnts, short order) /* pnts, order: number of pnts NOT corrected for cyclic */ { int a, b, order2, c; @@ -617,7 +572,7 @@ void makeknots(Nurb *nu, short uv, short type) /* 0: uniform, 1: endpoints, 2: b } } -void basisNurb(float t, short order, short pnts, float *knots, float *basis, int *start, int *end) +static void basisNurb(float t, short order, short pnts, float *knots, float *basis, int *start, int *end) { float d, e; int i, i1 = 0, i2 = 0 ,j, orderpluspnts, opp2, o2; @@ -839,100 +794,13 @@ void makeNurbfaces(Nurb *nu, float *data, int rowstride) MEM_freeN(jend); } - -void makeNurbcurve_forw(Nurb *nu, float *data) -/* *data: has to be 3*4*pntsu*resolu in size and zero-ed */ -{ - BPoint *bp; - float *basisu, *sum, *fp, *in; - float u, ustart, uend, ustep, sumdiv; - int i, j, k, len, resolu, istart, iend; - int wanted, org; - - if(nu->knotsu==0) return; - if(data==0) return; - - /* allocate and init */ - len= nu->pntsu; - if(len==0) return; - sum= (float *)MEM_callocN(sizeof(float)*len, "makeNurbcurve1"); - - resolu= nu->resolu*nu->pntsu; - if(resolu==0) { - MEM_freeN(sum); - return; - } - - fp= nu->knotsu; - ustart= fp[nu->orderu-1]; - uend= fp[nu->pntsu]; - ustep= (uend-ustart)/(resolu-1); - basisu= (float *)MEM_mallocN(sizeof(float)*(nu->orderu+nu->pntsu), "makeNurbcurve3"); - - in= data; - u= ustart; - for (k = nu->orderu - 1; k < nu->pntsu; k++){ - - wanted = (int)((nu->knotsu[k+1] - nu->knotsu[k]) / ustep); - org = 4; /* equal to order */ - if (org > wanted) org = wanted; - - for (j = org; j > 0; j--){ - - basisNurb(u, nu->orderu, nu->pntsu, nu->knotsu, basisu, &istart, &iend); - /* calc sum */ - sumdiv= 0.0; - fp= sum; - for(i= istart; i<=iend; i++, fp++) { - /* do the rational component */ - *fp= basisu[i]; - sumdiv+= *fp; - } - if(sumdiv!=0.0) if(sumdiv<0.999 || sumdiv>1.001) { - /* is this normalizing needed? */ - fp= sum; - for(i= istart; i<=iend; i++, fp++) { - *fp/= sumdiv; - } - } - - /* one! (1.0) real point */ - fp= sum; - bp= nu->bp+ istart; - for(i= istart; i<=iend; i++, bp++, fp++) { - - if(*fp!=0.0) { - in[0]+= (*fp) * bp->vec[0]; - in[1]+= (*fp) * bp->vec[1]; - in[2]+= (*fp) * bp->vec[2]; - } - } - - in+=3; - - u+= ustep; - } - - if (wanted > org){ - extend_spline(in - 3 * org, org, wanted); - in += 3 * (wanted - org); - u += ustep * (wanted - org); - } - } - - /* free */ - MEM_freeN(sum); - MEM_freeN(basisu); -} - - -void makeNurbcurve(Nurb *nu, float *data, int dim) +void makeNurbcurve(Nurb *nu, float *data, int resolu, int dim) /* data has to be dim*4*pntsu*resolu in size and zero-ed */ { BPoint *bp; float u, ustart, uend, ustep, sumdiv; float *basisu, *sum, *fp, *in; - int i, len, resolu, istart, iend, cycl; + int i, len, istart, iend, cycl; if(nu->knotsu==0) return; if(nu->orderu>nu->pntsu) return; @@ -943,7 +811,7 @@ void makeNurbcurve(Nurb *nu, float *data, int dim) if(len==0) return; sum= (float *)MEM_callocN(sizeof(float)*len, "makeNurbcurve1"); - resolu= nu->resolu*nu->pntsu; + resolu*= nu->pntsu; if(resolu==0) { MEM_freeN(sum); return; @@ -1363,7 +1231,7 @@ int cu_isectLL(float *v1, float *v2, float *v3, float *v4, short cox, short coy, } -short bevelinside(BevList *bl1,BevList *bl2) +static short bevelinside(BevList *bl1,BevList *bl2) { /* is bl2 INSIDE bl1 ? with left-right method and "labda's" */ /* returns '1' if correct hole */ @@ -1422,7 +1290,7 @@ struct bevelsort { int dir; }; -int vergxcobev(const void *a1, const void *a2) +static int vergxcobev(const void *a1, const void *a2) { const struct bevelsort *x1=a1,*x2=a2; @@ -1433,7 +1301,7 @@ int vergxcobev(const void *a1, const void *a2) /* this function cannot be replaced with atan2, but why? */ -void calc_bevel_sin_cos(float x1, float y1, float x2, float y2, float *sina, float *cosa) +static void calc_bevel_sin_cos(float x1, float y1, float x2, float y2, float *sina, float *cosa) { float t01, t02, x3, y3; @@ -1470,7 +1338,7 @@ void calc_bevel_sin_cos(float x1, float y1, float x2, float y2, float *sina, flo } -void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *data_a) +static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *data_a, int resolu) { BezTriple *pprev, *next, *last; float fac, dfac, t[4]; @@ -1493,9 +1361,9 @@ void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *data_a) else next= bezt+1; fac= 0.0; - dfac= 1.0f/(float)nu->resolu; + dfac= 1.0f/(float)resolu; - for(a=0; a<nu->resolu; a++, fac+= dfac) { + for(a=0; a<resolu; a++, fac+= dfac) { set_four_ipo(fac, t, KEY_BSPLINE); @@ -1519,7 +1387,7 @@ void makeBevelList(Object *ob) BevPoint *bevp, *bevp2, *bevp1 = NULL, *bevp0; float *data, *data_a, *v1, *v2, min, inp, x1, x2, y1, y2, vec[3]; struct bevelsort *sortdata, *sd, *sd1; - int a, b, len, nr, poly; + int a, b, len, nr, poly, resolu; /* this function needs an object, because of tflag and upflag */ cu= ob->data; @@ -1532,7 +1400,11 @@ void makeBevelList(Object *ob) while(nu) { if(nu->pntsu>1) { - + if(G.rendering && cu->resolu_ren!=0) + resolu= cu->resolu_ren; + else + resolu= nu->resolu; + if((nu->type & 7)==CU_POLY) { len= nu->pntsu; @@ -1558,7 +1430,7 @@ void makeBevelList(Object *ob) } else if((nu->type & 7)==CU_BEZIER) { - len= nu->resolu*(nu->pntsu+ (nu->flagu & 1) -1)+1; /* in case last point is not cyclic */ + len= resolu*(nu->pntsu+ (nu->flagu & 1) -1)+1; /* in case last point is not cyclic */ bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelList"); BLI_addtail(&(cu->bev), bl); @@ -1577,8 +1449,8 @@ void makeBevelList(Object *ob) bezt++; } - data= MEM_mallocN(3*sizeof(float)*(nu->resolu+1), "makeBevelList2"); - data_a= MEM_callocN(sizeof(float)*(nu->resolu+1), "data_a"); + data= MEM_mallocN(3*sizeof(float)*(resolu+1), "makeBevelList2"); + data_a= MEM_callocN(sizeof(float)*(resolu+1), "data_a"); while(a--) { if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) { @@ -1598,13 +1470,13 @@ void makeBevelList(Object *ob) v2= bezt->vec[0]; /* always do all three, to prevent data hanging around */ - forward_diff_bezier(v1[0], v1[3], v2[0], v2[3], data, nu->resolu, 3); - forward_diff_bezier(v1[1], v1[4], v2[1], v2[4], data+1, nu->resolu, 3); - forward_diff_bezier(v1[2], v1[5], v2[2], v2[5], data+2, nu->resolu, 3); + forward_diff_bezier(v1[0], v1[3], v2[0], v2[3], data, resolu, 3); + forward_diff_bezier(v1[1], v1[4], v2[1], v2[4], data+1, resolu, 3); + forward_diff_bezier(v1[2], v1[5], v2[2], v2[5], data+2, resolu, 3); if((nu->type & CU_2D)==0) { if(cu->flag & CU_3D) { - alfa_bezpart(prevbezt, bezt, nu, data_a); + alfa_bezpart(prevbezt, bezt, nu, data_a, resolu); } } @@ -1620,7 +1492,7 @@ void makeBevelList(Object *ob) v1= data; v2= data_a; - nr= nu->resolu; + nr= resolu; while(nr--) { bevp->x= v1[0]; @@ -1631,7 +1503,7 @@ void makeBevelList(Object *ob) v1+=3; v2++; } - bl->nr+= nu->resolu; + bl->nr+= resolu; } prevbezt= bezt; @@ -1651,7 +1523,7 @@ void makeBevelList(Object *ob) } else if((nu->type & 7)==CU_NURBS) { if(nu->pntsv==1) { - len= nu->resolu*nu->pntsu; + len= resolu*nu->pntsu; bl= MEM_mallocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelList3"); BLI_addtail(&(cu->bev), bl); bl->nr= len; @@ -1661,7 +1533,7 @@ void makeBevelList(Object *ob) bevp= (BevPoint *)(bl+1); data= MEM_callocN(4*sizeof(float)*len, "makeBevelList4"); /* has to be zero-ed */ - makeNurbcurve(nu, data, 4); + makeNurbcurve(nu, data, resolu, 4); v1= data; while(len--) { @@ -2346,7 +2218,7 @@ void sethandlesNurb(short code) } } -void swapdata(void *adr1, void *adr2, int len) +static void swapdata(void *adr1, void *adr2, int len) { if(len<=0) return; diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index c435544ad9e..530bcb0fa59 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -650,11 +650,17 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) BezTriple *bezt, *prevbezt; BPoint *bp; float *data, *v1, *v2; - int a, len; + int a, len, resolu; nu= nubase->first; while(nu) { if(nu->hide==0) { + + if(G.rendering && cu->resolu_ren!=0) + resolu= cu->resolu_ren; + else + resolu= nu->resolu; + if((nu->type & 7)==CU_BEZIER) { /* count */ @@ -668,7 +674,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) if(a==0 && (nu->flagu & 1)) bezt= nu->bezt; if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) len++; - else len+= nu->resolu; + else len+= resolu; if(a==0 && (nu->flagu & 1)==0) len++; @@ -709,10 +715,10 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) else { v1= prevbezt->vec[1]; v2= bezt->vec[0]; - forward_diff_bezier(v1[0], v1[3], v2[0], v2[3], data, nu->resolu, 3); - forward_diff_bezier(v1[1], v1[4], v2[1], v2[4], data+1, nu->resolu, 3); - forward_diff_bezier(v1[2], v1[5], v2[2], v2[5], data+2, nu->resolu, 3); - data+= 3*nu->resolu; + forward_diff_bezier(v1[0], v1[3], v2[0], v2[3], data, resolu, 3); + forward_diff_bezier(v1[1], v1[4], v2[1], v2[4], data+1, resolu, 3); + forward_diff_bezier(v1[2], v1[5], v2[2], v2[5], data+2, resolu, 3); + data+= 3*resolu; } if(a==0 && dl->type==DL_SEGM) { @@ -724,7 +730,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) } } else if((nu->type & 7)==CU_NURBS) { - len= nu->pntsu*nu->resolu; + len= nu->pntsu*resolu; dl= MEM_callocN(sizeof(DispList), "makeDispListsurf"); dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts"); BLI_addtail(dispbase, dl); @@ -736,7 +742,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) data= dl->verts; if(nu->flagu & 1) dl->type= DL_POLY; else dl->type= DL_SEGM; - makeNurbcurve(nu, data, 3); + makeNurbcurve(nu, data, resolu, 3); } else if((nu->type & 7)==CU_POLY) { len= nu->pntsu; @@ -1161,7 +1167,7 @@ void makeDispListSurf(Object *ob, ListBase *dispbase, int forRender) if(nu->flagu & 1) dl->type= DL_POLY; else dl->type= DL_SEGM; - makeNurbcurve(nu, data, 3); + makeNurbcurve(nu, data, nu->resolu, 3); } else { len= nu->resolu*nu->resolv; diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index ff88e8b1c48..238276dac04 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -144,6 +144,8 @@ typedef struct Curve { /* default */ short resolu, resolv; + short resolu_ren, resolv_ren; + int pad2; /* font part */ short len, lines, pos, spacemode; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 3828d8c4946..39375b38dc5 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -2197,6 +2197,7 @@ static void init_render_curve(Render *re, Object *ob, int only_verts) VertRen *ver; VlakRen *vlr; DispList *dl; + ListBase olddl={NULL, NULL}; Material *matar[32]; float len, *data, *fp, *orco=NULL; float n[3], mat[4][4]; @@ -2208,11 +2209,15 @@ static void init_render_curve(Render *re, Object *ob, int only_verts) /* no modifier call here, is in makedisp */ + if(cu->resolu_ren) + SWAP(ListBase, olddl, cu->disp); + /* test displist */ - if(cu->disp.first==0) makeDispListCurveTypes(ob, 0); + if(cu->disp.first==NULL) + makeDispListCurveTypes(ob, 0); dl= cu->disp.first; - if(cu->disp.first==0) return; - + if(cu->disp.first==NULL) return; + MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); MTC_Mat4Invert(ob->imat, mat); @@ -2389,6 +2394,12 @@ static void init_render_curve(Render *re, Object *ob, int only_verts) dl= dl->next; } + + /* not very elegant... but we want original displist in UI */ + if(cu->resolu_ren) { + freedisplist(&cu->disp); + SWAP(ListBase, olddl, cu->disp); + } } /* prevent phong interpolation for giving ray shadow errors (terminator problem) */ diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 7fd7e2777ec..028f3d43540 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -2269,7 +2269,7 @@ static void editing_panel_curve_type(Object *ob, Curve *cu) uiBlockBeginAlign(block); uiDefButS(block, NUM, B_SETRESOLU, "DefResolU:", 760,160,150,19, &cu->resolu, 1.0, 1024.0, 0, 0, "Default resolution"); - //uiDefBut(block, BUT, B_SETRESOLU, "Set", 880,160,30,19, 0, 0, 0, 0, 0, "Set resolution for interpolation"); + uiDefButS(block, NUM, B_NOP, "RenResolU", 760,140,150,19, &cu->resolu_ren, 0.0f, 1024, 0, 0, "Set resolution for rendering. A value of zero skips this operation."); uiBlockBeginAlign(block); uiDefButF(block, NUM, B_MAKEDISP, "Width:", 760,90,150,19, &cu->width, 0.0, 2.0, 1, 0, "Make interpolated result thinner or fatter"); @@ -2281,9 +2281,9 @@ static void editing_panel_curve_type(Object *ob, Curve *cu) uiBlockBeginAlign(block); uiBlockSetCol(block, TH_BUT_SETTING1); - uiDefButBitS(block, TOG, CU_BACK, B_MAKEDISP, "Back", 760,130,50,19, &cu->flag, 0, 0, 0, 0, "Draw filled back for curves"); - uiDefButBitS(block, TOG, CU_FRONT, B_MAKEDISP, "Front",810,130,50,19, &cu->flag, 0, 0, 0, 0, "Draw filled front for curves"); - uiDefButBitS(block, TOG, CU_3D, B_CU3D, "3D", 860,130,50,19, &cu->flag, 0, 0, 0, 0, "Allow Curve Object to be 3d, it doesn't fill then"); + uiDefButBitS(block, TOG, CU_BACK, B_MAKEDISP, "Back", 760,115,50,19, &cu->flag, 0, 0, 0, 0, "Draw filled back for curves"); + uiDefButBitS(block, TOG, CU_FRONT, B_MAKEDISP, "Front",810,115,50,19, &cu->flag, 0, 0, 0, 0, "Draw filled front for curves"); + uiDefButBitS(block, TOG, CU_3D, B_CU3D, "3D", 860,115,50,19, &cu->flag, 0, 0, 0, 0, "Allow Curve Object to be 3d, it doesn't fill then"); } } diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index adb4d91725f..40a83d03a94 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -2850,6 +2850,7 @@ void copy_attr(short event) cu1= base->object->data; cu1->resolu= cu->resolu; + cu1->resolu_ren= cu->resolu_ren; nu= cu1->nurb.first; |