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