Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

831 lines
23 KiB

  1. /**************************************************************************
  2. * *
  3. * Copyright (C) 1992, Silicon Graphics, Inc. *
  4. * *
  5. * These coded instructions, statements, and computer programs contain *
  6. * unpublished proprietary information of Silicon Graphics, Inc., and *
  7. * are protected by Federal copyright law. They may not be disclosed *
  8. * to third parties or copied or duplicated in any form, in whole or *
  9. * in part, without the prior written consent of Silicon Graphics, Inc. *
  10. * *
  11. **************************************************************************/
  12. /*
  13. * mapdesc.c++ - $Revision: 1.2 $
  14. * Derrick Burns - 1991
  15. */
  16. #include "glimport.h"
  17. #include "mystdio.h"
  18. #include "myassert.h"
  19. #include "mystring.h"
  20. #include "mymath.h"
  21. #include "backend.h"
  22. #include "nurbscon.h"
  23. #include "mapdesc.h"
  24. Mapdesc::Mapdesc( long _type, int _israt, int _ncoords, Backend& b )
  25. : backend( b )
  26. {
  27. type = _type;
  28. isrational = _israt;
  29. ncoords = _ncoords;
  30. hcoords = _ncoords + (_israt ? 0 : 1 );
  31. inhcoords = _ncoords - (_israt ? 1 : 0 );
  32. mask = ((1<<(inhcoords*2))-1);
  33. next = 0;
  34. assert( hcoords <= MAXCOORDS );
  35. assert( inhcoords >= 1 );
  36. pixel_tolerance = 1.0;
  37. error_tolerance = 1.0;
  38. bbox_subdividing = N_NOBBOXSUBDIVISION;
  39. culling_method = N_NOCULLING;
  40. sampling_method = N_NOSAMPLING;
  41. clampfactor = N_NOCLAMPING;
  42. minsavings = N_NOSAVINGSSUBDIVISION;
  43. s_steps = 0.0;
  44. t_steps = 0.0;
  45. maxrate = ( s_steps < 0.0 ) ? 0.0 : s_steps;
  46. maxsrate = ( s_steps < 0.0 ) ? 0.0 : s_steps;
  47. maxtrate = ( t_steps < 0.0 ) ? 0.0 : t_steps;
  48. identify( bmat );
  49. identify( cmat );
  50. identify( smat );
  51. for( int i = 0; i != inhcoords; i++ )
  52. bboxsize[i] = 1.0;
  53. }
  54. void
  55. Mapdesc::setBboxsize( INREAL *mat )
  56. {
  57. for( int i = 0; i != inhcoords; i++ )
  58. bboxsize[i] = (REAL) mat[i];
  59. }
  60. void
  61. Mapdesc::identify( REAL dest[MAXCOORDS][MAXCOORDS] )
  62. {
  63. memset( dest, 0, sizeof( dest ) );
  64. for( int i=0; i != hcoords; i++ )
  65. dest[i][i] = 1.0;
  66. }
  67. void
  68. Mapdesc::surfbbox( REAL bb[2][MAXCOORDS] )
  69. {
  70. backend.surfbbox( type, bb[0], bb[1] );
  71. }
  72. void
  73. Mapdesc::copy( REAL dest[MAXCOORDS][MAXCOORDS], long n, INREAL *src,
  74. long rstride, long cstride )
  75. {
  76. assert( n >= 0 );
  77. for( int i=0; i != n; i++ )
  78. for( int j=0; j != n; j++ )
  79. dest[i][j] = src[i*rstride + j*cstride];
  80. }
  81. /*--------------------------------------------------------------------------
  82. * copyPt - copy a homogeneous point
  83. *--------------------------------------------------------------------------
  84. */
  85. void
  86. Mapdesc::copyPt( REAL *d, REAL *s )
  87. {
  88. assert( hcoords > 0 );
  89. switch( hcoords ) {
  90. case 4:
  91. d[3] = s[3];
  92. d[2] = s[2];
  93. d[1] = s[1];
  94. d[0] = s[0];
  95. break;
  96. case 3:
  97. d[2] = s[2];
  98. d[1] = s[1];
  99. d[0] = s[0];
  100. break;
  101. case 2:
  102. d[1] = s[1];
  103. d[0] = s[0];
  104. break;
  105. case 1:
  106. d[0] = s[0];
  107. break;
  108. case 5:
  109. d[4] = s[4];
  110. d[3] = s[3];
  111. d[2] = s[2];
  112. d[1] = s[1];
  113. d[0] = s[0];
  114. break;
  115. default:
  116. memcpy( d, s, hcoords * sizeof( REAL ) );
  117. break;
  118. }
  119. }
  120. /*--------------------------------------------------------------------------
  121. * sumPt - compute affine combination of two homogeneous points
  122. *--------------------------------------------------------------------------
  123. */
  124. void
  125. Mapdesc::sumPt( REAL *dst, REAL *src1, REAL *src2, register REAL alpha, register REAL beta )
  126. {
  127. assert( hcoords > 0 );
  128. switch( hcoords ) {
  129. case 4:
  130. dst[3] = src1[3] * alpha + src2[3] * beta;
  131. dst[2] = src1[2] * alpha + src2[2] * beta;
  132. dst[1] = src1[1] * alpha + src2[1] * beta;
  133. dst[0] = src1[0] * alpha + src2[0] * beta;
  134. break;
  135. case 3:
  136. dst[2] = src1[2] * alpha + src2[2] * beta;
  137. dst[1] = src1[1] * alpha + src2[1] * beta;
  138. dst[0] = src1[0] * alpha + src2[0] * beta;
  139. break;
  140. case 2:
  141. dst[1] = src1[1] * alpha + src2[1] * beta;
  142. dst[0] = src1[0] * alpha + src2[0] * beta;
  143. break;
  144. case 1:
  145. dst[0] = src1[0] * alpha + src2[0] * beta;
  146. break;
  147. case 5:
  148. dst[4] = src1[4] * alpha + src2[4] * beta;
  149. dst[3] = src1[3] * alpha + src2[3] * beta;
  150. dst[2] = src1[2] * alpha + src2[2] * beta;
  151. dst[1] = src1[1] * alpha + src2[1] * beta;
  152. dst[0] = src1[0] * alpha + src2[0] * beta;
  153. break;
  154. default: {
  155. for( int i = 0; i != hcoords; i++ )
  156. dst[i] = src1[i] * alpha + src2[i] * beta;
  157. }
  158. break;
  159. }
  160. }
  161. /*--------------------------------------------------------------------------
  162. * clipbits - compute bit-vector indicating point/window position
  163. * of a (transformed) homogeneous point
  164. *--------------------------------------------------------------------------
  165. */
  166. unsigned int
  167. Mapdesc::clipbits( REAL *p )
  168. {
  169. assert( inhcoords >= 0 );
  170. assert( inhcoords <= 3 );
  171. register int nc = inhcoords;
  172. register REAL pw = p[nc];
  173. register REAL nw = -pw;
  174. register unsigned int bits = 0;
  175. if( pw == 0.0 ) return mask;
  176. if( pw > 0.0 ) {
  177. switch( nc ) {
  178. case 3:
  179. if( p[2] <= pw ) bits |= (1<<5);
  180. if( p[2] >= nw ) bits |= (1<<4);
  181. if( p[1] <= pw ) bits |= (1<<3);
  182. if( p[1] >= nw ) bits |= (1<<2);
  183. if( p[0] <= pw ) bits |= (1<<1);
  184. if( p[0] >= nw ) bits |= (1<<0);
  185. return bits;
  186. case 2:
  187. if( p[1] <= pw ) bits |= (1<<3);
  188. if( p[1] >= nw ) bits |= (1<<2);
  189. if( p[0] <= pw ) bits |= (1<<1);
  190. if( p[0] >= nw ) bits |= (1<<0);
  191. return bits;
  192. case 1:
  193. if( p[0] <= pw ) bits |= (1<<1);
  194. if( p[0] >= nw ) bits |= (1<<0);
  195. return bits;
  196. default: {
  197. int bit = 1;
  198. for( int i=0; i<nc; i++ ) {
  199. if( p[i] >= nw ) bits |= bit;
  200. bit <<= 1;
  201. if( p[i] <= pw ) bits |= bit;
  202. bit <<= 1;
  203. }
  204. #ifdef NT
  205. return 0;
  206. #else
  207. abort();
  208. #endif
  209. break;
  210. }
  211. }
  212. } else {
  213. switch( nc ) {
  214. case 3:
  215. if( p[2] <= nw ) bits |= (1<<5);
  216. if( p[2] >= pw ) bits |= (1<<4);
  217. if( p[1] <= nw ) bits |= (1<<3);
  218. if( p[1] >= pw ) bits |= (1<<2);
  219. if( p[0] <= nw ) bits |= (1<<1);
  220. if( p[0] >= pw ) bits |= (1<<0);
  221. return bits;
  222. case 2:
  223. if( p[1] <= nw ) bits |= (1<<3);
  224. if( p[1] >= pw ) bits |= (1<<2);
  225. if( p[0] <= nw ) bits |= (1<<1);
  226. if( p[0] >= pw ) bits |= (1<<0);
  227. return bits;
  228. case 1:
  229. if( p[0] <= nw ) bits |= (1<<1);
  230. if( p[0] >= pw ) bits |= (1<<0);
  231. return bits;
  232. default: {
  233. int bit = 1;
  234. for( int i=0; i<nc; i++ ) {
  235. if( p[i] >= pw ) bits |= bit;
  236. bit <<= 1;
  237. if( p[i] <= nw ) bits |= bit;
  238. bit <<= 1;
  239. }
  240. #ifdef NT
  241. return 0;
  242. #else
  243. abort();
  244. #endif
  245. break;
  246. }
  247. }
  248. }
  249. return bits;
  250. }
  251. /*--------------------------------------------------------------------------
  252. * xformRational - transform a homogeneous point
  253. *--------------------------------------------------------------------------
  254. */
  255. void
  256. Mapdesc::xformRational( Maxmatrix mat, REAL *d, REAL *s )
  257. {
  258. assert( hcoords >= 0 );
  259. if( hcoords == 3 ) {
  260. REAL x = s[0];
  261. REAL y = s[1];
  262. REAL z = s[2];
  263. d[0] = x*mat[0][0]+y*mat[1][0]+z*mat[2][0];
  264. d[1] = x*mat[0][1]+y*mat[1][1]+z*mat[2][1];
  265. d[2] = x*mat[0][2]+y*mat[1][2]+z*mat[2][2];
  266. } else if( hcoords == 4 ) {
  267. REAL x = s[0];
  268. REAL y = s[1];
  269. REAL z = s[2];
  270. REAL w = s[3];
  271. d[0] = x*mat[0][0]+y*mat[1][0]+z*mat[2][0]+w*mat[3][0];
  272. d[1] = x*mat[0][1]+y*mat[1][1]+z*mat[2][1]+w*mat[3][1];
  273. d[2] = x*mat[0][2]+y*mat[1][2]+z*mat[2][2]+w*mat[3][2];
  274. d[3] = x*mat[0][3]+y*mat[1][3]+z*mat[2][3]+w*mat[3][3];
  275. } else {
  276. for( int i=0; i != hcoords; i++ ) {
  277. d[i] = 0;
  278. for( int j = 0; j != hcoords; j++ )
  279. d[i] += s[j] * mat[j][i];
  280. }
  281. }
  282. }
  283. /*--------------------------------------------------------------------------
  284. * xformNonrational - transform a inhomogeneous point to a homogeneous point
  285. *--------------------------------------------------------------------------
  286. */
  287. void
  288. Mapdesc::xformNonrational( Maxmatrix mat, REAL *d, REAL *s )
  289. {
  290. if( inhcoords == 2 ) {
  291. REAL x = s[0];
  292. REAL y = s[1];
  293. d[0] = x*mat[0][0]+y*mat[1][0]+mat[2][0];
  294. d[1] = x*mat[0][1]+y*mat[1][1]+mat[2][1];
  295. d[2] = x*mat[0][2]+y*mat[1][2]+mat[2][2];
  296. } else if( inhcoords == 3 ) {
  297. REAL x = s[0];
  298. REAL y = s[1];
  299. REAL z = s[2];
  300. d[0] = x*mat[0][0]+y*mat[1][0]+z*mat[2][0]+mat[3][0];
  301. d[1] = x*mat[0][1]+y*mat[1][1]+z*mat[2][1]+mat[3][1];
  302. d[2] = x*mat[0][2]+y*mat[1][2]+z*mat[2][2]+mat[3][2];
  303. d[3] = x*mat[0][3]+y*mat[1][3]+z*mat[2][3]+mat[3][3];
  304. } else {
  305. assert( inhcoords >= 0 );
  306. for( int i=0; i != hcoords; i++ ) {
  307. d[i] = mat[inhcoords][i];
  308. for( int j = 0; j < inhcoords; j++ )
  309. d[i] += s[j] * mat[j][i];
  310. }
  311. }
  312. }
  313. /*--------------------------------------------------------------------------
  314. * xformAndCullCheck - transform a set of points that may be EITHER
  315. * homogeneous or inhomogeneous depending on the map description and
  316. * check if they are either completely inside, completely outside,
  317. * or intersecting the viewing frustrum.
  318. *--------------------------------------------------------------------------
  319. */
  320. int
  321. Mapdesc::xformAndCullCheck(
  322. REAL *pts, int uorder, int ustride, int vorder, int vstride )
  323. {
  324. assert( uorder > 0 );
  325. assert( vorder > 0 );
  326. unsigned int inbits = mask;
  327. unsigned int outbits = 0;
  328. REAL *p = pts;
  329. for( REAL *pend = p + uorder * ustride; p != pend; p += ustride ) {
  330. REAL *q = p;
  331. for( REAL *qend = q + vorder * vstride; q != qend; q += vstride ) {
  332. REAL cpts[MAXCOORDS];
  333. xformCulling( cpts, q );
  334. unsigned int bits = clipbits( cpts );
  335. outbits |= bits;
  336. inbits &= bits;
  337. if( ( outbits == mask ) && ( inbits != mask ) ) return CULL_ACCEPT;
  338. }
  339. }
  340. if( outbits != mask ) {
  341. return CULL_TRIVIAL_REJECT;
  342. } else if( inbits == mask ) {
  343. return CULL_TRIVIAL_ACCEPT;
  344. } else {
  345. return CULL_ACCEPT;
  346. }
  347. }
  348. /*--------------------------------------------------------------------------
  349. * cullCheck - check if a set of homogeneous transformed points are
  350. * either completely inside, completely outside,
  351. * or intersecting the viewing frustrum.
  352. *--------------------------------------------------------------------------
  353. */
  354. int
  355. Mapdesc::cullCheck( REAL *pts, int uorder, int ustride, int vorder, int vstride )
  356. {
  357. unsigned int inbits = mask;
  358. unsigned int outbits = 0;
  359. REAL *p = pts;
  360. for( REAL *pend = p + uorder * ustride; p != pend; p += ustride ) {
  361. REAL *q = p;
  362. for( REAL *qend = q + vorder * vstride; q != qend; q += vstride ) {
  363. unsigned int bits = clipbits( q );
  364. outbits |= bits;
  365. inbits &= bits;
  366. if( ( outbits == mask ) && ( inbits != mask ) ) return CULL_ACCEPT;
  367. }
  368. }
  369. if( outbits != mask ) {
  370. return CULL_TRIVIAL_REJECT;
  371. } else if( inbits == mask ) {
  372. return CULL_TRIVIAL_ACCEPT;
  373. } else {
  374. return CULL_ACCEPT;
  375. }
  376. }
  377. /*--------------------------------------------------------------------------
  378. * cullCheck - check if a set of homogeneous transformed points are
  379. * either completely inside, completely outside,
  380. * or intersecting the viewing frustrum.
  381. *--------------------------------------------------------------------------
  382. */
  383. int
  384. Mapdesc::cullCheck( REAL *pts, int order, int stride )
  385. {
  386. unsigned int inbits = mask;
  387. unsigned int outbits = 0;
  388. REAL *p = pts;
  389. for( REAL *pend = p + order * stride; p != pend; p += stride ) {
  390. unsigned int bits = clipbits( p );
  391. outbits |= bits;
  392. inbits &= bits;
  393. if( ( outbits == mask ) && ( inbits != mask ) ) return CULL_ACCEPT;
  394. }
  395. if( outbits != mask ) {
  396. return CULL_TRIVIAL_REJECT;
  397. } else if( inbits == mask ) {
  398. return CULL_TRIVIAL_ACCEPT;
  399. } else {
  400. return CULL_ACCEPT;
  401. }
  402. }
  403. /*--------------------------------------------------------------------------
  404. * xformSampling - transform a set of points that may be EITHER
  405. * homogeneous or inhomogeneous depending on the map description
  406. * into sampling space
  407. *--------------------------------------------------------------------------
  408. */
  409. void
  410. Mapdesc::xformSampling( REAL *pts, int order, int stride, REAL *sp, int outstride )
  411. {
  412. xformMat( smat, pts, order, stride, sp, outstride );
  413. }
  414. void
  415. Mapdesc::xformBounding( REAL *pts, int order, int stride, REAL *sp, int outstride )
  416. {
  417. xformMat( bmat, pts, order, stride, sp, outstride );
  418. }
  419. /*--------------------------------------------------------------------------
  420. * xformCulling - transform a set of points that may be EITHER
  421. * homogeneous or inhomogeneous depending on the map description
  422. * into culling space
  423. *--------------------------------------------------------------------------
  424. */
  425. void
  426. Mapdesc::xformCulling( REAL *pts, int order, int stride, REAL *cp, int outstride )
  427. {
  428. xformMat( cmat, pts, order, stride, cp, outstride );
  429. }
  430. /*--------------------------------------------------------------------------
  431. * xformCulling - transform a set of points that may be EITHER
  432. * homogeneous or inhomogeneous depending on the map description
  433. * into culling space
  434. *--------------------------------------------------------------------------
  435. */
  436. void
  437. Mapdesc::xformCulling( REAL *pts,
  438. int uorder, int ustride,
  439. int vorder, int vstride,
  440. REAL *cp, int outustride, int outvstride )
  441. {
  442. xformMat( cmat, pts, uorder, ustride, vorder, vstride, cp, outustride, outvstride );
  443. }
  444. /*--------------------------------------------------------------------------
  445. * xformSampling - transform a set of points that may be EITHER
  446. * homogeneous or inhomogeneous depending on the map description
  447. * into sampling space
  448. *--------------------------------------------------------------------------
  449. */
  450. void
  451. Mapdesc::xformSampling( REAL *pts,
  452. int uorder, int ustride,
  453. int vorder, int vstride,
  454. REAL *sp, int outustride, int outvstride )
  455. {
  456. xformMat( smat, pts, uorder, ustride, vorder, vstride, sp, outustride, outvstride );
  457. }
  458. void
  459. Mapdesc::xformBounding( REAL *pts,
  460. int uorder, int ustride,
  461. int vorder, int vstride,
  462. REAL *sp, int outustride, int outvstride )
  463. {
  464. xformMat( bmat, pts, uorder, ustride, vorder, vstride, sp, outustride, outvstride );
  465. }
  466. void
  467. Mapdesc::xformMat(
  468. Maxmatrix mat,
  469. REAL * pts,
  470. int order,
  471. int stride,
  472. REAL * cp,
  473. int outstride )
  474. {
  475. if( isrational ) {
  476. REAL *pend = pts + order * stride;
  477. for( REAL *p = pts ; p != pend; p += stride ) {
  478. xformRational( mat, cp, p );
  479. cp += outstride;
  480. }
  481. } else {
  482. REAL *pend = pts + order * stride;
  483. for( REAL *p = pts ; p != pend; p += stride ) {
  484. xformNonrational( mat, cp, p );
  485. cp += outstride;
  486. }
  487. }
  488. }
  489. void
  490. Mapdesc::xformMat( Maxmatrix mat, REAL *pts,
  491. int uorder, int ustride,
  492. int vorder, int vstride,
  493. REAL *cp, int outustride, int outvstride )
  494. {
  495. if( isrational ) {
  496. REAL *pend = pts + uorder * ustride;
  497. for( REAL *p = pts ; p != pend; p += ustride ) {
  498. REAL *cpts2 = cp;
  499. REAL *qend = p + vorder * vstride;
  500. for( REAL *q = p; q != qend; q += vstride ) {
  501. xformRational( mat, cpts2, q );
  502. cpts2 += outvstride;
  503. }
  504. cp += outustride;
  505. }
  506. } else {
  507. REAL *pend = pts + uorder * ustride;
  508. for( REAL *p = pts ; p != pend; p += ustride ) {
  509. REAL *cpts2 = cp;
  510. REAL *qend = p + vorder * vstride;
  511. for( REAL *q = p; q != qend; q += vstride ) {
  512. xformNonrational( mat, cpts2, q );
  513. cpts2 += outvstride;
  514. }
  515. cp += outustride;
  516. }
  517. }
  518. }
  519. /*--------------------------------------------------------------------------
  520. * subdivide - subdivide a curve along an isoparametric line
  521. *--------------------------------------------------------------------------
  522. */
  523. void
  524. Mapdesc::subdivide( REAL *src, REAL *dst, REAL v, int stride, int order )
  525. {
  526. REAL mv = 1.0 - v;
  527. for( REAL *send=src+stride*order; src!=send; send-=stride, dst+=stride ) {
  528. copyPt( dst, src );
  529. REAL *qpnt = src + stride;
  530. for( REAL *qp=src; qpnt!=send; qp=qpnt, qpnt+=stride )
  531. sumPt( qp, qp, qpnt, mv, v );
  532. }
  533. }
  534. /*--------------------------------------------------------------------------
  535. * subdivide - subdivide a patch along an isoparametric line
  536. *--------------------------------------------------------------------------
  537. */
  538. void
  539. Mapdesc::subdivide( REAL *src, REAL *dst, REAL v,
  540. int so, int ss, int to, int ts )
  541. {
  542. REAL mv = 1.0 - v;
  543. for( REAL *slast = src+ss*so; src != slast; src += ss, dst += ss ) {
  544. REAL *sp = src;
  545. REAL *dp = dst;
  546. for( REAL *send = src+ts*to; sp != send; send -= ts, dp += ts ) {
  547. copyPt( dp, sp );
  548. REAL *qp = sp;
  549. for( REAL *qpnt = sp+ts; qpnt != send; qp = qpnt, qpnt += ts )
  550. sumPt( qp, qp, qpnt, mv, v );
  551. }
  552. }
  553. }
  554. #define sign(x) ((x > 0) ? 1 : ((x < 0.0) ? -1 : 0))
  555. /*--------------------------------------------------------------------------
  556. * project - project a set of homogeneous coordinates into inhomogeneous ones
  557. *--------------------------------------------------------------------------
  558. */
  559. int
  560. Mapdesc::project( REAL *src, int rstride, int cstride,
  561. REAL *dest, int trstride, int tcstride,
  562. int nrows, int ncols )
  563. {
  564. int s = sign( src[inhcoords] );
  565. REAL *rlast = src + nrows * rstride;
  566. REAL *trptr = dest;
  567. for( REAL *rptr=src; rptr != rlast; rptr+=rstride, trptr+=trstride ) {
  568. REAL *clast = rptr + ncols * cstride;
  569. REAL *tcptr = trptr;
  570. for( REAL *cptr = rptr; cptr != clast; cptr+=cstride, tcptr+=tcstride ) {
  571. REAL *coordlast = cptr + inhcoords;
  572. if( sign( *coordlast ) != s ) return 0;
  573. REAL *tcoord = tcptr;
  574. for( REAL *coord = cptr; coord != coordlast; coord++, tcoord++ ) {
  575. *tcoord = *coord / *coordlast;
  576. }
  577. }
  578. }
  579. return 1;
  580. }
  581. /*--------------------------------------------------------------------------
  582. * project - project a set of homogeneous coordinates into inhomogeneous ones
  583. *--------------------------------------------------------------------------
  584. */
  585. int
  586. Mapdesc::project( REAL *src, int stride, REAL *dest, int tstride, int ncols )
  587. {
  588. int s = sign( src[inhcoords] );
  589. REAL *clast = src + ncols * stride;
  590. for( REAL *cptr = src, *tcptr = dest; cptr != clast; cptr+=stride, tcptr+=tstride ) {
  591. REAL *coordlast = cptr + inhcoords;
  592. if( sign( *coordlast ) != s ) return 0;
  593. for( REAL *coord = cptr, *tcoord = tcptr; coord != coordlast; coord++, tcoord++ )
  594. *tcoord = *coord / *coordlast;
  595. }
  596. return 1;
  597. }
  598. int
  599. Mapdesc::bboxTooBig(
  600. REAL *p,
  601. int rstride,
  602. int cstride,
  603. int nrows,
  604. int ncols,
  605. REAL bb[2][MAXCOORDS] )
  606. {
  607. REAL bbpts[MAXORDER][MAXORDER][MAXCOORDS];
  608. const int trstride = sizeof(bbpts[0]) / sizeof(REAL);
  609. const int tcstride = sizeof(bbpts[0][0]) / sizeof(REAL);
  610. // points have been transformed, therefore they are homogeneous
  611. // project points
  612. int val = project( p, rstride, cstride,
  613. &bbpts[0][0][0], trstride, tcstride, nrows, ncols );
  614. if( val == 0 ) return -1;
  615. // compute bounding box
  616. bbox( bb, &bbpts[0][0][0], trstride, tcstride, nrows, ncols );
  617. // find out if bounding box can't fit in unit cube
  618. if( bbox_subdividing == N_BBOXROUND ) {
  619. for( int k=0; k != inhcoords; k++ )
  620. if( ceilf(bb[1][k]) - floorf(bb[0][k]) > bboxsize[k] ) return 1;
  621. } else {
  622. for( int k=0; k != inhcoords; k++ )
  623. if( bb[1][k] - bb[0][k] > bboxsize[k] ) return 1;
  624. }
  625. return 0;
  626. }
  627. void
  628. Mapdesc::bbox(
  629. REAL bb[2][MAXCOORDS],
  630. REAL *p,
  631. int rstride,
  632. int cstride,
  633. int nrows,
  634. int ncols )
  635. {
  636. for( int k=0; k != inhcoords; k++ )
  637. bb[0][k] = bb[1][k] = p[k];
  638. for( int i=0; i != nrows; i++ )
  639. for( int j=0; j != ncols; j++ )
  640. for( k=0; k != inhcoords; k++ ) {
  641. REAL x = p[i*rstride + j*cstride + k];
  642. if( x < bb[0][k] ) bb[0][k] = x;
  643. else if( x > bb[1][k] ) bb[1][k] = x;
  644. }
  645. }
  646. /*--------------------------------------------------------------------------
  647. * calcVelocityRational - calculate upper bound on first partial derivative
  648. * of a homogeneous set of points and bounds on each row of points.
  649. *--------------------------------------------------------------------------
  650. */
  651. REAL
  652. Mapdesc::calcVelocityRational( REAL *p, int stride, int ncols )
  653. {
  654. REAL tmp[MAXORDER][MAXCOORDS];
  655. assert( ncols <= MAXORDER );
  656. const int tstride = sizeof(tmp[0]) / sizeof(REAL);
  657. if( project( p, stride, &tmp[0][0], tstride, ncols ) ) {
  658. return calcPartialVelocity( &tmp[0][0], tstride, ncols, 1, 1.0 );
  659. } else { /* XXX */
  660. return calcPartialVelocity( &tmp[0][0], tstride, ncols, 1, 1.0 );
  661. }
  662. }
  663. /*--------------------------------------------------------------------------
  664. * calcVelocityNonrational - calculate upper bound on first partial
  665. * derivative of a inhomogeneous set of points.
  666. *--------------------------------------------------------------------------
  667. */
  668. REAL
  669. Mapdesc::calcVelocityNonrational( REAL *pts, int stride, int ncols )
  670. {
  671. return calcPartialVelocity( pts, stride, ncols, 1, 1.0 );
  672. }
  673. int
  674. Mapdesc::isProperty( long property )
  675. {
  676. switch ( property ) {
  677. case N_PIXEL_TOLERANCE:
  678. case N_ERROR_TOLERANCE:
  679. case N_CULLING:
  680. case N_BBOX_SUBDIVIDING:
  681. case N_S_STEPS:
  682. case N_T_STEPS:
  683. case N_SAMPLINGMETHOD:
  684. case N_CLAMPFACTOR:
  685. case N_MINSAVINGS:
  686. return 1;
  687. default:
  688. return 0;
  689. }
  690. }
  691. REAL
  692. Mapdesc::getProperty( long property )
  693. {
  694. switch ( property ) {
  695. case N_PIXEL_TOLERANCE:
  696. return pixel_tolerance;
  697. case N_ERROR_TOLERANCE:
  698. return error_tolerance;
  699. case N_CULLING:
  700. return culling_method;
  701. case N_BBOX_SUBDIVIDING:
  702. return bbox_subdividing;
  703. case N_S_STEPS:
  704. return s_steps;
  705. case N_T_STEPS:
  706. return t_steps;
  707. case N_SAMPLINGMETHOD:
  708. return sampling_method;
  709. case N_CLAMPFACTOR:
  710. return clampfactor;
  711. case N_MINSAVINGS:
  712. return minsavings;
  713. default:
  714. #ifdef NT
  715. return( (REAL) 0.0 );
  716. #else
  717. abort();
  718. return -1; //not necessary, needed to shut up compiler
  719. #endif
  720. }
  721. }
  722. void
  723. Mapdesc::setProperty( long property, REAL value )
  724. {
  725. switch ( property ) {
  726. case N_PIXEL_TOLERANCE:
  727. pixel_tolerance = value;
  728. break;
  729. case N_ERROR_TOLERANCE:
  730. error_tolerance = value;
  731. break;
  732. case N_CULLING:
  733. culling_method = value;
  734. break;
  735. case N_BBOX_SUBDIVIDING:
  736. if( value <= 0.0 ) value = N_NOBBOXSUBDIVISION;
  737. bbox_subdividing = value;
  738. break;
  739. case N_S_STEPS:
  740. if( value < 0.0 ) value = 0.0;
  741. s_steps = value;
  742. maxrate = ( value < 0.0 ) ? 0.0 : value;
  743. maxsrate = ( value < 0.0 ) ? 0.0 : value;
  744. break;
  745. case N_T_STEPS:
  746. if( value < 0.0 ) value = 0.0;
  747. t_steps = value;
  748. maxtrate = ( value < 0.0 ) ? 0.0 : value;
  749. break;
  750. case N_SAMPLINGMETHOD:
  751. sampling_method = value;
  752. break;
  753. case N_CLAMPFACTOR:
  754. if( value <= 0.0 ) value = N_NOCLAMPING;
  755. clampfactor = value;
  756. break;
  757. case N_MINSAVINGS:
  758. if( value <= 0.0 ) value = N_NOSAVINGSSUBDIVISION;
  759. minsavings = value;
  760. break;
  761. default:
  762. #ifndef NT
  763. abort();
  764. #endif
  765. break;
  766. }
  767. }