Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/curve.c')
-rw-r--r--source/blender/blenkernel/intern/curve.c150
1 files changed, 112 insertions, 38 deletions
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index d02a7c0ab9e..396bdda9c10 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -348,9 +348,9 @@ void freeNurb(Nurb *nu)
if(nu->bp) MEM_freeN(nu->bp);
nu->bp= 0;
if(nu->knotsu) MEM_freeN(nu->knotsu);
- nu->knotsu= 0;
+ nu->knotsu= NULL;
if(nu->knotsv) MEM_freeN(nu->knotsv);
- nu->knotsv= 0;
+ nu->knotsv= NULL;
/* if(nu->trim.first) freeNurblist(&(nu->trim)); */
MEM_freeN(nu);
@@ -393,7 +393,7 @@ Nurb *duplicateNurb(Nurb *nu)
(BPoint*)MEM_mallocN((len)* sizeof(BPoint),"duplicateNurb3");
memcpy(newnu->bp, nu->bp, len*sizeof(BPoint));
- newnu->knotsu=newnu->knotsv= 0;
+ newnu->knotsu= newnu->knotsv= NULL;
if(nu->knotsu) {
len= KNOTSU(nu);
@@ -506,6 +506,7 @@ static void calcknots(float *knots, short aantal, short order, short type)
}
}
else if(type==2) {
+ /* Warning, the order MUST be 2 or 4, if this is not enforced, the displist will be corrupt */
if(order==4) {
k= 0.34;
for(a=0;a<t;a++) {
@@ -520,6 +521,9 @@ static void calcknots(float *knots, short aantal, short order, short type)
knots[a]= (float)floor(k);
}
}
+ else {
+ printf("bez nurb curve order is not 3 or 4, should never happen\n");
+ }
}
}
@@ -529,7 +533,8 @@ static void makecyclicknots(float *knots, short pnts, short order)
int a, b, order2, c;
if(knots==0) return;
- order2=order-1;
+
+ order2=order-1;
/* do first long rows (order -1), remove identical knots at endpoints */
if(order>2) {
@@ -549,26 +554,35 @@ static void makecyclicknots(float *knots, short pnts, short order)
}
-void makeknots(Nurb *nu, short uv, short type) /* 0: uniform, 1: endpoints, 2: bezier */
+/* type - 0: uniform, 1: endpoints, 2: bezier, note, cyclic nurbs are always uniform */
+void makeknots(Nurb *nu, short uv, short type)
{
if( (nu->type & 7)==CU_NURBS ) {
- if(uv & 1) {
+ if(uv == 1) {
if(nu->knotsu) MEM_freeN(nu->knotsu);
- if(nu->pntsu>1) {
+ if(check_valid_nurb_u(nu)) {
nu->knotsu= MEM_callocN(4+sizeof(float)*KNOTSU(nu), "makeknots");
- calcknots(nu->knotsu, nu->pntsu, nu->orderu, type);
- if(nu->flagu & 1) makecyclicknots(nu->knotsu, nu->pntsu, nu->orderu);
+ if(nu->flagu & CU_CYCLIC) {
+ calcknots(nu->knotsu, nu->pntsu, nu->orderu, 0); /* cyclic should be uniform */
+ makecyclicknots(nu->knotsu, nu->pntsu, nu->orderu);
+ } else {
+ calcknots(nu->knotsu, nu->pntsu, nu->orderu, type);
+ }
}
- else nu->knotsu= 0;
- }
- if(uv & 2) {
+ else nu->knotsu= NULL;
+
+ } else if(uv == 2) {
if(nu->knotsv) MEM_freeN(nu->knotsv);
- if(nu->pntsv>1) {
+ if(check_valid_nurb_v(nu)) {
nu->knotsv= MEM_callocN(4+sizeof(float)*KNOTSV(nu), "makeknots");
- calcknots(nu->knotsv, nu->pntsv, nu->orderv, type);
- if(nu->flagv & 1) makecyclicknots(nu->knotsv, nu->pntsv, nu->orderv);
+ if(nu->flagv & CU_CYCLIC) {
+ calcknots(nu->knotsv, nu->pntsv, nu->orderv, 0); /* cyclic should be uniform */
+ makecyclicknots(nu->knotsv, nu->pntsv, nu->orderv);
+ } else {
+ calcknots(nu->knotsv, nu->pntsv, nu->orderv, type);
+ }
}
- else nu->knotsv= 0;
+ else nu->knotsv= NULL;
}
}
}
@@ -645,7 +659,7 @@ void makeNurbfaces(Nurb *nu, float *data, int rowstride)
int i, j, iofs, jofs, cycl, len, resolu, resolv;
int istart, iend, jsta, jen, *jstart, *jend, ratcomp;
- if(nu->knotsu==0 || nu->knotsv==0) return;
+ if(nu->knotsu==NULL || nu->knotsv==NULL) return;
if(nu->orderu>nu->pntsu) return;
if(nu->orderv>nu->pntsv) return;
if(data==0) return;
@@ -679,24 +693,24 @@ void makeNurbfaces(Nurb *nu, float *data, int rowstride)
fp= nu->knotsu;
ustart= fp[nu->orderu-1];
- if(nu->flagu & 1) uend= fp[nu->pntsu+nu->orderu-1];
+ if(nu->flagu & CU_CYCLIC) uend= fp[nu->pntsu+nu->orderu-1];
else uend= fp[nu->pntsu];
- ustep= (uend-ustart)/(resolu-1+(nu->flagu & 1));
+ ustep= (uend-ustart)/(resolu-1+(nu->flagu & CU_CYCLIC));
basisu= (float *)MEM_mallocN(sizeof(float)*KNOTSU(nu), "makeNurbfaces3");
fp= nu->knotsv;
vstart= fp[nu->orderv-1];
- if(nu->flagv & 1) vend= fp[nu->pntsv+nu->orderv-1];
+ if(nu->flagv & CU_CYCLIC) vend= fp[nu->pntsv+nu->orderv-1];
else vend= fp[nu->pntsv];
- vstep= (vend-vstart)/(resolv-1+(nu->flagv & 1));
+ vstep= (vend-vstart)/(resolv-1+(nu->flagv & CU_CYCLIC));
len= KNOTSV(nu);
basisv= (float *)MEM_mallocN(sizeof(float)*len*resolv, "makeNurbfaces3");
jstart= (int *)MEM_mallocN(sizeof(float)*resolv, "makeNurbfaces4");
jend= (int *)MEM_mallocN(sizeof(float)*resolv, "makeNurbfaces5");
/* precalculation of basisv and jstart,jend */
- if(nu->flagv & 1) cycl= nu->orderv-1;
+ if(nu->flagv & CU_CYCLIC) cycl= nu->orderv-1;
else cycl= 0;
v= vstart;
basis= basisv;
@@ -706,7 +720,7 @@ void makeNurbfaces(Nurb *nu, float *data, int rowstride)
v+= vstep;
}
- if(nu->flagu & 1) cycl= nu->orderu-1;
+ if(nu->flagu & CU_CYCLIC) cycl= nu->orderu-1;
else cycl= 0;
in= data;
u= ustart;
@@ -803,7 +817,7 @@ void makeNurbcurve(Nurb *nu, float *data, int resolu, int dim)
float *basisu, *sum, *fp, *in;
int i, len, istart, iend, cycl;
- if(nu->knotsu==0) return;
+ if(nu->knotsu==NULL) return;
if(nu->orderu>nu->pntsu) return;
if(data==0) return;
@@ -820,12 +834,12 @@ void makeNurbcurve(Nurb *nu, float *data, int resolu, int dim)
fp= nu->knotsu;
ustart= fp[nu->orderu-1];
- if(nu->flagu & 1) uend= fp[nu->pntsu+nu->orderu-1];
+ if(nu->flagu & CU_CYCLIC) uend= fp[nu->pntsu+nu->orderu-1];
else uend= fp[nu->pntsu];
- ustep= (uend-ustart)/(resolu-1+(nu->flagu & 1));
+ ustep= (uend-ustart)/(resolu-1+(nu->flagu & CU_CYCLIC));
basisu= (float *)MEM_mallocN(sizeof(float)*KNOTSU(nu), "makeNurbcurve3");
- if(nu->flagu & 1) cycl= nu->orderu-1;
+ if(nu->flagu & CU_CYCLIC) cycl= nu->orderu-1;
else cycl= 0;
in= data;
@@ -1425,14 +1439,14 @@ static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *
/* returns a point */
if(prevbezt==nu->bezt) {
- if(nu->flagu & 1) pprev= last;
+ if(nu->flagu & CU_CYCLIC) pprev= last;
else pprev= prevbezt;
}
else pprev= prevbezt-1;
/* next point */
if(bezt==last) {
- if(nu->flagu & 1) next= nu->bezt;
+ if(nu->flagu & CU_CYCLIC) next= nu->bezt;
else next= bezt;
}
else next= bezt+1;
@@ -1478,7 +1492,7 @@ void makeBevelList(Object *ob)
while(nu) {
/* 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(nu->pntsu<2 || ((nu->type & 7)==CU_NURBS && nu->pntsu < nu->orderu)) {
+ if(!check_valid_nurb_u(nu)) {
bl= MEM_callocN(sizeof(BevList)+1*sizeof(BevPoint), "makeBevelList");
BLI_addtail(&(cu->bev), bl);
bl->nr= 0;
@@ -1493,7 +1507,7 @@ void makeBevelList(Object *ob)
bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelList");
BLI_addtail(&(cu->bev), bl);
- if(nu->flagu & 1) bl->poly= 0;
+ if(nu->flagu & CU_CYCLIC) bl->poly= 0;
else bl->poly= -1;
bl->nr= len;
bl->flag= 0;
@@ -1512,17 +1526,17 @@ void makeBevelList(Object *ob)
}
else if((nu->type & 7)==CU_BEZIER) {
- len= resolu*(nu->pntsu+ (nu->flagu & 1) -1)+1; /* in case last point is not cyclic */
+ 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");
BLI_addtail(&(cu->bev), bl);
- if(nu->flagu & 1) bl->poly= 0;
+ if(nu->flagu & CU_CYCLIC) bl->poly= 0;
else bl->poly= -1;
bevp= (BevPoint *)(bl+1);
a= nu->pntsu-1;
bezt= nu->bezt;
- if(nu->flagu & 1) {
+ if(nu->flagu & CU_CYCLIC) {
a++;
prevbezt= nu->bezt+(nu->pntsu-1);
}
@@ -1595,7 +1609,7 @@ void makeBevelList(Object *ob)
MEM_freeN(data);
MEM_freeN(data_a);
- if((nu->flagu & 1)==0) { /* not cyclic: endpoint */
+ 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];
@@ -1611,7 +1625,7 @@ void makeBevelList(Object *ob)
BLI_addtail(&(cu->bev), bl);
bl->nr= len;
bl->flag= 0;
- if(nu->flagu & 1) bl->poly= 0;
+ if(nu->flagu & CU_CYCLIC) bl->poly= 0;
else bl->poly= -1;
bevp= (BevPoint *)(bl+1);
@@ -2209,7 +2223,7 @@ void calchandlesNurb(Nurb *nu) /* first, if needed, set handle flags */
a= nu->pntsu;
bezt= nu->bezt;
- if(nu->flagu & 1) prev= bezt+(a-1);
+ if(nu->flagu & CU_CYCLIC) prev= bezt+(a-1);
else prev= 0;
next= bezt+1;
@@ -2217,7 +2231,7 @@ void calchandlesNurb(Nurb *nu) /* first, if needed, set handle flags */
calchandleNurb(bezt, prev, next, 0);
prev= bezt;
if(a==1) {
- if(nu->flagu & 1) next= nu->bezt;
+ if(nu->flagu & CU_CYCLIC) next= nu->bezt;
else next= 0;
}
else next++;
@@ -2608,3 +2622,63 @@ void curve_applyVertexCos(Curve *cu, ListBase *lb, float (*vertexCos)[3])
}
}
}
+
+int check_valid_nurb_u( struct Nurb *nu )
+{
+ if (nu==NULL) return 0;
+ if (nu->pntsu <= 1) return 0;
+ if ((nu->type & 7)!=CU_NURBS) return 1; /* not a nurb, lets assume its valid */
+
+ if (nu->pntsu < nu->orderu) return 0;
+ if (((nu->flag & CU_CYCLIC)==0) && ((nu->flagu>>1) & 2)) { /* Bezier U Endpoints */
+ if (nu->orderu==4) {
+ if (nu->pntsu < 5) return 0; /* bezier with 4 orderu needs 5 points */
+ } else if (nu->orderu != 3) return 0; /* order must be 3 or 4 */
+ }
+ return 1;
+}
+int check_valid_nurb_v( struct Nurb *nu)
+{
+ if (nu==NULL) return 0;
+ if (nu->pntsv <= 1) return 0;
+ if ((nu->type & 7)!=CU_NURBS) return 1; /* not a nurb, lets assume its valid */
+
+ if (nu->pntsv < nu->orderv) return 0;
+ if (((nu->flag & CU_CYCLIC)==0) && ((nu->flagv>>1) & 2)) { /* Bezier V Endpoints */
+ if (nu->orderv==4) {
+ if (nu->pntsv < 5) return 0; /* bezier with 4 orderu needs 5 points */
+ } else if (nu->orderv != 3) return 0; /* order must be 3 or 4 */
+ }
+ return 1;
+}
+
+int clamp_nurb_order_u( struct Nurb *nu )
+{
+ int change = 0;
+ if(nu->pntsu<nu->orderu) {
+ nu->orderu= nu->pntsu;
+ change= 1;
+ }
+ if(((nu->flag & CU_CYCLIC)==0) && (nu->flagu>>1)&2) {
+ CLAMP(nu->orderu, 3,4);
+ change= 1;
+ }
+ return change;
+}
+
+int clamp_nurb_order_v( struct Nurb *nu)
+{
+ int change = 0;
+ if(nu->pntsv<nu->orderv) {
+ nu->orderv= nu->pntsv;
+ change= 1;
+ }
+ if(((nu->flag & CU_CYCLIC)==0) && (nu->flagv>>1)&2) {
+ CLAMP(nu->orderv, 3,4);
+ change= 1;
+ }
+ return change;
+}
+
+
+