41 #include "glimports.h"
47 #include "nurbsconsts.h"
50 Mapdesc::Mapdesc(
long _type,
int _israt,
int _ncoords,
Backend& b )
56 hcoords = _ncoords + (_israt ? 0 : 1 );
57 inhcoords = _ncoords - (_israt ? 1 : 0 );
58 mask = ((1<<(inhcoords*2))-1);
61 assert( hcoords <= MAXCOORDS );
62 assert( inhcoords >= 1 );
64 pixel_tolerance = 1.0;
65 error_tolerance = 1.0;
66 bbox_subdividing = N_NOBBOXSUBDIVISION;
67 culling_method = N_NOCULLING;
68 sampling_method = N_NOSAMPLING;
69 clampfactor = N_NOCLAMPING;
70 minsavings = N_NOSAVINGSSUBDIVISION;
73 maxrate = ( s_steps < 0.0 ) ? 0.0 : s_steps;
74 maxsrate = ( s_steps < 0.0 ) ? 0.0 : s_steps;
75 maxtrate = ( t_steps < 0.0 ) ? 0.0 : t_steps;
79 for(
int i = 0; i != inhcoords; i++ )
84 Mapdesc::setBboxsize( INREAL *mat )
86 for(
int i = 0; i != inhcoords; i++ )
87 bboxsize[i] = (REAL) mat[i];
91 Mapdesc::identify( REAL dest[MAXCOORDS][MAXCOORDS] )
93 memset( dest, 0,
sizeof( dest ) );
94 for(
int i=0; i != hcoords; i++ )
99 Mapdesc::surfbbox( REAL bb[2][MAXCOORDS] )
101 backend.surfbbox( type, bb[0], bb[1] );
105 Mapdesc::copy( REAL dest[MAXCOORDS][MAXCOORDS],
long n, INREAL *src,
106 long rstride,
long cstride )
109 for(
int i=0; i != n; i++ )
110 for(
int j=0; j != n; j++ )
111 dest[i][j] = src[i*rstride + j*cstride];
119 Mapdesc::copyPt( REAL *d, REAL *s )
121 assert( hcoords > 0 );
149 memcpy( d, s, hcoords *
sizeof( REAL ) );
159 Mapdesc::sumPt( REAL *dst, REAL *src1, REAL *src2,
register REAL alpha,
register REAL beta )
161 assert( hcoords > 0 );
164 dst[3] = src1[3] * alpha + src2[3] * beta;
165 dst[2] = src1[2] * alpha + src2[2] * beta;
166 dst[1] = src1[1] * alpha + src2[1] * beta;
167 dst[0] = src1[0] * alpha + src2[0] * beta;
170 dst[2] = src1[2] * alpha + src2[2] * beta;
171 dst[1] = src1[1] * alpha + src2[1] * beta;
172 dst[0] = src1[0] * alpha + src2[0] * beta;
175 dst[1] = src1[1] * alpha + src2[1] * beta;
176 dst[0] = src1[0] * alpha + src2[0] * beta;
179 dst[0] = src1[0] * alpha + src2[0] * beta;
182 dst[4] = src1[4] * alpha + src2[4] * beta;
183 dst[3] = src1[3] * alpha + src2[3] * beta;
184 dst[2] = src1[2] * alpha + src2[2] * beta;
185 dst[1] = src1[1] * alpha + src2[1] * beta;
186 dst[0] = src1[0] * alpha + src2[0] * beta;
189 for(
int i = 0; i != hcoords; i++ )
190 dst[i] = src1[i] * alpha + src2[i] * beta;
202 Mapdesc::clipbits( REAL *p )
204 assert( inhcoords >= 0 );
205 assert( inhcoords <= 3 );
207 register int nc = inhcoords;
208 register REAL pw = p[nc];
209 register REAL nw = -pw;
210 register unsigned int bits = 0;
212 if( pw == 0.0 )
return mask;
217 if( p[2] <= pw ) bits |= (1<<5);
218 if( p[2] >= nw ) bits |= (1<<4);
219 if( p[1] <= pw ) bits |= (1<<3);
220 if( p[1] >= nw ) bits |= (1<<2);
221 if( p[0] <= pw ) bits |= (1<<1);
222 if( p[0] >= nw ) bits |= (1<<0);
225 if( p[1] <= pw ) bits |= (1<<3);
226 if( p[1] >= nw ) bits |= (1<<2);
227 if( p[0] <= pw ) bits |= (1<<1);
228 if( p[0] >= nw ) bits |= (1<<0);
231 if( p[0] <= pw ) bits |= (1<<1);
232 if( p[0] >= nw ) bits |= (1<<0);
236 for(
int i=0; i<nc; i++ ) {
237 if( p[i] >= nw ) bits |= bit;
239 if( p[i] <= pw ) bits |= bit;
249 if( p[2] <= nw ) bits |= (1<<5);
250 if( p[2] >= pw ) bits |= (1<<4);
251 if( p[1] <= nw ) bits |= (1<<3);
252 if( p[1] >= pw ) bits |= (1<<2);
253 if( p[0] <= nw ) bits |= (1<<1);
254 if( p[0] >= pw ) bits |= (1<<0);
257 if( p[1] <= nw ) bits |= (1<<3);
258 if( p[1] >= pw ) bits |= (1<<2);
259 if( p[0] <= nw ) bits |= (1<<1);
260 if( p[0] >= pw ) bits |= (1<<0);
263 if( p[0] <= nw ) bits |= (1<<1);
264 if( p[0] >= pw ) bits |= (1<<0);
268 for(
int i=0; i<nc; i++ ) {
269 if( p[i] >= pw ) bits |= bit;
271 if( p[i] <= nw ) bits |= bit;
287 Mapdesc::xformRational( Maxmatrix mat, REAL *d, REAL *s )
289 assert( hcoords >= 0 );
295 d[0] = x*mat[0][0]+y*mat[1][0]+z*mat[2][0];
296 d[1] = x*mat[0][1]+y*mat[1][1]+z*mat[2][1];
297 d[2] = x*mat[0][2]+y*mat[1][2]+z*mat[2][2];
298 }
else if( hcoords == 4 ) {
303 d[0] = x*mat[0][0]+y*mat[1][0]+z*mat[2][0]+w*mat[3][0];
304 d[1] = x*mat[0][1]+y*mat[1][1]+z*mat[2][1]+w*mat[3][1];
305 d[2] = x*mat[0][2]+y*mat[1][2]+z*mat[2][2]+w*mat[3][2];
306 d[3] = x*mat[0][3]+y*mat[1][3]+z*mat[2][3]+w*mat[3][3];
308 for(
int i=0; i != hcoords; i++ ) {
310 for(
int j = 0; j != hcoords; j++ )
311 d[i] += s[j] * mat[j][i];
321 Mapdesc::xformNonrational( Maxmatrix mat, REAL *d, REAL *s )
323 if( inhcoords == 2 ) {
326 d[0] = x*mat[0][0]+y*mat[1][0]+mat[2][0];
327 d[1] = x*mat[0][1]+y*mat[1][1]+mat[2][1];
328 d[2] = x*mat[0][2]+y*mat[1][2]+mat[2][2];
329 }
else if( inhcoords == 3 ) {
333 d[0] = x*mat[0][0]+y*mat[1][0]+z*mat[2][0]+mat[3][0];
334 d[1] = x*mat[0][1]+y*mat[1][1]+z*mat[2][1]+mat[3][1];
335 d[2] = x*mat[0][2]+y*mat[1][2]+z*mat[2][2]+mat[3][2];
336 d[3] = x*mat[0][3]+y*mat[1][3]+z*mat[2][3]+mat[3][3];
338 assert( inhcoords >= 0 );
339 for(
int i=0; i != hcoords; i++ ) {
340 d[i] = mat[inhcoords][i];
341 for(
int j = 0; j < inhcoords; j++ )
342 d[i] += s[j] * mat[j][i];
355 Mapdesc::xformAndCullCheck(
356 REAL *pts,
int uorder,
int ustride,
int vorder,
int vstride )
358 assert( uorder > 0 );
359 assert( vorder > 0 );
361 unsigned int inbits = mask;
362 unsigned int outbits = 0;
365 for( REAL *pend = p + uorder * ustride; p != pend; p += ustride ) {
367 for( REAL *qend = q + vorder * vstride; q != qend; q += vstride ) {
368 REAL cpts[MAXCOORDS];
369 xformCulling( cpts, q );
370 unsigned int bits = clipbits( cpts );
373 if( ( outbits == (
unsigned int)mask ) && ( inbits != (
unsigned int)mask ) )
return CULL_ACCEPT;
377 if( outbits != (
unsigned int)mask ) {
378 return CULL_TRIVIAL_REJECT;
379 }
else if( inbits == (
unsigned int)mask ) {
380 return CULL_TRIVIAL_ACCEPT;
393 Mapdesc::cullCheck( REAL *pts,
int uorder,
int ustride,
int vorder,
int vstride )
395 unsigned int inbits = mask;
396 unsigned int outbits = 0;
399 for( REAL *pend = p + uorder * ustride; p != pend; p += ustride ) {
401 for( REAL *qend = q + vorder * vstride; q != qend; q += vstride ) {
402 unsigned int bits = clipbits( q );
405 if( ( outbits == (
unsigned int)mask ) && ( inbits != (
unsigned int)mask ) )
return CULL_ACCEPT;
409 if( outbits != (
unsigned int)mask ) {
410 return CULL_TRIVIAL_REJECT;
411 }
else if( inbits == (
unsigned int)mask ) {
412 return CULL_TRIVIAL_ACCEPT;
425 Mapdesc::cullCheck( REAL *pts,
int order,
int stride )
427 unsigned int inbits = mask;
428 unsigned int outbits = 0;
431 for( REAL *pend = p + order * stride; p != pend; p += stride ) {
432 unsigned int bits = clipbits( p );
435 if( ( outbits == (
unsigned int)mask ) && ( inbits != (
unsigned int)mask ) )
return CULL_ACCEPT;
438 if( outbits != (
unsigned int)mask ) {
439 return CULL_TRIVIAL_REJECT;
440 }
else if( inbits == (
unsigned int)mask ) {
441 return CULL_TRIVIAL_ACCEPT;
454 Mapdesc::xformSampling( REAL *pts,
int order,
int stride, REAL *sp,
int outstride )
456 xformMat( smat, pts, order, stride, sp, outstride );
460 Mapdesc::xformBounding( REAL *pts,
int order,
int stride, REAL *sp,
int outstride )
462 xformMat( bmat, pts, order, stride, sp, outstride );
472 Mapdesc::xformCulling( REAL *pts,
int order,
int stride, REAL *cp,
int outstride )
474 xformMat( cmat, pts, order, stride, cp, outstride );
484 Mapdesc::xformCulling( REAL *pts,
485 int uorder,
int ustride,
486 int vorder,
int vstride,
487 REAL *cp,
int outustride,
int outvstride )
489 xformMat( cmat, pts, uorder, ustride, vorder, vstride, cp, outustride, outvstride );
499 Mapdesc::xformSampling( REAL *pts,
500 int uorder,
int ustride,
501 int vorder,
int vstride,
502 REAL *sp,
int outustride,
int outvstride )
504 xformMat( smat, pts, uorder, ustride, vorder, vstride, sp, outustride, outvstride );
508 Mapdesc::xformBounding( REAL *pts,
509 int uorder,
int ustride,
510 int vorder,
int vstride,
511 REAL *sp,
int outustride,
int outvstride )
513 xformMat( bmat, pts, uorder, ustride, vorder, vstride, sp, outustride, outvstride );
526 REAL *pend = pts + order * stride;
527 for( REAL *p = pts ; p != pend; p += stride ) {
528 xformRational( mat, cp, p );
532 REAL *pend = pts + order * stride;
533 for( REAL *p = pts ; p != pend; p += stride ) {
534 xformNonrational( mat, cp, p );
541 Mapdesc::xformMat( Maxmatrix mat, REAL *pts,
542 int uorder,
int ustride,
543 int vorder,
int vstride,
544 REAL *cp,
int outustride,
int outvstride )
547 REAL *pend = pts + uorder * ustride;
548 for( REAL *p = pts ; p != pend; p += ustride ) {
550 REAL *qend = p + vorder * vstride;
551 for( REAL *q = p; q != qend; q += vstride ) {
552 xformRational( mat, cpts2, q );
558 REAL *pend = pts + uorder * ustride;
559 for( REAL *p = pts ; p != pend; p += ustride ) {
561 REAL *qend = p + vorder * vstride;
562 for( REAL *q = p; q != qend; q += vstride ) {
563 xformNonrational( mat, cpts2, q );
577 Mapdesc::subdivide( REAL *src, REAL *dst, REAL v,
int stride,
int order )
581 for( REAL *send=src+stride*order; src!=send; send-=stride, dst+=stride ) {
583 REAL *qpnt = src + stride;
584 for( REAL *qp=src; qpnt!=send; qp=qpnt, qpnt+=stride )
585 sumPt( qp, qp, qpnt, mv, v );
595 Mapdesc::subdivide( REAL *src, REAL *dst, REAL v,
596 int so,
int ss,
int to,
int ts )
600 for( REAL *slast = src+ss*so; src != slast; src += ss, dst += ss ) {
603 for( REAL *send = src+ts*to; sp != send; send -= ts, dp += ts ) {
606 for( REAL *qpnt = sp+ts; qpnt != send; qp = qpnt, qpnt += ts )
607 sumPt( qp, qp, qpnt, mv, v );
613 #define sign(x) ((x > 0) ? 1 : ((x < 0.0) ? -1 : 0))
620 Mapdesc::project( REAL *src,
int rstride,
int cstride,
621 REAL *dest,
int trstride,
int tcstride,
622 int nrows,
int ncols )
624 int s = sign( src[inhcoords] );
625 REAL *rlast = src + nrows * rstride;
627 for( REAL *rptr=src; rptr != rlast; rptr+=rstride, trptr+=trstride ) {
628 REAL *clast = rptr + ncols * cstride;
630 for( REAL *cptr = rptr; cptr != clast; cptr+=cstride, tcptr+=tcstride ) {
631 REAL *coordlast = cptr + inhcoords;
632 if( sign( *coordlast ) != s )
return 0;
633 REAL *tcoord = tcptr;
634 for( REAL *coord = cptr; coord != coordlast; coord++, tcoord++ ) {
635 *tcoord = *coord / *coordlast;
647 Mapdesc::project( REAL *src,
int stride, REAL *dest,
int tstride,
int ncols )
649 int s = sign( src[inhcoords] );
651 REAL *clast = src + ncols * stride;
652 for( REAL *cptr = src, *tcptr = dest; cptr != clast; cptr+=stride, tcptr+=tstride ) {
653 REAL *coordlast = cptr + inhcoords;
654 if( sign( *coordlast ) != s )
return 0;
655 for( REAL *coord = cptr, *tcoord = tcptr; coord != coordlast; coord++, tcoord++ )
656 *tcoord = *coord / *coordlast;
669 REAL bb[2][MAXCOORDS] )
671 REAL bbpts[MAXORDER][MAXORDER][MAXCOORDS];
672 const int trstride =
sizeof(bbpts[0]) /
sizeof(REAL);
673 const int tcstride =
sizeof(bbpts[0][0]) /
sizeof(REAL);
677 int val = project( p, rstride, cstride,
678 &bbpts[0][0][0], trstride, tcstride, nrows, ncols );
679 if( val == 0 )
return -1;
682 bbox( bb, &bbpts[0][0][0], trstride, tcstride, nrows, ncols );
685 if( bbox_subdividing == N_BBOXROUND ) {
686 for(
int k=0; k != inhcoords; k++ )
687 if( ceilf(bb[1][k]) - floorf(bb[0][k]) > bboxsize[k] )
return 1;
689 for(
int k=0; k != inhcoords; k++ )
690 if( bb[1][k] - bb[0][k] > bboxsize[k] )
return 1;
697 REAL bb[2][MAXCOORDS],
705 for( k=0; k != inhcoords; k++ )
706 bb[0][k] = bb[1][k] = p[k];
708 for(
int i=0; i != nrows; i++ )
709 for(
int j=0; j != ncols; j++ )
710 for( k=0; k != inhcoords; k++ ) {
711 REAL x = p[i*rstride + j*cstride + k];
712 if( x < bb[0][k] ) bb[0][k] = x;
713 else if( x > bb[1][k] ) bb[1][k] = x;
723 Mapdesc::calcVelocityRational( REAL *p,
int stride,
int ncols )
725 REAL tmp[MAXORDER][MAXCOORDS];
727 assert( ncols <= MAXORDER );
729 const int tstride =
sizeof(tmp[0]) /
sizeof(REAL);
731 if( project( p, stride, &tmp[0][0], tstride, ncols ) ) {
732 return calcPartialVelocity( &tmp[0][0], tstride, ncols, 1, 1.0 );
734 return calcPartialVelocity( &tmp[0][0], tstride, ncols, 1, 1.0 );
744 Mapdesc::calcVelocityNonrational( REAL *pts,
int stride,
int ncols )
746 return calcPartialVelocity( pts, stride, ncols, 1, 1.0 );
750 Mapdesc::isProperty(
long property )
752 switch ( property ) {
753 case N_PIXEL_TOLERANCE:
754 case N_ERROR_TOLERANCE:
756 case N_BBOX_SUBDIVIDING:
759 case N_SAMPLINGMETHOD:
769 Mapdesc::getProperty(
long property )
771 switch ( property ) {
772 case N_PIXEL_TOLERANCE:
773 return pixel_tolerance;
774 case N_ERROR_TOLERANCE:
775 return error_tolerance;
777 return culling_method;
778 case N_BBOX_SUBDIVIDING:
779 return bbox_subdividing;
784 case N_SAMPLINGMETHOD:
785 return sampling_method;
797 Mapdesc::setProperty(
long property, REAL value )
800 switch ( property ) {
801 case N_PIXEL_TOLERANCE:
802 pixel_tolerance = value;
804 case N_ERROR_TOLERANCE:
805 error_tolerance = value;
808 culling_method = value;
810 case N_BBOX_SUBDIVIDING:
811 if( value <= 0.0 ) value = N_NOBBOXSUBDIVISION;
812 bbox_subdividing = value;
815 if( value < 0.0 ) value = 0.0;
817 maxrate = ( value < 0.0 ) ? 0.0 : value;
818 maxsrate = ( value < 0.0 ) ? 0.0 : value;
821 if( value < 0.0 ) value = 0.0;
823 maxtrate = ( value < 0.0 ) ? 0.0 : value;
825 case N_SAMPLINGMETHOD:
826 sampling_method = value;
829 if( value <= 0.0 ) value = N_NOCLAMPING;
833 if( value <= 0.0 ) value = N_NOSAVINGSSUBDIVISION;