This commit is contained in:
watrabi
2025-09-18 17:55:52 -04:00
commit 977f1ff4b8
15030 changed files with 17324420 additions and 0 deletions
+373
View File
@@ -0,0 +1,373 @@
#include "../sg.h"
static sgFloat min_function ( lpD_POINT p1, lpD_POINT p2 );
static sgFloat min_derivativ( lpD_POINT p1, lpD_POINT p2, lpD_POINT d );
static sgFloat sqrt_derivates( sgFloat *G, short n );
/**********************************************************
* function - function to be minimazied
* derivativs - derivativ of function to be minimazied
* C1, C2 - function's parameters
* X - beginning point, return - point of local min
* n - number of parameters
* number_of_iter - acceptable number of iterations
* for this reliz number of parameter <=5
*/
sgFloat Fletchjer_Paur( functionFP function, derivativs derivativs,
void *C1, void *C2, sgFloat *X, short n,
short number_of_iteration ){
short i, j, iter;
sgFloat H[5][5]; // matrix must be n x n !!!!!!!!!!!!!!!!!!
sgFloat P[5], Q[5], U[5], V[5], Y[5], G[5], D[5], M[5];
sgFloat z, w, r, kk, wk, dk, Fp, Fq, Fr, step, Gp, Gq, Gr, min1=-1;
sgFloat G3, eps_dd, eps_nn;
eps_dd=eps_d*eps_d;
eps_nn=eps_n*eps_n;
//bilding of begining matrix H - it's unit matrix
for( i=0; i<n; i++ ) for( j=0; j<n; j++ ) H[i][j] = ( i==j ) ? (1.) : (0.);
for( iter=0; iter <= number_of_iteration; iter++ ){
for( i=0; i<n; i++ ) Y[i] = P[i] = X[i];
//calculating of new quantity of function into point X
Fp = (*function)( C1, C2, X );
if( fabs(Fp) < eps_dd ) return (0);
//calculating of new paticular derivates of function
/*G3 =*/ (*derivativs)( C1, C2, X, G );
//calculating of beginning direction {d} = -[H]{g};
for( i=0; i<n; i++ ){
U[i] = G[i];
for( D[i]=0., j=0; j<n; j++ ) D[i] -= H[i][j]*G[j];
}
//linear founding of min on function f( x + step*d )
//------------------> calculating of point P
while(1){
//calculating of gradient for point P
for( Gp = 0., i=0; i<n; i++ ) Gp += G[i]*D[i];
//founding of min along direction and choising of step from formula
// min{1, -2(Fp - Fm)/Gp}
// where Fp = F(P),
// Fm - approximation of real quantity of min, in my case Fm = 0
if( fabs(Gp) < eps_dd ) { step = 1.; break; }
if( ( step = fabs( 2*Fp/Gp ) ) > 1. ) step = 1.;
if( Gp < -eps_dd ) break;
// calculating of new point P
for( i=0; i<n; i++ ) P[i] = X[i] = P[i] - step*D[i];
//calculating of new quantity of function into point P
Fp = (*function)( C1, C2, P );
if( fabs(Fp) < eps_dd ) return (0);
//calculating of new paticular derivates of function
/*G3 =*/ (*derivativs)( C1, C2, P, G );
}
//------------------> calculating of point Q
while(1){
//calculating of next point Q x(i+1) = x(i) + step*d(i)
for( i=0; i<n; i++ ) Q[i] = X[i] = P[i] + step*D[i];
//calculating of new quantity of function into point Q
Fq = (*function)( C1, C2, Q );
if( fabs( Fq ) < eps_dd ) return (0);
//calculating of new paticular derivates of function
/*G3 =*/ (*derivativs)( C1, C2, Q, G );
//calculating of gradient for point Q
for( Gq = 0., i=0; i<n; i++ ) Gq += G[i]*D[i];
// if( Gq > 0. || Fq > Fp ) break;
if( Gq > eps_dd || Fq > Fp ) break;
step *= 2; //increase step to "expand" min
}
while(1){
//min lay on [p,q]
z = 3*( Fp - Fq )/step + Gp + Gq;
// if( ( w = z*z - Gp*Gq ) < 0. ) w = 0.;
if( ( w = z*z - Gp*Gq ) < -eps_dd ) w = 0.;
w = sqrt( w );
//approximation of min
r = step*( 1. - ( Gq + w - z )/( Gq - Gp + 2*w ) );
//calculating of new point
for( i=0; i<n; i++ ) X[i] = P[i] + r*D[i];
//calculating of new quantity of function into point X
Fr = (*function)( C1, C2, X );
if( fabs(Fr) < eps_dd ) return (0);
//calculating of new paticular derivates of function
G3 = (*derivativs)( C1, C2, X, G );
//calculating of gradient for point X
for( Gr=0., i=0; i<n; i++ ) Gr += G[i]*D[i];
if( fabs( Gr ) < eps_dd ) break;
if( ( Fr < Fp || fabs( Fp - Fr )<= eps_dd ) &&
( Fr < Fq || fabs( Fq - Fr )<= eps_dd ) ) break;
// if( Fr <= Fp && Fr <= Fq ) break;
// if( Gr > 0. ){
if( Gr > eps_dd ){ // choise span [p,r]
step = r;
for( i=0; i<n; i++ ) Q[i] = X[i];
//??????
Fq = Fr; Gq = Gr;
break;
}
//taking [r,q]
step -= r;
for( i=0; i<n; i++ ) P[i] = X[i];
Fp = Fr; Gp = Gr;
}
//changing of matrix H
// H(i+1) = H(i) + A(i) + B(i)
// A(i) = Vi*ViT / ( ViT*Ui)
// B(i) = - Hi Ui UiT Hi / (UiT Hi Ui)
for( i=0; i<n ; i++ ){
U[i] = G[i] - U[i];
V[i] = X[i] - Y[i];
}
for( kk=0, wk=0, dk=0, i=0; i<n; i++ ){
for( M[i]=0, j=0; j<n; j++ ) M[i] += H[i][j]*U[j];
kk += M[i]*U[i];
wk += V[i]*U[i];
dk += V[i]*V[i];
}
if( kk != 0 && wk != 0 ) {
kk=1./kk; wk=1./wk;
for( i=0; i<n; i++ )
for( j=0; j<n; j++ )
H[i][j] = H[i][j] - M[i]*M[j]*kk + V[i]*V[j]*wk;
}
//control
// if( sqrt(dk) < eps_dd || G3 < eps_dd ) break;
if( dk < eps_nn || G3 < eps_d ) break;
} // end of iteration loop
min1 = ( Fr > Fp ) ? (Fp) : (Fr);
min1 = ( min1 > Fq ) ? (Fq) : (min1);
return( sqrt(min1) );
}
//---------------------------------------------------------->
//================================SPLINE========================================
/***********************************************************
* functions for NURBScurve-to-point distance minimization
*/
sgFloat function_0( void *sply_dat, void *point, sgFloat X[] ){
D_POINT p1, *p;
//point on NURBS curve
get_point_on_sply( (lpSPLY_DAT)sply_dat, X[0], &p1, 0 );
//initial point
p=(D_POINT*)point;
//function to be minimized
return( min_function( &p1, p ) );
}
sgFloat derivativs_0( void *sply_dat, void *point, sgFloat X[], sgFloat G[] ){
D_POINT p1, d1, *p;
//point and derivative on NURBS curve
get_point_on_sply( (lpSPLY_DAT)sply_dat, X[0], &p1, 0 );
get_point_on_sply( (lpSPLY_DAT)sply_dat, X[0], &d1, 1 );
p=(D_POINT*)point;
G[0] = min_derivativ( &p1, p, &d1 );
return( sqrt_derivates( G, 1 ) );
}
/***********************************************************
* functions for NURBScurve-to-line distance minimization
*/
sgFloat function_1( void *sply_dat, void *line, sgFloat X[] ){
D_POINT p1, p2, *p;
//point on NURBS curve
get_point_on_sply( (lpSPLY_DAT)sply_dat, X[0], &p1, 0 );
//parametrical line is r=p1+(p2-p1)*lambda;
p=(D_POINT*)line;
//point on line
p2.x = p[0].x + ( p[1].x - p[0].x )*X[1];
p2.y = p[0].y + ( p[1].y - p[0].y )*X[1];
p2.z = p[0].z + ( p[1].z - p[0].z )*X[1];
//function to be minimized
return( min_function( &p1, &p2 ) );
}
sgFloat derivativs_1( void *sply_dat, void *line, sgFloat X[], sgFloat G[] ){
D_POINT p1, p2, d1, d2, *p;
//point and derivativ on NURBS curve
get_point_on_sply( (lpSPLY_DAT)sply_dat, X[0], &p1, 0 );
get_point_on_sply( (lpSPLY_DAT)sply_dat, X[0], &d1, 1 );
//parametrical line is r=p+(p1-p)*lambda;
p=(D_POINT*)line;
//point and dirivativ on line
d2.x = p[1].x - p[0].x;
d2.y = p[1].y - p[0].y;
d2.z = p[1].z - p[0].z;
p2.x = p[0].x + d2.x*X[1];
p2.y = p[0].y + d2.y*X[1];
p2.z = p[0].z + d2.z*X[1];
G[0] = min_derivativ( &p1, &p2, &d1 );
G[1] = -1.*min_derivativ( &p1, &p2, &d2 );
return( sqrt_derivates( G, 2 ) );
}
/***********************************************************
* functions for NURBScurve-to-plane distance minimization
*/
sgFloat function_2( void *sply_dat, void *plane, sgFloat X[] ){
D_POINT p1, p2, *p;
//point on NURBS curve
get_point_on_sply( (lpSPLY_DAT)sply_dat, X[0], &p1, 0 );
//parametrical plane is r=p+(p1-p)*lambda+(p2-p)*nu;
p=(D_POINT*)plane;
//point on plane
p2.x = p[0].x + ( p[1].x - p[0].x )*X[1] + ( p[2].x - p[0].x )*X[2];
p2.y = p[0].y + ( p[1].x - p[0].x )*X[1] + ( p[2].x - p[0].x )*X[2];
p2.z = p[0].z + ( p[1].x - p[0].x )*X[1] + ( p[2].x - p[0].x )*X[2];
//function to be minimized
return( min_function( &p1, &p2 ) );
}
sgFloat derivativs_2( void *sply_dat, void *plane, sgFloat X[], sgFloat G[] ){
D_POINT p1, p2, d1, d2, d3, *p;
//point and derivativ on NURBS curve
get_point_on_sply( (lpSPLY_DAT)sply_dat, X[0], &p1, 0 );
get_point_on_sply( (lpSPLY_DAT)sply_dat, X[0], &d1, 1 );
//parametrical plane is r=p+(p1-p)*lambda+(p2-p)*nu;
p=(D_POINT*)plane;
//derivativ by first plane parameter
d2.x = p[1].x - p[0].x;
d2.y = p[1].y - p[0].y;
d2.z = p[1].z - p[0].z;
//derivativ by second plane parameter
d3.x = p[2].x - p[0].x;
d3.y = p[2].y - p[0].y;
d3.z = p[2].z - p[0].z;
//point on plane
p2.x = p[0].x + d2.x*X[1] + d3.x*X[2];
p2.y = p[0].y + d2.y*X[1] + d3.y*X[2];
p2.z = p[0].z + d2.z*X[1] + d3.z*X[2];
G[0] = min_derivativ( &p1, &p2, &d1 );
G[1] = -1.*min_derivativ( &p1, &p2, &d2 );
G[2] = -1.*min_derivativ( &p1, &p2, &d3 );
return( sqrt_derivates( G, 3 ) );
}
/***********************************************************
* functions for NURBScurve-to-NURBScurve distance minimization
*/
sgFloat function_3( void *sply_dat1, void *sply_dat2, sgFloat X[] ){
D_POINT p1, p2;
get_point_on_sply( (lpSPLY_DAT)sply_dat1, X[0], &p1, 0 );
get_point_on_sply( (lpSPLY_DAT)sply_dat2, X[1], &p2, 0 );
return( min_function( &p1, &p2 ) );
}
sgFloat derivativs_3( void *sply_dat1, void *sply_dat2, sgFloat X[], sgFloat G[] ){
D_POINT p1, p2, d1, d2;
get_point_on_sply( (lpSPLY_DAT)sply_dat1, X[0], &p1, 0 );
get_point_on_sply( (lpSPLY_DAT)sply_dat1, X[0], &d1, 1 );
get_point_on_sply( (lpSPLY_DAT)sply_dat2, X[1], &p2, 0 );
get_point_on_sply( (lpSPLY_DAT)sply_dat2, X[1], &d2, 1 );
G[0] = min_derivativ( &p1, &p2, &d1 );
G[1] = -1.*min_derivativ( &p1, &p2, &d2 );
return( sqrt_derivates( G, 2 ) );
}
/**********************************************************
* function to be minimized
*/
static sgFloat min_function( lpD_POINT p1, lpD_POINT p2 ){
return(( p1->x - p2->x )*( p1->x - p2->x )+
( p1->y - p2->y )*( p1->y - p2->y )+
( p1->z - p2->z )*( p1->z - p2->z ) );
}
/**********************************************************
* derivatives
*/
static sgFloat min_derivativ( lpD_POINT p1, lpD_POINT p2, lpD_POINT d ){
return( 2*( p1->x - p2->x )*d->x +
2*( p1->y - p2->y )*d->y +
2*( p1->z - p2->z )*d->z );
}
static sgFloat sqrt_derivates( sgFloat *G, short n ){
short i;
sgFloat t=0;
for( i=0; i<n; i++ ) t += G[i]*G[i];
return ( sqrt(t) );
}
//================================SURFACE=======================================
/***********************************************************
* functions for NURBSsurface-to-point distance minimization
*/
sgFloat function_0_0( void *srf_dat, void *point, sgFloat X[] ){
D_POINT p1, *p;
//point on NURBS surface
get_point_on_surface( (lpSURF_DAT)srf_dat, X[0], X[1], &p1 );
//initial point
p=(D_POINT*)point;
//function to be minimized
return( min_function( &p1, p ) );
}
sgFloat derivativs_0_0( void *srf_dat, void *point, sgFloat X[], sgFloat G[] ){
D_POINT p1, d1, d2, *p;
//point and derivative on NURBS surface
get_point_on_surface( (lpSURF_DAT)srf_dat, X[0], X[1], &p1 );
get_deriv_on_surface( (lpSURF_DAT)srf_dat, X[0], X[1], &d1, 0 );
get_deriv_on_surface( (lpSURF_DAT)srf_dat, X[0], X[1], &d2, 0 );
p=(D_POINT*)point;
G[0] = min_derivativ( &p1, p, &d1 );
G[1] = min_derivativ( &p1, p, &d2 );
return( sqrt_derivates( G, 2 ) );
}
+64
View File
@@ -0,0 +1,64 @@
#include "../sg.h"
/**********************************************************
* Free memory for matrix m x n
*/
void free_matrix( sgFloat **L, short n ){
while( n > 0 ) SGFree( L[--n] );
SGFree(L);
}
/**********************************************************
* Expand memory for matrix m x n
* m - number of rows
* n - number of colomns
* return =**L - if memory expand; or = NULL
*/
sgFloat ** mem_matrix( short m, short n ){
short i;
sgFloat **L;
if( (L = (sgFloat**)SGMalloc( sizeof(sgFloat*) * m) ) == NULL) goto err;
for( i = 0; i < m; i++ ) {
if( (L[i] = (sgFloat*)SGMalloc(sizeof(sgFloat) * n) ) == NULL ){
free_matrix( L, i );
goto err;
}
}
return L;
err:
nurbs_handler_err(SPL_NO_MEMORY);
return NULL;
}
//-------------------------------------->>>>>>>>>>>>
/**********************************************************
* Free memory for matrix m x n
*/
void free_matrix_point( lpD_POINT *L, short n ){
while( n > 0 ) SGFree( L[--n] );
SGFree(L);
}
/**********************************************************
* Expand memory for matrix m x n
* m - number of rows
* n - number of colomns
* return =**L - if memory expand; or = NULL
*/
lpD_POINT * mem_matrix_point( short m, short n ){
short i;
lpD_POINT *L;
if( (L = (D_POINT**)SGMalloc( sizeof(lpD_POINT) * m) ) == NULL) goto err;
for( i = 0; i < m; i++ ) {
if( (L[i] = (D_POINT*)SGMalloc(sizeof(D_POINT) * n) ) == NULL ){
free_matrix_point( L, i );
goto err;
}
}
return L;
err:
nurbs_handler_err(SPL_NO_MEMORY);
return NULL;
}
+425
View File
@@ -0,0 +1,425 @@
#include "../sg.h"
//spline must be APPR!!!!
//----------------------------------------------------------------->>>>>>>>>>>>>
static void create_NURBS_line(lpSPLY_DAT sply, sgFloat *v1, sgFloat *v2);
static BOOL create_NURBS_arc( lpSPLY_DAT sply_dat, sgFloat *center, sgFloat *Ort_X,
sgFloat *Ort_Y, sgFloat r, sgFloat a_begin, sgFloat fi);
static void create_NURBS_circle(lpSPLY_DAT sply, sgFloat *center, sgFloat *ort1,
sgFloat *ort2, sgFloat r1, sgFloat r2);
static OSCAN_COD nrb_cre_scan(hOBJ hobj,lpSCAN_CONTROL lpsc);
static OSCAN_COD nrb_line (lpOBJ obj,lpSCAN_CONTROL lpsc);
static OSCAN_COD nrb_circle (lpOBJ obj,lpSCAN_CONTROL lpsc);
static OSCAN_COD nrb_arc (lpOBJ obj,lpSCAN_CONTROL lpsc);
static OSCAN_COD nrb_spline (lpOBJ obj,lpSCAN_CONTROL lpsc);
typedef struct {
SPLY_DAT sply_dat;
BOOL first;
} NRB_DAT; //
typedef NRB_DAT * lpNRB_DAT;
static OSCAN_COD (**nrb_typeg)(lpOBJ obj,lpSCAN_CONTROL lpsc);
/*******************************************************************************
* ( OPATH, OLINE, OCIRCLE, OARC, OSPLINE)
* NURBS
*/
BOOL transform_to_NURBS(hOBJ hobj, hOBJ *hobj_new){
SCAN_CONTROL sc;
BOOL rt=FALSE;
OSTATUS status;
// sgFloat coeff;
lpOBJ obj, obj1;
lpGEO_SPLINE gspline;
NRB_DAT nrb_dat;
nrb_typeg = (OSCAN_COD(**)(lpOBJ obj,lpSCAN_CONTROL lpsc))GetMethodArray(OMT_TRANSTONURBS);
nrb_typeg[OLINE] = nrb_line; // OLINE
nrb_typeg[OCIRCLE]= nrb_circle; // OCIRCLE
nrb_typeg[OARC] = nrb_arc; // OARC
nrb_typeg[OSPLINE]= nrb_spline; // OSPLINE
//----------------->>>>
//create new hobj
if((*hobj_new = o_alloc(OSPLINE)) == NULL) return FALSE;
obj=(lpOBJ)(*hobj_new);
obj1=(lpOBJ)hobj;
copy_obj_nongeo_par( obj1, obj);
// set_obj_nongeo_par(obj);
if (!get_status_path(hobj, &status)) return FALSE;
gspline = (lpGEO_SPLINE)(obj->geo_data);
//----------------->>>>
//initializate spline structure
if( !init_sply_dat( SPL_NEW, 2, SPL_APPR, &nrb_dat.sply_dat )) return FALSE;
nrb_dat.first=TRUE;
init_scan(&sc);
sc.user_geo_scan = nrb_cre_scan;
reinterpret_cast<lpNRB_DAT &>(sc.data) = &nrb_dat;
if(o_scan(hobj,&sc) == OSFALSE) goto err;
//reparametrization for all ribs
if( nrb_dat.sply_dat.U[0]!=0. || nrb_dat.sply_dat.U[nrb_dat.sply_dat.numU-1]!=1.)
if( !Reparametrization( nrb_dat.sply_dat.nump, nrb_dat.sply_dat.numU,
0, 1, nrb_dat.sply_dat.degree, nrb_dat.sply_dat.U,
nrb_dat.sply_dat.P, nrb_dat.sply_dat.u )) goto err;
if( nrb_dat.sply_dat.nump > 2 ) calculate_P(&nrb_dat.sply_dat, 0);
if( status & ST_CLOSE ) nrb_dat.sply_dat.sdtype = (SPLY_TYPE_IN)(nrb_dat.sply_dat.sdtype | SPL_CLOSE);
//convert spline to geo spline
if( !create_geo_sply(&nrb_dat.sply_dat, gspline)) goto err;
rt=TRUE;
err:
free_sply_dat(&nrb_dat.sply_dat);
return rt;
}
static OSCAN_COD nrb_cre_scan(hOBJ hobj,lpSCAN_CONTROL lpsc){
lpOBJ obj;
BOOL cod;
obj = (lpOBJ)hobj;
cod = nrb_typeg[lpsc->type](obj,lpsc);
return (OSCAN_COD)cod;
}
//----------------------------------------------------------------->>>>>>>>>>>>>
/*******************************************************************************
* Create new object, it's a line as NURBS
*/
#pragma argsused
static OSCAN_COD nrb_line(lpOBJ obj, lpSCAN_CONTROL lpsc){
lpNRB_DAT data = (lpNRB_DAT)(lpsc->data);
lpGEO_LINE gline;
SPLY_DAT sply_dat, sply_tmp;
/*typedef struct {
D_POINT v1;
D_POINT v2;
}GEO_LINE;
*/
gline = (lpGEO_LINE)obj->geo_data;
if(data->first){
create_NURBS_line(&data->sply_dat, (sgFloat*)&gline->v1, (sgFloat*)&gline->v2 );
if( lpsc->status & ST_DIRECT) if( !Reorient_Spline( &data->sply_dat ) ) return OSFALSE;
data->first=FALSE;
}else{
//initializate spline structure
if( !init_sply_dat( SPL_NEW, 2, SPL_APPR, &sply_dat )) return (OSCAN_COD)FALSE;
create_NURBS_line(&sply_dat, (sgFloat*)&gline->v1, (sgFloat*)&gline->v2 );
if( lpsc->status & ST_DIRECT) if( !Reorient_Spline( &sply_dat ) ) goto err;
if( !Two_Spline_Union_Dat(&sply_dat, &data->sply_dat, &sply_tmp)) goto err;
static int ccc = 0;
ccc++;
free_sply_dat(&data->sply_dat);
data->sply_dat=sply_tmp;
free_sply_dat(&sply_dat);
}
return OSTRUE;
err:
free_sply_dat(&sply_dat);
free_sply_dat(&sply_tmp);
return OSFALSE;
}
/*******************************************************************************
* Create line as NURBS
*/
static void create_NURBS_line(lpSPLY_DAT sply, sgFloat* v1, sgFloat* v2){
short i;
// put knots into spline
for( i=0; i<3; i++) {
sply->U[i]=0.;
sply->U[i+3]=1.;
// put weigth into spline
sply->P[i].vertex[3]=1.;
}
// put control points into spline
for( i=0; i<3; i++ ){
sply->P[0].vertex[i]=v1[i];
sply->P[2].vertex[i]=v2[i];
sply->P[1].vertex[i]=(sply->P[0].vertex[i]+sply->P[2].vertex[i])/2.;
}
sply->numU=6;
sply->nump=sply->numk=3;
parameter_free_APPR( sply->nump-1, 2, sply->P, sply->u, NULL );
}
//----------------------------------------------------------------->>>>>>>>>>>>>
/*******************************************************************************
* Create new object, it's an arc as NURBS
*/
#pragma argsused
static OSCAN_COD nrb_arc(lpOBJ obj, lpSCAN_CONTROL lpsc){
lpNRB_DAT data = (lpNRB_DAT)(lpsc->data);
lpGEO_ARC garc;
MATR matr;
D_POINT Ort_X, Ort_Y;
SPLY_DAT sply_dat, sply_tmp;
/*
typedef struct {
sgFloat r;
D_POINT n; //
D_POINT vc;
D_POINT vb;
D_POINT ve;
sgFloat ab;
sgFloat angle;
}GEO_ARC;
*/
garc = (lpGEO_ARC)obj->geo_data;
//detect points on orts
// first ort
o_hcunit(matr);
if( !o_rotate_xyz( matr, &garc->vc, &garc->n, -garc->ab ))return OSFALSE;
o_hcncrd( matr, &garc->vb, &Ort_X);
dpoint_sub( &Ort_X, &garc->vc, &Ort_X );
if( !dnormal_vector ( &Ort_X )) return OSFALSE;
// second ort
o_hcunit(matr);
if( !o_rotate_xyz( matr, &garc->vc, &garc->n, -garc->ab+M_PI/2. ))return OSFALSE;
o_hcncrd( matr, &garc->vb, &Ort_Y);
dpoint_sub( &Ort_Y, &garc->vc, &Ort_Y );
if( !dnormal_vector ( &Ort_Y )) return OSFALSE;
if(data->first){
if( !create_NURBS_arc(&data->sply_dat, (sgFloat*)&garc->vc, (sgFloat*)&Ort_X,
(sgFloat*)&Ort_Y, garc->r, garc->ab, garc->angle)) return OSFALSE;
if( lpsc->status & ST_DIRECT) if( !Reorient_Spline( &data->sply_dat ) ) return OSFALSE;
data->first=FALSE;
}else{
//initializate spline structure
if( !init_sply_dat( SPL_NEW, 2, SPL_APPR, &sply_dat )) return (OSCAN_COD)FALSE;
if( !create_NURBS_arc(&sply_dat, (sgFloat*)&garc->vc, (sgFloat*)&Ort_X,
(sgFloat*)&Ort_Y, garc->r, garc->ab, garc->angle)) goto err0;
if( lpsc->status & ST_DIRECT) if( !Reorient_Spline( &sply_dat ) ) goto err0;
if( !Two_Spline_Union_Dat(&sply_dat, &data->sply_dat, &sply_tmp)) goto err;
free_sply_dat(&data->sply_dat);
data->sply_dat=sply_tmp;
free_sply_dat(&sply_dat);
}
return OSTRUE;
err:
free_sply_dat(&sply_tmp);
err0:
free_sply_dat(&sply_dat);
return OSFALSE;
}
static BOOL create_NURBS_arc( lpSPLY_DAT sply_dat, sgFloat* center, sgFloat* Ort_X,
sgFloat* Ort_Y, sgFloat r, sgFloat a_begin, sgFloat fi){
short i, ii, j, index, narc, n_p;
sgFloat d_fi, w1, c, s, c1, s1, angle, f;
DA_POINT P0, P1, P2, T0, T2;
GEO_LINE gline1, gline2;
//detect number of part the arc consist of
f=fabs(fi);
if( ( f < M_PI/2. ) || ( fabs(f-M_PI/2.) < eps_n ) ) narc=1;
else {
if( ( f < M_PI ) || ( fabs(f-M_PI ) < eps_n ) ) narc=2;
else {
if( ( f < 3*M_PI/2. ) || ( fabs(f-3*M_PI/2.) < eps_n ) ) narc=3;
else if( ( f < 2*M_PI ) || ( fabs(f-2*M_PI ) < eps_n ) ) narc=4;
}
}
// create control points and put them into spline
d_fi=fi/narc;
j=2*narc+1;
sply_dat->nump=sply_dat->numk=j;
w1=cos(d_fi/2.);
c=cos(a_begin); c1=r*c;
s=sin(a_begin); s1=r*s;
for( i=0; i<3; i++) P0[i]=center[i] + c1*Ort_X[i] + s1*Ort_Y[i];
Create_4D_From_3D( &sply_dat->P[0], (sgFloat *)&P0, 1.);
for( i=0; i<3; i++) T0[i] = P0[i] - s*Ort_X[i] + c*Ort_Y[i];
//create line on points
memcpy( &gline1.v1, P0, sizeof(D_POINT));
memcpy( &gline1.v2, T0, sizeof(D_POINT));
angle=a_begin;
for(ii=1, index=0; ii<=narc; ii++, index+=2 ){
angle += d_fi;
if( angle > 2*M_PI || fabs( angle - 2*M_PI )< eps_n ) angle -=2*M_PI;
c=cos(angle); c1=r*c;
s=sin(angle); s1=r*s;
for( i=0; i<3; i++) P2[i] = center[i] + c1*Ort_X[i] + s1*Ort_Y[i];
Create_4D_From_3D( &sply_dat->P[index+2], (sgFloat *)&P2, 1.);
for( i=0; i<3; i++) T2[i] = P2[i] - s*Ort_X[i] + c*Ort_Y[i];
//create line on points
memcpy( &gline2.v1, P2, sizeof(D_POINT));
memcpy( &gline2.v2, T2, sizeof(D_POINT));
//detect intersection of the two lines
if( !intersect_3d_ll(&gline1, 0, &gline2, 0, (lpD_POINT)&P1, &n_p) ) return FALSE;
if( n_p==0 ) return FALSE;
Create_4D_From_3D( &sply_dat->P[index+1], (sgFloat *)&P1, w1);
// P0=P2;
// T0=T2;
memcpy( P0, P2, sizeof(DA_POINT));
memcpy( T0, T2, sizeof(DA_POINT));
memcpy( &gline1.v1, P0, sizeof(D_POINT));
memcpy( &gline1.v2, T0, sizeof(D_POINT));
}
//create knots and put them into spline
//nuber of knots = number_of_control_points+degree+1
sply_dat->numU=j+2+1;
for(i=0;i<3; i++){ sply_dat->U[i]=0.; sply_dat->U[i+j]=1.;}
switch(narc){
case 1:
break;
case 2:
sply_dat->U[3] = sply_dat->U[4] = 0.5;
break;
case 3:
sply_dat->U[3] = sply_dat->U[4] = 1./3.;
sply_dat->U[5] = sply_dat->U[6] = 2./3.;
break;
case 4:
sply_dat->U[3] = sply_dat->U[4] = 0.25;
sply_dat->U[5] = sply_dat->U[6] = 0.5;
sply_dat->U[7] = sply_dat->U[8] = 0.75;
break;
}
parameter_free_APPR( sply_dat->nump-1, 2, sply_dat->P, sply_dat->u, NULL );
return TRUE;
}
//----------------------------------------------------------------->>>>>>>>>>>>>
/*******************************************************************************
* Create new object, it's a circle as NURBS
*/
#pragma argsused
static OSCAN_COD nrb_circle(lpOBJ obj, lpSCAN_CONTROL lpsc){
lpNRB_DAT data = (lpNRB_DAT)(lpsc->data);
lpGEO_CIRCLE gcirc;
D_POINT Ort_X, Ort_Y;
sgFloat r1, r2;
gcirc = (lpGEO_CIRCLE)obj->geo_data;
//detect two points on circle
init_ecs_arc((lpGEO_ARC)gcirc, ECS_CIRCLE);
// first ort
get_point_on_arc(0., &Ort_X);
dpoint_sub( &Ort_X, &gcirc->vc, &Ort_X );
if( !dnormal_vector ( &Ort_X )) return OSFALSE;
//first radii
r1=gcirc->r;
// second ort
get_point_on_arc(1./4., &Ort_Y);
dpoint_sub( &Ort_Y, &gcirc->vc, &Ort_Y );
if( !dnormal_vector ( &Ort_Y )) return OSFALSE;
// second radii
r2=r1;
if(data->first){
create_NURBS_circle( &data->sply_dat, (sgFloat*)&gcirc->vc, (sgFloat*)&Ort_X,
(sgFloat*)&Ort_Y, r1, r2);
if( lpsc->status & ST_DIRECT) if( !Reorient_Spline( &data->sply_dat ) ) return OSFALSE;
data->first=FALSE;
}
return OSTRUE;
}
/**********************************************************
* create nurbs curve for circle/ellipse
*/
static void create_NURBS_circle( lpSPLY_DAT sply, sgFloat *center, sgFloat *ort1,
sgFloat * ort2, sgFloat r1, sgFloat r2){
short i;
// put knots into spline
for( i=0; i<3; i++ ) { sply->U[i]=0.; sply->U[i+7]=1.; }
sply->U[3]=0.25;
sply->U[4]=sply->U[5]=0.5;
sply->U[6]=0.75;
sply->numU=10;
// put weigth into spline
for( i=0; i<3; i++ ) sply->P[3*i].vertex[3]=1.;
sply->P[1].vertex[3]=sply->P[2].vertex[3]=sply->P[4].vertex[3]=sply->P[5].vertex[3]=0.5;
// put control points into spline
for( i=0; i<3; i++ ) sply->P[0].vertex[i] = center[i]+r1*ort1[i];
memcpy( &sply->P[6], &sply->P[0], sizeof(W_NODE) );
for( i=0; i<3; i++ ){
sply->P[1].vertex[i] = (sply->P[0].vertex[i]+r2*ort2[i])/2.;
sply->P[2].vertex[i] = (center[i]+r2*ort2[i]-r1*ort1[i])/2.;
sply->P[3].vertex[i] = center[i]-r1*ort1[i];
}
for( i=0; i<3; i++ ){
sply->P[4].vertex[i]= (sply->P[3].vertex[i]-r2*ort2[i])/2.;
sply->P[5].vertex[i]= (center[i]-r2*ort2[i]+r1*ort1[i])/2.;
}
sply->nump=sply->numk=7;
parameter_free_APPR( sply->nump-1, 2, sply->P, sply->u, NULL );
}
//-------------------------------------------->>>>>>>>>>>>>
/**********************************************************
* Create new object, it's a spline as NURBS
*/
#pragma argsused
static OSCAN_COD nrb_spline(lpOBJ obj, lpSCAN_CONTROL lpsc){
lpNRB_DAT data = (lpNRB_DAT)(lpsc->data);
BOOL ret=OSFALSE;
SPLY_DAT sply_dat, sply_tmp;
lpGEO_SPLINE gspline;
gspline = (lpGEO_SPLINE)obj->geo_data;
if(data->first){
// if( !begin_use_sply(gspline, &data->sply_dat)) return OSFALSE;
if( !unpack_geo_sply( gspline, &data->sply_dat)) return OSFALSE;
if( data->sply_dat.sdtype & SPL_INT ) if( !change_INT_APPR(&data->sply_dat) ) return OSFALSE;
if( lpsc->status & ST_DIRECT) if( !Reorient_Spline(&data->sply_dat) ) return OSFALSE;
// parameter_free_APPR( data->sply_dat.nump-1, 2, data->sply_dat.P, data->sply_dat.u, NULL );
data->first=FALSE;
return OSTRUE;
}else{
//initializate spline structure
if( !begin_use_sply(gspline, &sply_dat)) return OSFALSE;
if( sply_dat.sdtype & SPL_INT ) if( !change_INT_APPR(&sply_dat) ) goto err;
if( lpsc->status & ST_DIRECT) if( !Reorient_Spline(&sply_dat) ) goto err;
parameter_free_APPR( data->sply_dat.nump-1, 2, data->sply_dat.P, data->sply_dat.u, NULL );
if( !Two_Spline_Union_Dat(&sply_dat, &data->sply_dat, &sply_tmp)) goto err1;
free_sply_dat(&data->sply_dat);
data->sply_dat=sply_tmp;
free_sply_dat(&sply_dat);
}
return OSTRUE;
err1:
free_sply_dat(&sply_tmp);
err:
free_sply_dat(&sply_dat);
return (OSCAN_COD)ret;
}
+421
View File
@@ -0,0 +1,421 @@
#include "../sg.h"
static void calculate_free_U(short n_c, short p_c, sgFloat *u_c, sgFloat *U_c );
//static sgFloat calculate_R_Sum( short n_c, lpW_NODE P, sgFloat *N);
static void calc_w_point(lpSPLY_DAT sply_dat, lpD_POINT p, sgFloat *N);
static void calc_w_deriv(lpSPLY_DAT sply_dat, short degree,
lpD_POINT p, short deriv, sgFloat *N_i, sgFloat *N_j);
/*******************************************************************************
* Obtaining B-sply basis function of degree p
* U_p - parametrical vector
* u_p - parameter
*/
sgFloat nurbs_basis_func( short i, short p, sgFloat *U_p, sgFloat u_p ){
sgFloat N, N1;
if( p == 0 ){ // degree 0
if( U_p[i] <= u_p && u_p < U_p[i+1] ) return(1);
if( U_p[i] < U_p[i+1] && u_p == U_p[i+1] && u_p == 1 ) return(1);
return(0);
}
// degree p
N=0;
if( ( N1 = U_p[i+p] - U_p[i] ) != 0. )
N = ( u_p - U_p[i] )*nurbs_basis_func( i, p-1, U_p, u_p )/N1;
if( ( N1 = U_p[i+p+1] - U_p[i+1] ) != 0. )
N = N + ( U_p[i+p+1] - u_p )*nurbs_basis_func( i+1, p-1, U_p, u_p )/N1;
return( N );
}
/*******************************************************************************
* Obtaining parameter values by centripetal method
* n_c - number of points
* p_c - degree of curve
* Q_tmp - curve to creation parametrical vector
* U_c - parametrical vector
*/
void parameter( lpSPLY_DAT sply_dat, short condition, BOOL p ){
short i;
sgFloat *U=NULL;
if( p ) U = sply_dat->U;
if( sply_dat->sdtype & SPL_APPR ){
parameter_free_APPR( sply_dat->nump-1, sply_dat->degree, sply_dat->P,
sply_dat->u, U );
if( p ) sply_dat->numU = sply_dat->nump+sply_dat->degree+1;
}else{
if( p ) sply_dat->numU = sply_dat->nump+sply_dat->degree+1;
switch(condition){
case 0://free NURBS
parameter_free( sply_dat->numk-1, sply_dat->degree, sply_dat->knots,
sply_dat->u, U );
if( p ) sply_dat->numU = sply_dat->numk+sply_dat->degree+1;
break;
case 1://closed NURBS without derivates
parameter_closed( sply_dat->numk-1, sply_dat->degree, sply_dat->knots,
sply_dat->u, U );
if( p ) sply_dat->numU = sply_dat->numk+sply_dat->degree+1+2;
break;
case 2://free NURBS with derivates
parameter_deriv( sply_dat->numk-1, sply_dat->degree, sply_dat->knots,
sply_dat->derivates, sply_dat->u, U );
if( p ) for( i=0; i<sply_dat->numk; i++)
if( sply_dat->derivates[i].num ) sply_dat->numU++;
break;
case 3://closed NURBS with derivates
parameter_deriv_closed( sply_dat->numk-1, sply_dat->degree, sply_dat->knots,
sply_dat->derivates, sply_dat->u, U );
if( p ){
sply_dat->numU = sply_dat->numk+sply_dat->degree+1+2;
for( i=1; i<sply_dat->numk-1; i++)
if( sply_dat->derivates[i].num ) sply_dat->numU++;
}
break;
}
}
}
/*******************************************************************************
* Obtaining parameter values by centripetal method and
* creating U-vector
*/
void parameter_free( short n_c, short p_c, lpDA_POINT Q_tmp,
sgFloat *u_c, sgFloat *U_c ){
short i;
sgFloat S;
//decrease nurbs degree
while( n_c + 1 < p_c + 1 ) p_c--;
if( p_c <= 0 ) return;
//calculate parameters for points, begin and end - interval [0,1]
u_c[0]=0.; u_c[n_c]=1.;
// compute sum
for( S=0., i=1; i<=n_c; i++ )
S += sqrt(dpoint_distance( (lpD_POINT)Q_tmp[i], (lpD_POINT)Q_tmp[i-1] ));
S = 1./S;
//compute parameters
for( i=1; i<n_c; i++ )
u_c[i] = u_c[i-1] +
sqrt(dpoint_distance( (lpD_POINT)Q_tmp[i], (lpD_POINT)Q_tmp[i-1] ))*S;
//calculate vector U for computation
if( U_c != NULL ) calculate_free_U( n_c, p_c, u_c, U_c );
}
/*******************************************************************************
* Obtaining parameter values by centripetal method and
* creating U-vector
*/
void parameter_free_APPR( short n_c, short p_c, lpW_NODE P, sgFloat *u_c, sgFloat *U_c ){
short i;
sgFloat S;
//decrease nurbs degree
while( n_c + 1 < p_c + 1 ) p_c--;
if( p_c <= 0 ) return;
//calculate parameters for points, begin and end - interval [0,1]
u_c[0]=0.; u_c[n_c]=1.;
// compute sum
for( S=0, i=1; i<=n_c; i++ ) S+=dpoint_distance_4dl( &P[i], &P[i-1] );
S=1./S;
//compute parameters
for( i=1; i<n_c; i++ )
u_c[i] = u_c[i-1] + dpoint_distance_4dl( &P[i], &P[i-1] )*S;
//calculate vector U for computation
if( U_c != NULL ) calculate_free_U( n_c, p_c, u_c, U_c );
}
/*******************************************************************************
* calculate vector U
*/
static void calculate_free_U(short n_c, short p_c, sgFloat *u_c, sgFloat *U_c ){
short i, j, k;
sgFloat S, l;
//calculate vector U for computation
l = 1./(sgFloat)p_c;
for( i=0; i<=p_c; i++ ) U_c[i] = 0;
for( i=p_c+1, j=1; j<=n_c-p_c; i++, j++ ) {
for( S=0, k=j; k<=j+p_c-1; k++ ) S = S + u_c[k];
U_c[i] = l*S;
}
for( i=n_c+1; i<=n_c+p_c+1; i++ ) U_c[i] = 1;
}
/*******************************************************************************
* Obtaining parameter values by centripetal method for
* closed curve
*/
void parameter_closed( short n_c, short p_c, lpDA_POINT Q_tmp,
sgFloat *u_c, sgFloat *U_c ){
short i;
parameter_free( n_c, p_c, Q_tmp, u_c, U_c );
if( U_c != NULL ){
for( i=n_c+p_c+1; i>=p_c+1; i-- ) U_c[i+1] = U_c[i];
U_c[p_c+1] /= 2;
for( i=n_c+p_c+2; i>=n_c+2; i-- ) U_c[i+1] = U_c[i];
U_c[n_c+2] = (U_c[n_c+1]+1)/2;
}
}
/*******************************************************************************
* Obtaining parameter values by centripetal method for
* free curve with derivates
*/
void parameter_deriv( short n_c, short p_c, lpDA_POINT Q_tmp, lpSNODE deriv,
sgFloat *u_c, sgFloat *U_c ){
short i, j, k, l, t;
parameter_free( n_c, p_c, Q_tmp, u_c, U_c );
if( U_c != NULL ){
l=n_c+p_c+1;
if(dpoint_distance((lpD_POINT)Q_tmp[0],
(lpD_POINT)Q_tmp[n_c - 1])< eps_d ) t=n_c-1;
else t=n_c;
for( i=0; i<=t; i++)
if( deriv[i].num ){
for( j=0; j<l; j++ )
if( ( U_c[j] <= u_c[i] && u_c[i] < U_c[j+1] ) ||
( U_c[j] < U_c[j+1] && u_c[i] == U_c[j+1] && u_c[i] == 1 ) ){
for( k=l; k>=j+1; k-- ) U_c[k+1] = U_c[k];
U_c[j+1] = ( U_c[j+1] + U_c[j])/2;
l++;
break;
}
}
}
}
/*******************************************************************************
* Obtaining parameter values by centripetal method for
* closed curve with derivates
*/
void parameter_deriv_closed( short n_c, short p_c, lpDA_POINT Q_tmp, lpSNODE deriv,
sgFloat *u_c, sgFloat *U_c ){
short i, j, k, l;
parameter_free( n_c, p_c, Q_tmp, u_c, U_c );
if( U_c != NULL ){
for( i=n_c+p_c+1; i>=p_c+1; i-- ) U_c[i+1] = U_c[i];
U_c[p_c+1] /= 2;
for( i=n_c+p_c+2; i>=n_c+2; i-- ) U_c[i+1] = U_c[i];
U_c[n_c+2] = (U_c[n_c+1]+1)/2;
l=n_c+p_c+3;//¤«­  ¢¥ª®  U
for( i=1; i<=n_c-1; i++)
if( deriv[i].num ){
for( j=0; j<l; j++ )
if( ( U_c[j] <= u_c[i] && u_c[i] < U_c[j+1] ) ||
( U_c[j] < U_c[j+1] && u_c[i] == U_c[j+1] && u_c[i] == 1 ) ){
for( k=l; k>=j+1; k-- ) U_c[k+1] = U_c[k];
U_c[j+1] = ( U_c[j+1] + U_c[j])/2;
l++;
break;
}
}
}
}
//------------------------------------------------------------------------------
/*******************************************************************************
* Obtaining parameter values by centripetal method for
* closed curve with derivates
*/
/*static sgFloat calculate_R_Sum( short n_c, lpW_NODE P, sgFloat *N){
short j;
sgFloat S=0;
for( j=0; j<n_c; j++ ) if( N[j]>0 ) S += P[j].vertex[3]*N[j];
return( S );
} */
/**********************************************************
* Obtaining the point for NURBS with weight
* sply_dat - spline
* t - point's parameter to calculate derivates
* p - calculated point
*/
BOOL Calculate_Weight_Point(lpSPLY_DAT sply_dat, short degree, sgFloat t, lpD_POINT p){
short i;
sgFloat *N;
if((N=(sgFloat*)SGMalloc(sply_dat->nump*sizeof(sgFloat)))==NULL) return FALSE;
for( i=0; i<sply_dat->nump; i++ )
if( sply_dat->U[i] <= t && t <= sply_dat->U[i + degree + 1] )
N[i] = nurbs_basis_func( i, degree, sply_dat->U, t );
calc_w_point(sply_dat, p, N );
SGFree(N);
return TRUE;
}
static void calc_w_point(lpSPLY_DAT sply_dat, lpD_POINT p, sgFloat *N){
short i, k;
sgFloat w;
W_NODE node;
memset( &node, 0, sizeof(W_NODE));
for( i=0; i<sply_dat->nump; i++ )
if( N[i] != 0 )
for( k=0; k<4; k++ ) node.vertex[k] += sply_dat->P[i].vertex[k]*N[i];
Create_3D_From_4D( &node, (sgFloat *)p, &w);
}
/**********************************************************
* Obtaining the first degree derivates for NURBS with weight
* sply_dat - spline
* t - point's parameter to calculate derivates
* p - calculated derivates
* deriv - degree of derivate
*/
BOOL Calculate_Weight_Deriv(lpSPLY_DAT sply_dat, short degree, sgFloat t,
lpD_POINT p, short deriv){
BOOL ret=FALSE;
short i;
sgFloat *N_j, *N_i;
if((N_j=(sgFloat*)SGMalloc(sply_dat->nump*sizeof(sgFloat)))==NULL) return FALSE;
if((N_i=(sgFloat*)SGMalloc(sply_dat->nump*sizeof(sgFloat)))==NULL) goto err;
for( i=0; i<sply_dat->nump; i++ )
if( sply_dat->U[i] <= t && t <= sply_dat->U[i+degree+1] )
N_j[i] = nurbs_basis_func( i, degree, sply_dat->U, t );
for( i=1; i<sply_dat->nump; i++ )
if( sply_dat->U[i] <= t && t <= sply_dat->U[i + degree] )
N_i[i] = nurbs_basis_func( i, degree-1, sply_dat->U, t );
calc_w_deriv( sply_dat, degree, p, deriv, N_i, N_j);
ret=TRUE;
err:
if(N_j) SGFree(N_j);
if(N_i) SGFree(N_i);
return ret;
}
#pragma argsused
static void calc_w_deriv(lpSPLY_DAT sply_dat, short degree,
lpD_POINT p, short deriv, sgFloat *N_i, sgFloat *N_j){
short i, j, k;
sgFloat feet, w_w, w_der, wi, wj, wi0;
sgFloat *ppoint;
DA_POINT point={0,0,0}, A={0,0,0}, pi, pj, pi0 ;
ppoint = (sgFloat*)p;
//------------>>>>>>>>>>weight
w_w=0;
for( i=0; i<sply_dat->nump; i++ )
if( N_j[i] != 0 ) w_w += sply_dat->P[i].vertex[3]*N_j[i];
//------------>>>>>>>>>>derivates of weight
w_der=0;
for( i=1; i<sply_dat->nump; i++ ){
if( N_i[i] != 0 )
if( (feet = sply_dat->U[i+degree] - sply_dat->U[i]) > eps_n )
w_der += (sply_dat->P[i].vertex[3] - sply_dat->P[i-1].vertex[3])*N_i[i]/feet;
}
w_der *= degree;
//------------>>>>>>>>>>point
calc_w_point(sply_dat, (lpD_POINT)&point, N_j);
//------------>>>>>>>>>> A`[u]
for(j=0; j<sply_dat->nump; j++)
if( N_j[j] !=0 ){
Create_3D_From_4D( &sply_dat->P[j], (sgFloat *)pj, &wj);
for(i=1; i<sply_dat->nump; i++)
if( N_i[i] !=0 ){
Create_3D_From_4D( &sply_dat->P[i-1], (sgFloat *)pi0, &wi0);
Create_3D_From_4D( &sply_dat->P[i], (sgFloat *)pi, &wi);
if( (feet = (sply_dat->U[i+degree] - sply_dat->U[i])) > eps_n ){
feet=N_j[j]*N_i[i]/feet;
for( k=0; k<3; k++)
// A[k] += feet*(sply_dat->P[j].vertex[3]*(sply_dat->P[i].vertex[k]-
// sply_dat->P[i-1].vertex[k])+
// sply_dat->P[j].vertex[k]*(sply_dat->P[i].vertex[3]-
// sply_dat->P[i-1].vertex[3]));
A[k] += feet*(wj*(pi[k]-pi0[k])+pj[k]*(wi-wi0));
}
}
}
for(i=0; i<3; i++) ppoint[i]=(degree*A[i]-w_der*point[i])/w_w;
}
/**********************************************************
* Obtaining the point for NURBS without weight
* sply_dat - spline
* t - point's parameter to calculate derivates
* p - calculated point
*/
void Calculate_Point(lpSPLY_DAT sply_dat, short degree, sgFloat t, lpD_POINT p){
short i, j;
sgFloat N_j, *point;
point = (sgFloat*)p;
for( i=0; i<sply_dat->nump; i++ )
if( sply_dat->U[i] <= t && t <= sply_dat->U[i+degree+1] )
if( ( N_j = nurbs_basis_func( i, degree, sply_dat->U, t )) != 0 ){
for(j=0; j<3; j++) point[j] += sply_dat->P[i].vertex[j]*N_j;
}
}
/**********************************************************
* Obtaining the first degree derivates for NURBS with weight
* sply_dat - spline
* t - point's parameter to calculate derivates
* p - calculated derivates
* deriv - degree of derivate
*/
void Calculate_Deriv(lpSPLY_DAT sply_dat, short degree, sgFloat t,
lpD_POINT p, short deriv){
short i, j, k;
sgFloat N_j, feet, feet1;
sgFloat *point;
point = (sgFloat*)p;
if( deriv==1){
for( i=1; i<sply_dat->nump; i++ )
if( sply_dat->U[i] <= t && t <= sply_dat->U[i + degree] )
if( ( N_j = nurbs_basis_func( i, degree-1, sply_dat->U, t )) != 0 ){
feet = sply_dat->U[i+degree] - sply_dat->U[i];
if ( feet >= eps_n ){
N_j /= feet;
for( j=0; j<3; j++) point[j] += (sply_dat->P[i].vertex[j] -
sply_dat->P[i-1].vertex[j])*N_j;
}
}
for( j=0; j<3; j++) point[j] *= degree;
}else{
for( j=2; j<sply_dat->nump; j++ ){
// if( sply_dat->U[j] <= t && t <= sply_dat->U[j+degree-1] ){
i=j-1;
if( ( N_j = nurbs_basis_func( j, degree-2, sply_dat->U, t )) != 0 ){
if( (feet = sply_dat->U[i+degree] - sply_dat->U[i+1]) >= eps_n ){
N_j /= feet;
if( (feet=sply_dat->U[i+degree+1] - sply_dat->U[i+1]) >= eps_n )
feet = 1./feet;
else feet = 0.;
if( (feet1=sply_dat->U[i+degree] - sply_dat->U[i]) >= eps_n )
feet1 = 1./feet1;
else feet1 = 0.;
for( k=0; k<3; k++ )
point[k] += ( sply_dat->P[j-2].vertex[k]*feet1 -
sply_dat->P[j-1].vertex[k]*(feet + feet1) +
sply_dat->P[j ].vertex[k]*feet )*N_j;
}
}
// }
}
for(j=0; j<3; j++) point[j] *= degree*(degree-1);
}
}
+129
View File
@@ -0,0 +1,129 @@
#include "../sg.h"
static void write_P_from_knots(lpSPLY_DAT sply_dat, short condition );
BOOL calculate_P(lpSPLY_DAT sply_dat, short condition){
short p_c, k, i, nnn;
sgFloat **A;
nnn = (sply_dat->sdtype & SPL_INT) ? sply_dat->numk : sply_dat->nump;
k=nnn+sply_dat->numd;
p_c = sply_dat->degree;
//decrease nurbs degree
while( nnn < p_c+1 ) p_c--;
if( p_c <= 0 ){
nurbs_handler_err(SPL_INTERNAL_ERROR);
return FALSE;
}
if( sply_dat->sdtype & SPL_APPR ){ // approximative spline
if( ( sply_dat->sdtype&SPL_GEO ) ){
// if( sply_dat->nump > sply_dat->numk){
// SGFree( sply_dat->knots );
// if( (sply_dat->knots = SGMalloc(sply_dat->nump*sizeof(DA_POINT)))== NULL) return FALSE;
// }
}
for( i=0; i<sply_dat->nump; i++ )
get_point_on_sply( sply_dat, sply_dat->u[i],
(lpD_POINT)&sply_dat->knots[i], 0);
sply_dat->numk = sply_dat->nump;
}else{ // interpolative spline
if( (A = mem_matrix( k+1, k+1 )) == NULL) return FALSE;
write_P_from_knots( sply_dat, condition ); //rigth part of equation
nurbs_matrix_create( sply_dat, p_c, A, condition );
if( condition == 0 || condition == 2 ){
//NURBS free or NURBS free with derivates
if( !gauss( A, sply_dat->P, k-1) ) goto err;
sply_dat->nump = k; //number of point in convex
}else if( (condition == 1 || condition == 3) && sply_dat->degree > 1 ){
// NURBS is closed with/without derivates
// for closer consider c(1) = c(n), c`(1)=c`(n), c``(1)=c``(n),
// and in matrix - first string c(1)=P(1);
// second string c`(1)-c`(n)=0;
// n+1-th string c``(1)-c``(n)=0;
if( !gauss( A, sply_dat->P, k ) ) goto err;
memcpy(&sply_dat->P[k+1], &sply_dat->P[0], sizeof(DA_POINT));
sply_dat->nump = k + 2; //number of point in convex
}
free_matrix( A, k+1 );
}
return TRUE;
err:
free_matrix( A, k+1 );
nurbs_handler_err(SPL_INTERNAL_ERROR);
return FALSE;
}
/**********************************************************
* Put right part of equation
*/
static void write_P_from_knots(lpSPLY_DAT sply_dat, short condition ){
short i, j, k;
switch(condition){
case 0://free
for( i=0; i<sply_dat->numk; i++ ){
for( j=0; j<3 ;j++ ) sply_dat->P[i].vertex[j]=sply_dat->knots[i][j];
sply_dat->P[i].vertex[3]=1.;
}
break;
case 1://closed
for( j=0; j<3 ;j++ ) sply_dat->P[0].vertex[j]=sply_dat->knots[0][j];
sply_dat->P[0].vertex[3]=1.;
for( j=0; j<3 ;j++ ) sply_dat->P[1].vertex[j]=0.;
sply_dat->P[1].vertex[3]=1.;
for( i=2; i<=sply_dat->numk-1; i++ ){
for( j=0; j<3 ;j++ ) sply_dat->P[i].vertex[j]=sply_dat->knots[i-1][j];
sply_dat->P[i].vertex[3]=1.;
}
for( j=0; j<3 ;j++ ) sply_dat->P[sply_dat->numk].vertex[j]=0.;
sply_dat->P[sply_dat->numk].vertex[3]=1.;
break;
case 2: //free with derivates
for( i=0, j=0; i<sply_dat->numk-1; i++, j++ ){
for( k=0; k<3; k++ ) sply_dat->P[j].vertex[k]=sply_dat->knots[i][k];
sply_dat->P[j].vertex[3]=1.;
if( sply_dat->derivates[i].num ){
j++;
for( k=0; k<3; k++ ) sply_dat->P[j].vertex[k]=sply_dat->derivates[i].p[k];
sply_dat->P[j].vertex[3]=1.;
}
}
if( sply_dat->derivates[sply_dat->numk-1].num ){
for( k=0; k<3; k++ ) sply_dat->P[j].vertex[k]=sply_dat->derivates[sply_dat->numk-1].p[k];
sply_dat->P[j].vertex[3]=1.;
j++;
}
for( k=0; k<3; k++ ) sply_dat->P[j].vertex[k]=sply_dat->knots[sply_dat->numk-1][k];
sply_dat->P[j].vertex[3]=1.;
break;
case 3://closed with derivates
for( j=0; j<3 ;j++ ) sply_dat->P[0].vertex[j]=sply_dat->knots[0][j];
sply_dat->P[0].vertex[3]=1.;
for( j=0; j<3 ;j++ ) sply_dat->P[1].vertex[j]=0.;
sply_dat->P[1].vertex[3]=1.;
j=2;
if( sply_dat->derivates[0].num ){
for( k=0; k<3; k++ ) sply_dat->P[j].vertex[k]=sply_dat->derivates[0].p[k];
sply_dat->P[j++].vertex[3]=1.;
}
for( i=1; i<sply_dat->numk-1; i++, j++ ){
for( k=0; k<3; k++ ) sply_dat->P[j].vertex[k]=sply_dat->knots[i][k];
sply_dat->P[j].vertex[3]=1.;
if( sply_dat->derivates[i].num ){
j++;
for( k=0; k<3; k++ ) sply_dat->P[j].vertex[k]=sply_dat->derivates[i].p[k];
sply_dat->P[j].vertex[3]=1.;
}
}
if( sply_dat->derivates[sply_dat->numk-1].num ){
for( k=0; k<3; k++ ) sply_dat->P[j].vertex[k]=sply_dat->derivates[sply_dat->numk-1].p[k];
sply_dat->P[j++].vertex[3]=1.;
}
for( k=0; k<3; k++ ) sply_dat->P[j].vertex[k]=sply_dat->knots[sply_dat->numk-1][k];
sply_dat->P[j].vertex[3]=1.;
break;
}
}
+583
View File
@@ -0,0 +1,583 @@
#include "../sg.h"
static BOOL Extract_Spline_Part(lpSPLY_DAT spline, sgFloat t1, sgFloat t2,
sgFloat **U_new1, lpW_NODE *P_new1, sgFloat **u_new1,
short *k1, short *k2);
static void Create_Trim_Spline( sgFloat *U_new, lpW_NODE P_new, sgFloat *u_new,
short k1, short k2, short p, lpSPLY_DAT spline );
//------------------------------------------------------------------------->>>>>
//----------->>>Create break point into NURBS Curves <<<-----------
//------------------------------------------------------------------------->>>>>
/*******************************************************************************
* Insert nessesary knot into NURBS curve to create break point.
* That points are marked to edit together
* type - =0 - create multiply point to change curve form
* =1 - create break point to trim curve
* type >20 - insert knot with multiplicity (type-20)
*/
BOOL Create_Multy_Point( lpSPLY_DAT spline, sgFloat t1, short type ){
BOOL rt=FALSE;
short nump_new, k, r, s;
sgFloat *U_new=NULL, *u_new=NULL;
W_NODE *P_new=NULL;
//k - position the t1 into control vector
//s - number of t1 into control vector
//r - number of insertion of the parameter t1 to create break point
if( !Detect_Multy_Insertion( spline->U, spline->degree, t1, spline->nump, &s, &k )) return FALSE;
r=spline->degree-s;
if( type == 1 ) r++;
if( type > 20 ) r=type-20;
if( r>0 ){ // need to insert knots
if( !Insert_Knot( spline->U, spline->P, spline->u, spline->nump, spline->degree,
t1, &U_new, &P_new, &u_new, &nump_new, r, k, s ) ) goto err;
// modify spline structure
if( !Modify_Spline_Str( spline, U_new, nump_new+spline->degree+1,
P_new, u_new, nump_new, spline->degree ) ) goto err;
}
rt=TRUE;
err:
if( P_new ) SGFree( P_new );
if( U_new ) SGFree( U_new );
if( u_new ) SGFree( u_new );
return rt;
}
//---------------------------------------------------------------->>>>>
// ------------------>>>Get NURBS Curve Part<<<------------------
//---------------------------------------------------------------->>>>>
/**********************************************************
* get part of NURBS curve from parameter t1 to t2 by inserting
* multiplying knots, reparametrizat to [0,1] and covert to Geo
*/
BOOL Get_Part_Spline_Geo(lpSPLY_DAT spline, sgFloat t1, sgFloat t2,
lpGEO_SPLINE geo_spline){
BOOL rt=FALSE;
short bound1, bound2;
sgFloat *U_new1=NULL, *u_new1=NULL;
W_NODE *P_new1=NULL;
SPLY_DAT sply_dat;
//extract spline part by inserting knots
//bound1 - the begin point of changing into control vector
//bound2 - the end point of changing into control vector
if( !Extract_Spline_Part(spline, t1, t2, &U_new1, &P_new1, &u_new1, &bound1, &bound2 ) ) goto err0;
Create_Trim_Spline( U_new1, P_new1, u_new1, bound1, bound2, spline->degree, &sply_dat );
//reparametrization to [0,1]
if( !Reparametrization( sply_dat.nump, sply_dat.numU, 0, 1, spline->degree,
sply_dat.U, sply_dat.P, sply_dat.u )) goto err;
if( !create_geo_sply(&sply_dat, geo_spline )) goto err;
rt=TRUE;
err:
free_sply_dat( &sply_dat );
err0:
if( P_new1 ) SGFree( P_new1 );
if( U_new1 ) SGFree( U_new1 );
if( u_new1 ) SGFree( u_new1 );
return rt;
}
/**********************************************************
* get part of NURBS curve from parameter t1 to t2 by inserting
* multiplying knots and create new sply_dat with param [t1 t2]
*/
BOOL Get_Part_Spline_Dat(lpSPLY_DAT spline, sgFloat t1, sgFloat t2,
lpSPLY_DAT sply_dat){
BOOL rt=FALSE;
short bound1, bound2;
sgFloat *U_new1=NULL, *u_new1=NULL;
W_NODE *P_new1=NULL;
//extract spline part by inserting knots
if( !Extract_Spline_Part(spline, t1, t2, &U_new1, &P_new1, &u_new1, &bound1, &bound2 ) ) goto err;
//create new spline
Create_Trim_Spline( U_new1, P_new1, u_new1, bound1, bound2, spline->degree, sply_dat );
rt=TRUE;
err:
if( P_new1 ) SGFree( P_new1 );
if( U_new1 ) SGFree( U_new1 );
if( u_new1 ) SGFree( u_new1 );
return rt;
}
/*******************************************************************
* Extract part of spline [t1, t2]
*/
static BOOL Extract_Spline_Part(lpSPLY_DAT spline, sgFloat t1, sgFloat t2,
sgFloat **U_new1, lpW_NODE *P_new1, sgFloat **u_new1,
short *bound1, short *bound2 ){
BOOL rt=FALSE;
short i, nump_new1, nump_new2, k, r, s;
sgFloat *U_new2=NULL, *u_new2=NULL;
W_NODE *P_new2=NULL;
//insert knots on the first end
if( (*P_new1=(W_NODE *)SGMalloc(spline->nump*sizeof(W_NODE))) == NULL ) goto err;
if( (*U_new1=(sgFloat *)SGMalloc(spline->numU*sizeof(sgFloat))) == NULL ) goto err;
if( (*u_new1=(sgFloat *)SGMalloc(spline->nump*sizeof(sgFloat))) == NULL ) goto err;
//convert into 4D-space
for( i=0; i<spline->nump; i++ ){
memcpy( &((*P_new1)[i]), &spline->P[i], sizeof(W_NODE) );
(*u_new1)[i]=spline->u[i];
}
for( i=0; i<spline->numU; i++ ) (*U_new1)[i]=spline->U[i];
nump_new1=spline->nump;
//k - position the t1 into control vector
//s - number of t1 into control vector
//r - number of insertion of the parameter t1
if( !Detect_Multy_Insertion( *U_new1, spline->degree, t1, nump_new1, &s, &k )) goto err;
if( (r=spline->degree-s+1)>0 ){ // need to insert knots
if( !Insert_Knot( *U_new1, *P_new1, *u_new1, nump_new1, spline->degree,
t1, &U_new2, &P_new2, &u_new2, &nump_new2, r, k, s ) ) goto err;
SGFree(*U_new1); *U_new1=U_new2; U_new2=NULL;
SGFree(*u_new1); *u_new1=u_new2; u_new2=NULL;
SGFree(*P_new1); *P_new1=P_new2; P_new2=NULL;
nump_new1=nump_new2;
// for left end only
(*bound1)=k-s+1;
} else (*bound1)=k;
//insert knots on the second end
if( !Detect_Multy_Insertion( *U_new1, spline->degree, t2, nump_new1, &s, &k )) goto err;
if( (r=spline->degree-s+1)>0 ){
if( !Insert_Knot( *U_new1, *P_new1, *u_new1, nump_new1, spline->degree,
t2, &U_new2, &P_new2, &u_new2, &nump_new2, r, k, s ) ) goto err;
SGFree(*U_new1); *U_new1=U_new2; U_new2=NULL;
SGFree(*u_new1); *u_new1=u_new2; u_new2=NULL;
SGFree(*P_new1); *P_new1=P_new2; P_new2=NULL;
// nump_new1=nump_new2;
// for right end only
(*bound2)=k+r;
} else (*bound2)=k;
if( s==(spline->degree+1) ) (*bound2)+=spline->degree;
rt=TRUE;
err:
if( P_new2 ) SGFree( P_new2 );
if( U_new2 ) SGFree( U_new2 );
if( u_new2 ) SGFree( u_new2 );
return rt;
}
/**********************************************************
* create new spline respect to part of intial spline [t1,t2]
*/
static void Create_Trim_Spline( sgFloat *U_new, lpW_NODE P_new, sgFloat *u_new,
short k1, short k2, short p, lpSPLY_DAT sply_dat ){
short i, j;
//initialization of new spline
init_sply_dat(SPL_NEW, p, SPL_APPR, sply_dat );
//write points and weights
sply_dat->nump = sply_dat->numk = k2 - p - k1;
if (sply_dat->allocSizeFor_P<sply_dat->nump &&
sply_dat->P)
{
SGFree(sply_dat->P);
sply_dat->P = (W_NODE*)SGMalloc(sply_dat->nump*sizeof(W_NODE));
sply_dat->allocSizeFor_P = sply_dat->nump;
}
if (sply_dat->allocSizeFor_u<sply_dat->nump &&
sply_dat->u)
{
SGFree(sply_dat->u);
sply_dat->u = (sgFloat*)SGMalloc(sply_dat->nump*sizeof(sgFloat));
sply_dat->allocSizeFor_u = sply_dat->nump;
}
for(i=k1, j=0; i<=k2-p-1; i++, j++)
{
if (j<sply_dat->allocSizeFor_P)
memcpy( &sply_dat->P[j], &P_new[i], sizeof(W_NODE) );
else
assert(0);
if (j<sply_dat->allocSizeFor_u)
sply_dat->u[j]=u_new[i];
else
assert(0);
}
// write vector
sply_dat->numU = sply_dat->nump+p+1;
if (sply_dat->allocSizeFor_U<sply_dat->numU &&
sply_dat->U)
{
SGFree(sply_dat->U);
sply_dat->U = (sgFloat*)SGMalloc(sply_dat->numU*sizeof(sgFloat));
sply_dat->allocSizeFor_U = sply_dat->numU;
}
for(i=k1, j=0; i<=k2; i++, j++ )
if (j<sply_dat->allocSizeFor_U)
sply_dat->U[j]=U_new[i];
else
assert(0);
}
/**********************************************************
* create new NURBS curve from two splines( sply_dat2+sply_dat1)
* by merge knot's vectors and P-vectors and deleting of the
* multiplying knots degree of the splines must be !!! equal
*/
BOOL Two_Spline_Union_Dat(lpSPLY_DAT sply_dat1, lpSPLY_DAT sply_dat2,
lpSPLY_DAT sply_new){
/* BOOL ret;
short i, d, new_nump; //,r;
sgFloat delta;
sgFloat *U_new1, *u_new1;//, *U_new2=NULL;
W_NODE *P_new1;//, *P_new2=NULL;
//write points and weights from first spline
if( (P_new1=(W_NODE *)SGMalloc((sply_dat1->nump+sply_dat2->nump)*sizeof(W_NODE))) == NULL ) return FALSE;
memcpy( P_new1, sply_dat2->P, sply_dat2->nump*sizeof(W_NODE) );
//add second spline into new one
for( i=0; i<sply_dat1->nump; i++ ) P_new1[sply_dat2->nump+i-1] = sply_dat1->P[i];
// write parameters
if( (u_new1=(sgFloat *)SGMalloc((sply_dat1->nump+sply_dat2->nump)*sizeof(sgFloat))) == NULL ) goto err;
memcpy( u_new1, sply_dat2->u, sply_dat2->nump*sizeof(sgFloat) );
delta=sply_dat2->u[sply_dat2->nump-1];
for( i=0; i<sply_dat1->nump; i++ ) u_new1[sply_dat2->nump+i-1] = sply_dat1->u[i]+delta;
// write vector
d=sply_dat1->degree+1;
if( (U_new1=(sgFloat *)SGMalloc((sply_dat1->numU+sply_dat2->numU)*sizeof(sgFloat))) == NULL ) goto err;
memcpy( U_new1, sply_dat2->U, sply_dat2->numU*sizeof(sgFloat) );
delta=sply_dat2->U[sply_dat2->numU-1];
for(i=d; i<sply_dat1->numU; i++ ) U_new1[sply_dat2->numU+i-d-1]=sply_dat1->U[i]+delta;
new_nump=sply_dat1->nump+sply_dat2->nump-1;
//initialization of new spline
init_sply_dat(SPL_NEW, sply_dat1->degree, SPL_APPR, sply_new );
sply_new->nump = sply_new->numk = new_nump;
memcpy( sply_new->P, P_new1, new_nump*sizeof(W_NODE) );
memcpy( sply_new->u, u_new1, new_nump*sizeof(sgFloat) );
sply_new->numU = new_nump+sply_dat1->degree+1;
memcpy( sply_new->U, U_new1, sply_new->numU*sizeof(sgFloat) );
// SGFree( U_new2 ); SGFree( P_new2 );
ret=TRUE;
err:
if(U_new1) SGFree( U_new1 );
if(u_new1) SGFree( u_new1 );
if(P_new1) SGFree( P_new1 );
return ret;
*/
BOOL ret=FALSE;
short i, d, new_nump; //,r;
sgFloat delta;
sgFloat *U_new1, *u_new1;
W_NODE *P_new1;
P_new1 = NULL;
u_new1 = NULL;
U_new1 = NULL;
//write points and weights from first spline
if( (P_new1=(W_NODE *)SGMalloc((sply_dat1->nump+sply_dat2->nump)*sizeof(W_NODE))) == NULL ) return FALSE;
memcpy( P_new1, sply_dat2->P, sply_dat2->nump*sizeof(W_NODE) );
//add second spline into new one
for( i=0; i<sply_dat1->nump; i++ )
P_new1[sply_dat2->nump+i-1] = sply_dat1->P[i];
// write parameters
if( (u_new1=(sgFloat *)SGMalloc((sply_dat1->nump+sply_dat2->nump)*sizeof(sgFloat))) == NULL ) goto err;
memcpy( u_new1, sply_dat2->u, sply_dat2->nump*sizeof(sgFloat) );
delta=sply_dat2->u[sply_dat2->nump-1];
for( i=0; i<sply_dat1->nump; i++ ) u_new1[sply_dat2->nump+i-1] = sply_dat1->u[i]+delta;
// write vector
d=sply_dat1->degree+1;
if( (U_new1=(sgFloat *)SGMalloc((sply_dat1->numU+sply_dat2->numU)*sizeof(sgFloat))) == NULL ) goto err;
memcpy( U_new1, sply_dat2->U, sply_dat2->numU*sizeof(sgFloat) );
delta=sply_dat2->U[sply_dat2->numU-1];
for(i=d; i<sply_dat1->numU; i++ ) U_new1[sply_dat2->numU+i-d-1]=sply_dat1->U[i]+delta;
//try to delete multiply points
new_nump=sply_dat1->nump+sply_dat2->nump-1;
// r=Del_Knot( U_new1, P_new1, &new_nump,
// sply_dat1->numu+sply_dat2->numu-d-1, sply_dat1->degree,
// 1., d);
//initialization of new spline
init_sply_dat(SPL_NEW, sply_dat1->degree, SPL_APPR, sply_new );
sply_new->nump = sply_new->numk = new_nump;
// RA -
// ( init_sply_dat 250 )
// . ?
// RA - memcpy( sply_new->P, P_new1, new_nump*sizeof(W_NODE) );
// RA - memcpy( sply_new->u, u_new1, new_nump*sizeof(sgFloat) );
//RA Begin
if (sply_new->allocSizeFor_knots<sply_new->numk &&
sply_new->knots)
{
SGFree(sply_new->knots);
sply_new->knots = (DA_POINT*)SGMalloc(sply_new->numk*sizeof(DA_POINT));
sply_new->allocSizeFor_knots = sply_new->numk;
}
memset(sply_new->knots,0,sply_new->allocSizeFor_knots*sizeof(DA_POINT));
if (sply_new->allocSizeFor_P<new_nump &&
sply_new->P)
{
SGFree(sply_new->P);
sply_new->P = (W_NODE*)SGMalloc(new_nump*sizeof(W_NODE));
sply_new->allocSizeFor_P = new_nump;
}
memcpy( sply_new->P, P_new1, new_nump*sizeof(W_NODE) );
if (sply_new->allocSizeFor_u<new_nump &&
sply_new->u)
{
SGFree(sply_new->u);
sply_new->u = (sgFloat*)SGMalloc(new_nump*sizeof(sgFloat));
sply_new->allocSizeFor_u = new_nump;
}
memcpy( sply_new->u, u_new1, new_nump*sizeof(sgFloat) );
//RA End
sply_new->numU = new_nump+sply_dat1->degree+1;
// RA - memcpy( sply_new->U, U_new1, sply_new->numu*sizeof(sgFloat) );
//RA Begin
if (sply_new->allocSizeFor_U<sply_new->numU &&
sply_new->U)
{
SGFree(sply_new->U);
sply_new->U = (sgFloat*)SGMalloc(sply_new->numU*sizeof(sgFloat));
sply_new->allocSizeFor_U = sply_new->numU;
}
memcpy( sply_new->U, U_new1, sply_new->numU*sizeof(sgFloat) );
//RA End
ret=TRUE;
err:
if(U_new1) SGFree( U_new1 );
if(u_new1) SGFree( u_new1 );
if(P_new1) SGFree( P_new1 );
return ret;
}
//---------------------------------------------------------------->>>>>
// ----------------->>>Increase NURBS Degree<<<------------------
//---------------------------------------------------------------->>>>>
/**********************************************************
* Increase spline degree
*/
BOOL Increase_Spline_Degree(lpSPLY_DAT sply_dat, short new_degree){
BOOL rt=FALSE;
short i, j, k, l, m, r, s, k1, add, m_del;
short nump_new1, nump_new2, degree_plus, *r_insert=NULL;
sgFloat *U_new1, *u_new1, *U_new2=NULL, *u_new2=NULL, *par_insert=NULL;
W_NODE *P_new1, *P_new2=NULL;
add=new_degree-sply_dat->degree;
degree_plus=sply_dat->degree+1;
if( (P_new1=(W_NODE *)SGMalloc(sply_dat->nump*sizeof(W_NODE))) == NULL) return FALSE;
if( (u_new1=(sgFloat *)SGMalloc(sply_dat->nump*sizeof(sgFloat))) == NULL) goto err;
for( i=0; i<sply_dat->nump; i++ ){
memcpy( &P_new1[i], &sply_dat->P[i], sizeof(W_NODE) );
u_new1[i]=sply_dat->u[i];
}
if( sply_dat->nump==degree_plus ){ //It's Beze Curve already!
//increase degree for composite curve
nump_new2=0;
Increase_Composite_Curve_Degree( P_new1, &P_new2, u_new1, &u_new2, degree_plus,
&nump_new2, sply_dat->degree, add);
//create new control knots vector
if( (U_new1=(sgFloat *)SGMalloc((nump_new2+new_degree+1)*sizeof(sgFloat)))==NULL) goto err;
for(i=0; i<new_degree+1; i++) { U_new1[i]=0.; U_new1[i+new_degree+1]=1.;}
k=2*(new_degree+1);
}else{ // It's not Beze Curve - create composite curve from initial curve
U_new1=(sgFloat *)SGMalloc(sply_dat->numU*sizeof(sgFloat));
for( i=0; i<sply_dat->numU; i++ ) U_new1[i]=sply_dat->U[i];
nump_new1=sply_dat->nump;
m=0;
if((r_insert =(short *)SGMalloc((sply_dat->nump-degree_plus)*sizeof(short)))==NULL) goto err;
if((par_insert=(sgFloat *)SGMalloc((sply_dat->nump-degree_plus)*sizeof(sgFloat)))==NULL) goto err1;
//insert knots on the each parameter
for(i=degree_plus, j=1; j<=sply_dat->nump-degree_plus; i++, j++ ) {
//detect r=number of the insertions for j-th knot
if( !Detect_Multy_Insertion( U_new1, sply_dat->degree, sply_dat->U[i],
nump_new1, &s, &k1)) goto err1;
if( (r=sply_dat->degree-s+1)>0 ){ //if this node must be insert to create Beze Curve
r_insert[m]=r;
par_insert[m++]=sply_dat->U[i];
if( !Insert_Knot( U_new1, P_new1, u_new1, nump_new1, sply_dat->degree,
sply_dat->U[i], &U_new2, &P_new2, &u_new2, &nump_new2, r, k1, s ) ) goto err;
SGFree(U_new1); U_new1=U_new2; U_new2=NULL;
SGFree(u_new1); u_new1=u_new2; u_new2=NULL;
SGFree(P_new1); P_new1=P_new2; P_new2=NULL;
nump_new1=nump_new2; nump_new2=0;
}
}
//increase degree for composite curve
Increase_Composite_Curve_Degree(P_new1, &P_new2, u_new1, &u_new2, nump_new1,
&nump_new2, sply_dat->degree, add);
k=0;
SGFree(U_new1);
//create new control knots vector
if( (U_new1=(sgFloat *)SGMalloc((nump_new2+new_degree+1)*sizeof(sgFloat)))==NULL) goto err1;
for(i=0; i<new_degree+1; i++) U_new1[k++]=0.;
for( j=1; j<=sply_dat->nump-degree_plus; j+=s ) {
//detect multiplisity
for( s=0, l=1; l<=sply_dat->nump-degree_plus; l++ )
if( fabs(sply_dat->U[j+sply_dat->degree]-sply_dat->U[l+sply_dat->degree]) < eps_n ) s++;
for( l=0; l<new_degree+1; l++ ) U_new1[k++]=sply_dat->U[j+sply_dat->degree];
}
for(i=0; i<new_degree+1; i++) U_new1[k++]=1.;
//deleting if the inserted knots
m_del=0;
for( i=0; i<m; i++ )
m_del+=Del_Knot( U_new1, P_new2, u_new2, &nump_new2, nump_new2+new_degree+1,
new_degree, par_insert[i], r_insert[i]);
k-=m_del;
SGFree( par_insert ); par_insert=NULL;
SGFree( r_insert ); r_insert=NULL;
}
//modify spline structure for increase degree
if( !Modify_Spline_Str( sply_dat, U_new1, k, P_new2, u_new2, nump_new2, new_degree ) ) goto err;
rt=TRUE;
err1:
if( par_insert ) SGFree( par_insert ); if( r_insert ) SGFree( r_insert );
err:
if( P_new1 ) SGFree( P_new1 ); if( P_new2 ) SGFree( P_new2 );
if( U_new1 ) SGFree( U_new1 ); if( U_new2 ) SGFree( U_new2 );
if( u_new1 ) SGFree( u_new1 ); if( u_new2 ) SGFree( u_new2 );
return rt;
}
//---------------------------------------------------------------->>>>>
// ------------->>>NURBS Curve reparametrization<<<------------------
//---------------------------------------------------------------->>>>>
/**********************************************************
* [ab] - initial interval i.e [ab]->[cd]
* [cd] - rezalting interval
* p - degree
* U - control parametrical vector
*/
BOOL Reparametrization( short nump, short numu, sgFloat c, sgFloat d, short p,
sgFloat *U, lpW_NODE P, sgFloat *u ){
short i, j;
sgFloat w0, wn, Gamma, Alfa, S, t1, t2, a, b;
a=U[0];
b=U[numu-1];
w0=pow((double)P[0].vertex[3], (double)1./p);
wn=pow((double)P[nump-1].vertex[3], (double)1./p);
for( i=0; i<numu; i++ ){
t1=w0*(b-U[i]); t2=wn*(U[i]-a);
if( (Alfa =( t1 + t2 ) ) < eps_n ) return FALSE;
U[i] = ( t1*c + t2*d )/Alfa;
}
a=u[0];
b=u[nump-1];
for( i=0; i<nump; i++ ){
t1=w0*(b-u[i]); t2=wn*(u[i]-a);
if( (Alfa =( t1 + t2 ) ) < eps_n ) return FALSE;
u[i] = ( t1*c + t2*d )/Alfa;
}
// Gamma = wn-w0;
// Alfa = wn*d-w0*c;
Gamma = 0;
Alfa = d-c;
for( i=0; i<nump; i++ ){
for( S=1., j=1; j<=p; j++ ) S = S*( Gamma*U[i+j] - Alfa );
P[i].vertex[3] *= S;
}
return TRUE;
}
//---------------------------------------------------------------->>>>>
// ------------->>>NURBS Curve reorientation<<<------------------
//---------------------------------------------------------------->>>>>
/**********************************************************
* reorientation of spline
*/
BOOL Reorient_Spline( lpSPLY_DAT sply_dat ){
short ii;
sgFloat *U;
lpW_NODE P_tmp;
if( (P_tmp=(W_NODE *)SGMalloc( sply_dat->nump*sizeof(W_NODE)))==NULL) return FALSE;
memcpy(P_tmp, sply_dat->P, sply_dat->nump*sizeof(W_NODE));
for( ii=0; ii<sply_dat->nump; ii++)
memcpy( &sply_dat->P[ii], &P_tmp[sply_dat->nump-1-ii], sizeof(W_NODE));
SGFree(P_tmp);
if( (U=(sgFloat *)SGMalloc( sply_dat->numU*sizeof(sgFloat)))==NULL) goto err;
memcpy(U, sply_dat->U, sply_dat->numU*sizeof(sgFloat));
for( ii=0; ii<sply_dat->numU; ii++){
U[ii]-=1.;
sply_dat->U[sply_dat->numU-1-ii]=fabs(U[ii]);
}
memcpy(U, sply_dat->u, sply_dat->nump*sizeof(sgFloat));
for( ii=0; ii<sply_dat->nump; ii++){
U[ii]-=1.;
sply_dat->u[sply_dat->nump-1-ii]=fabs(U[ii]);
}
SGFree(U);
return TRUE;
err:
SGFree(P_tmp);
return FALSE;
}
//---------------------------------------------------------------->>>>>
// ------------->>>NURBS Modify work structure <<<------------------
//---------------------------------------------------------------->>>>>
/**********************************************************
* Modify NURBS by new control points and vector
*/
BOOL Modify_Spline_Str( lpSPLY_DAT sply_dat, sgFloat *U_new, short numu,
lpW_NODE P_new, sgFloat *u_new, short nump, short degree ){
//write control vector
if( numu>MAX_POINT_ON_SPLINE ){
SGFree( sply_dat->U );
if( (sply_dat->U=(sgFloat *)SGMalloc(numu*sizeof(sgFloat)))==NULL ) return FALSE;
}
memcpy( sply_dat->U, U_new, numu*sizeof(sgFloat) );
sply_dat->numU=numu;
//write control points
if( nump>MAX_POINT_ON_SPLINE ){
SGFree( sply_dat->P );
SGFree( sply_dat->knots );
SGFree( sply_dat->u );
if( (sply_dat->P=(W_NODE *)SGMalloc(nump*sizeof(W_NODE)))==NULL) return FALSE;
if( (sply_dat->knots=(DA_POINT*)SGMalloc(nump*sizeof(DA_POINT)))==NULL) return FALSE;
if( (sply_dat->u=(sgFloat *)SGMalloc(nump*sizeof(sgFloat)))==NULL ) return FALSE;
}
memcpy( sply_dat->P, P_new, nump*sizeof(W_NODE) );
memcpy( sply_dat->u, u_new, nump*sizeof(sgFloat) );
sply_dat->nump=nump;
sply_dat->degree = degree;
calculate_P(sply_dat, 0);
return TRUE;
}
+143
View File
@@ -0,0 +1,143 @@
#include "../sg.h"
/**********************************************************
* obtain NURBScurve-to-point distance
* spl - NURBS curve
* point - point for curve-to-point distance
* t - point or point projection lie on curve with parameter t
* dist - distance between point and its projection
*/
BOOL Spline_By_Point( lpSPLY_DAT spl, void *point, sgFloat *t, sgFloat *dist ){
sgFloat X[1];
D_POINT node;
X[0]=*t;
if( (*dist = Fletchjer_Paur( function_0, derivativs_0,
(void *)spl, (void *)point,
X, 1, 50 )) == -1 ) return FALSE;
*t=X[0];
// if( fabs(*dist) > eps_d ){ // point out of curve
if( X[0] < -eps_n ) *t=0;
if( X[0] > 1.+eps_n ) *t=1.;
get_point_on_sply( spl, *t, &node, 0 );
*dist= dpoint_distance( (D_POINT *)point, &node );
// }
return TRUE;
}
/**********************************************************
* obtain NURBScurve-to-plane distance
* spl - NURBS curve
* plane - points on plane
* t - point lie on curve with parameter t
* dist - distance between point and its projection
*/
BOOL Spline_By_Plane( lpSPLY_DAT spl, void *plane,
sgFloat *t, sgFloat *bound, sgFloat *dist ){
sgFloat X[3];
//found parameter for the begining point on curve
X[0]=*t;
//found parameter for the begining point on plane
//the plane parametrization is made trought beginning point =>
X[1]=X[2]=0.;
// if(!Spline_By_Point( spl, &point[0], &X[0], dist )) return FALSE;
if( (*dist = Fletchjer_Paur( function_2, derivativs_2,
(void *)spl, (void *)plane,
X, 3, 400 )) == -1 ) return FALSE;
if( ( bound[0] <= X[0] && X[0] < bound[1] ) ||
( X[0] == 1. && bound[1] == 1. )) *t=X[0];
else *t=-1.;
return TRUE;
}
/**********************************************************
* obtain NURBS curve-to-line distance
* spl - NURBS curve
* line - points on line
* t - point or point projection lie on curve with parameter t
* dist - distance between point and its projection
* span - number of the interval intersection found on
*/
BOOL Spline_By_Line( lpSPLY_DAT spl, void *line,
sgFloat *t_sply, sgFloat *t_line,
sgFloat *bound, sgFloat *dist ){
sgFloat X[2];
D_POINT *point;
//found parameter for the begining point on curve and line
X[0]=*t_sply;
X[1]=*t_line;
point=(D_POINT*)line;
if( (*dist = Fletchjer_Paur( function_1, derivativs_1,
(void *)spl, (void *)point,
X, 2, 400 )) == -1 ) return FALSE;
if( ( bound[0] <= X[0] && X[0] < bound[1] ) ||
( X[0] == 1. && bound[1] == 1. )) *t_sply=X[0];
else *t_sply=-1.;
return TRUE;
}
/**********************************************************
* obtain sply-by-sply intersections
* sply_dat1 - data for first spline
* sply_dat2 - data for second spline
* intersect_list - list of intersection points
*/
BOOL Spline_By_Spline( lpSPLY_DAT spl1, void *spl2,
sgFloat *t1, sgFloat *t2,
sgFloat *bound1, sgFloat *bound2,
sgFloat *dist ){
sgFloat X[2];
//found parameter for the begining point on the first curve
X[0]=*t1;
X[1]=*t2;
if( (*dist = Fletchjer_Paur( function_3, derivativs_3,
(void *)spl1, (void *)spl2,
X, 2, 400 )) == -1 ) return FALSE;
if( ( bound1[0] <= X[0] && X[0] < bound1[1] ) ||
( X[0] == 1. && bound1[1] == 1. )) *t1=X[0];
// else *t1=-1.;
if( ( bound2[0] <= X[1] && X[1] < bound2[1] ) ||
( X[1] == 1. && bound2[1] == 1. )) *t2=X[1];
// else *t2=-1.;
// *t1=X[0]; *t2=X[1];
return TRUE;
}
/**********************************************************
* obtain NURBSsurface-to-point distance
* srf - NURBS surface
* point - point for curve-to-point distance
* tu, tv- point or point projection lie on surface with parameter (tu,tv)
* dist - distance between point and its projection
*/
BOOL Surface_By_Point( lpSURF_DAT srf, void *point, sgFloat *tu, sgFloat *tv, sgFloat *dist ){
sgFloat X[2];
D_POINT node;
X[0]=*tu;
X[1]=*tv;
if( (*dist = Fletchjer_Paur( function_0_0, derivativs_0_0,
(void *)srf, (void *)point,
X, 2, 50 )) == -1 ) return FALSE;
*tu=X[0];
*tv=X[1];
// if( fabs(*dist) > eps_d ){ // point out of curve
if( X[0] < -eps_n ) *tu=0;
if( X[0] > 1.+eps_n ) *tu=1.;
if( X[1] < -eps_n ) *tv=0;
if( X[1] > 1.+eps_n ) *tv=1.;
if( !get_point_on_surface( srf, *tu, *tv, &node ) ) return FALSE;
*dist= dpoint_distance( (D_POINT *)point, &node );
// }
return TRUE;
}
+357
View File
@@ -0,0 +1,357 @@
#include "../sg.h"
static BOOL NURBS_Knot_Ins( short nump, short p, sgFloat *U, lpW_NODE P, sgFloat *u, sgFloat t,
short k, short s, short r, sgFloat *U_new, lpW_NODE P_new, sgFloat *u_new);
/*static short NURBS_Knot_Del( sgFloat *U, lpW_NODE P, short *nump, short d, sgFloat t,
short k, short s, short r);
// sgFloat *U_new, lpW_NODE P_new, short *nump_new,
*/
static void Increase_Beze_Degree(lpW_NODE beze1, sgFloat *u1, lpW_NODE beze2, sgFloat *u2,
short degree, short add );
static sgFloat c_beze(short k1, short k2);
static short factor(short k);
/*******************************************************************************
* Main function for multy inserting knot
* U - initial control vector
* P - initial control points
* nump -number of control points
* p - degree of spline
* t - parameter of the inserting knot
* U_new - new control vector
* P_new - new control points
* nump_new - number of new control points
* r - number of insertions to create break point
* k - number of span into control vector for new knot
* s - number of existing inserting knot
* type - =0 - insert full break point
* =1 - insert knot r times
*/
BOOL Insert_Knot( sgFloat *U, lpW_NODE P, sgFloat *u, short nump, short p, sgFloat t,
sgFloat **U_new, lpW_NODE *P_new, sgFloat **u_new, short *nump_new,
short r, short k, short s ){
short num;
num = nump + p + 1;
//number of inserting points = p-s+r-1;
*nump_new=nump+r;
if( (*U_new = (sgFloat*)SGMalloc( ( num + r )*sizeof(sgFloat) ) ) == NULL ) return FALSE;
if( (*P_new = (W_NODE *)SGMalloc( ( *nump_new )*sizeof(W_NODE) ) ) == NULL ) return FALSE;
if( (*u_new = (sgFloat*)SGMalloc( ( *nump_new )*sizeof(sgFloat) ) ) == NULL ) return FALSE;
//insert nessesary number of knots
NURBS_Knot_Ins( nump, p, U, P, u, t, k, s, r, *U_new, *P_new, *u_new );
return TRUE;
}
/*******************************************************************************
* multiplicity insert ( r times ) knot t
* nump - length of P
* d - degree
* U - char. vector
* P - points of the char. poligon
* t - knot to be insert
* k - number of knot to be insert into vector U
* s - multiplicity of existing knot t into vector U ( may be =0 )
* r - multiplicity of insertinon
* U_new, P_New - new vector and poligon
* type - =0 - insert full break point
* =1 - insert knot r times
*/
static BOOL NURBS_Knot_Ins( short nump, short d, sgFloat *U, lpW_NODE P, sgFloat *u,
sgFloat t, short k, short s, short r,
sgFloat *U_new, lpW_NODE P_new, sgFloat *u_new){
BOOL rt=FALSE;
short i, j, mp, jjj, jj, L;//, number_t;
sgFloat alpha, *uu;
lpW_NODE PP;
if( (PP = (lpW_NODE)SGMalloc((d+1)*sizeof(W_NODE))) == NULL ) return FALSE;
if( (uu = (sgFloat*)SGMalloc((d+1)*sizeof(sgFloat))) == NULL ) goto err;
mp = nump + d + 1;
//create new knot vector
for( i=0; i<=k; i++ ) U_new[i] = U[i];
for( i=1; i<=r; i++ ) U_new[k+i] = t;
for( i=k+1; i<mp; i++ ) U_new[i+r] = U[i];
//save knot points
for( i=0; i<=k-d; i++ ) {P_new[i] = P[i]; u_new[i] = u[i];}
for( i=k-s; i<nump; i++ ) {P_new[i+r] = P[i]; u_new[i+r] = u[i];}
for( i=0; i<=d-s; i++ ) {PP[i] = P[k-d+i]; uu[i] = u[k-d+i];}
L=k-d;
jjj=(r+s==d+1)?(r):(r+1);
// jjj=r;
//insert knor r times
for( j=1; j<jjj; j++ ){
L = k-d+j;
for( i=0; i<=d-j-s; i++ ){
alpha = (t-U[L+i])/(U[i+k+1]-U[L+i]);
for( jj=0; jj<4; jj++ )
PP[i].vertex[jj]=alpha*PP[i+1].vertex[jj] + (1.-alpha)*PP[i].vertex[jj];
uu[i]=alpha*uu[i+1] + (1.-alpha)*uu[i];
}
P_new[L] = PP[0];
if( j==jjj-1 ) u_new[L] = t;
else u_new[L] = uu[0];
P_new[k+r-j-s] = PP[d-j-s]; u_new[k+r-j-s] = uu[d-j-s];
}
for( i=L+1; i<k-s; i++ ) { P_new[i] = PP[i-L]; u_new[i] = uu[i-L];}
// L=-1;
// for( i=0; i<mp+r; i++ )
// if( fabs(U_new[i]-t)<eps_n && fabs(U_new[i]-U_new[i+1])<eps_n){
// L=i;
// break;
// }
// if( L>0 ) u_new[L-1]=t;
// for( i=0; i<nump+d-s; i++ ) u_new[i]=(U_new[i+1]+U_new[i+2])/2.;
rt=TRUE;
SGFree(uu);
err:
SGFree(PP);
return rt;
}
//-------------------------------------------------------------------------->>>>
/*******************************************************************************
* multiplicity delete ( r times ) knot t
* nump - length of P
* d - degree
* U - char. vector
* P - points of the char. poligon
* t - knot to be delete
* k - number of knot to be delete into vector U
* s - multiplicity of existing knot t into vector U ( may be =0 )
* r - multiplicity of deleting
* U_new, P_New - new vector and poligon
*/
short Del_Knot( sgFloat *U, lpW_NODE P, sgFloat *u, short *nump, short numu, short d,
sgFloat t, short r ){
short i, i1, j, j1, k, s, del=0;
short iii;
sgFloat alphai, alphaj;
W_NODE node;
for( j1=0; j1<r; j1++ ){
//detect number of knot to be deleted
s=0; k=-1;
for( i=0; i<numu; i++ ) if( fabs(t-U[i])<eps_n ) { k=i; s++; }
if( k<0 ) return del;
//try to delete knot with number <k> r times
// return(NURBS_Knot_Del( U, P, nump, d, t, k, s, r));
i=k-d; j=k-s;
while(j-i>0){
alphai=(t-U[i])/(U[i+d+1]-U[i]);
alphaj=(t-U[j])/(U[j+d+1]-U[j]);
for( iii=0; iii<4; iii++ ){
P[i].vertex[iii]=(P[i].vertex[iii]-(1-alphai)*P[i-1].vertex[iii])/alphai;
P[j].vertex[iii]=(P[j].vertex[iii]-alphaj*P[j+1].vertex[iii])/(1-alphaj);
}
u[i]=(u[i]-(1-alphai)*u[i-1])/alphai;
u[j]=(u[j]-alphaj*u[j+1])/(1-alphaj);
i++; j--;
}
if( dpoint_distance_4d(&P[i-1], &P[j+1])<eps_d ){
for( i1=i+1; i1<*nump; i1++ ){
memcpy(&P[i1-1], &P[i1], sizeof(W_NODE));
u[i1-1]=u[i1];
}
(*nump)--;
for( i1=k; i1<numu-1; i1++ ) U[i1]=U[i1+1];
numu--;
del++;
}else{
alphai=(t-U[i])/(U[i+d+1]-U[i]);
for( iii=0; iii<4; iii++ )
node.vertex[iii]=alphai*P[i+1].vertex[iii]+(1-alphai)*P[i-1].vertex[iii];
if( dpoint_distance_4d(&P[i], &node)<eps_d ){
for( i1=i+1; i1<*nump; i1++ ){
memcpy(&P[i1-1], &P[i1], sizeof(W_NODE));
u[i1-1]=u[i1];
}
(*nump)--;
for( i1=k; i1<numu; i1++ ) U[i1-1]=U[i1];
numu--;
del++;
}
}
// if( del < j1+1 ) return 0;
}
return del;
}
/**********************************************************
* multiplicity delete ( r times ) knot t
* nump - length of P
* d - degree
* U - char. vector
* P - points of the char. poligon
* t - knot to be delete
* k - number of knot to be delete into vector U
* s - multiplicity of existing knot t into vector U ( may be =0 )
* r - multiplicity of deleting
* U_new, P_New - new vector and poligon
* nump_new - length of P_new
*/
/*static short NURBS_Knot_Del( sgFloat *U, lpW_NODE P, short *nump, short d, sgFloat t,
short k, short s, short r){
short i, j, l, m, n=0, iii;
short first, last;
sgFloat alphai, alphaj;
W_NODE *point, p;
if( (point = SGMalloc((*nump)*sizeof(W_NODE))) == NULL ) return 0;
for( i=0; i<*nump; i++ ) point[i]=P[i];
// memset(point, 0, nump*sizeof(W_NODE));
first=k-d+1;
last =k-s-1;
// if (s==d+1) last++;
for( l=1; l<=r; l++ ){
j=++last;
i=--first;
while(j-i>l-1){
alphai=(t-U[i])/(U[i+d+l]-U[i]);
alphaj=(t-U[j-l+1])/(U[j+d+1]-U[j-l+1]);
for( iii=0; iii<4; iii++ ){
point[i].vertex[iii]=(point[i].vertex[iii]-(1-alphai)*point[i-1].vertex[iii])/alphai;
point[j].vertex[iii]=(point[j].vertex[iii]-alphaj*point[j+1].vertex[iii])/(1-alphaj);
}
i++; j--;
}
if(dpoint_distance_4dl(&point[i-1], &point[j+1])<eps_d){
//delete point and knot
for (m=i-1; m<*nump-1; m++) point[m]=point[m+1];
for (m=k; m<*nump+d+1-1; m++) U[m]=U[m+1];
//k--; s--; r--;
(*nump)--; n++;
}else{
alphai=(t-U[i])/(U[i+d+1+l]-U[i]);
for( iii=0; iii<4; iii++ ) p.vertex[iii]=alphai*point[i+l+1].vertex[iii]+
(1-alphai)*point[i-1].vertex[iii];
if(fabs(dpoint_distance_4dl(&P[i], &p))<=eps_d){
//delete point and knot
for (m=i-1; m<*nump-1; m++) point[m]=point[m+1];
for (m=k; m<*nump+d+1-1; m++) U[m]=U[m+1];
//k--; s--; r--;
(*nump)--; n++;
}
}
}
// if(n==0) goto err; // imposible to delete this knot
// modify control vector
for( i=0; i<*nump; i++) P[i]=point[i];
//err:
SGFree(point);
return (n);
}
*/
//------------------------------------------------------------------------>>>>>>
/*******************************************************************************
* create the Beze from the composite curve
* P_new1 - initial control points
* P_new2 - rezulting control points
* span - number of span
* degree - initial degree
* add - increase degree on add
*/
BOOL Increase_Composite_Curve_Degree(lpW_NODE P_new1, lpW_NODE *P_new2,
sgFloat *u_new1, sgFloat **u_new2,
short nump_new1, short *nump_new2,
short degree, short add){
short j, k, j1, j2, nump;
sgFloat *u1=NULL, *u2=NULL;
lpW_NODE beze1/*=NULL*/, beze2=NULL;
if( (*P_new2 = (W_NODE *)SGMalloc( ( 2*nump_new1)*sizeof(W_NODE) ) ) == NULL ) return FALSE;
if( (*u_new2 = (sgFloat*)SGMalloc( ( 2*nump_new1)*sizeof(sgFloat) ) ) == NULL ) return FALSE;
j1=j2=0;
while( j2<nump_new1-1 ){
for( j=j1+1; j<nump_new1-1; j++)
if( (dpoint_distance_4d( &P_new1[j], &P_new1[j+1] )) < eps_d ) break;
j2=j;
nump=j2-j1+1;
if( (beze1 = (W_NODE *)SGMalloc( nump*sizeof(W_NODE) ) ) == NULL ) goto err;
if( (u1 = (sgFloat*)SGMalloc( nump*sizeof(sgFloat) ) ) == NULL ) goto err;
if( (beze2 = (W_NODE *)SGMalloc( ( nump+add)*sizeof(W_NODE) ) ) == NULL ) goto err;
if( (u2 = (sgFloat*)SGMalloc( (nump+add)*sizeof(sgFloat) ) ) == NULL ) goto err;
for( j=j1, k=0; j<=j2; j++, k++ ) { beze1[k]=P_new1[j]; u1[k]=u_new1[j]; }
//increase degree of the Beze segment
Increase_Beze_Degree( beze1, u1, beze2, u2, degree, add );
// if( j1==0 ) (*P_new2)[(*nump_new2)++]=beze1[0];
// for( j=1; j<nump+add-1; j++ ) (*P_new2)[(*nump_new2)++]=beze2[j];
// if( j2==nump_new1-1) (*P_new2)[(*nump_new2)++]=beze1[nump-1];
for( j=0; j<=nump+add-1; j++ ){
(*P_new2)[(*nump_new2) ]=beze2[j];
(*u_new2)[(*nump_new2)++]=u2[j];
}
// if( j2==nump_new1-1) (*P_new2)[(*nump_new2)++]=beze1[nump-1];
SGFree( beze1 ); /*beze1=NULL;*/
SGFree( u1 ); u1 =NULL;
SGFree( beze2 ); beze2=NULL;
SGFree( u2 ); u2 =NULL;
j1=j2+1;
}
return TRUE;
err:
if(beze1) SGFree(beze1);
if(u1) SGFree(u1);
if(beze2) SGFree(beze2);
if(u2) SGFree(u2);
return FALSE;
}
/*******************************************************************************
* increase degree of the Beze segment
* beze1 - initial segment
* beze2 - resalting segment
* degree - initial degree
* add - changing degreee
*/
static void Increase_Beze_Degree(lpW_NODE beze1, sgFloat *u1,
lpW_NODE beze2, sgFloat *u2, short degree, short add ){
short i, j, k, i1, i2;
sgFloat L, L_i;
for( i=0; i<=degree+add; i++ ){//increase degree for span
i1=max(0, i-add);
i2=min(degree,i);
L_i=1./c_beze(degree+add, i);
for( j=i1; j<=i2; j++ ){
L=c_beze(degree, j)*c_beze(add, i-j)*L_i;
for( k=0; k<4; k++ ) beze2[i].vertex[k] += L*beze1[j].vertex[k];
u2[i] += L*u1[j];
}
}
}
static sgFloat c_beze(short k1, short k2){
return (factor(k1)/(factor(k2)*factor(k1-k2)));
}
static short factor(short k){
short i, l=1;
if( k==0 ) return l;
for( i=1; i<=k; i++ ) l*=i;
return l;
}
//-------------------------------------------------------------------------->>>>
+244
View File
@@ -0,0 +1,244 @@
#include "../sg.h"
static void first_deriv( short num_of_eqv, short p_c, sgFloat *u_c, sgFloat *U_c,
sgFloat **A, short i, short num, short beg_end );
static void second_deriv( short num_of_eqv, short p_c, sgFloat *u_c, sgFloat *U_c,
sgFloat **A, short i, short num, short beg_end );
static void mash_string(sgFloat **A, short num_of_eqv, short string,
lpW_NODE P, short type );
/**********************************************************
* Create matrix for nurbs curve
* n_c - number of points on curve
* p_c - degree of curve
* U_c - knot vector for curve
* A - matrix
* gran = 0 - free NURBS; 1 - closed NURBS
* 2 - free NURBS with derivates; 3 - closed NURBS with derivates
*/
void nurbs_matrix_create( lpSPLY_DAT sply_dat, short p_c, sgFloat **A, short gran ){
short i, j, k, num_of_eqv, n_c;
n_c = sply_dat->numk-1;
num_of_eqv=n_c+sply_dat->numd;
if( gran==1 || gran==3 ) num_of_eqv += 1;
switch( gran){
case 0: //free NURBS
A[0][0] = 1;
for( i=1 ; i<n_c; i++ )
for( j=0; j<=num_of_eqv; j++ )
if( sply_dat->U[j] <= sply_dat->u[i] &&
sply_dat->u[i] <= sply_dat->U[j+p_c+1] )
A[i][j] = nurbs_basis_func( j, p_c, sply_dat->U, sply_dat->u[i] );
A[n_c][n_c] = 1;
break;
case 1: //closed NURBS
A[0][0] = 1;
//first derivates into begining point
first_deriv( num_of_eqv+1, p_c, sply_dat->u, sply_dat->U, A, 0, 1, 0 );
//first derivates into end point
first_deriv( num_of_eqv+1, p_c, sply_dat->u, sply_dat->U, A, n_c, 1, 1 );
mash_string ( A, num_of_eqv, 1, &sply_dat->P[1], 0 );
for( i=2 ; i<n_c; i++ )
for( j=0; j<=num_of_eqv; j++ )
if( sply_dat->U[j] <= sply_dat->u[i-1] &&
sply_dat->u[i-1] <= sply_dat->U[j+p_c+1] )
A[i][j] = nurbs_basis_func( j, p_c, sply_dat->U, sply_dat->u[i-1] );
//because have changed U-vector
for( j=0; j<=num_of_eqv+1; j++ )
if( sply_dat->U[j] <= sply_dat->u[i-1] &&
sply_dat->u[i-1] <= sply_dat->U[j+p_c+1] )
A[n_c][j%(n_c+2)] = nurbs_basis_func( j, p_c, sply_dat->U, sply_dat->u[i-1] );
//second derivates into begining point
second_deriv( num_of_eqv+1, p_c, sply_dat->u, sply_dat->U, A, 0, n_c+1, 0 );
//second derivates into end point
second_deriv( num_of_eqv+1, p_c, sply_dat->u, sply_dat->U, A, n_c, n_c+1, 1 );
mash_string ( A, num_of_eqv, n_c+1, &sply_dat->P[n_c], 0 );
break;
case 2://free NURBS with derivates
for( k=0, i=0 ; i<n_c; i++, k++ ){
for( j=0; j<=num_of_eqv; j++ )
if( sply_dat->U[j] <= sply_dat->u[i] &&
sply_dat->u[i] <= sply_dat->U[j+p_c+1] )
A[k][j] = nurbs_basis_func( j, p_c, sply_dat->U, sply_dat->u[i] );
if( sply_dat->derivates[i].num ){
k++;
first_deriv( num_of_eqv, p_c, sply_dat->u, sply_dat->U, A, i, k, 0 );
for( j=0; j<=num_of_eqv; j++ ) A[k][j] *=p_c;
mash_string ( A, num_of_eqv, k, &sply_dat->P[k], 1 );
}
}
if( sply_dat->derivates[n_c].num ){
// k++;
first_deriv( num_of_eqv, p_c, sply_dat->u, sply_dat->U, A, n_c, k, 0 );
for( j=0; j<=num_of_eqv; j++ ) A[k][j] *=p_c;
mash_string ( A, num_of_eqv, k, &sply_dat->P[k], 1 );
}
A[num_of_eqv][num_of_eqv]=1;
break;
case 3://closed NURBS with derivates
A[0][0] = 1;
//first derivates into begining point
first_deriv( num_of_eqv+1, p_c, sply_dat->u, sply_dat->U, A, 0, 1, 0 );
//first derivates into end point
first_deriv( num_of_eqv+1, p_c, sply_dat->u, sply_dat->U, A, n_c, 1, 1 );
mash_string ( A, num_of_eqv, 1, &sply_dat->P[1], 0 );
k=2;
if( sply_dat->derivates[0].num ){
first_deriv( num_of_eqv, p_c, sply_dat->u, sply_dat->U, A, 0, k, 0 );
for( j=0; j<=num_of_eqv; j++ ) A[k][j] *=p_c;
mash_string ( A, num_of_eqv, k, &sply_dat->P[k], 1 );
k++;
}
for( i=1; i<n_c; i++, k++ ){
for( j=0; j<=num_of_eqv; j++ )
if( sply_dat->U[j] <= sply_dat->u[i] &&
sply_dat->u[i] <= sply_dat->U[j+p_c+1] )
A[k][j] = nurbs_basis_func( j, p_c, sply_dat->U, sply_dat->u[i] );
if( sply_dat->derivates[i].num ){
k++;
first_deriv( num_of_eqv, p_c, sply_dat->u, sply_dat->U, A, i, k, 0 );
for( j=0; j<=num_of_eqv; j++ ) A[k][j] *=p_c;
mash_string ( A, num_of_eqv, k, &sply_dat->P[k], 1 );
}
}
/* if( sply_dat->derivates[n_c].num ){
// k++;
first_deriv( num_of_eqv, p_c, sply_dat->u, sply_dat->U, A, n_c, k, 0 );
for( j=0; j<=num_of_eqv; j++ ) A[k][j] *=p_c;
mash_string ( A, num_of_eqv, k, &sply_dat->P[k], 1 );
k++;
}
*/
//second derivates into begining point
second_deriv( num_of_eqv+1, p_c, sply_dat->u, sply_dat->U, A, 0, k, 0 );
//second derivates into end point
second_deriv( num_of_eqv+1, p_c, sply_dat->u, sply_dat->U, A, n_c, k, 1 );
mash_string ( A, num_of_eqv, k, &sply_dat->P[k], 0 );
break;
}
}
/***********************************************************
* first derivates into point
* beg_num = 0 - points from 0 till n-1
* beg_num = 1 - point n
*/
static void first_deriv( short num_of_eqv, short p_c, sgFloat *u_c, sgFloat *U_c,
sgFloat **A, short i, short num, short beg_end ){
// sgFloat A[25][25], short i, short num, short beg_end ){
short j;
sgFloat t;
for( j=1; j<=num_of_eqv; j++ ){
if( U_c[j] <= u_c[i] && u_c[i] <= U_c[j+p_c] ){
if( (t = U_c[j+p_c]-U_c[j] ) >= eps_n )
t = nurbs_basis_func( j, p_c-1, U_c, u_c[i] )/t;
else t = 0.;
if(!beg_end){
A[num][j-1] -= t;
A[num][j ] += t;
}else{
A[num][j-1] +=t;
A[num][j%num_of_eqv] -=t;
}
}
}
}
/***********************************************************
* second derivates into point
* beg_num = 0 - points from 0 till n-1
* beg_num = 1 - point n
*/
static void second_deriv( short num_of_eqv, short p_c, sgFloat *u_c, sgFloat *U_c,
sgFloat **A, short k, short num, short beg_end ){
// sgFloat A[25][25], short k, short num, short beg_end ){
short i, j;
sgFloat t, t1, t2;
for( j=2; j<=num_of_eqv; j++ ){
if( U_c[j] <= u_c[k] && u_c[k] <= U_c[j+p_c-1] ){
i=j-1;
if( (t = U_c[i+p_c]-U_c[i+1]) >= eps_n )
t = nurbs_basis_func( j, p_c-2, U_c, u_c[k] )/t;
else t = 0.;
if( (t1 = U_c[i+p_c+1]-U_c[i+1]) >= eps_n ) t1 = 1./t1;
else t1 = 0.;
if( (t2 = U_c[i+p_c ]-U_c[i ]) >= eps_n ) t2 = 1./t2;
else t2 = 0.;
if(!beg_end){
A[num][j-2] += t*t2;
A[num][j-1] -= t*(t1+t2);
A[num][j] += t*t1;
}else{
A[num][j-2] -= t*t2;
A[num][j-1] += t*(t1+t2);
A[num][j%num_of_eqv] -= t*t1;
}
}
}
}
/***********************************************************
* masht. of string coeffisients to be <= 1
*/
static void mash_string(sgFloat **A, short num_of_eqv, short string,
lpW_NODE P, short type ){
short j;
sgFloat max;
for( max=0., j=0; j<=num_of_eqv; j++ )
if( fabs(A[string][j]) > max ) max=fabs(A[string][j]);
if( fabs(max) <= eps_n ) return;
for( j=0; j<=num_of_eqv; j++ ) A[string][j] /= max;
if( type ) for( j=0; j<3; j++ ) P->vertex[j] /=max;
// (*P)[j] /= max;
}
/**********************************************************
* Solution of equations sistem A*x=y, range of A = u
*/
BOOL gauss( sgFloat **A, lpW_NODE y, short u ){
//BOOL gauss( sgFloat A[25][25], lpDA_POINT y, short u ){
short i, j, k, l, n, m, t;
sgFloat s;
for(n=0; n<=u; n++){
for( k=-1, l=n; l<=u; l++ ){
if( A[l][n] != 0 ){
k=l;
break;
}
}
if( k == -1 ) return FALSE;
if( k != n ){
for( m=n; m<=u; m++ ) change_AB(&A[n][m], &A[k][m]);
for( t=0; t<3; t++ ) change_AB(&y[n].vertex[t], &y[k].vertex[t]);
}
s=1/A[n][n];
for( t=0; t<3; t++ ) y[n].vertex[t] *= s;
for(j=u; j>=n; j-- ) A[n][j] *= s;
for( i=k+1; i<=u; i++){
for( j=n+1; j<=u; j++)
A[i][j] -= A[i][n]*A[n][j];
for( t=0; t<3; t++ ) y[i].vertex[t] -= A[i][n]*y[n].vertex[t];
}
}
for( i=u; i>=0; i--)
for( k=i-1; k>=0; k-- ){
if( fabs(A[k][i]) > eps_n )
for( t=0; t<3; t++ ) y[k].vertex[t] = y[k].vertex[t] - A[k][i]*y[i].vertex[t];
}
return TRUE;
}
//-------------------------------------------------------->
void change_AB( sgFloat *i, sgFloat *j ){
sgFloat k;
k = *i; *i = *j; *j = k;
}
+228
View File
@@ -0,0 +1,228 @@
#include "../sg.h"
static void create_work_vector( sgFloat *U, short numu, sgFloat *U_max,
short *K_max, short*m);
static void merge_work_vector(sgFloat *U_max, short *K_max, short *m_max,
sgFloat *U_tmp, short *K_tmp, short m_tmp);
/**********************************************************
* Merge two or more control vectors to create common
* control vector vector
*/
BOOL Merge_Control_Vectors( lpVDIM ribs ){
BOOL rt=FALSE;
short nump_new1, nump_new2;
short i=0, ii, r, k, s, m_max, m_tmp;
short *K_max/*=NULL*/, *K_tmp=NULL;
sgFloat *U_max/*=NULL*/, *U_tmp=NULL;
SPLY_DAT sply;
sgFloat *U_new1=NULL, *u_new1/*=NULL*/, *U_new2=NULL, *u_new2=NULL;
W_NODE *P_new1=NULL, *P_new2=NULL;
long RA_max = 0;
while( read_elem( ribs, i++, &sply ))
{
RA_max+=sply.allocSizeFor_U;
}
// RA - if((U_max=(sgFloat*)SGMalloc(2*MAX_POINT_ON_SPLINE*sizeof(sgFloat))) == NULL) return FALSE;
// RA - if((K_max=(short *)SGMalloc(2*MAX_POINT_ON_SPLINE*sizeof(short))) == NULL) goto err;
// RA - if((U_tmp=(sgFloat*)SGMalloc(MAX_POINT_ON_SPLINE *sizeof(sgFloat))) == NULL) goto err;
// RA - if((K_tmp=(short *)SGMalloc(MAX_POINT_ON_SPLINE *sizeof(short))) == NULL) goto err;
if((U_max=(sgFloat*)SGMalloc(2*RA_max*sizeof(sgFloat))) == NULL) return FALSE;
if((K_max=(short *)SGMalloc(2*RA_max*sizeof(short))) == NULL) goto err;
if((U_tmp=(sgFloat*)SGMalloc(RA_max *sizeof(sgFloat))) == NULL) goto err;
if((K_tmp=(short *)SGMalloc(RA_max *sizeof(short))) == NULL) goto err;
i=0;
//create Max control vector
while( read_elem( ribs, i++, &sply ))
{
if(i==1)
{ //if first - put into vector
create_work_vector(sply.U, sply.numU, U_max, K_max, &m_max);
}
else
{
create_work_vector(sply.U, sply.numU, U_tmp, K_tmp, &m_tmp);
merge_work_vector(U_max, K_max, &m_max, U_tmp, K_tmp, m_tmp);
}
}
//add knots into all ribs
ii=0;
while( read_elem( ribs, ii++, &sply )){ //read current rib
if( (P_new1=(W_NODE*)SGMalloc(sply.nump*sizeof(W_NODE))) == NULL) goto err;
if( (u_new1=(sgFloat*)SGMalloc(sply.nump*sizeof(sgFloat))) == NULL) goto err1;
for( i=0; i<sply.nump; i++ ){
memcpy( &P_new1[i], &sply.P[i], sizeof(W_NODE) );
u_new1[i]=sply.u[i];
}
if( (U_new1=(sgFloat*)SGMalloc(sply.numU*sizeof(sgFloat))) == NULL ) goto err1;
for( i=0; i<sply.numU; i++ ) U_new1[i]=sply.U[i];
nump_new1=sply.nump;
//insert new knots
for( i=0; i<m_max; i++ ){
if( !Detect_Multy_Insertion( U_new1, sply.degree, U_max[i],
nump_new1, &s, &k)) goto err1;
r=K_max[i]-s;
if( r>0 ){
nump_new2=0;
if( !Insert_Knot( U_new1, P_new1, u_new1, nump_new1, sply.degree, U_max[i],
&U_new2, &P_new2, &u_new2, &nump_new2, r, k, s ) ) goto err1;
SGFree(U_new1); U_new1=U_new2; U_new2=NULL;
SGFree(P_new1); P_new1=P_new2; P_new2=NULL;
SGFree(u_new1); u_new1=u_new2; u_new2=NULL;
nump_new1=nump_new2;
}
}
// modify spline structure
if( !Modify_Spline_Str( &sply, U_new1, nump_new1+sply.degree+1, P_new1, u_new1,
nump_new1, sply.degree ) ) goto err1;
if( P_new1 ) SGFree( P_new1 ); P_new1=NULL;
if( U_new1 ) SGFree( U_new1 ); U_new1=NULL;
if( u_new1 ) SGFree( u_new1 ); u_new1=NULL;
if( !write_elem( ribs, ii-1, &sply )) goto err1;
}
rt=TRUE;
err1:
if( P_new1 ) SGFree( P_new1 ); if( P_new2 ) SGFree( P_new2 );
if( U_new1 ) SGFree( U_new1 ); if( U_new2 ) SGFree( U_new2 );
if( u_new1 ) SGFree( u_new1 ); if( u_new2 ) SGFree( u_new2 );
err:
if( K_tmp ) SGFree(K_tmp); if( U_tmp ) SGFree(U_tmp);
if( K_max ) SGFree(K_max); if( U_max ) SGFree(U_max);
return rt;
}
static void create_work_vector( sgFloat *U, short numu, sgFloat *U_max,short *K_max, short*m)
{
short j=0, k, s;
*m=0;
while(1)
{
for( s=0, k=j; k<numu; k++ )
if( fabs(U[j]-U[k])<eps_n ) s++;
U_max[(*m)]=U[j];
K_max[(*m)++]=s;
if( (j+=s)>=numu-1) break;
}
}
static void merge_work_vector(sgFloat *U_max, short *K_max, short *m_max,
sgFloat *U_tmp, short *K_tmp, short m_tmp){
short i, j, l;
for( i=0; i<m_tmp; i++ )
for( j=0; j<*m_max; j++ )
if( fabs(U_tmp[i]-U_max[j])<eps_n ){ //equal
if( K_max[j]<K_tmp[i] ) K_max[j]=K_tmp[i];
break;
}else{
if( (U_max[j]<U_tmp[i]) && (U_tmp[i]<U_max[j+1])){
for(l=*m_max-1; l>=j+1; l-- ){
U_max[l+1]=U_max[l];
K_max[l+1]=K_max[l];
}
U_max[j+1]=U_tmp[i];
K_max[j+1]=K_tmp[i];
(*m_max)++;
break;
}
}
}
//---------------------------------------------------------------->>>>>
/**********************************************************
* Create 4d point from 3d weight point
* for use nonrational B-spline
*/
void Create_4D_From_3D( lpW_NODE node, sgFloat *point, sgFloat w){
short i;
for( i=0; i<3; i++ ) node->vertex[i] = w*point[i];
node->vertex[3]=w;
}
/***********************************************************
* Create 3d weight point from 4d point
* for use rational B-spline
*/
void Create_3D_From_4D( lpW_NODE node, sgFloat *point, sgFloat *w){
short i;
sgFloat t;
*w=node->vertex[3];
t = ((*w)==0) ? (1) : (*w);
for( i=0; i<3; i++) point[i]=node->vertex[i]/t;
}
/**********************************************************
* Calculate 2point_distance into 4D-space
*/
sgFloat dpoint_distance_4d(lpW_NODE p1, lpW_NODE p2){
return(sqrt( (p1->vertex[0]-p2->vertex[0])*(p1->vertex[0]-p2->vertex[0])+
(p1->vertex[1]-p2->vertex[1])*(p1->vertex[1]-p2->vertex[1])+
(p1->vertex[2]-p2->vertex[2])*(p1->vertex[2]-p2->vertex[2])+
(p1->vertex[3]-p2->vertex[3])*(p1->vertex[3]-p2->vertex[3]) ));
}
/**********************************************************
* Calculate 2point_distance into 3D-space
* (convert 4D-point into 3D-point)
*/
sgFloat dpoint_distance_4dl(lpW_NODE p1, lpW_NODE p2){
sgFloat t;
D_POINT pp1, pp2;
t = ((p1->vertex[3])==0) ? (1) : (p1->vertex[3]);
pp1.x=p1->vertex[0]/t;
pp1.y=p1->vertex[1]/t;
pp1.z=p1->vertex[2]/t;
t = ((p2->vertex[3])==0) ? (1) : (p2->vertex[3]);
pp2.x=p2->vertex[0]/t;
pp2.y=p2->vertex[1]/t;
pp2.z=p2->vertex[2]/t;
t=dpoint_distance( &pp1, &pp2 );
return ( t );
}
//---------------------------------------------------------------->>>>>
/**********************************************************
* Detect multiplisity of insertion for parameter T and
* interval of the insertion
* U - control vector
* p - degree
* nump - number of points
* s - number of existing parameter
* kk - number of interval
*/
BOOL Detect_Multy_Insertion(sgFloat *U, short p, sgFloat t, short nump, short *s,
short *k ){
short i, num;
num = nump + p + 1;
//detect multiplisity
for( *s=0, i=0; i<num; i++ ) if( fabs(U[i]-t) <= eps_n ) (*s)++;
if( (*s) == p+1 ){
for( (*k)=0; (*k)<num; (*k)++ ) if( fabs( U[*k]-t ) <= eps_n ) break;
//number of insertions to create break point
return TRUE;
}
//detect span for insertion
for( (*k)=0; (*k)<num-1; (*k)++ ){
if( U[*k] <= t && t < U[*k+1] ) break;
if( U[*k] < U[*k+1] && t == U[*k+1] && t == 1. ) break;
}
if( *k>num-1 ) return FALSE;
return TRUE;
}
+505
View File
@@ -0,0 +1,505 @@
#include "../sg.h"
static BOOL calculate_sply(lpSPLY_DAT sply_dat);
BOOL add_sply_point(lpSPLY_DAT sply_dat, lpD_POINT point, short num){
int i;
if( sply_dat->sdtype & SPL_INT) {
if( sply_dat->numk >= MAX_POINT_ON_SPLINE )
if( !expand_spl( sply_dat, MAX_POINT_ON_SPLINE/2, sply_dat->degree, 0) ) return FALSE;
if( num == 0 ){
for( i=sply_dat->numk-1; i >= 0; i--) {
memcpy(&sply_dat->knots[i+1], &sply_dat->knots[i], sizeof(DA_POINT));
memcpy(&sply_dat->derivates[i+1], &sply_dat->derivates[i], sizeof(SNODE));
}
}
memcpy(&sply_dat->knots[num], point, sizeof(D_POINT));
sply_dat->derivates[num].num = 0; //
sply_dat->numk++;
return calculate_sply(sply_dat);
} else {
if( sply_dat->nump >= MAX_POINT_ON_SPLINE )
if( !expand_spl( sply_dat, MAX_POINT_ON_SPLINE/2, sply_dat->degree, 2) ) return FALSE;
if( num == 0 )
for( i=sply_dat->nump-1; i >= 0; i--){
memcpy(&sply_dat->P[i+1], &sply_dat->P[i], sizeof(W_NODE));
if( spl_work & EDIT_SPL )sply_dat->u[i+1] = sply_dat->u[i];
}
Create_4D_From_3D( &sply_dat->P[num], (sgFloat *)point, 1. );//
sply_dat->nump++;
if( sply_dat->nump > 2 ){
if( spl_work & CRE_SPL ) parameter( sply_dat, 0, TRUE );
if( spl_work & EDIT_SPL ) spl_work = (SPL_WORK)(spl_work | ADD_SPL);
return calculate_P(sply_dat, 0); //
}else{
memcpy(&sply_dat->knots[num], point, sizeof(D_POINT));
return TRUE;
}
}
}
BOOL insert_sply_point(lpSPLY_DAT sply_dat, short num, lpD_POINT point){
short i;
sgFloat D1, D2, w1, w2, s, u_ins;
D_POINT point1, point2;
if (sply_dat->sdtype & SPL_INT) {
if (sply_dat->numk >= MAX_POINT_ON_SPLINE)
if( !expand_spl( sply_dat, MAX_POINT_ON_SPLINE/2, sply_dat->degree, 0)) return FALSE;
//
for( i=sply_dat->numk-1; i >= num; i-- ) {
memcpy(&sply_dat->knots[i+1], &sply_dat->knots[i], sizeof(DA_POINT));
memcpy(&sply_dat->derivates[i+1], &sply_dat->derivates[i], sizeof(SNODE));
}
memcpy(&sply_dat->knots[num], point, sizeof(D_POINT));
sply_dat->derivates[num].num = 0; //
sply_dat->numk++;
} else {
if (sply_dat->nump >= MAX_POINT_ON_SPLINE)
if( !expand_spl( sply_dat, MAX_POINT_ON_SPLINE/2, sply_dat->degree, 2)) return FALSE;
//
Create_3D_From_4D( &sply_dat->P[num-1], (sgFloat *)&point1, &w1);
Create_3D_From_4D( &sply_dat->P[num], (sgFloat *)&point2, &w2);
D1=dpoint_distance( point, &point1);
D2=dpoint_distance( point, &point2);
s=w1*D1/(w1*D1+w2*D2);
u_ins=sply_dat->U[num]+s*(sply_dat->U[num+sply_dat->degree]-sply_dat->U[num]);
//
if( !Create_Multy_Point( sply_dat, u_ins, 21 )) return FALSE;
}
return TRUE;
}
BOOL close_sply(lpSPLY_DAT sply_dat){
short i;
sgFloat w;
D_POINT point;
//W_NODE point;
GEO_LINE gline1, gline2;
if( sply_dat->sdtype & SPL_CLOSE ) {
nurbs_handler_err(SPL_INTERNAL_ERROR);
return FALSE;
}
if( sply_dat->sdtype & SPL_INT ) {
if( sply_dat->numk<3 ) {
nurbs_handler_err(SPL_EMPTY_DATA);
return FALSE;
}
if( sply_dat->numk >= MAX_POINT_ON_SPLINE || sply_dat->nump+2 >= MAX_POINT_ON_SPLINE )
if( !expand_spl( sply_dat, MAX_POINT_ON_SPLINE/2, sply_dat->degree, 0)) return FALSE;
if( !dpoint_eq((lpD_POINT)&sply_dat->knots[0], (lpD_POINT)&sply_dat->knots[sply_dat->numk-1], eps_d)) sply_dat->numk++;
memcpy(&sply_dat->knots[sply_dat->numk-1], &sply_dat->knots[0], sizeof(D_POINT));
} else {
if( sply_dat->nump<3 ) {
nurbs_handler_err(SPL_EMPTY_DATA);
return FALSE;
}
if( sply_dat->nump+2 >= MAX_POINT_ON_SPLINE )
if( !expand_spl( sply_dat, MAX_POINT_ON_SPLINE/2, sply_dat->degree, 2)) return FALSE;
/* if( sply_dat->degree > 1 ){
//for smoth closer add new point r(n-1) = 2*r0 - r1
for( i=0; i<4; i++) point.vertex[i]=2*sply_dat->P[0].vertex[i] - sply_dat->P[1].vertex[i];
if( dpoint_distance_4dl( &sply_dat->P[sply_dat->nump-1], &point) > eps_d ){
Create_3D_From_4D( &point, (sgFloat *)&point1, &w);
if( !add_sply_point( sply_dat, &point1, sply_dat->nump) ) return FALSE;
sply_dat->P[sply_dat->numk-1].vertex[3]=w;
}
}
if( dpoint_distance_4dl( &sply_dat->P[0], &point) > eps_d ) sply_dat->nump++;
*/
//create line on spline points
Create_3D_From_4D( &sply_dat->P[0], (sgFloat *)&gline1.v1, &w);
Create_3D_From_4D( &sply_dat->P[1], (sgFloat *)&gline1.v2, &w);
Create_3D_From_4D( &sply_dat->P[sply_dat->nump-2], (sgFloat *)&gline2.v1, &w);
Create_3D_From_4D( &sply_dat->P[sply_dat->nump-1], (sgFloat *)&gline2.v2, &w);
//---------------------------------------------------------
//detect intersection of the two lines
if( !intersect_3d_ll(&gline1, 0, &gline2, 0, &point, &i) ) return FALSE;
//---------------------------------------------------------
if ( i != 0 ){ // there are points of intersection
if( !add_sply_point( sply_dat, &point, sply_dat->nump) ) return FALSE;
sply_dat->nump++;
memcpy(&sply_dat->P[sply_dat->nump-1], &sply_dat->P[0], sizeof(W_NODE));
}else return FALSE;
}
sply_dat->sdtype = (SPLY_TYPE_IN)(sply_dat->sdtype | SPL_CLOSE);
return calculate_sply(sply_dat);
}
BOOL move_sply_point(lpSPLY_DAT sply_dat, short num, lpD_POINT point){
short i;
sgFloat w, l1, l2;
sgFloat r, pp[3];
if (sply_dat->sdtype & SPL_INT) {
l1=l2=10.*eps_d;
if( num>0 ) l1 = dpoint_distance((lpD_POINT)&sply_dat->knots[num-1], point);
else if( sply_dat->sdtype&SPL_CLOSE )
l1 = dpoint_distance((lpD_POINT)&sply_dat->knots[sply_dat->numk-2], point);
if( num<sply_dat->numk )l2 = dpoint_distance((lpD_POINT)&sply_dat->knots[num+1], point);
else if( sply_dat->sdtype & SPL_CLOSE )
l2 = dpoint_distance((lpD_POINT)&sply_dat->knots[1], point);
if( l1<eps_d || l2<eps_d ) {
// put_message(SPL_BAD_POINT, NULL, 0); //
return FALSE;
}
memcpy(&sply_dat->knots[num], point, sizeof(D_POINT));
if( sply_dat->sdtype&SPL_CLOSE && (num==0 || num==sply_dat->numk-1))
memcpy(&sply_dat->knots[(num)?0:sply_dat->numk-1], point, sizeof(D_POINT));
return calculate_sply(sply_dat);
}else{
w=sply_dat->P[num].vertex[3];
Create_4D_From_3D( &sply_dat->P[num], (sgFloat *)point, w );//
memcpy(&sply_dat->knots[num], point, sizeof(D_POINT));
if( sply_dat->sdtype&SPL_CLOSE && (num==0 || num==sply_dat->nump-1)){
Create_4D_From_3D( &sply_dat->P[(num)?0:sply_dat->nump-1], (sgFloat *)point, w );
memcpy(&sply_dat->knots[(num)?0:sply_dat->nump-1], point, sizeof(D_POINT));
}
if( sply_dat->nump > 2 ){
if( spl_work & CRE_SPL ) parameter( sply_dat, 0, TRUE );
if( spl_work & ADD_SPL ){
spl_work = (SPL_WORK)(spl_work & (~ADD_SPL));
if( num == 0 ){
Create_3D_From_4D( &sply_dat->P[0], (sgFloat *)pp, &w );
if( (r=dpoint_distance( (lpD_POINT)point, (lpD_POINT)pp ))<eps_d ) return TRUE;
r/=spl_length(sply_dat);
for( i=sply_dat->numU-1; i >= 0; i--) sply_dat->U[i+1] = sply_dat->U[i]+r;
sply_dat->u[0]=0;
sply_dat->U[0]=sply_dat->U[1]=sply_dat->U[2]=0;
}else{
Create_3D_From_4D( &sply_dat->P[num-1], (sgFloat *)pp, &w );
if( (r=dpoint_distance( (lpD_POINT)point, (lpD_POINT)pp ))<eps_d ) return TRUE;
r/=spl_length_P(sply_dat);
sply_dat->u[num]=sply_dat->u[num-1]+r;
for( i=0; i<sply_dat->degree+1; i++ )
sply_dat->U[sply_dat->nump+i]=sply_dat->U[sply_dat->nump-1]+r;
}
Create_4D_From_3D( &sply_dat->P[num], (sgFloat *)point, 1. );//
sply_dat->numU++;
if( !Reparametrization( sply_dat->nump, sply_dat->numU, 0, 1, sply_dat->degree,
sply_dat->U, sply_dat->P, sply_dat->u )) return FALSE;
}
return calculate_P(sply_dat, 0); //
}else{
memcpy(&sply_dat->knots[num], point, sizeof(D_POINT));
return TRUE;
}
}
}
BOOL delete_sply_point(lpSPLY_DAT sply_dat, short num){
short i, l, beg;
if (sply_dat->sdtype & SPL_INT) {
//
if( (sply_dat->sdtype & SPL_CLOSE) && sply_dat->numk<sply_dat->degree+2 ) {
sply_dat->sdtype = (SPLY_TYPE_IN)(sply_dat->sdtype & ~SPL_CLOSE);
sply_dat->numk--;
if( num==sply_dat->numk ) num = 0;
}
if( num != sply_dat->numk - 1 && num != 0) { //
if( dpoint_distance((lpD_POINT)&sply_dat->knots[num - 1],
(lpD_POINT)&sply_dat->knots[num + 1])<eps_d) goto err;
}else{ //
if( sply_dat->sdtype & SPL_CLOSE ) { //
num=0;
if(dpoint_distance((lpD_POINT)&sply_dat->knots[1],
(lpD_POINT)&sply_dat->knots[sply_dat->numk-2])<eps_d) goto err;
// - 1
memcpy(&sply_dat->knots[sply_dat->numk-1], &sply_dat->knots[1], sizeof(D_POINT));
memcpy(&sply_dat->derivates[sply_dat->numk-1], &sply_dat->derivates[1], sizeof(SNODE));
}
}
//
if( (l = sply_dat->numk-num-1)>0 ) {
if (sply_dat->derivates[num].num) sply_dat->numd--;
memcpy(&sply_dat->knots[num], &sply_dat->knots[num+1], l*sizeof(D_POINT));
memcpy(&sply_dat->derivates[num], &sply_dat->derivates[num+1], l*sizeof(SNODE));
}
sply_dat->numk--;
return calculate_sply(sply_dat);
} else {//--------------------->>>>>>>> APPR spline
//
if( (sply_dat->sdtype&SPL_CLOSE ) && sply_dat->nump<sply_dat->degree+2 ) {
sply_dat->sdtype = (SPLY_TYPE_IN)(sply_dat->sdtype & ~SPL_CLOSE);
sply_dat->nump--;
if( num == sply_dat->nump ) num=0;
}
//
if( sply_dat->sdtype & SPL_CLOSE && ( num == sply_dat->nump-1 || num == 0 ))
memcpy( &sply_dat->P[sply_dat->nump-1], &sply_dat->P[1], sizeof(W_NODE));// 1
//
if( (l = sply_dat->nump-num-1 ) > 0){
memcpy(&sply_dat->P[num], &sply_dat->P[num+1], l*sizeof(W_NODE));
memcpy(&sply_dat->u[num], &sply_dat->u[num+1], l*sizeof(sgFloat));
}
sply_dat->nump--;
if( spl_work&CRE_SPL ) parameter( sply_dat, 0, TRUE );
else{
if( num==0 ) beg=sply_dat->degree+2;
else{
if( num==sply_dat->nump ) beg=sply_dat->nump+2;
else{
if( num==sply_dat->nump-1 ) beg=sply_dat->degree+1+num-1;
else beg = sply_dat->degree+1+num;
}
}
for( i=beg; i<sply_dat->numU; i++ ) sply_dat->U[i-1]=sply_dat->U[i];
sply_dat->numU--;
if( num==0 || num==sply_dat->nump)
Reparametrization( sply_dat->nump, sply_dat->numU, 0, 1, sply_dat->degree,
sply_dat->U, sply_dat->P, sply_dat->u );
}
return calculate_P(sply_dat, 0); //
}
err:
nurbs_handler_err(SPL_BAD_POINT); //
return FALSE;
}
BOOL break_close_sply( lpSPLY_DAT sply_dat, short num ){
short i, n;
DA_POINT da1;
W_NODE wn;
SNODE sn1;
if( sply_dat->sdtype&SPL_INT ) {
if( num<sply_dat->numk-1 ) { //
// num+1
n=sply_dat->numk-2;
for( i=num+1; i>0; i-- ) {
memcpy(da1, sply_dat->knots[0], sizeof(DA_POINT));
sn1 = sply_dat->derivates[0];
memcpy(sply_dat->knots[0], sply_dat->knots[1], n * sizeof(DA_POINT));
memcpy(&sply_dat->derivates[0], &sply_dat->derivates[1], n * sizeof(SNODE));
memcpy(sply_dat->knots[n], da1, sizeof(DA_POINT));
sply_dat->derivates[n] = sn1;
}
}
sply_dat->numk--;
}else{
if( num<sply_dat->nump-1 ) { //
// num+1
n=sply_dat->nump-2;
for( i=num+1; i>0; i-- ) {
memcpy(&wn, &sply_dat->P[0], sizeof(W_NODE));
memcpy(&sply_dat->P[0], &sply_dat->P[1], n*sizeof(W_NODE));
memcpy(&sply_dat->P[n], &wn, sizeof(W_NODE));
}
}
sply_dat->nump--;
}
sply_dat->sdtype = (SPLY_TYPE_IN)(sply_dat->sdtype & ~SPL_CLOSE);
return calculate_sply(sply_dat);
}
BOOL set_derivate_to_point(lpSPLY_DAT sply_dat, short num, lpD_POINT derivates){
if( sply_dat->sdtype & SPL_APPR) return TRUE;
if( (num == 0) || (num == sply_dat->numk - 1) ){// first/end point && closed
if( dpoint_distance((lpD_POINT)&sply_dat->knots[0],
(lpD_POINT)&sply_dat->knots[sply_dat->numk - 1]) < eps_d ){
if( dskalar_product(derivates,derivates) < eps_d )
get_point_on_sply(sply_dat, sply_dat->u[num], derivates, 1);
memcpy(sply_dat->derivates[0].p, derivates, sizeof(D_POINT));
memcpy(sply_dat->derivates[sply_dat->numk - 1].p, derivates, sizeof(D_POINT));
if( sply_dat->derivates[0].num == 0 ){
sply_dat->derivates[0].num=1;
sply_dat->numd++;
}
if( sply_dat->derivates[sply_dat->numk - 1].num == 0 ){
sply_dat->derivates[sply_dat->numk - 1].num=1;
sply_dat->numd++;
}
if( sply_dat->nump+1 >= MAX_POINT_ON_SPLINE )
if( !expand_spl( sply_dat, MAX_POINT_ON_SPLINE/2, sply_dat->degree, 1 ))
return FALSE;
return calculate_sply(sply_dat);
}
}
memcpy(sply_dat->derivates[num].p, derivates, sizeof(D_POINT));
if (!sply_dat->derivates[num].num) {
sply_dat->derivates[num].num = 1;
sply_dat->numd++;
}
if( sply_dat->nump >= MAX_POINT_ON_SPLINE ){
if( !expand_spl( sply_dat, MAX_POINT_ON_SPLINE/2, sply_dat->degree, 1 ))
return FALSE;
}
return calculate_sply(sply_dat);
}
BOOL fix_free_derivate_to_point(lpSPLY_DAT sply_dat, short num, BOOL fix){
D_POINT deriv;
if (sply_dat->sdtype & SPL_APPR) return TRUE;
if (fix && !sply_dat->derivates[num].num) {
get_point_on_sply(sply_dat, sply_dat->u[num], &deriv, 1);
memcpy(sply_dat->derivates[num].p, &deriv, sizeof(D_POINT));
sply_dat->derivates[num].num=1;
sply_dat->numd++;
}
if (!fix && sply_dat->derivates[num].num) {
sply_dat->derivates[num].num = 0;
sply_dat->numd--;
}
if( sply_dat->nump >= MAX_POINT_ON_SPLINE )
if( !expand_spl( sply_dat, MAX_POINT_ON_SPLINE/2, sply_dat->degree, 1 ))
return FALSE;
return calculate_sply(sply_dat);
}
/*******************************************************************************
* Change spline type from INT to APPR
*/
BOOL change_INT_APPR(lpSPLY_DAT sply_dat){
short i;
if( sply_dat->sdtype & SPL_APPR) return FALSE;
// free arrays for short spline
if (sply_dat->derivates) {
SGFree(sply_dat->derivates);
sply_dat->derivates = NULL;
}
sply_dat->numd = 0;
// new arrays for APPR spline
//change spline type
sply_dat->sdtype = (SPLY_TYPE_IN)(sply_dat->sdtype & ~SPL_INT);
sply_dat->sdtype = (SPLY_TYPE_IN)(sply_dat->sdtype | SPL_APPR);
//all weight put into 1 at the begining
for( i=0; i<sply_dat->nump; i++ ) sply_dat->P[i].vertex[3] = 1.;
// calculate_sply(sply_dat);
return TRUE;
}
/*******************************************************************************
* Change spline type from APPR to INT
*/
BOOL change_APPR_INT(lpSPLY_DAT sply_dat){
short j = MAX_POINT_ON_SPLINE, i;
if( sply_dat->sdtype & SPL_INT) return FALSE;
// free array for APPR spline
if( sply_dat->P ){
SGFree( sply_dat->P );
sply_dat->P = NULL;
}
// new arrays for short spline
if((sply_dat->P = (W_NODE*)SGMalloc((2*j+2)*sizeof(W_NODE))) == NULL)return FALSE;
//all weight put into 1
for( i=0; i<2*j+2; i++ ) sply_dat->P[i].vertex[3] = 1.;
if((sply_dat->derivates = (SNODE*)SGMalloc(j*sizeof(SNODE))) == NULL) return FALSE;
memset(sply_dat->derivates, 0, j*sizeof(SNODE));
sply_dat->numd = 0;
sply_dat->sdtype = (SPLY_TYPE_IN)(sply_dat->sdtype & ~SPL_APPR);
sply_dat->sdtype = (SPLY_TYPE_IN)(sply_dat->sdtype | SPL_INT);
calculate_sply(sply_dat);
return TRUE;
}
/*******************************************************************************
* Change spline degree( for APPR spline ONLY!!!)
*/
BOOL change_degree(lpSPLY_DAT sply_dat, short new_p ){
if( sply_dat->sdtype & SPL_INT ) return TRUE;
if( new_p <= 0 ) return FALSE;
if( new_p == sply_dat->degree ) return TRUE;
if( new_p > sply_dat->degree ) if( !Increase_Spline_Degree( sply_dat, new_p)) return FALSE;
// else if( !Decrease_Spline_Degree( sply_dat, new_p)) return FALSE;
return calculate_P(sply_dat, 0);
}
/*******************************************************************************
* Change weight
* num - number of point
* new_w - new weight
*/
BOOL change_weight(lpSPLY_DAT sply_dat, short num, sgFloat new_w ){
sgFloat w;
D_POINT point;
if( sply_dat->sdtype & SPL_INT ) return TRUE;
if( new_w<0 && new_w>1 ) return FALSE;
Create_3D_From_4D( &sply_dat->P[num], (sgFloat *)&point, &w );
Create_4D_From_3D( &sply_dat->P[num], (sgFloat *)&point, new_w );
return calculate_P(sply_dat, 0);
}
/*******************************************************************************
* Put break into spline knots
* if APR-spline - put sgFloat spline knot
*/
BOOL add_break_knots(lpSPLY_DAT sply_dat, short num ){
if( sply_dat->sdtype & SPL_INT ) return TRUE;
if( !Create_Multy_Point( sply_dat, sply_dat->u[num], 0 ) ) return FALSE;
return TRUE;
}
/*******************************************************************************
* Extract break from spline point
* i.e. extract sgFloat spline knot
*/
BOOL del_break_knots(lpSPLY_DAT sply_dat, short num ){
if( sply_dat->sdtype & SPL_INT ) return TRUE;
if( !Del_Knot( sply_dat->U, sply_dat->P, sply_dat->u, &sply_dat->nump,
sply_dat->numU, sply_dat->degree, sply_dat->u[num], sply_dat->degree) )
return FALSE;
return calculate_P(sply_dat, 0);
}
/*******************************************************************************
* Calculate spline
*/
static BOOL calculate_sply(lpSPLY_DAT sply_dat){
short nnn, condition, i;
sgFloat weight;
nnn = (sply_dat->sdtype & SPL_INT) ? sply_dat->numk : sply_dat->nump;
if (nnn > 2) {
//detect the spline type
if( sply_dat->sdtype & SPL_CLOSE ){
if( sply_dat->numd == 0 ) condition=1; // closed without derivation
else{
if( sply_dat->derivates[0].num == 1 ) condition=2; //special case of closed spline
else condition=3; // closed with derivates
}
}else{
if( sply_dat->numd == 0 ) condition=0; // without derivation
else condition=2; //with derivates
}
//-------->>>>>>>>>>>>>>>>>>>>>>>>>>
//!!!!!!!!! , .. .
parameter( sply_dat, condition, TRUE );
return calculate_P(sply_dat, condition); //
} else if (sply_dat->sdtype & SPL_APPR) {
sply_dat->numk = sply_dat->nump;
for( i=0; i<sply_dat->nump; i++ )
Create_3D_From_4D( &sply_dat->P[i], (sgFloat *)&sply_dat->knots[i], &weight);
}
return TRUE;
}
+36
View File
@@ -0,0 +1,36 @@
#include "../sg.h"
void nurbs_handler_err(short cod,...)
{
char s[255], ss[20];
short len;
strncpy(s, GetIDS(IDS_SG159), sizeof(s) - 1);
len = sizeof(s) - strlen(s);
switch (cod) {
case SPL_NO_MEMORY: //
strncat(s,GetIDS(IDS_SG160),len);
break;
case SPL_NO_HEAP: //
strncat(s,GetIDS(IDS_SG161),len);
break;
case SPL_MAX: //
strncat(s,GetIDS(IDS_SG163),len);
break;
case SPL_INTERNAL_ERROR: //
strncat(s,GetIDS(IDS_SG166),len);
break;
case SPL_ENPTY_DATA: //
strncat(s,GetIDS(IDS_SG167),len);
break;
case SPL_BAD_POINT: //
strncat(s, GetIDS(IDS_SG168),len);
break;
default:
strncat(s,GetIDS(IDS_SG186),len);
//itoa(cod,ss,10);
strncat(s,ss,sizeof(s) - strlen(s));
break;
}
put_message(EMPTY_MSG, s, 0);
}
+135
View File
@@ -0,0 +1,135 @@
#include "../sg.h"
static BOOL check_line1(lpF_PLPOINT min,lpF_PLPOINT max,
lpF_PLPOINT p1, lpF_PLPOINT p2);
static BOOL check_point1(lpF_PLPOINT min, lpF_PLPOINT max, lpF_PLPOINT p);
BOOL find_sply_knot(lpD_POINT vp, lpSPLY_DAT spl, short *numint, short *numknot){
sgFloat l1=0.0, l2, w;
F_PLPOINT min, max, fp1, fp2;
D_POINT p1, p2;
BOOL knot = TRUE;
short i;
//
// l1 = f_tfm_x(&curr_w3->fwind, trap_size/2 + 1) - f_tfm_x(&curr_w3->fwind, 0);
min.x = (float)(vp->x - l1);
min.y = (float)(vp->y - l1);
max.x = (float)(vp->x + l1);
max.y = (float)(vp->y + l1);
//
*numint = *numknot = 0;
if (spl->sdtype & SPL_INT) {
get_first_sply_point(spl, 0., FALSE, &p1);
} else {
Create_3D_From_4D( &spl->P[0], (sgFloat *)&p1, &w);
i = 1;
}
gcs_to_vcs(&p1, &p1); fp1.x = (float)p1.x; fp1.y = (float)p1.y;
if(spl->numk == 1) return check_point1(&min, &max, &fp1);
l1 = 0.;
while (TRUE) {
if (spl->sdtype & SPL_INT) {
if (!get_next_sply_point_and_knot(spl, &p2, &knot)) break;
} else {
if (i >= spl->nump) break;
Create_3D_From_4D( &spl->P[i++], (sgFloat *)&p2, &w);
knot = TRUE;
}
gcs_to_vcs(&p2, &p2); fp2.x = (float)p2.x; fp2.y = (float)p2.y;
//
if(check_line1(&min, &max, &fp1, &fp2))goto met_find;
l1 += dpoint_distance_2d(&p1, &p2);
if (knot) {
(*numint)++;
l1 = 0.;
}
p1 = p2; fp1 = fp2;
}
return FALSE;
met_find:
l1 += dpoint_distance_2d(vp, &p1);
l2 = dpoint_distance_2d(vp, &p2);
while (!knot) {
p1 = p2;
get_next_sply_point_and_knot(spl, &p2, &knot);
gcs_to_vcs(&p2, &p2);
l2 += dpoint_distance_2d(&p1, &p2);
}
*numknot = (l1 > l2) ? *numint + 1 : *numint;
return TRUE;
}
static BOOL check_line1(lpF_PLPOINT min,lpF_PLPOINT max,
lpF_PLPOINT p1, lpF_PLPOINT p2){
float x1,y1,x2,y2,rc;
register short i,j,k;
x1=p1->x;
y1=p1->y;
x2=p2->x;
y2=p2->y;
if (x1 < min->x ) i=1;
else {
if (x1 > max->x) i=2;
else i=0;
}
if (y1 < min->y) i |=4;
else {
if(y1 > max->y) i |=8;
}
if (x2 < min->x ) j=1;
else {
if (x2 > max->x) j=2;
else j=0;
}
if (y2 < min->y) j |=4;
else {
if(y2 > max->y) j |=8;
}
if ( !i || !j ) return TRUE;
if ( (i & j) != 0) return FALSE;
for (;;) {
if ( !i || !j ) return TRUE;
if ( (i & j)) return FALSE;
if ( !i ) {
k=i; i=j; j=k;
rc=x1; x1=x2; x2=rc;
rc=y1; y1=y2; y2=rc;
}
if ( (i & 1) ) {
y1=y1+(y2-y1)*(min->x-x1)/(x2-x1);
x1=min->x;
} else if ( i & 2 ) {
y1=y1+(y2-y1)*(max->x-x1)/(x2-x1);
x1=max->x;
}
else if ( i & 4 ) {
x1=x1+(x2-x1)*(min->y-y1)/(y2-y1);
y1=min->y;
}
else if ( i & 8 ) {
x1=x1+(x2-x1)*(max->y-y1)/(y2-y1);
y1=max->y;
}
if (x1 < min->x ) i=1;
else {
if (x1 > max->x) i=2;
else i=0;
}
if (y1 < min->y) i |=4;
else {
if(y1 > max->y) i |=8;
}
}
}
static BOOL check_point1(lpF_PLPOINT min, lpF_PLPOINT max, lpF_PLPOINT p){
if ( p->x >= min->x && p->y >= min->y &&
p->x <= max->x && p->y <= max->y) return TRUE;
return FALSE;
}
+471
View File
@@ -0,0 +1,471 @@
#include "../sg.h"
static BOOL Intersect_Spline_By_Spline( lpOBJ obj, hOBJ hspl, short type,
lpVDIM data, lpVDIM data1, short sign);
static OSCAN_COD inter_geo_scan(hOBJ hobj,lpSCAN_CONTROL lpsc);
static OSCAN_COD inter_line (hOBJ hobj,lpSCAN_CONTROL lpsc);
static OSCAN_COD inter_circle (hOBJ hobj,lpSCAN_CONTROL lpsc);
static OSCAN_COD inter_arc (hOBJ hobj,lpSCAN_CONTROL lpsc);
static OSCAN_COD inter_spline (hOBJ hobj,lpSCAN_CONTROL lpsc);
static OSCAN_COD (**inter_typeg)(hOBJ obj,lpSCAN_CONTROL lpsc);
typedef struct {
hOBJ hspl;
short type;
lpVDIM data;
lpVDIM data1;
} INTER_DAT; //
typedef INTER_DAT * lpINTER_DAT;
BOOL intersection_with_spline( hOBJ hspl, hOBJ hcont, short type,
lpVDIM data, lpVDIM data1){
SCAN_CONTROL sc;
INTER_DAT inter_dat;
inter_typeg = (OSCAN_COD(**)(hOBJ obj,lpSCAN_CONTROL lpsc))GetMethodArray(OMT_SPLINTER);
inter_typeg[OLINE] = inter_line; // OLINE
inter_typeg[OCIRCLE]= inter_circle; // OCIRCLE
inter_typeg[OARC] = inter_arc; // OARC
inter_typeg[OSPLINE]= inter_spline; // OSPLINE
inter_dat.hspl =hspl;
inter_dat.type =type;
inter_dat.data =data;
inter_dat.data1=data1;
init_scan(&sc);
sc.user_geo_scan = inter_geo_scan;
reinterpret_cast<lpINTER_DAT &>(sc.data) = &inter_dat;
if (o_scan(hcont,&sc) == OSFALSE) return FALSE;
return TRUE;
}
static OSCAN_COD inter_geo_scan(hOBJ hobj,lpSCAN_CONTROL lpsc){
return( inter_typeg[lpsc->type](hobj,lpsc));
}
/************************************************
* --- OSCAN_COD inter_line ---
*
************************************************/
/**********************************************************
* detect intersection spline by line
* spl - spline
* hline - line
* type - type of the returning data
* =0 - returns VIM for parameters of intersection points
* =1 - returns VIM for intersection points
* data - returning VDIM ( type is detected by user )
*/
#pragma argsused
static OSCAN_COD inter_line(hOBJ hobj, lpSCAN_CONTROL lpsc){
BOOL rt=OSFALSE;
short i, j, j1, n_p, k, l, span_base=60, span_base1=10, span;
sgFloat *t_intersec;
sgFloat t, t1, t_beg, dist, t_sply, t_line, bound[2], tmp_bound;
//------------------------>>
lpOBJ obj, obj1;
lpGEO_SPLINE gspline;
SPLY_DAT sply_dat;
//------------------------>>
lpGEO_LINE gline;
GEO_LINE gline1;
D_POINT p, v1, v2, vv2;
lpINTER_DAT data = (lpINTER_DAT)(lpsc->data);
obj1 = (lpOBJ)data->hspl;
gspline = (lpGEO_SPLINE)(obj1->geo_data);
obj = (lpOBJ)hobj;
gline = (lpGEO_LINE)obj->geo_data;
if((t_intersec=(sgFloat*)SGMalloc(100*sizeof(sgFloat))) == NULL ) return OSFALSE;
l=0;
//found beginning point for intersection
if( !begin_use_sply( gspline, &sply_dat) ) goto err1;
for(i=0; i<sply_dat.numk-1; i++ ){
t = sply_dat.u[i+1] - sply_dat.u[i];
span=span_base + (short)(t*100);
t = t/span;
memcpy(&v1, &sply_dat.knots[i], sizeof(DA_POINT));
bound[0]=sply_dat.u[i];
//-------->>>>>>>>>>>>>>>>>>>>
for( j=1; j<=span; j++ ){
t_beg = sply_dat.u[i]+t*j;
bound[1] = tmp_bound = t_beg;
if( j==span ) memcpy(&v2, &sply_dat.knots[i+1], sizeof(DA_POINT));
else get_point_on_sply(&sply_dat, t_beg, &v2, 0);
//create line on spline points
gline1.v1=v1;
gline1.v2=v2;
//detect intersection of the two lines
if( !intersect_3d_ll(gline, 1, &gline1, 1, &p, &n_p) ) goto err2;
//---------------------------------------------------------------------------
if ( n_p != 0 ){ // there are points of intersection
t_beg=bound[0];
t1 = t/span_base1;
for( j1=1; j1<=span_base1; j1++ ){
t_beg += t1;
bound[1]=t_beg;
if( j==span_base1 ) memcpy(&vv2, &v2, sizeof(DA_POINT));
else get_point_on_sply(&sply_dat, t_beg, &vv2, 0);
//create line on spline points
gline1.v1=v1;
gline1.v2=vv2;
//detect intersection of the two lines
if( !intersect_3d_ll(gline, 1, &gline1, 1, &p, &n_p) ) goto err2;
if ( n_p != 0 ){ // there are points of intersection
t_sply=bound[0];
if(!Spline_By_Point( &sply_dat, (void *)&p, &t_sply, &dist )) goto err2;
t_line = dpoint_distance(&p, &gline->v1)/
dpoint_distance(&gline->v2, &gline->v1);
//call function for calculate real point of intersection
if( !Spline_By_Line( &sply_dat, gline,
&t_sply, &t_line, bound, &dist ) ) goto err2;
// if( dist >= eps_d || t_beg < 0. ) continue; // tested point is out of the spline
if( t_sply < 0. ) continue; //tested point out of span
if( l!=0 ){
for( k=0; k<l; k++ )
if( fabs( t_intersec[k] - t_sply ) < eps_n )// this point already exists
break;
if( k>=l ) t_intersec[l++] = t_sply;
}else t_intersec[l++] = t_sply;
}
v1=vv2;
bound[0]=bound[1];
}
}
//---------------------------------------------------------------------------
v1=v2;
bound[0]=tmp_bound;
}
//-------->>>>>>>>>>>>>>>>>>>>
}
if( data->type==0 ){ //returns only parameter of intersection points
for( i=0; i<l; i++) if( !add_elem( data->data, &t_intersec[i] ) ) goto err2;
}else{
for( i=0; i<l; i++){
get_point_on_sply(&sply_dat, t_intersec[i], &p, 0);
if( !add_elem( data->data, &p ) ) goto err2;
}
}
rt=OSTRUE;
err2:
end_use_sply( gspline, &sply_dat );
err1:
SGFree(t_intersec);
return (OSCAN_COD)rt;
}
/************************************************
* --- OSCAN_COD inter_spline ---
*
************************************************/
#pragma argsused
static OSCAN_COD inter_spline(hOBJ hobj, lpSCAN_CONTROL lpsc){
lpINTER_DAT data = (lpINTER_DAT)(lpsc->data);
lpOBJ obj;
obj = (lpOBJ)hobj;
return (OSCAN_COD)(Intersect_Spline_By_Spline( obj, data->hspl, data->type,
data->data, data->data1, 0 ));
}
/**********************************************************
* detect intersection spline by spline
* hspl1 - first spline
* hspl2 - second spline
* type - type of the returning data
* =0 - returns VIM for parameters of intersection points
* =1 - returns VIM for intersection points
* data - VDIM for points of intersection
* data1 - VDIM for parameters of intersection points(in term 2-d spl)
* in case of type=0
* sign - =0-detect sply_by_sply intersection
* =1-detect autointersection
*/
static BOOL Intersect_Spline_By_Spline( lpOBJ obj, hOBJ hspl, short type,
lpVDIM data, lpVDIM data1, short sign){
BOOL rt=OSFALSE;
short span1, span2, span_base=5;
short j, jj, i, ii, n_p, l, k;
sgFloat *intersect, *intersect1=NULL;
sgFloat t1, t2, t_beg1, t_beg2, dist;
sgFloat t_sply1, t_sply2, bound1[2], bound2[2], bound1_tmp, bound2_tmp;
//------------------------>>
lpOBJ obj1;
lpGEO_SPLINE gspline1, gspline2;
SPLY_DAT sply_dat1, sply_dat2;
//------------------------>>
GEO_LINE gline1, gline2;
D_POINT p, p1, p2, v1, v2; //, pp2, vv2;
// spline
obj1 = (lpOBJ)hspl;
gspline1 = (lpGEO_SPLINE)(obj1->geo_data);
gspline2 = (lpGEO_SPLINE)(obj->geo_data);
if((intersect =(sgFloat*)SGMalloc(100*sizeof(sgFloat))) == NULL ) return OSFALSE;
if( type != 0 ) if((intersect1=(sgFloat*)SGMalloc(100*sizeof(sgFloat))) == NULL ) goto err0;
l=0;
//begin
if( !begin_use_sply( gspline1, &sply_dat1) ) goto err1;
// if( gspline1->type & SPLY_APPR) change_APPR_INT(&sply_dat1);
if( !begin_use_sply( gspline2, &sply_dat2) ) goto err2;
// if( gspline2->type & SPLY_APPR) change_APPR_INT(&sply_dat2);
//---------------------------------------------------------
for(i=0; i<sply_dat1.numk-1; i++ ){ //first spline
t1 = sply_dat1.u[i+1] - sply_dat1.u[i]; //take i-th interval
span1 = span_base + (short)(t1*100);
t1 = t1/span1;
memcpy(&v1, &sply_dat1.knots[i], sizeof(DA_POINT));
bound1[0]=sply_dat1.u[i]; //--------------->>>>>
//---------------------------------------------------------
for( j=1; j<=span1; j++ ){ //devide i-th interval into the smaller ones
t_beg1 = sply_dat1.u[i]+t1*j;
bound1[1]=bound1_tmp=t_beg1;//--------------->>>>>
if( j==span1 ) memcpy(&v2, &sply_dat1.knots[i+1], sizeof(DA_POINT));
else get_point_on_sply(&sply_dat1, t_beg1, &v2, 0);
//create line on spline points
gline1.v1=v1;
gline1.v2=v2;
//---------------------------------------------------------
for(ii=0; ii<sply_dat2.numk-1; ii++ ){ //second spline
if( sign&&ii==i ) continue; // imposible to intersect the same segment(for autointer.)
t2 = sply_dat2.u[ii+1] - sply_dat2.u[ii]; //take ii-th interval
span2 = span_base + (short)(t2*100);
t2 = t2/span2;
memcpy(&p1, &sply_dat2.knots[ii], sizeof(DA_POINT));
bound2[0]=sply_dat2.u[ii];//--------------->>>>>
//---------------------------------------------------------
for( jj=1; jj<=span2; jj++ ){ //devide ii-th interval into the smaller ones
t_beg2 = sply_dat2.u[ii]+t2*jj;
bound2[1]=bound2_tmp=t_beg2;//--------------->>>>>
if( jj==span2 ) memcpy(&p2, &sply_dat2.knots[ii+1], sizeof(DA_POINT));
else get_point_on_sply(&sply_dat2, t_beg2, &p2, 0);
//create line on spline points
gline2.v1=p1;
gline2.v2=p2;
//---------------------------------------------------------
//detect intersection of the two lines
if( !intersect_3d_ll(&gline1, 1, &gline2, 1, &p, &n_p) ) goto err3;
//---------------------------------------------------------
if ( n_p != 0 ){ // there are points of intersection
//--------------------------------->>>>>>
//call function for calculate real point of intersection
t_sply1=bound1[0];
// if(!Spline_By_Point( &sply_dat1, (void *)&p, &t_sply1, &dist )) goto err3;
t_sply2=bound2[0];
// if(!Spline_By_Point( &sply_dat2, (void *)&p, &t_sply2, &dist )) goto err3;
if( !Spline_By_Spline( &sply_dat1, (void *)&sply_dat2, &t_sply1,
&t_sply2, bound1, bound2, &dist ) ) goto err3;
// if( dist >= eps_d || t_sply1 < 0.||t_sply2 < 0. ) continue; // tested point is out of the spline
if( l!=0 ){
for( k=0; k<l; k++ )
if( fabs( intersect[k] - t_sply1 ) < eps_n )// this point already exists
break;
if( k>=l ){
intersect[l++] = t_sply1;
if( type==0 ) intersect1[l-1]=t_sply2;
}
}else{
intersect[l++] = t_sply1;
if( type==0 ) intersect1[l-1]=t_sply2;
}
}
//---------------------------------------------------------
p1=p2;
bound2[0]=bound2_tmp;
}
}
v1=v2;
bound1[0]=bound1_tmp;
}
}
if(type==0){
for( i=0; i<l; i++){
if( !add_elem( data, &intersect[i] ) ) goto err3;
if( sign !=1 ) if( !add_elem( data1, &intersect1[i] ) ) goto err3;
}
}else{
for( i=0; i<l; i++){
get_point_on_sply(&sply_dat1, intersect[i], &p, 0);
if( !add_elem( data, &p ) ) goto err3;
}
}
rt=OSTRUE;
err3:
end_use_sply(gspline1, &sply_dat2);
err2:
end_use_sply(gspline2, &sply_dat1);
err1:
if( intersect1 != NULL ) SGFree(intersect1);
err0:
SGFree(intersect);
return rt;
}
/************************************************
* --- OSCAN_COD inter_arc ---
*
************************************************/
/**********************************************************
* detect intersection spline by arc
* hspl - spline
* harc - circular arc
* type - type of the returning data
* =0 - returns VIM for parameters of intersection points
* =1 - returns VIM for intersection points
* data - returning VDIM ( type is detected by user )
*/
static OSCAN_COD inter_arc(hOBJ hobj, lpSCAN_CONTROL lpsc){
BOOL rt;
//------------------------>>
hOBJ hspl_arc=NULL;
lpOBJ obj;
//------------------------>>
lpINTER_DAT data = (lpINTER_DAT)(lpsc->data);
//create new hobj
if(!transform_to_NURBS( hobj, &hspl_arc )) return OSFALSE;
obj = (lpOBJ)hspl_arc;
//detect intersection of two splines
rt=Intersect_Spline_By_Spline( obj, data->hspl, data->type,
data->data, data->data1, 0 );
o_free(hspl_arc, NULL);
return (OSCAN_COD)rt;
}
/**********************************************************
* detect intersection spline by circle
* hspl - spline
* harc - circle
* type - type of the returning data
* =0 - returns VIM for parameters of intersection points
* =1 - returns VIM for intersection points
* data - VDIM for points of intersection
*/
static OSCAN_COD inter_circle(hOBJ hobj, lpSCAN_CONTROL lpsc){
BOOL rt;
//------------------------>>
hOBJ hspl_circ=NULL;
lpOBJ obj;
//------------------------>>
lpINTER_DAT data = (lpINTER_DAT)(lpsc->data);
//create new hobj
if(!transform_to_NURBS( hobj, &hspl_circ )) return OSFALSE;
obj = (lpOBJ)hspl_circ;
//detect intersection of two splines
rt=Intersect_Spline_By_Spline( obj, data->hspl, data->type,
data->data, data->data1, 0 );
o_free(hspl_circ, NULL);
return (OSCAN_COD)rt;
}
/**********************************************************
* devide spline by point into two splines
* spl - spline
* type -=0 point.x is point parameter
* =1 - point - point of the deviding
* spl_l, spl_r - obtaining splines after the deviding
*/
BOOL Devide_Spline_By_Point(hOBJ hspl, short type, lpD_POINT point,
hOBJ hspl_l, hOBJ hspl_r){
BOOL rt=OSFALSE;
sgFloat t, dist;
lpOBJ obj, obj1;
lpGEO_SPLINE gspline;
SPLY_DAT sply_dat;
lpGEO_SPLINE spline;
obj = (lpOBJ)hspl;
gspline = (lpGEO_SPLINE)(obj->geo_data);
//begin use spline
if( !begin_use_sply( gspline, &sply_dat) ) return OSFALSE;
//detect parameter for the dividing point
if( type==1 ) if( !Spline_By_Point( &sply_dat, point, &t, &dist )) goto err1;
else t=point->x;
//split spline into two parts
//first part
if((hspl_l = o_alloc(OSPLINE)) == NULL) goto err1;
obj1 = (lpOBJ)hspl_l;
obj1->color = obj->color; //
obj1->ltype = obj->ltype; //
obj1->lthickness = obj->lthickness; //
spline = (lpGEO_SPLINE)(obj1->geo_data);
if( !Get_Part_Spline_Geo(&sply_dat, 0, t, spline )){
o_free(hspl_l,NULL);
goto err1;
}
copy_obj_attrib(hspl, hspl_l);
//second part
if((hspl_r = o_alloc(OSPLINE)) == NULL) goto err1;
obj1 = (lpOBJ)hspl_r;
obj1->color = obj->color; //
obj1->ltype = obj->ltype; //
obj1->lthickness = obj->lthickness; //
spline = (lpGEO_SPLINE)(obj1->geo_data);
if( !Get_Part_Spline_Geo(&sply_dat, t, 0, spline )){
o_free(hspl_r,NULL);
goto err1;
}
copy_obj_attrib(hspl, hspl_r);
rt=OSTRUE;
err1:
end_use_sply(gspline, &sply_dat);
return rt;
}
/**********************************************************
* detect autointersection spline
* hspl - spline
* type - type of the returning data
* =0 - returns VIM for parameters of intersection points
* =1 - returns VIM for intersection points
* data - VDIM for points of intersection
*/
BOOL AutoIntersect_Spline(hOBJ hspl, short type, lpVDIM data){
BOOL rt;
hOBJ hobj_n;
if ( !o_copy_obj(hspl, &hobj_n,"") ) return FALSE;
rt=Intersect_Spline_By_Spline((OBJ*)hspl, hobj_n, type, data, NULL, 1);
o_free(hobj_n, NULL);
return rt;
}
//----------------------------------------------------->>>>
+35
View File
@@ -0,0 +1,35 @@
#include "../sg.h"
/**********************************************************
* Spline length foundation
*/
sgFloat spl_length( lpSPLY_DAT sply_dat ){
sgFloat S=0, sigma = c_h_tolerance;
D_POINT p1, p2;
short i;
if( sply_dat->degree == 1 ){
for( i=0; i<sply_dat->numk-1; i++ )
S += dpoint_distance( (lpD_POINT)&sply_dat->knots[i],
(lpD_POINT)&sply_dat->knots[i+1] );
} else {
get_first_sply_point( sply_dat, sigma, FALSE, &p1);
// while( get_next_sply_point_tolerance( sply_dat, &p2, &knot ) ){
while( get_next_sply_point( sply_dat, &p2 ) ){
S += dpoint_distance( &p1, &p2 );
p1.x=p2.x; p1.y=p2.y; p1.z=p2.z;
}
}
return S;
}
/**********************************************************
* Spline length foundation
*/
sgFloat spl_length_P( lpSPLY_DAT sply_dat ){
short i;
sgFloat S=0;
for( i=0; i<sply_dat->nump-1; i++ ) S += dpoint_distance_4dl( &sply_dat->P[i], &sply_dat->P[i+1] );
return S;
}
+254
View File
@@ -0,0 +1,254 @@
#include "../sg.h"
static sgFloat calc_sply_step(lpSPLY_DAT sply_dat, sgFloat t, sgFloat sigma);
static void set_interval_data(lpSPLY_DAT sply_dat, lpD_POINT p);
static short get_close_interval(lpSPLY_DAT sply_dat);
static short int_flag; // (//)(1/0/-1)
static short first_interval; //
static short last_interval; //
static short interval; //
static short num_int_p; //
static short cur_int_p; //
static sgFloat s_tolerance; //
static sgFloat step_int; //
//static sgFloat min_step_size; //
static sgFloat length; //
/**********************************************************
*
* deriv =0 - get point with parameter t
* =1 - first derivates into point with parameter t
* =2 - second derivates into point with parameter t
*/
void get_point_on_sply(lpSPLY_DAT sply_dat, sgFloat t,
lpD_POINT p, short deriv){
short degree, nnn;
//sgFloat weight;
//D_POINT point, point1;
p->x=p->y=p->z=0.;
if (t < eps_n) t = 0.;
if (t > 1 - eps_n) t = 1.;
if (-eps_n >= t || t >= 1 + eps_n) {
memset(p, 0, sizeof(D_POINT));
return;
}
nnn = (sply_dat->sdtype&SPL_INT) ? sply_dat->numk : sply_dat->nump;
if( nnn <= 2 ){
p->x = sply_dat->knots[0][0]*(1-t)+sply_dat->knots[1][0]*t;
p->y = sply_dat->knots[0][1]*(1-t)+sply_dat->knots[1][1]*t;
p->z = sply_dat->knots[0][2]*(1-t)+sply_dat->knots[1][2]*t;
return;
}
degree = sply_dat->degree;
while( nnn < degree + 1 ) degree--;
if( degree <= 0 ) return;
if( sply_dat->sdtype & SPL_INT ){ // short spline
switch( deriv ){
case 0: //point with parameter t
Calculate_Point( sply_dat, degree, t, p);
break;
case 1: //firs,second derivates into point with parameter t
case 2:
Calculate_Deriv( sply_dat, degree, t, p, deriv);
break;
}
}else{ // APPR spline with weight
switch( deriv ){
case 0://point with parameter t
Calculate_Weight_Point(sply_dat, degree, t, p);
break;
case 1://first derivates into point with parameter t
Calculate_Weight_Deriv(sply_dat, degree, t, p, deriv);
break;
case 2://second derivates into point with parameter t
break;
}
}
return;
}
void get_first_sply_point(lpSPLY_DAT sply_dat, sgFloat sigma, BOOL back,
lpD_POINT p){
short i;
sigma = 0.; // : , !
// if( sply_dat->degree == 1 ) sigma = 0.;
if( sigma > 0. ){
s_tolerance = sigma; //
length = 0;
for( i=0; i<sply_dat->numk-1; i++ )
length += dpoint_distance( (lpD_POINT)&sply_dat->knots[i],
(lpD_POINT)&sply_dat->knots[i+1] );
int_flag = ( back ) ? -1 : 1; // /
step_int = ( back ) ? 1. : 0.; //
cur_int_p = ( back ) ? sply_dat->numk-2 : 1; //
memcpy(p, &sply_dat->knots[ cur_int_p-int_flag], sizeof(D_POINT));
// get_point_on_sply(sply_dat, step_int, p, 0 ); //
// min_step_size = 1./(sply_dat->numk*INTERNAL_SPLINE_POINT);
} else {
i = sply_dat->numk - 1;
get_first_sply_segment_point(sply_dat, sigma, (back)?i:0, (back)?0:i, p);
}
}
void get_first_sply_segment_point(lpSPLY_DAT sply_dat, sgFloat sigma,
short bknot, short eknot, lpD_POINT p){
sigma = 0.; // : , !
if(sply_dat->sdtype&SPL_CLOSE){
if(abs(eknot - bknot) + 1 >= sply_dat->numk){
bknot = 0;
eknot = sply_dat->numk - 1;
}
}else{
if(bknot < 0) bknot = 0;
if(bknot > 0 && bknot > sply_dat->numk - 1) bknot = sply_dat->numk - 1;
if(eknot < 0) eknot = 0;
if(eknot > 0 && eknot > sply_dat->numk - 1) eknot = sply_dat->numk - 1;
}
first_interval = min(bknot, eknot);
last_interval = max(bknot, eknot) - 1;
int_flag = isg(eknot - bknot);
s_tolerance = sigma;
if(!int_flag)
memcpy(p, &sply_dat->knots[bknot], sizeof(D_POINT));
else
{
interval = (int_flag > 0) ? first_interval - 1 : last_interval + 1;
set_interval_data(sply_dat, p);
}
}
BOOL get_next_sply_point(lpSPLY_DAT sply_dat, lpD_POINT p){
BOOL knot;
if( s_tolerance > 0. )
return get_next_sply_point_tolerance( sply_dat, p, &knot );
else return get_next_sply_point_and_knot(sply_dat, p, &knot);
}
BOOL get_next_sply_point_tolerance(lpSPLY_DAT sply_dat, lpD_POINT p, BOOL *knot ){
sgFloat t;
//------------------------------------------------------------------------------
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
return get_next_sply_point_and_knot(sply_dat, p, knot);
//------------------------------------------------------------------------------
if( int_flag > 0 && step_int >= 1. ) return FALSE; //
if( int_flag < 0 && step_int <= 0. ) return FALSE; //
*knot = FALSE;
if( sply_dat->degree == 1 ){
step_int = sply_dat->u[cur_int_p];
memcpy(p, &sply_dat->knots[cur_int_p], sizeof(D_POINT));
*knot = TRUE;
cur_int_p += int_flag;
return TRUE;
}
t = calc_sply_step( sply_dat, step_int, s_tolerance);
t /= length;
// if( t > min_step_size ) t=min_step_size;
t = step_int + int_flag*t;
if( t < eps_n ) t = 0.;
if( t > 1.-eps_n ) t = 1.;
if( fabs( t-sply_dat->u[cur_int_p] )< eps_n ||
(t>sply_dat->u[cur_int_p]&&int_flag==1) ||
(t<sply_dat->u[cur_int_p]&&int_flag==-1) ){ //
step_int = sply_dat->u[cur_int_p];
memcpy(p, &sply_dat->knots[cur_int_p], sizeof(D_POINT));
*knot = TRUE;
cur_int_p += int_flag;
}else{
step_int = t;
get_point_on_sply(sply_dat, step_int, p, 0 ); //
}
return TRUE;
}
BOOL get_next_sply_point_and_knot(lpSPLY_DAT sply_dat, lpD_POINT p, BOOL *knot){
short i, ic;
if(!int_flag) return FALSE; //
if(++cur_int_p > num_int_p){
set_interval_data(sply_dat, p);
*knot = TRUE;
}else{
i = (int_flag > 0) ? cur_int_p : num_int_p - cur_int_p + 1;
ic = get_close_interval(sply_dat);
get_point_on_sply(sply_dat, sply_dat->u[ic] + i*step_int, p, FALSE);
*knot = FALSE;
}
return TRUE;
}
static void set_interval_data(lpSPLY_DAT sply_dat, lpD_POINT p){
short ic;
sgFloat t;
interval += int_flag;
ic = get_close_interval(sply_dat);
memcpy(p, &sply_dat->knots[(int_flag > 0) ? ic : ic + 1], sizeof(D_POINT));
if(interval > last_interval || interval < first_interval)
int_flag = 0;
else{
// if(s_tolerance > 0.) num_int_p = calc_sply_step(sply_dat, ic, s_tolerance);
// else
if( sply_dat->numk > 2 ){
/* while(1){
if( (t=sply_dat->u[ic+1] - sply_dat->u[ic]) > eps_n) break;
interval += int_flag;
ic = get_close_interval(sply_dat);
memcpy(p, &sply_dat->knots[(int_flag > 0) ? ic : ic + 1], sizeof(D_POINT));
if(interval > last_interval || interval < first_interval){
int_flag = 0;
return;
}
}
*/
t=sply_dat->u[ic+1] - sply_dat->u[ic];
num_int_p = INTERNAL_SPLINE_POINT+(short)(t*100);
step_int = t/(num_int_p +1);
} else {
num_int_p = INTERNAL_SPLINE_POINT;
step_int = 1./(num_int_p +1);
}
cur_int_p = 0;
}
}
static sgFloat calc_sply_step(lpSPLY_DAT sply_dat, sgFloat t, sgFloat sigma){
sgFloat ro, r1, r2, r3;
D_POINT p_1, p_2;
get_point_on_sply( sply_dat, t, &p_1, 1 );
get_point_on_sply( sply_dat, t, &p_2, 2 );
//ro( )= 1/
r1 = dskalar_product( &p_1, &p_1 );
r2 = dskalar_product( &p_2, &p_2 );
r3 = dskalar_product( &p_1, &p_2 );
ro = r1*sqrt(r1);
r1 = r1*r2 - r3*r3;
if( r1 <= eps_n ) return ( 2*sigma );
else{
ro= ro/sqrt( r1 );
if( (r1 = 2*ro-sigma ) <= eps_n ) return ( sqrt(8*sigma*ro) );
else return ( sqrt(4*sigma*(2*ro-sigma)) );
}
}
/**********************************************************
*
*/
static short get_close_interval(lpSPLY_DAT sply_dat){
short num;
if(sply_dat->sdtype & SPL_CLOSE){
num = sply_dat->numk - 1;
if(interval < 0) return interval + num;
if(interval >= num) return interval - num;
}
return interval;
}
+618
View File
@@ -0,0 +1,618 @@
#include "../sg.h"
static BOOL check_spl_max(lpSPLY_DAT spl, short num, short degree );
BOOL begin_use_sply(lpGEO_SPLINE geo_sply, lpSPLY_DAT sply_dat){
short i, j, type;
sgFloat *u;//, w;
lpDA_POINT p;
lpSNODE d;
//
memset(sply_dat, 0, sizeof(SPLY_DAT));
if (geo_sply->type & SPLY_NURBS){ // NURBS
if ( geo_sply->type & SPLY_APPR ) {//
//
type = SPL_APPR;
// ---------------->>>>>>>>> <<<<<<<<<<-------------
//
if((sply_dat->knots = (DA_POINT*)SGMalloc(geo_sply->nump*sizeof(DA_POINT))) == NULL) goto err;
sply_dat->allocSizeFor_knots = geo_sply->nump;
if((sply_dat->P = (W_NODE *)SGMalloc(geo_sply->nump*sizeof(W_NODE ))) == NULL) goto err;
sply_dat->allocSizeFor_P = geo_sply->nump;
//
if((sply_dat->u = (sgFloat *)SGMalloc((geo_sply->nump)*sizeof(sgFloat))) == NULL) goto err;
sply_dat->allocSizeFor_u = geo_sply->nump;
//
p = (lpDA_POINT)geo_sply->hpoint;
d = (lpSNODE)geo_sply->hderivates;
//
memcpy(sply_dat->knots, p, geo_sply->nump*sizeof(DA_POINT));
for( i=0; i<geo_sply->nump; i++ ){
Create_4D_From_3D( &sply_dat->P[i], (sgFloat *)&p[i], d[i].p[1] );
sply_dat->u[i]=d[i].p[0]; //
}
sply_dat->nump = sply_dat->numk = geo_sply->nump;
sply_dat->numd = 0;
// ---------------->>>>>>>>> <<<<<<<<<<-------------
//
if( geo_sply->numu )
i = geo_sply->numu;
else
i = geo_sply->nump+geo_sply->degree+1;
if((sply_dat->U = (sgFloat *)SGMalloc(i*sizeof(sgFloat))) == NULL) goto err;
sply_dat->allocSizeFor_U = i;
//
if( geo_sply->numu )
{
u = (sgFloat*)geo_sply->hvector;
memcpy(sply_dat->U, u, geo_sply->numu*sizeof(sgFloat));
sply_dat->numU = i;
}
} else { //
//
type = SPL_INT;
// ---------------->>>>>>>>> <<<<<<<<<<--------------------------
//
if((sply_dat->knots = (DA_POINT*)SGMalloc(geo_sply->nump*sizeof(DA_POINT))) == NULL) goto err;
sply_dat->allocSizeFor_knots = geo_sply->nump;
//
if((sply_dat->u = (sgFloat *)SGMalloc((geo_sply->nump)*sizeof(sgFloat))) == NULL) goto err;
sply_dat->allocSizeFor_u = geo_sply->nump;
//
p = (lpDA_POINT)geo_sply->hpoint;
memcpy(sply_dat->knots, p, geo_sply->nump*sizeof(DA_POINT));
sply_dat->numk = geo_sply->nump;
// -
i=geo_sply->numd+geo_sply->nump;
if(geo_sply->type & SPLY_CLOSE) i+=2;
if((sply_dat->P = (W_NODE *)SGMalloc(i*sizeof(W_NODE))) == NULL) goto err;
sply_dat->allocSizeFor_P = i;
// == 1.
for( j=0; j<i; j++ ) sply_dat->P[j].vertex[3]=1.;
sply_dat->nump = i;
// ---------------->>>>>>>>> <<<<<<<<<<--------------------
//
if((sply_dat->derivates = (SNODE *)SGMalloc(geo_sply->nump*sizeof(SNODE ))) == NULL) goto err;
sply_dat->allocSizeFor_derivates = geo_sply->nump;
//
if( geo_sply->numd ){
d = (lpSNODE)geo_sply->hderivates;
for (i = 0; i < geo_sply->numd; i++) {
if (0 <= d[i].num && d[i].num < geo_sply->numd) {
memcpy(sply_dat->derivates[d[i].num].p, d[i].p, sizeof(DA_POINT));
sply_dat->derivates[d[i].num].num = 1;
}
}
}
sply_dat->numd = geo_sply->numd;
// ---------------->>>>>>>>> <<<<<<<<<<-------------
//
if( geo_sply->numu ) i = geo_sply->numu;
else i = 2*(geo_sply->nump+geo_sply->degree+1);
if((sply_dat->U = (sgFloat *)SGMalloc(i*sizeof(sgFloat))) == NULL) goto err;
sply_dat->allocSizeFor_U = i;
//
if( geo_sply->numu ){
u = (sgFloat*)geo_sply->hvector;
memcpy(sply_dat->U, u, geo_sply->numu*sizeof(sgFloat));
sply_dat->numU = i;
}
}
}
if( geo_sply->type & SPLY_CLOSE ) sply_dat->sdtype = SPL_CLOSE;
//
if( !init_sply_dat( SPL_GEO, geo_sply->degree, type, sply_dat)) goto err1;
return TRUE;
err:
nurbs_handler_err(SPL_NO_MEMORY);
err1:
free_sply_dat(sply_dat);
return FALSE;
}
/**********************************************************
*
* , sply_dat
*/
#pragma argsused
void end_use_sply(lpGEO_SPLINE geo_sply, lpSPLY_DAT sply_dat){
free_sply_dat( sply_dat );
}
/*********************************************************
* sply_dat
*/
BOOL init_sply_dat(char sdtype, short degree, short type, lpSPLY_DAT sply_dat ){
short num_point, i, condition;
if( sdtype & SPL_GEO ){ // ,
//
sply_dat->sdtype = (SPLY_TYPE_IN)(sply_dat->sdtype | sdtype); //
sply_dat->sdtype = (SPLY_TYPE_IN)(sply_dat->sdtype | type); ///
// num_point = sply_dat->numk;
if(sply_dat->sdtype & SPL_CLOSE){
if( sply_dat->numd == 0 ) condition=1; // closed without derivation
else{
if( sply_dat->derivates[0].num == 1 ) condition=2; //special case of closed spline
else condition=3; // closed with derivates
}
}else{
if( sply_dat->numd == 0 ) condition=0; // without derivation
else condition=2; //with derivates
}
} else { // .
memset(sply_dat, 0, sizeof(SPLY_DAT));
num_point = MAX_POINT_ON_SPLINE;
sply_dat->sdtype = (SPLY_TYPE_IN)(sply_dat->sdtype | sdtype); //
sply_dat->sdtype = (SPLY_TYPE_IN)(sply_dat->sdtype | SPL_FREE); //
condition=0;
if ( type & SPL_APPR ) { //
if((sply_dat->knots = (DA_POINT*)SGMalloc(num_point*sizeof(DA_POINT))) == NULL) goto err;
sply_dat->allocSizeFor_knots = num_point;
if((sply_dat->P = (W_NODE *)SGMalloc(num_point*sizeof(W_NODE ))) == NULL) goto err;
sply_dat->allocSizeFor_P = num_point;
if((sply_dat->U = (sgFloat *)SGMalloc((num_point+degree+1)*sizeof(sgFloat))) == NULL) goto err;
sply_dat->allocSizeFor_U = num_point+degree+1;
for (i=0; i<num_point; i++) sply_dat->P[i].vertex[3] = 1.;//
} else { //
if((sply_dat->knots = (DA_POINT*)SGMalloc(num_point*sizeof(DA_POINT))) == NULL) goto err;
sply_dat->allocSizeFor_knots = num_point;
if((sply_dat->derivates = (SNODE *)SGMalloc(num_point*sizeof(SNODE))) == NULL) goto err;
sply_dat->allocSizeFor_derivates = num_point;
if((sply_dat->P = (W_NODE *)SGMalloc((2*num_point+2)*sizeof(W_NODE))) == NULL) goto err;
sply_dat->allocSizeFor_P = 2*num_point+2;
if((sply_dat->U = (sgFloat *)SGMalloc((2*(num_point+degree+1))*sizeof(sgFloat))) == NULL) goto err;
sply_dat->allocSizeFor_U = 2*(num_point+degree+1);
for (i = 0; i < num_point; i++) sply_dat->P[i].vertex[3] = 1.;
}
//
if((sply_dat->u = (sgFloat *)SGMalloc((num_point)*sizeof(sgFloat))) == NULL) goto err;
sply_dat->allocSizeFor_u = num_point;
}
sply_dat->degree = degree;
sply_dat->sdtype = (SPLY_TYPE_IN)(sply_dat->sdtype | type); ///
if( sply_dat->numk > 2 ){
if( sply_dat->sdtype & SPL_INT ){
if( sply_dat->numU ) parameter( sply_dat, condition, FALSE );
else{
sply_dat->numU = 2*(sply_dat->nump+sply_dat->degree+1); ;
parameter( sply_dat, condition, TRUE );
}
}
calculate_P(sply_dat, condition);
}
return TRUE;
err:
free_sply_dat( sply_dat );
nurbs_handler_err(SPL_NO_MEMORY);
return FALSE;
}
void free_sply_dat( lpSPLY_DAT sply_dat){
if (sply_dat->knots) {
SGFree(sply_dat->knots);
sply_dat->knots = NULL;
sply_dat->allocSizeFor_knots = 0;
}
if (sply_dat->derivates) {
SGFree(sply_dat->derivates);
sply_dat->derivates = NULL;
sply_dat->allocSizeFor_derivates = 0;
}
if (sply_dat->P) {
SGFree(sply_dat->P);
sply_dat->P = NULL;
sply_dat->allocSizeFor_P = 0;
}
if (sply_dat->U) {
SGFree(sply_dat->U);
sply_dat->U = NULL;
sply_dat->allocSizeFor_U = 0;
}
if (sply_dat->u) {
SGFree(sply_dat->u);
sply_dat->u = NULL;
sply_dat->allocSizeFor_u = 0;
}
}
BOOL create_geo_sply(lpSPLY_DAT sply_dat, lpGEO_SPLINE geo_sply){
short i, j;
sgFloat *u;
lpDA_POINT p;
lpSNODE d;
if( sply_dat->numk < sply_dat->degree+1 ){
put_message(SPL_EMPTY_DATA, NULL, 0);
return FALSE;
}
// ,
memset( geo_sply, 0, sizeof(GEO_SPLINE));
//
geo_sply->degree = sply_dat->degree;
//
geo_sply->type = SPLY_NURBS;
if( sply_dat->sdtype & SPL_APPR ) geo_sply->type |= SPLY_APPR;
if( sply_dat->sdtype & SPL_CLOSE) geo_sply->type |= SPLY_CLOSE;
if( sply_dat->sdtype & SPL_APPR ){ //
// ---------------->>>>>>>>> <<<<<<<<<<--------------------------
if((geo_sply->hpoint =
SGMalloc(sply_dat->nump*sizeof(DA_POINT))) == NULL) return FALSE;
p = (lpDA_POINT)geo_sply->hpoint;
if((geo_sply->hderivates =
SGMalloc(sply_dat->nump*sizeof(SNODE))) == NULL) return FALSE;
d = (lpSNODE)geo_sply->hderivates;
for( i=0; i<sply_dat->nump; i++ )
{
if (i<sply_dat->allocSizeFor_P)
Create_3D_From_4D( &sply_dat->P[i], (sgFloat *)&p[i], &d[i].p[1]);
else
{
assert(0);
}
if (i<sply_dat->allocSizeFor_u)
d[i].p[0]=sply_dat->u[i]; //
else
{
assert(0);
}
}
geo_sply->nump = geo_sply->numd = sply_dat->nump;
// ---------------->>>>>>>>> <<<<<<<<<<-------------
if((geo_sply->hvector =
SGMalloc(sply_dat->numU*sizeof(sgFloat))) == NULL) return FALSE;
u = (sgFloat*)geo_sply->hvector;
memcpy( u, sply_dat->U, sply_dat->numU*sizeof(sgFloat));
geo_sply->numu = sply_dat->numU;
}else{ //
// ---------------->>>>>>>>> <<<<<<<<<<--------------------------
if((geo_sply->hpoint =
SGMalloc(sply_dat->numk*sizeof(DA_POINT))) == NULL) return FALSE;
p = (lpDA_POINT)geo_sply->hpoint;
memcpy( p, sply_dat->knots, sply_dat->numk*sizeof(DA_POINT));
geo_sply->nump = sply_dat->numk;
// ---------------->>>>>>>>> <<<<<<<<<<--------------------
if( sply_dat->numd ){
if((geo_sply->hderivates =
SGMalloc(sply_dat->numd*sizeof(SNODE))) == NULL) return FALSE;
d = (lpSNODE)geo_sply->hderivates;
for( j=0, i=0; i<sply_dat->numk; i++ )
if( sply_dat->derivates[i].num ){
memcpy( d[j].p, sply_dat->derivates[i].p, sizeof(DA_POINT));
d[j++].num = i;
}
}
geo_sply->numd = sply_dat->numd;
// ---------------->>>>>>>>> <<<<<<<<<<-------------
if((geo_sply->hvector =
SGMalloc(sply_dat->numU*sizeof(sgFloat))) == NULL) return FALSE;
u = (sgFloat*)geo_sply->hvector;
memcpy( u, sply_dat->U, sply_dat->numU*sizeof(sgFloat));
geo_sply->numu = sply_dat->numU;
}
return TRUE;
}
BOOL unpack_geo_sply(lpGEO_SPLINE geo_sply, lpSPLY_DAT sply_dat){
short i, condition;
sgFloat *u;
lpDA_POINT p;
lpSNODE d;
if(sply_dat->sdtype & SPL_GEO) {
put_message(SPL_INTERNAL_ERROR, NULL, 0);
return FALSE;
}
if(geo_sply->type & SPLY_NURBS)
{
if( (geo_sply->type & SPLY_APPR) != 0 )
{//
sply_dat->sdtype = SPL_APPR;
// ---------------->>>>>>>>> <<<<<<<<<<--------------
p = (lpDA_POINT)geo_sply->hpoint;
d = (lpSNODE)geo_sply->hderivates;
// RA-BEGIN
if (geo_sply->nump>sply_dat->allocSizeFor_knots &&
sply_dat->knots)
{
SGFree(sply_dat->knots);
sply_dat->knots = (lpDA_POINT)SGMalloc(geo_sply->nump*sizeof(DA_POINT));
sply_dat->allocSizeFor_knots = geo_sply->nump;
}
if (geo_sply->nump>sply_dat->allocSizeFor_P &&
sply_dat->P)
{
SGFree(sply_dat->P);
sply_dat->P = (W_NODE*)SGMalloc(geo_sply->nump*sizeof(W_NODE));
sply_dat->allocSizeFor_P = geo_sply->nump;
}
if (geo_sply->nump>sply_dat->allocSizeFor_u &&
sply_dat->u)
{
SGFree(sply_dat->u);
sply_dat->u = (sgFloat*)SGMalloc(geo_sply->nump*sizeof(sgFloat));
sply_dat->allocSizeFor_u = geo_sply->nump;
}
// RA - END
memcpy(sply_dat->knots, p, geo_sply->nump*sizeof(DA_POINT));
for( i=0; i<geo_sply->nump; i++ )
{
Create_4D_From_3D( &sply_dat->P[i], (sgFloat *)&p[i], d[i].p[1] );
sply_dat->u[i]=d[i].p[0]; //
}
sply_dat->nump = sply_dat->numk = geo_sply->nump;
sply_dat->numd = 0;
// ---------------->>>>>>>>> <<<<<<<<<<-------------
if( geo_sply->numu )
{
// RA-BEGIN
if (geo_sply->numu>sply_dat->allocSizeFor_U &&
sply_dat->U)
{
SGFree(sply_dat->U);
sply_dat->U =(sgFloat*)SGMalloc(geo_sply->numu*sizeof(sgFloat));
sply_dat->allocSizeFor_U = geo_sply->numu;
}
// RA - END
u = (sgFloat*)geo_sply->hvector;
memcpy(sply_dat->U, u, geo_sply->numu*sizeof(sgFloat));
sply_dat->numU = geo_sply->numu;
}
}
else
{ //
sply_dat->sdtype = SPL_INT;
// ---------------->>>>>>>>> <<<<<<<<<<--------------------------
// RA-BEGIN
if (geo_sply->nump>sply_dat->allocSizeFor_knots &&
sply_dat->knots)
{
SGFree(sply_dat->knots);
sply_dat->knots = (lpDA_POINT)SGMalloc(geo_sply->nump*sizeof(DA_POINT));
sply_dat->allocSizeFor_knots = geo_sply->nump;
}
// RA - END
p = (lpDA_POINT)geo_sply->hpoint;
memcpy(sply_dat->knots, p, geo_sply->nump*sizeof(DA_POINT));
sply_dat->numk = geo_sply->nump;
// ---------------->>>>>>>>> <<<<<<<<<<--------------------
if( geo_sply->numd )
{
d = (lpSNODE)geo_sply->hderivates;
for(i=0; i<sply_dat->numd; i++ )
{
if (d[i].num<sply_dat->allocSizeFor_derivates)
{
memcpy(sply_dat->derivates[d[i].num].p, d[i].p, sizeof(DA_POINT));
sply_dat->derivates[d[i].num].num = 1;
}
else
{
assert(0);
}
}
}
sply_dat->numd = geo_sply->numd;
// ---------------->>>>>>>>> <<<<<<<<<<-------------
if( geo_sply->numu )
{
u = (sgFloat*)geo_sply->hvector;
if (geo_sply->numu<sply_dat->allocSizeFor_U)
{
memcpy(sply_dat->U, u, geo_sply->numu*sizeof(sgFloat));
sply_dat->numU = geo_sply->numu;
}
else
{
assert(0);
}
}
}
}
if(geo_sply->type & SPLY_CLOSE)
{
sply_dat->sdtype = (SPLY_TYPE_IN)(sply_dat->sdtype | SPL_CLOSE);
if( sply_dat->numd > 0 )
{
if( sply_dat->derivates[0].num == 1 )
condition=2;
else
condition=3;
}else
condition=1;
}
else
{
sply_dat->sdtype = (SPLY_TYPE_IN)(sply_dat->sdtype | SPL_FREE);
if( sply_dat->numd > 0 )
condition=2;
else
condition=0;
}
sply_dat->degree=geo_sply->degree;
if( sply_dat->numk > 2 )
{
if( sply_dat->sdtype & SPL_INT )
{
if( sply_dat->numU )
parameter( sply_dat, condition, FALSE );
else
{
sply_dat->numU = geo_sply->nump+geo_sply->degree+1;
parameter( sply_dat, condition, TRUE );
}
}
calculate_P(sply_dat, condition); //
}
return TRUE;
}
/**********************************************************
* expand memory for spline
* num - number of add element
* degree - degree of curve
* type = 0 - add point
* 1 - add derivation
* 2 - add knot
*/
BOOL expand_spl( lpSPLY_DAT spline, short num, short degree, short type ){
UINT size;
VLD vld;
VI_LOCATION loc;
if ( !check_spl_max( spline, num, degree) ) return FALSE;
init_vld(&vld);
// Save information
if( spline->P && spline->nump )
if( !add_vld_data( &vld, sizeof(W_NODE)*(spline->nump), &spline->P[0])) goto err;
if( spline->U && spline->numU )
if( !add_vld_data( &vld, sizeof(sgFloat)*(spline->numU), &spline->U[0])) goto err;
if( type == 0 || type == 2 ){
if( spline->knots && spline->numk )
if( !add_vld_data( &vld, sizeof(DA_POINT)*(spline->numk), &spline->knots[0])) goto err;
if( spline->u && spline->numk )
if( !add_vld_data( &vld, sizeof(sgFloat)*(spline->numk), &spline->u[0])) goto err;
if( spline->derivates && spline->numd ){
if( !add_vld_data( &vld, sizeof(SNODE)*(spline->numk), &spline->derivates[0])) goto err;}
}
//
if( spline->P ){ SGFree(spline->P); spline->P = NULL; spline->allocSizeFor_P=0;}
if( spline->U ){ SGFree(spline->U); spline->U = NULL; spline->allocSizeFor_U=0;}
if( type == 0 || type == 2 ){
if( spline->knots){ SGFree(spline->knots); spline->knots = NULL; spline->allocSizeFor_knots=0;}
if( spline->u) { SGFree(spline->u); spline->u = NULL; spline->allocSizeFor_u=0;}
if( spline->derivates ){ SGFree(spline->derivates); spline->derivates = NULL; spline->allocSizeFor_derivates=0;}
}
// Alloc memory
size = sizeof(W_NODE)*(MAX_POINT_ON_SPLINE+num);
if( ( spline->P = (W_NODE *)SGMalloc(size)) == NULL ) goto err1;
spline->allocSizeFor_P=MAX_POINT_ON_SPLINE+num;
size = sizeof(sgFloat)*(MAX_POINT_ON_SPLINE+num+degree+1);
if( ( spline->U = (sgFloat *)SGMalloc(size)) == NULL ) goto err1;
spline->allocSizeFor_U=MAX_POINT_ON_SPLINE+num+degree+1;
if( type == 0 || type == 2 ){
size = sizeof(DA_POINT)*(MAX_POINT_ON_SPLINE+num);
if( ( spline->knots = (DA_POINT*)SGMalloc(size)) == NULL ) goto err1;
spline->allocSizeFor_knots=MAX_POINT_ON_SPLINE+num;
size = sizeof(sgFloat)*(MAX_POINT_ON_SPLINE+num);
if( ( spline->u = (sgFloat *)SGMalloc(size)) == NULL ) goto err1;
spline->allocSizeFor_u=MAX_POINT_ON_SPLINE+num;
if( type == 0 ){
size = sizeof(SNODE)*(MAX_POINT_ON_SPLINE+num);
if( ( spline->derivates = (SNODE *)SGMalloc(size)) == NULL ) goto err1;
spline->allocSizeFor_derivates=MAX_POINT_ON_SPLINE+num;
}
}
// rearrange the spline
loc.hpage = vld.listh.hhead;
loc.offset = sizeof(RAW);
begin_read_vld(&loc);
size = sizeof(W_NODE)*(spline->nump);
read_vld_data(size,&spline->P[0]);
size = sizeof(sgFloat)*(spline->numU);
read_vld_data(size,&spline->U[0]);
if( type == 0 || type == 1 ){
size = sizeof(DA_POINT)*(spline->numk);
read_vld_data(size,&spline->knots[0]);
size = sizeof(sgFloat)*(spline->numk);
read_vld_data(size,&spline->u[0]);
if( type == 0 ){
size = sizeof(SNODE)*(spline->numk);
read_vld_data(size,&spline->derivates[0]);
}
}
end_read_vld();
free_vld_data(&vld);
return TRUE;
err:
nurbs_handler_err(SPL_NO_MEMORY);
free_vld_data(&vld);
return FALSE;
err1:
nurbs_handler_err(SPL_NO_HEAP);
free_vld_data(&vld);
return FALSE;
}
static BOOL check_spl_max(lpSPLY_DAT spl, short num, short degree ){
if ( sizeof(*spl->P)*(long)(spl->nump+num) >= 65535L ) goto err;
if ( sizeof(*spl->U)*(long)(spl->nump+degree+num+1) >= 65535L ) goto err;
if ( sizeof(*spl->knots)*(long)(spl->numk+num) >= 65535L ) goto err;
if ( sizeof(*spl->u)*(long)(spl->numk+num) >= 65535L ) goto err;
if ( sizeof(*spl->derivates)*(long)(spl->numk+num) >= 65535L ) goto err;
return TRUE;
err:
nurbs_handler_err(SPL_MAX);
return FALSE;
}