diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 268cf34fb64..f123c14fddf 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -41,7 +41,7 @@ struct ListBase; struct MemFile; #define BLENDER_VERSION 247 -#define BLENDER_SUBVERSION 5 +#define BLENDER_SUBVERSION 6 #define BLENDER_MINVERSION 245 #define BLENDER_MINSUBVERSION 15 diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 006e3ac1e79..25d6d78c4aa 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -65,15 +65,14 @@ void minmaxNurb( struct Nurb *nu, float *min, float *max); void makeknots( struct Nurb *nu, short uv, short type); -void makeNurbfaces( struct Nurb *nu, float *data, int rowstride); -void makeNurbcurve( struct Nurb *nu, float *data, int resolu, int dim); +void makeNurbfaces(struct Nurb *nu, float *coord_array, int rowstride); +void makeNurbcurve(struct Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, int resolu); 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); void makeBevelList( struct Object *ob); -float calc_curve_subdiv_radius( struct Curve *cu, struct Nurb *nu, int cursubdiv); void calchandleNurb( struct BezTriple *bezt, struct BezTriple *prev, struct BezTriple *next, int mode); void calchandlesNurb( struct Nurb *nu); diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 49d25b0652d..c12fe920594 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -247,7 +247,7 @@ void tex_space_curve(Curve *cu) { DispList *dl; BoundBox *bb; - float *data, min[3], max[3], loc[3], size[3]; + float *fp, min[3], max[3], loc[3], size[3]; int tot, doit= 0; if(cu->bb==NULL) cu->bb= MEM_callocN(sizeof(BoundBox), "boundbox"); @@ -262,10 +262,10 @@ void tex_space_curve(Curve *cu) else tot= dl->nr*dl->parts; if(tot) doit= 1; - data= dl->verts; + fp= dl->verts; while(tot--) { - DO_MINMAX(data, min, max); - data+= 3; + DO_MINMAX(fp, min, max); + fp += 3; } dl= dl->next; } @@ -650,8 +650,8 @@ static void basisNurb(float t, short order, short pnts, float *knots, float *bas } -void makeNurbfaces(Nurb *nu, float *data, int rowstride) -/* data has to be 3*4*resolu*resolv in size, and zero-ed */ +void makeNurbfaces(Nurb *nu, float *coord_array, int rowstride) +/* coord_array has to be 3*4*resolu*resolv in size, and zero-ed */ { BPoint *bp; float *basisu, *basis, *basisv, *sum, *fp, *in; @@ -662,7 +662,7 @@ void makeNurbfaces(Nurb *nu, float *data, int rowstride) if(nu->knotsu==NULL || nu->knotsv==NULL) return; if(nu->orderu>nu->pntsu) return; if(nu->orderv>nu->pntsv) return; - if(data==0) return; + if(coord_array==NULL) return; /* allocate and initialize */ len= nu->pntsu*nu->pntsv; @@ -722,7 +722,7 @@ void makeNurbfaces(Nurb *nu, float *data, int rowstride) if(nu->flagu & CU_CYCLIC) cycl= nu->orderu-1; else cycl= 0; - in= data; + in= coord_array; u= ustart; while(resolu--) { @@ -809,17 +809,19 @@ void makeNurbfaces(Nurb *nu, float *data, int rowstride) MEM_freeN(jend); } -void makeNurbcurve(Nurb *nu, float *data, int resolu, int dim) -/* data has to be dim*4*pntsu*resolu in size and zero-ed */ +void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, int resolu) +/* coord_array has to be 3*4*pntsu*resolu in size and zero-ed + * tilt_array and radius_array will be written to if valid */ { BPoint *bp; float u, ustart, uend, ustep, sumdiv; - float *basisu, *sum, *fp, *in; + float *basisu, *sum, *fp; + float *coord_fp= coord_array, *tilt_fp= tilt_array, *radius_fp= radius_array; int i, len, istart, iend, cycl; if(nu->knotsu==NULL) return; if(nu->orderu>nu->pntsu) return; - if(data==0) return; + if(coord_array==0) return; /* allocate and initialize */ len= nu->pntsu; @@ -842,7 +844,6 @@ void makeNurbcurve(Nurb *nu, float *data, int resolu, int dim) if(nu->flagu & CU_CYCLIC) cycl= nu->orderu-1; else cycl= 0; - in= data; u= ustart; while(resolu--) { @@ -877,17 +878,24 @@ void makeNurbcurve(Nurb *nu, float *data, int resolu, int dim) if(*fp!=0.0) { - in[0]+= (*fp) * bp->vec[0]; - in[1]+= (*fp) * bp->vec[1]; - if(dim>=3) { - in[2]+= (*fp) * bp->vec[2]; - if(dim==4) in[3]+= (*fp) * bp->alfa; - } + coord_fp[0]+= (*fp) * bp->vec[0]; + coord_fp[1]+= (*fp) * bp->vec[1]; + coord_fp[2]+= (*fp) * bp->vec[2]; + + if (tilt_fp) + (*tilt_fp) += (*fp) * bp->alfa; + + if (radius_fp) + (*radius_fp) += (*fp) * bp->radius; + } } - in+= dim; - + coord_fp+= 3; + + if (tilt_fp) tilt_fp++; + if (radius_fp) radius_fp++; + u+= ustep; } @@ -932,7 +940,7 @@ float *make_orco_surf(Object *ob) Nurb *nu; int a, b, tot=0; int sizeu, sizev; - float *data, *orco; + float *fp, *coord_array; /* first calculate the size of the datablock */ nu= cu->nurb.first; @@ -955,7 +963,7 @@ float *make_orco_surf(Object *ob) nu= nu->next; } /* makeNurbfaces wants zeros */ - data= orco= MEM_callocN(3*sizeof(float)*tot, "make_orco"); + fp= coord_array= MEM_callocN(3*sizeof(float)*tot, "make_orco"); nu= cu->nurb.first; while(nu) { @@ -969,15 +977,15 @@ float *make_orco_surf(Object *ob) for(b=0; b< sizeu; b++) { for(a=0; a< sizev; a++) { - if(sizev <2) data[0]= 0.0f; - else data[0]= -1.0f + 2.0f*((float)a)/(sizev - 1); + if(sizev <2) fp[0]= 0.0f; + else fp[0]= -1.0f + 2.0f*((float)a)/(sizev - 1); - if(sizeu <2) data[1]= 0.0f; - else data[1]= -1.0f + 2.0f*((float)b)/(sizeu - 1); + if(sizeu <2) fp[1]= 0.0f; + else fp[1]= -1.0f + 2.0f*((float)b)/(sizeu - 1); - data[2]= 0.0; + fp[2]= 0.0; - data+= 3; + fp+= 3; } } } @@ -999,10 +1007,10 @@ float *make_orco_surf(Object *ob) tdata = _tdata + 3 * (use_b * nu->resolv + use_a); - data[0]= (tdata[0]-cu->loc[0])/cu->size[0]; - data[1]= (tdata[1]-cu->loc[1])/cu->size[1]; - data[2]= (tdata[2]-cu->loc[2])/cu->size[2]; - data+= 3; + fp[0]= (tdata[0]-cu->loc[0])/cu->size[0]; + fp[1]= (tdata[1]-cu->loc[1])/cu->size[1]; + fp[2]= (tdata[2]-cu->loc[2])/cu->size[2]; + fp+= 3; } } @@ -1012,7 +1020,7 @@ float *make_orco_surf(Object *ob) nu= nu->next; } - return orco; + return coord_array; } @@ -1024,7 +1032,7 @@ float *make_orco_curve(Object *ob) Curve *cu = ob->data; DispList *dl; int u, v, numVerts; - float *fp, *orco; + float *fp, *coord_array; int remakeDisp = 0; if (!(cu->flag&CU_UV_ORCO) && cu->key && cu->key->refkey) { @@ -1052,7 +1060,7 @@ float *make_orco_curve(Object *ob) } } - fp= orco= MEM_mallocN(3*sizeof(float)*numVerts, "cu_orco"); + fp= coord_array= MEM_mallocN(3*sizeof(float)*numVerts, "cu_orco"); for (dl=cu->disp.first; dl; dl=dl->next) { if (dl->type==DL_INDEX3) { for (u=0; unr; u++, fp+=3) { @@ -1102,7 +1110,7 @@ float *make_orco_curve(Object *ob) makeDispListCurveTypes(ob, 0); } - return orco; + return coord_array; } @@ -1429,7 +1437,7 @@ static void calc_bevel_sin_cos(float x1, float y1, float x2, float y2, float *si } -static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *data_a, int resolu) +static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *tilt_array, float *radius_array, int resolu) { BezTriple *pprev, *next, *last; float fac, dfac, t[4]; @@ -1455,10 +1463,30 @@ static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float * dfac= 1.0f/(float)resolu; for(a=0; atilt_interp==3) { /* May as well support for tilt also 2.47 ease interp */ + tilt_array[a] = prevbezt->alfa + (bezt->alfa - prevbezt->alfa)*(3.0f*fac*fac - 2.0f*fac*fac*fac); + } else { + set_four_ipo(fac, t, nu->tilt_interp); + tilt_array[a]= t[0]*pprev->alfa + t[1]*prevbezt->alfa + t[2]*bezt->alfa + t[3]*next->alfa; + } + } - set_four_ipo(fac, t, nu->tilt_interp); - - data_a[a]= t[0]*pprev->alfa + t[1]*prevbezt->alfa + t[2]*bezt->alfa + t[3]*next->alfa; + if (radius_array) { + if (nu->radius_interp==3) { + /* Support 2.47 ease interp + * Note! - this only takes the 2 points into account, + * giving much more localized results to changes in radius, sometimes you want that */ + radius_array[a] = prevbezt->radius + (bezt->radius - prevbezt->radius)*(3.0f*fac*fac - 2.0f*fac*fac*fac); + } else { + + /* reuse interpolation from tilt if we can */ + if (tilt_array==NULL || nu->tilt_interp != nu->radius_interp) { + set_four_ipo(fac, t, nu->radius_interp); + } + radius_array[a]= t[0]*pprev->radius + t[1]*prevbezt->radius + t[2]*bezt->radius + t[3]*next->radius; + } + } } } @@ -1476,13 +1504,19 @@ void makeBevelList(Object *ob) BPoint *bp; BevList *bl, *blnew, *blnext; BevPoint *bevp, *bevp2, *bevp1 = NULL, *bevp0; - float *data, *data_a, *v1, *v2, min, inp, x1, x2, y1, y2, vec[3]; + float min, inp, x1, x2, y1, y2, vec[3]; + float *coord_array, *tilt_array=NULL, *radius_array=NULL, *coord_fp, *tilt_fp=NULL, *radius_fp; + float *v1, *v2; struct bevelsort *sortdata, *sd, *sd1; int a, b, nr, poly, resolu, len=0; - + int do_tilt, do_radius; + /* this function needs an object, because of tflag and upflag */ cu= ob->data; + /* do we need to calculate the radius for each point? */ + do_radius = (cu->bevobj || cu->taperobj || (cu->flag & CU_FRONT) || (cu->flag & CU_BACK)) ? 0 : 1; + /* STEP 1: MAKE POLYS */ BLI_freelistN(&(cu->bev)); @@ -1490,10 +1524,14 @@ void makeBevelList(Object *ob) else nu= cu->nurb.first; while(nu) { + + /* check if we will calculate tilt data */ + do_tilt = ((nu->type & CU_2D) && (cu->flag & CU_3D)==0) ? 0 : 1; + /* check we are a single point? also check we are not a surface and that the orderu is sane, * enforced in the UI but can go wrong possibly */ if(!check_valid_nurb_u(nu)) { - bl= MEM_callocN(sizeof(BevList)+1*sizeof(BevPoint), "makeBevelList"); + bl= MEM_callocN(sizeof(BevList)+1*sizeof(BevPoint), "makeBevelList1"); BLI_addtail(&(cu->bev), bl); bl->nr= 0; } else { @@ -1504,7 +1542,7 @@ void makeBevelList(Object *ob) if((nu->type & 7)==CU_POLY) { len= nu->pntsu; - bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelList"); + bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelList2"); BLI_addtail(&(cu->bev), bl); if(nu->flagu & CU_CYCLIC) bl->poly= 0; @@ -1519,6 +1557,7 @@ void makeBevelList(Object *ob) bevp->y= bp->vec[1]; bevp->z= bp->vec[2]; bevp->alfa= bp->alfa; + bevp->radius= bp->radius; bevp->f1= SELECT; bevp++; bp++; @@ -1527,7 +1566,7 @@ void makeBevelList(Object *ob) else if((nu->type & 7)==CU_BEZIER) { len= resolu*(nu->pntsu+ (nu->flagu & CU_CYCLIC) -1)+1; /* in case last point is not cyclic */ - bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelList"); + bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelBPoints"); BLI_addtail(&(cu->bev), bl); if(nu->flagu & CU_CYCLIC) bl->poly= 0; @@ -1545,8 +1584,13 @@ void makeBevelList(Object *ob) bezt++; } - data= MEM_mallocN(3*sizeof(float)*(resolu+1), "makeBevelList2"); - data_a= MEM_callocN(sizeof(float)*(resolu+1), "data_a"); + coord_array= coord_fp= MEM_mallocN(3*sizeof(float)*(resolu+1), "makeBevelCoords"); + + if(do_tilt) + tilt_array= tilt_fp= MEM_callocN(sizeof(float)*(resolu+1), "makeBevelTilt"); + + if (do_radius) + radius_array= radius_fp= MEM_callocN(sizeof(float)*(resolu+1), "nakeBevelRadius"); while(a--) { if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) { @@ -1555,6 +1599,7 @@ void makeBevelList(Object *ob) bevp->y= prevbezt->vec[1][1]; bevp->z= prevbezt->vec[1][2]; bevp->alfa= prevbezt->alfa; + bevp->radius= prevbezt->radius; bevp->f1= SELECT; bevp->f2= 0; bevp++; @@ -1566,16 +1611,12 @@ 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, 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, resolu); - } - } + forward_diff_bezier(v1[0], v1[3], v2[0], v2[3], coord_array, resolu, 3); + forward_diff_bezier(v1[1], v1[4], v2[1], v2[4], coord_array+1, resolu, 3); + forward_diff_bezier(v1[2], v1[5], v2[2], v2[5], coord_array+2, resolu, 3); + if (do_tilt || do_radius) + alfa_bezpart(prevbezt, bezt, nu, tilt_array, radius_array, resolu); /* indicate with handlecodes double points */ if(prevbezt->h1==prevbezt->h2) { @@ -1586,18 +1627,28 @@ void makeBevelList(Object *ob) else if(prevbezt->h2==0 || prevbezt->h2==HD_VECT) bevp->f1= SELECT; } - v1= data; - v2= data_a; nr= resolu; + coord_fp = coord_array; + tilt_fp = tilt_array; + radius_fp = radius_array; + while(nr--) { - bevp->x= v1[0]; - bevp->y= v1[1]; - bevp->z= v1[2]; - bevp->alfa= v2[0]; + bevp->x= coord_fp[0]; + bevp->y= coord_fp[1]; + bevp->z= coord_fp[2]; + coord_fp+=3; + + if (do_tilt) { + bevp->alfa= *tilt_fp; + tilt_fp++; + } + + if (do_radius) { + bevp->radius= *radius_fp; + radius_fp++; + } bevp++; - v1+=3; - v2++; } bl->nr+= resolu; @@ -1606,17 +1657,19 @@ void makeBevelList(Object *ob) bezt++; } - MEM_freeN(data); - MEM_freeN(data_a); + MEM_freeN(coord_array); + if (do_tilt) MEM_freeN(tilt_array); + if (do_radius) MEM_freeN(radius_array); + coord_array = tilt_array = radius_array = NULL; if((nu->flagu & CU_CYCLIC)==0) { /* not cyclic: endpoint */ bevp->x= prevbezt->vec[1][0]; bevp->y= prevbezt->vec[1][1]; bevp->z= prevbezt->vec[1][2]; bevp->alfa= prevbezt->alfa; + bevp->radius= prevbezt->radius; bl->nr++; } - } else if((nu->type & 7)==CU_NURBS) { if(nu->pntsv==1) { @@ -1629,21 +1682,40 @@ void makeBevelList(Object *ob) else bl->poly= -1; bevp= (BevPoint *)(bl+1); - data= MEM_callocN(4*sizeof(float)*len, "makeBevelList4"); /* has to be zero-ed */ - makeNurbcurve(nu, data, resolu, 4); + coord_array= coord_fp= MEM_callocN(3*sizeof(float)*len, "makeBevelCoords"); /* has to be zero-ed */ + + if(do_tilt) + tilt_array= tilt_fp= MEM_callocN(sizeof(float)*len, "makeBevelTilt"); + + if (do_radius) + radius_array= radius_fp= MEM_callocN(sizeof(float)*len, "nakeBevelRadius"); + + makeNurbcurve(nu, coord_array, tilt_array, radius_array, resolu); - v1= data; while(len--) { - bevp->x= v1[0]; - bevp->y= v1[1]; - bevp->z= v1[2]; - bevp->alfa= v1[3]; + bevp->x= coord_fp[0]; + bevp->y= coord_fp[1]; + bevp->z= coord_fp[2]; + coord_fp+=3; + + if (do_tilt) { + bevp->alfa= *tilt_fp; + tilt_fp++; + } + + if (do_radius) { + bevp->radius= *radius_fp; + radius_fp++; + } + bevp->f1= bevp->f2= 0; bevp++; - v1+=4; } - MEM_freeN(data); + MEM_freeN(coord_array); + if (do_tilt) MEM_freeN(tilt_array); + if (do_radius) MEM_freeN(radius_array); + coord_array = tilt_array = radius_array = NULL; } } } @@ -1678,7 +1750,7 @@ void makeBevelList(Object *ob) blnext= bl->next; if(bl->nr && bl->flag) { nr= bl->nr- bl->flag+1; /* +1 because vectorbezier sets flag too */ - blnew= MEM_mallocN(sizeof(BevList)+nr*sizeof(BevPoint), "makeBevelList"); + blnew= MEM_mallocN(sizeof(BevList)+nr*sizeof(BevPoint), "makeBevelList4"); memcpy(blnew, bl, sizeof(BevList)); blnew->nr= 0; BLI_remlink(&(cu->bev), bl); @@ -1886,137 +1958,6 @@ void makeBevelList(Object *ob) } } -/* calculates a bevel width (radius) for a particular subdivided curve part, - * based on the radius value of the surrounding CVs */ -float calc_curve_subdiv_radius(Curve *cu, Nurb *nu, int cursubdiv) -{ - BezTriple *bezt, *beztfirst, *beztlast, *beztnext, *beztprev; - BPoint *bp, *bpfirst, *bplast; - int resolu; - float prevrad=0.0, nextrad=0.0, rad=0.0, ratio=0.0; - int vectseg=0, subdivs=0; - - if((nu==NULL) || (nu->pntsu<=1)) return 1.0; - bezt= nu->bezt; - bp = nu->bp; - - if(G.rendering && cu->resolu_ren!=0) resolu= cu->resolu_ren; - else resolu= nu->resolu; - - if(((nu->type & 7)==CU_BEZIER) && (bezt != NULL)) { - beztfirst = nu->bezt; - beztlast = nu->bezt + (nu->pntsu - 1); - - /* loop through the CVs to end up with a pointer to the CV before the subdiv in question, and a ratio - * of how far that subdiv is between this CV and the next */ - while(bezt<=beztlast) { - beztnext = bezt+1; - beztprev = bezt-1; - vectseg=0; - - if (subdivs==cursubdiv) { - ratio= 0.0; - break; - } - - /* check to see if we're looking at a vector segment (no subdivisions) */ - if (nu->flagu & CU_CYCLIC) { - if (bezt == beztfirst) { - if ((beztlast->h2==HD_VECT) && (bezt->h1==HD_VECT)) vectseg = 1; - } else { - if ((beztprev->h2==HD_VECT) && (bezt->h1==HD_VECT)) vectseg = 1; - } - } else if ((bezt->h2==HD_VECT) && (beztnext->h1==HD_VECT)) vectseg = 1; - - - if (vectseg==0) { - /* if it's NOT a vector segment, check to see if the subdiv falls within the segment */ - subdivs += resolu; - - if (cursubdiv < subdivs) { - ratio = 1.0 - ((subdivs - cursubdiv)/(float)resolu); - break; - } - } else { - /* must be a vector segment.. loop again! */ - subdivs += 1; - } - - bezt++; - } - - /* Now we have a nice bezt pointer to the CV that we want. But cyclic messes it up, so must correct for that.. - * (cyclic goes last-> first -> first+1 -> first+2 -> ...) */ - if (nu->flagu & CU_CYCLIC) { - if (bezt == beztfirst) bezt = beztlast; - else bezt--; - } - - /* find the radii at the bounding CVs and interpolate between them based on ratio */ - rad = prevrad = bezt->radius; - - if ((bezt == beztlast) && (nu->flagu & CU_CYCLIC)) { /* loop around */ - bezt= beztfirst; - } else if (bezt != beztlast) { - bezt++; - } - nextrad = bezt->radius; - - } - else if( ( ((nu->type & 7)==CU_NURBS) || ((nu->type & 7)==CU_POLY)) && (bp != NULL)) { - /* follows similar algo as for bezt above */ - bpfirst = nu->bp; - bplast = nu->bp + (nu->pntsu - 1); - - if ((nu->type & 7)==CU_POLY) resolu=1; - - while(bp<=bplast) { - if (subdivs==cursubdiv) { - ratio= 0.0; - break; - } - - subdivs += resolu; - - if (cursubdiv < subdivs) { - ratio = 1.0 - ((subdivs - cursubdiv)/(float)resolu); - break; - } - - bp++; - } - - if ( ((nu->type & 7)==CU_NURBS) && (nu->flagu & CU_CYCLIC)) { - if (bp >= bplast) bp = bpfirst; - else bp++; - } else if ( bp > bplast ) { - /* this can happen in rare cases, refer to bug [#8596] */ - bp = bplast; - } - - rad = prevrad = bp->radius; - - if ((bp == bplast) && (nu->flagu & CU_CYCLIC)) { /* loop around */ - bp= bpfirst; - } else if (bp < bplast) { - bp++; - } - nextrad = bp->radius; - - } - - - if (nextrad != prevrad) { - /* smooth interpolation */ - rad = prevrad + (nextrad-prevrad)*(3.0f*ratio*ratio - 2.0f*ratio*ratio*ratio); - } - - if (rad > 0.0) - return rad; - else - return 1.0; -} - /* ****************** HANDLES ************** */ /* diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index e55006b6c1c..598973d6974 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -871,7 +871,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) data= dl->verts; if(nu->flagu & CU_CYCLIC) dl->type= DL_POLY; else dl->type= DL_SEGM; - makeNurbcurve(nu, data, resolu, 3); + makeNurbcurve(nu, data, NULL, NULL, resolu); } else if((nu->type & 7)==CU_POLY) { len= nu->pntsu; @@ -1339,7 +1339,7 @@ void makeDispListSurf(Object *ob, ListBase *dispbase, int forRender) if(nu->flagu & CU_CYCLIC) dl->type= DL_POLY; else dl->type= DL_SEGM; - makeNurbcurve(nu, data, nu->resolu, 3); + makeNurbcurve(nu, data, NULL, NULL, nu->resolu); } else { len= nu->resolu*nu->resolv; @@ -1486,7 +1486,7 @@ void makeDispListCurveTypes(Object *ob, int forOrco) float fac=1.0; if (cu->taperobj==NULL) { if ( (cu->bevobj!=NULL) || !((cu->flag & CU_FRONT) || (cu->flag & CU_BACK)) ) - fac = calc_curve_subdiv_radius(cu, nu, a); + fac = bevp->radius; } else { fac = calc_taper(cu->taperobj, a, bl->nr); } diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 38f480f39b8..878cb08c950 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -1674,7 +1674,6 @@ int do_guide(ParticleKey *state, int pa_num, float time, ListBase *lb) /* TODO */ //else{ ///* curve size*/ - // calc_curve_subdiv_radius(cu,cu->nurb.first,((Nurb*)cu->nurb.first)-> //} par.co[0]=par.co[1]=par.co[2]=0.0f; VECCOPY(key.co,pa_loc); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index f2478421737..a193e89d26c 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7868,6 +7868,20 @@ static void do_versions(FileData *fd, Library *lib, Main *main) la->skyblendfac= 1.0f; } } + + /* set the curve radius interpolation to 2.47 default - easy */ + if (main->versionfile < 247 || (main->versionfile == 247 && main->subversionfile < 6)) { + Curve *cu; + Nurb *nu; + + for(cu= main->curve.first; cu; cu= cu->id.next) { + for(nu= cu->nurb.first; nu; nu= nu->next) { + if (nu) { + nu->radius_interp = 3; + } + } + } + } /* 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/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 3722c365f39..f809cac037d 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -68,7 +68,7 @@ typedef struct BevList { # # typedef struct BevPoint { - float x, y, z, alfa, sina, cosa, mat[3][3]; + float x, y, z, alfa, radius, sina, cosa, mat[3][3]; short f1, f2; } BevPoint; @@ -115,7 +115,7 @@ typedef struct Nurb { BezTriple *bezt; short tilt_interp; /* KEY_LINEAR, KEY_CARDINAL, KEY_BSPLINE */ - short pad; + short radius_interp; int charidx; } Nurb; diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 8d7e2f673b6..cb2feebfe89 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -3361,9 +3361,9 @@ static void editing_panel_curve_tools(Object *ob, Curve *cu) if(ob->type==OB_CURVE) { uiDefBut(block, LABEL, 0, "Convert", 463,173,72, 18, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); - uiDefBut(block, BUT,B_CONVERTPOLY,"Poly", 467,152,72, 18, 0, 0, 0, 0, 0, "Converts selected into regular Polygon vertices"); - uiDefBut(block, BUT,B_CONVERTBEZ,"Bezier", 467,132,72, 18, 0, 0, 0, 0, 0, "Converts selected to Bezier triples"); - uiDefBut(block, BUT,B_CONVERTNURB,"Nurb", 467,112,72, 18, 0, 0, 0, 0, 0, "Converts selected to Nurbs Points"); + uiDefBut(block, BUT,B_CONVERTPOLY,"Poly", 450,152,110, 18, 0, 0, 0, 0, 0, "Converts selected into regular Polygon vertices"); + uiDefBut(block, BUT,B_CONVERTBEZ,"Bezier", 450,132,110, 18, 0, 0, 0, 0, 0, "Converts selected to Bezier triples"); + uiDefBut(block, BUT,B_CONVERTNURB,"Nurb", 450,112,110, 18, 0, 0, 0, 0, 0, "Converts selected to Nurbs Points"); } uiBlockBeginAlign(block); uiDefBut(block, BUT,B_UNIFU,"Uniform U", 565,152,102, 18, 0, 0, 0, 0, 0, "Nurbs only; interpolated result doesn't go to end points in U"); @@ -3374,7 +3374,7 @@ static void editing_panel_curve_tools(Object *ob, Curve *cu) uiDefBut(block, BUT,B_BEZV,"V", 670,112,50, 18, 0, 0, 0, 0, 0, "Nurbs only; make knots array mimic a Bezier in V"); uiBlockEndAlign(block); - uiDefBut(block, BUT,B_SETWEIGHT,"Set Weight", 465,11,95,49, 0, 0, 0, 0, 0, "Nurbs only; set weight for select points"); + uiDefBut(block, BUT,B_SETWEIGHT,"Set Weight", 450,11,110,49, 0, 0, 0, 0, 0, "Nurbs only; set weight for select points"); uiBlockBeginAlign(block); uiDefButF(block, NUM,0,"Weight:", 565,36,102,22, &editbutweight, 0.01, 100.0, 10, 0, "The weight you can assign"); @@ -3393,10 +3393,15 @@ static void editing_panel_curve_tools(Object *ob, Curve *cu) if(nu) { if (ob->type==OB_CURVE) { uiDefBut(block, LABEL, 0, "Tilt", - 467,87,72, 18, 0, 0, 0, 0, 0, ""); + 450,90,72, 18, 0, 0, 0, 0, 0, ""); /* KEY_LINEAR, KEY_CARDINAL, KEY_BSPLINE */ - uiDefButS(block, MENU, B_TILTINTERP, "Tilt Interpolation %t|Linear %x0|Cardinal %x1|BSpline %x2", - 467,67,72, 18, &(nu->tilt_interp), 0, 0, 0, 0, "Tilt interpolation"); + uiDefButS(block, MENU, B_TILTINTERP, "Tilt Interpolation %t|Linear%x0|Cardinal%x1|BSpline %x2|Ease%x3", + 495,90,66, 18, &(nu->tilt_interp), 0, 0, 0, 0, "Tadius interpolation for 3D curves"); + + uiDefBut(block, LABEL, 0, "Radius", + 450,70,72, 18, 0, 0, 0, 0, 0, ""); + uiDefButS(block, MENU, B_TILTINTERP, "Radius Interpolation %t|Linear%x0|Cardinal%x1|BSpline %x2|Ease%x3", + 495,70,66, 18, &(nu->radius_interp), 0, 0, 0, 0, "Radius interpolation"); } uiBlockBeginAlign(block); diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 527b36d0df4..83eeca5689f 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -4004,16 +4004,14 @@ static void drawnurb(Base *base, Nurb *nurb, int dt) while (nr-->0) { /* accounts for empty bevel lists */ float ox,oy,oz; // Offset perpendicular to the curve float dx,dy,dz; // Delta along the curve - - fac = calc_curve_subdiv_radius(cu, nu, (bl->nr - nr)) * G.scene->editbutsize; - ox = fac*bevp->mat[0][0]; - oy = fac*bevp->mat[0][1]; - oz = fac*bevp->mat[0][2]; + ox = bevp->radius*bevp->mat[0][0]; + oy = bevp->radius*bevp->mat[0][1]; + oz = bevp->radius*bevp->mat[0][2]; - dx = fac*bevp->mat[2][0]; - dy = fac*bevp->mat[2][1]; - dz = fac*bevp->mat[2][2]; + dx = bevp->radius*bevp->mat[2][0]; + dy = bevp->radius*bevp->mat[2][1]; + dz = bevp->radius*bevp->mat[2][2]; glBegin(GL_LINE_STRIP); glVertex3f(bevp->x - ox - dx, bevp->y - oy - dy, bevp->z - oz - dz);