forked from bartvdbraak/blender
* The displist would be uninitialized when nurbs bezieru/v was set and the order wasnt 3 or 4. add a function that checks nurbs can produce a valid line. check_valid_nurb_u/v
* when check_valid_nurb_u/v fails, no curve is allocated or drawn. * knotsu/v could be NULL but some functions didn't check for this, make sure this is checked for everywhere. * The interface didnt change check the order when the bezier u/v flag was set, added functions clamp_nurb_order_u/v that takes into accound the number of points and the bezier u/v flag.
This commit is contained in:
parent
b7c6da39ae
commit
0a90a52442
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
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->knotsu= 0;
|
||||
makeknots(newnu, 1, newnu->flagu>>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);
|
||||
}
|
||||
}
|
||||
if(nu->pntsv==newnu->pntsv) {
|
||||
newnu->knotsv= MEM_mallocN(sizeof(float)*KNOTSV(nu), "adduplicateN7");
|
||||
memcpy(newnu->knotsv, nu->knotsv, sizeof(float)*KNOTSV(nu));
|
||||
}
|
||||
else {
|
||||
newnu->knotsv= 0;
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user