fix for [#11744] NurbCurve Radius incorrect
authorCampbell Barton <ideasman42@gmail.com>
Tue, 23 Sep 2008 13:35:32 +0000 (13:35 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 23 Sep 2008 13:35:32 +0000 (13:35 +0000)
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.

source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_curve.h
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/particle.c
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_curve_types.h
source/blender/src/buttons_editing.c
source/blender/src/drawobject.c

index 268cf34fb649c2fdd04b5cdc9ffd340eafd5d247..f123c14fddf10ceb4c9281edad4dabdeaef27e5a 100644 (file)
@@ -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
index 006e3ac1e79631aa5020ea89efcae363be4803e8..25d6d78c4aac23a97c504349c0f34b4c28d818db 100644 (file)
@@ -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);
index 49d25b0652d26d9a59d0469285ffcb30fbc4e495..c12fe920594e806b384ca964c077d6640fdfb349 100644 (file)
@@ -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 ************** */
 
 /*
index e55006b6c1cfd3cfee1455a45475ec5c7ad0ffaf..598973d6974b7e120103a9fa6cfeaae2cdb6110d 100644 (file)
@@ -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);
                                                                }
index 38f480f39b8f87a1c8eb80260c02149f56e00bfb..878cb08c95034cf1494e0de52e24554d8e16632d 100644 (file)
@@ -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);
index f24784217379e2201bce56701d1ce4b4b469963e..a193e89d26c4ad0f139543c73c57ad95a86e0b13 100644 (file)
@@ -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! */
 
index 3722c365f397dfd1f294ddaf540224b45916db47..f809cac037d0a3cbba911997fc487aafdb68f10b 100644 (file)
@@ -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;
index 8d7e2f673b6372ccebbbbf7900426d46f9e9162b..cb2feebfe8937747a73f13cdf0a262c26654e6a8 100644 (file)
@@ -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);
index 527b36d0df418813358a65ed0e27723a6112b5ae..83eeca5689f2d82d6e332daf4334607755426318 100644 (file)
@@ -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);