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:
-rw-r--r--source/blender/blenkernel/BKE_curve.h7
-rw-r--r--source/blender/blenkernel/intern/curve.c80
-rw-r--r--source/blender/blenkernel/intern/displist.c2
-rw-r--r--source/blender/blenkernel/intern/font.c4
-rw-r--r--source/blender/src/buttons_editing.c8
-rw-r--r--source/blender/src/editcurve.c138
6 files changed, 162 insertions, 77 deletions
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 60444675047..edb4721de4e 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -84,5 +84,12 @@ void switchdirectionNurb( struct Nurb *nu);
float (*curve_getVertexCos(struct Curve *cu, struct ListBase *lb, int *numVerts_r))[3];
void curve_applyVertexCos(struct Curve *cu, struct ListBase *lb, float (*vertexCos)[3]);
+/* nurb checks if they can be drawn, also clamp order func */
+int check_valid_nurb_u( struct Nurb *nu);
+int check_valid_nurb_v( struct Nurb *nu);
+
+int clamp_nurb_order_u( struct Nurb *nu);
+int clamp_nurb_order_v( struct Nurb *nu);
+
#endif
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index d02a7c0ab9e..d2028e653c5 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");
+ }
}
}
@@ -554,7 +558,7 @@ void makeknots(Nurb *nu, short uv, short type) /* 0: uniform, 1: endpoints, 2: b
if( (nu->type & 7)==CU_NURBS ) {
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);
@@ -563,7 +567,7 @@ void makeknots(Nurb *nu, short uv, short type) /* 0: uniform, 1: endpoints, 2: b
}
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);
@@ -645,7 +649,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;
@@ -803,7 +807,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;
@@ -1478,7 +1482,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;
@@ -2608,3 +2612,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->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->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->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->flagv>>1)&2) {
+ CLAMP(nu->orderv, 3,4);
+ change= 1;
+ }
+ return change;
+}
+
+
+
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index aa436441056..a8f300f4315 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -783,7 +783,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
else
resolu= nu->resolu;
- if(nu->pntsu<2 || ((nu->type & 7)==CU_NURBS && nu->pntsu < nu->orderu));
+ if(!check_valid_nurb_u(nu));
else if((nu->type & 7)==CU_BEZIER) {
/* count */
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 09c93962990..52275e507dd 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -440,7 +440,7 @@ static void build_underline(Curve *cu, float x1, float y1, float x2, float y2, i
if (nu2 == NULL) return;
nu2->resolu= cu->resolu;
nu2->bezt = NULL;
- nu2->knotsu = nu2->knotsv = 0;
+ nu2->knotsu = nu2->knotsv = NULL;
nu2->flag= 0;
nu2->charidx = charidx+1000;
if (mat_nr > 0) nu2->mat_nr= mat_nr-1;
@@ -529,7 +529,7 @@ static void buildchar(Curve *cu, unsigned long character, CharInfo *info, float
memcpy(nu2, nu1, sizeof(struct Nurb));
nu2->resolu= cu->resolu;
nu2->bp = 0;
- nu2->knotsu = nu2->knotsv = 0;
+ nu2->knotsu = nu2->knotsv = NULL;
nu2->flag= CU_SMOOTH;
nu2->charidx = charidx;
if (info->mat_nr) {
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index 8a37f713164..6e57736845e 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -3106,11 +3106,13 @@ void do_curvebuts(unsigned short event)
if(event<B_UNIFV) {
nu->flagu &= 1;
nu->flagu += ((event-B_UNIFU)<<1);
+ clamp_nurb_order_u(nu);
makeknots(nu, 1, nu->flagu>>1);
}
else if(nu->pntsv>1) {
nu->flagv &= 1;
nu->flagv += ((event-B_UNIFV)<<1);
+ clamp_nurb_order_v(nu);
makeknots(nu, 2, nu->flagv>>1);
}
}
@@ -3148,13 +3150,11 @@ void do_curvebuts(unsigned short event)
if(G.obedit) {
nu= get_actNurb();
if(nu && (nu->type & 7)==CU_NURBS ) {
- if(nu->orderu>nu->pntsu) {
- nu->orderu= nu->pntsu;
+ if(clamp_nurb_order_u(nu)) {
scrarea_queue_winredraw(curarea);
}
makeknots(nu, 1, nu->flagu>>1);
- if(nu->orderv>nu->pntsv) {
- nu->orderv= nu->pntsv;
+ if(clamp_nurb_order_v(nu)) {
scrarea_queue_winredraw(curarea);
}
makeknots(nu, 2, nu->flagv>>1);
diff --git a/source/blender/src/editcurve.c b/source/blender/src/editcurve.c
index 7f9ba2cb8d2..3cb951c319b 100644
--- a/source/blender/src/editcurve.c
+++ b/source/blender/src/editcurve.c
@@ -335,7 +335,7 @@ void load_editNurb()
BLI_addtail(&(cu->nurb), newnu);
if((nu->type & 7)==CU_NURBS) {
- if(nu->pntsu < nu->orderu) nu->orderu= nu->pntsu;
+ clamp_nurb_order_u(nu);
}
}
}
@@ -689,7 +689,7 @@ void deleteflagNurb(short flag)
nu->pntsv= newv;
MEM_freeN(nu->bp);
nu->bp= newbp;
- if(nu->orderv>nu->pntsv) nu->orderv= nu->pntsv;
+ clamp_nurb_order_v(nu);
makeknots(nu, 2, nu->flagv>>1);
}
@@ -729,13 +729,13 @@ void deleteflagNurb(short flag)
nu->pntsu= nu->pntsv;
nu->pntsv= 1;
SWAP(short, nu->orderu, nu->orderv);
- if(nu->orderu>nu->pntsu) nu->orderu= nu->pntsu;
+ clamp_nurb_order_u(nu);
if(nu->knotsv) MEM_freeN(nu->knotsv);
- nu->knotsv= 0;
+ nu->knotsv= NULL;
}
else {
nu->pntsu= newu;
- if(nu->orderu>nu->pntsu) nu->orderu= nu->pntsu;
+ clamp_nurb_order_u(nu);
}
makeknots(nu, 1, nu->flagu>>1);
}
@@ -946,7 +946,7 @@ void adduplicateflagNurb(short flag)
}
/* knots */
- newnu->knotsu= 0;
+ newnu->knotsu= NULL;
makeknots(newnu, 1, newnu->flagu>>1);
}
bp++;
@@ -991,9 +991,11 @@ void adduplicateflagNurb(short flag)
newnu->pntsv= newv;
newnu->bp =
(BPoint*)MEM_mallocN(newu * newv * sizeof(BPoint), "adduplicateN6");
- newnu->orderu= MIN2(nu->orderu, newu);
- newnu->orderv= MIN2(nu->orderv, newv);
-
+ clamp_nurb_order_u(newnu);
+ clamp_nurb_order_v(newnu);
+
+ newnu->knotsu= newnu->knotsv= NULL;
+
bp= newnu->bp;
bp1= nu->bp;
for(a=0; a<nu->pntsv; a++) {
@@ -1005,23 +1007,20 @@ void adduplicateflagNurb(short flag)
}
}
}
- if(nu->pntsu==newnu->pntsu) {
- newnu->knotsu= MEM_mallocN(sizeof(float)*KNOTSU(nu), "adduplicateN6");
- memcpy(newnu->knotsu, nu->knotsu, sizeof(float)*KNOTSU(nu));
- }
- else {
- newnu->knotsu= 0;
- makeknots(newnu, 1, newnu->flagu>>1);
- }
- if(nu->pntsv==newnu->pntsv) {
- newnu->knotsv= MEM_mallocN(sizeof(float)*KNOTSV(nu), "adduplicateN7");
- memcpy(newnu->knotsv, nu->knotsv, sizeof(float)*KNOTSV(nu));
+ if (check_valid_nurb_u(newnu)) {
+ if(nu->pntsu==newnu->pntsu && nu->knotsu) {
+ newnu->knotsu= MEM_dupallocN( nu->knotsu );
+ } else {
+ makeknots(newnu, 1, newnu->flagu>>1);
+ }
}
- else {
- newnu->knotsv= 0;
- makeknots(newnu, 2, newnu->flagv>>1);
+ if (check_valid_nurb_v(newnu)) {
+ if(nu->pntsv==newnu->pntsv && nu->knotsv) {
+ newnu->knotsv= MEM_dupallocN( nu->knotsv );
+ } else {
+ makeknots(newnu, 2, newnu->flagv>>1);
+ }
}
-
}
MEM_freeN(usel);
}
@@ -2154,9 +2153,9 @@ int convertspline(short type, Nurb *nu)
if(type==0) { /* to Poly */
nu->type &= ~7;
if(nu->knotsu) MEM_freeN(nu->knotsu); /* python created nurbs have a knotsu of zero */
- nu->knotsu= 0;
+ nu->knotsu= NULL;
if(nu->knotsv) MEM_freeN(nu->knotsv);
- nu->knotsv= 0;
+ nu->knotsv= NULL;
}
else if(type==CU_BEZIER) { /* to Bezier */
nr= nu->pntsu/3;
@@ -2185,7 +2184,7 @@ int convertspline(short type, Nurb *nu)
MEM_freeN(nu->bp);
nu->bp= 0;
MEM_freeN(nu->knotsu);
- nu->knotsu= 0;
+ nu->knotsu= NULL;
nu->pntsu= nr;
nu->type &= ~7;
nu->type+= 1;
@@ -3042,26 +3041,28 @@ void makecyclicNurb()
calchandlesNurb(nu);
}
else if(nu->pntsv==1 && (nu->type & 7)==CU_NURBS) {
- a= nu->pntsu;
- bp= nu->bp;
- while(a--) {
- if( bp->f1 & SELECT ) {
- if(nu->flagu & CU_CYCLIC) nu->flagu--;
- else {
- nu->flagu++;
- nu->flagu &= ~2; /* endpoint flag, fixme */
- fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN");
- b= (nu->orderu+nu->pntsu);
- memcpy(fp, nu->knotsu, sizeof(float)*b);
- MEM_freeN(nu->knotsu);
- nu->knotsu= fp;
+ if (nu->knotsu) { /* if check_valid_nurb_u fails the knotsu can be NULL */
+ a= nu->pntsu;
+ bp= nu->bp;
+ while(a--) {
+ if( bp->f1 & SELECT ) {
+ if(nu->flagu & CU_CYCLIC) nu->flagu--;
+ else {
+ nu->flagu++;
+ nu->flagu &= ~2; /* endpoint flag, fixme */
+ fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN");
+ b= (nu->orderu+nu->pntsu);
+ memcpy(fp, nu->knotsu, sizeof(float)*b);
+ MEM_freeN(nu->knotsu);
+ nu->knotsu= fp;
- makeknots(nu, 1, 0); /* 1==u 0==uniform */
+ makeknots(nu, 1, 0); /* 1==u 0==uniform */
+ }
+ break;
}
- break;
+ bp++;
}
- bp++;
}
}
else if(nu->type==CU_NURBS) {
@@ -3078,26 +3079,34 @@ void makecyclicNurb()
if(nu->flagu & CU_CYCLIC) nu->flagu--;
else {
nu->flagu++;
- fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN");
- b= (nu->orderu+nu->pntsu);
- memcpy(fp, nu->knotsu, sizeof(float)*b);
- MEM_freeN(nu->knotsu);
- nu->knotsu= fp;
+ if (check_valid_nurb_u(nu)) {
+ fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN");
+ b= (nu->orderu+nu->pntsu);
+ if (nu->knotsu) { /* null if check_valid_nurb_u failed before but is valid now */
+ memcpy(fp, nu->knotsu, sizeof(float)*b);
+ MEM_freeN(nu->knotsu);
+ }
+ nu->knotsu= fp;
- makeknots(nu, 1, 0); /* 1==u 0==uniform */
+ makeknots(nu, 1, 0); /* 1==u 0==uniform */
+ }
}
}
if(cyclmode==2 && nu->pntsv>1) {
if(nu->flagv & 1) nu->flagv--;
else {
nu->flagv++;
- fp= MEM_mallocN(sizeof(float)*KNOTSV(nu), "makecyclicN");
- b= (nu->orderv+nu->pntsv);
- memcpy(fp, nu->knotsv, sizeof(float)*b);
- MEM_freeN(nu->knotsv);
- nu->knotsv= fp;
+ if (check_valid_nurb_v(nu)) {
+ fp= MEM_mallocN(sizeof(float)*KNOTSV(nu), "makecyclicN");
+ b= (nu->orderv+nu->pntsv);
+ if (nu->knotsv) { /* null if check_valid_nurb_v failed before but is valid now */
+ memcpy(fp, nu->knotsv, sizeof(float)*b);
+ MEM_freeN(nu->knotsv);
+ }
+ nu->knotsv= fp;
- makeknots(nu, 2, 0); /* 2==v 0==uniform */
+ makeknots(nu, 2, 0); /* 2==v 0==uniform */
+ }
}
}
break;
@@ -3674,10 +3683,13 @@ void delNurb()
}
}
- /* Never allow the order to exceed the number of points */
- if ((nu!= NULL) && ((nu->type & 7)==CU_NURBS) && (nu->pntsu < nu->orderu)) {
- nu->orderu = nu->pntsu;
+ /* Never allow the order to exceed the number of points
+ - note, this is ok but changes unselected nurbs, disable for now */
+ /*
+ if ((nu!= NULL) && ((nu->type & 7)==CU_NURBS)) {
+ clamp_nurb_order_u(nu);
}
+ */
nu= next;
}
/* 2nd loop, delete small pieces: just for curves */
@@ -3725,10 +3737,12 @@ void delNurb()
MEM_freeN(nu->bp);
nu->bp= bp1;
- /* Never allow the order to exceed the number of points */
- if ((nu->type & 7)==CU_NURBS && (nu->pntsu < nu->orderu)) {
- nu->orderu = nu->pntsu;
- }
+ /* Never allow the order to exceed the number of points\
+ - note, this is ok but changes unselected nurbs, disable for now */
+ /*
+ if ((nu->type & 7)==CU_NURBS) {
+ clamp_nurb_order_u(nu);
+ }*/
}
makeknots(nu, 1, nu->flagu>>1);
}