fix for [#11744] NurbCurve Radius incorrect

removed calc_curve_subdiv_radius(), curve radius is now calculated the same way as tilt.

Added radius interpolation menu matching tilt interpolation, needed to add "Ease" interpolation type to keep 2.47 curves looking the same.
This commit is contained in:
Campbell Barton 2008-09-23 13:35:32 +00:00
parent 47032c251d
commit d72d4a5058
9 changed files with 190 additions and 234 deletions

@ -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

@ -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);

@ -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; u<dl->nr; 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; a<resolu; a++, fac+= dfac) {
if (tilt_array) {
if (nu->tilt_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 ************** */
/*

@ -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);
}

@ -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);

@ -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! */

@ -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;

@ -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);

@ -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);