2 ** License Applicability. Except to the extent portions of this file are
3 ** made subject to an alternative license as permitted in the SGI Free
4 ** Software License B, Version 1.1 (the "License"), the contents of this
5 ** file are subject only to the provisions of the License. You may not use
6 ** this file except in compliance with the License. You may obtain a copy
7 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
10 ** http://oss.sgi.com/projects/FreeB
12 ** Note that, as provided in the License, the Software is distributed on an
13 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
18 ** Original Code. The Original Code is: OpenGL Sample Implementation,
19 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21 ** Copyright in any portions created by third parties is as indicated
22 ** elsewhere herein. All Rights Reserved.
24 ** Additional Notice Provisions: The application programming interfaces
25 ** established by SGI in conjunction with the Original Code are The
26 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29 ** Window System(R) (Version 1.3), released October 19, 1998. This software
30 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31 ** published by SGI, but has not been independently verified as being
32 ** compliant with the OpenGL(R) version 1.2.1 Specification.
38 * $Date: 2001/03/17 00:25:41 $ $Revision: 1.1 $
39 * $Header: /home/krh/git/sync/mesa-cvs-repo/Mesa/src/glu/sgi/libnurbs/internals/nurbsinterfac.cc,v 1.1 2001/03/17 00:25:41 brianp Exp $
42 #include "glimports.h"
44 #include "nurbsconsts.h"
45 #include "nurbstess.h"
48 #include "displaylist.h"
49 #include "knotvector.h"
52 #define THREAD( work, arg, cleanup ) \
55 dl->append( (PFVS)&NurbsTessellator::work, (void *) arg, (PFVS)&NurbsTessellator::cleanup );\
61 #define THREAD2( work ) \
63 dl->append( (PFVS)&NurbsTessellator::work, 0, 0 );\
68 NurbsTessellator::NurbsTessellator( BasicCurveEvaluator
&c
, BasicSurfaceEvaluator
& e
)
69 : subdivider( renderhints
, backend
),
72 o_pwlcurvePool( sizeof( O_pwlcurve
), 32, "o_pwlcurvePool" ),
73 o_nurbscurvePool( sizeof( O_nurbscurve
), 32, "o_nurbscurvePool"),
74 o_curvePool( sizeof( O_curve
), 32, "o_curvePool" ),
75 o_trimPool( sizeof( O_trim
), 32, "o_trimPool" ),
76 o_surfacePool( sizeof( O_surface
), 1, "o_surfacePool" ),
77 o_nurbssurfacePool( sizeof( O_nurbssurface
), 4, "o_nurbssurfacePool" ),
78 propertyPool( sizeof( Property
), 32, "propertyPool" ),
79 quiltPool( sizeof( Quilt
), 32, "quiltPool" )
86 jumpbuffer
= newJumpbuffer();
87 subdivider
.setJumpbuffer( jumpbuffer
);
90 NurbsTessellator::~NurbsTessellator( void )
98 *nextNurbssurface
= 0;
103 deleteJumpbuffer(jumpbuffer
);
108 /*-----------------------------------------------------------------------------
109 * bgnsurface - allocate and initialize an o_surface structure
112 *-----------------------------------------------------------------------------
115 NurbsTessellator::bgnsurface( long nuid
)
117 O_surface
*o_surface
= new(o_surfacePool
) O_surface
;
118 o_surface
->nuid
= nuid
;
119 THREAD( do_bgnsurface
, o_surface
, do_freebgnsurface
);
122 /*-----------------------------------------------------------------------------
123 * bgncurve - allocate an initialize an o_curve structure
126 *-----------------------------------------------------------------------------
129 NurbsTessellator::bgncurve( long nuid
)
131 O_curve
*o_curve
= new(o_curvePool
) O_curve
;
132 o_curve
->nuid
= nuid
;
133 THREAD( do_bgncurve
, o_curve
, do_freebgncurve
);
135 /*-----------------------------------------------------------------------------
139 *-----------------------------------------------------------------------------
143 NurbsTessellator::endcurve( void )
145 THREAD2( do_endcurve
);
148 /*-----------------------------------------------------------------------------
149 * endsurface - user level end of surface call
152 *-----------------------------------------------------------------------------
155 NurbsTessellator::endsurface( void )
157 THREAD2( do_endsurface
);
161 /*-----------------------------------------------------------------------------
162 * bgntrim - allocate and initialize a new trim loop structure (o_trim )
165 *-----------------------------------------------------------------------------
168 NurbsTessellator::bgntrim( void )
170 O_trim
*o_trim
= new(o_trimPool
) O_trim
;
171 THREAD( do_bgntrim
, o_trim
, do_freebgntrim
);
174 /*-----------------------------------------------------------------------------
178 *-----------------------------------------------------------------------------
181 NurbsTessellator::endtrim( void )
183 THREAD2( do_endtrim
);
187 /*-----------------------------------------------------------------------------
190 * count - number of points on curve
191 * array - array of points on curve
192 * byte_stride - distance between points in bytes
193 * type - valid data flag
196 *-----------------------------------------------------------------------------
199 NurbsTessellator::pwlcurve( long count
, INREAL array
[], long byte_stride
, long type
)
201 Mapdesc
*mapdesc
= maplist
.locate( type
);
209 if ( (type
!= N_P2D
) && (type
!= N_P2DR
) ) {
219 if( byte_stride
< 0 ) {
226 if( mapdesc
->isRational() ) {
228 INREAL x
= p
[0]; INREAL y
= p
[1]; INREAL w
= p
[2];
229 p
= (INREAL
*) (((char *) p
) + byte_stride
);
230 for( long i
= 1; i
!= count
; i
++ ) {
231 if( p
[0] == x
&& p
[1] == y
&& p
[2] == w
) break;
232 x
= p
[0]; y
= p
[1]; w
= p
[2];
233 p
= (INREAL
*) (((char *) p
) + byte_stride
);
237 dprintf( "point %d (%f,%f)\n", i
, x
, y
);
243 INREAL x
= p
[0]; INREAL y
= p
[1];
244 p
= (INREAL
*) (((char *) p
) + byte_stride
);
245 for( long i
= 1; i
!= count
; i
++ ) {
246 if( p
[0] == x
&& p
[1] == y
) break;
248 p
= (INREAL
*) (((char *) p
) + byte_stride
);
252 dprintf( "point %d (%f,%f)\n", i
, x
, y
);
259 O_pwlcurve
*o_pwlcurve
= new(o_pwlcurvePool
) O_pwlcurve( type
, count
, array
, byte_stride
, extTrimVertexPool
.get((int)count
) );
260 THREAD( do_pwlcurve
, o_pwlcurve
, do_freepwlcurve
);
264 /*-----------------------------------------------------------------------------
268 *-----------------------------------------------------------------------------
271 NurbsTessellator::nurbscurve(
272 long nknots
, /* number of p knots */
273 INREAL knot
[], /* nondecreasing knot values in p */
274 long byte_stride
, /* distance in bytes between control points */
275 INREAL ctlarray
[], /* pointer to first control point */
276 long order
, /* order of spline */
277 long type
) /* description of range space */
280 Mapdesc
*mapdesc
= maplist
.locate( type
);
288 if( ctlarray
== 0 ) {
294 if( byte_stride
< 0 ) {
302 knots
.init( nknots
, byte_stride
, order
, knot
);
303 if( do_check_knots( &knots
, "curve" ) ) return;
305 O_nurbscurve
*o_nurbscurve
= new(o_nurbscurvePool
) O_nurbscurve(type
);
306 o_nurbscurve
->bezier_curves
= new(quiltPool
) Quilt(mapdesc
);
307 o_nurbscurve
->bezier_curves
->toBezier( knots
,ctlarray
, mapdesc
->getNcoords() );
309 THREAD( do_nurbscurve
, o_nurbscurve
, do_freenurbscurve
);
313 /*-----------------------------------------------------------------------------
316 * Client: User routine
317 *-----------------------------------------------------------------------------
320 NurbsTessellator::nurbssurface(
321 long sknot_count
, /* number of s knots */
322 INREAL sknot
[], /* nondecreasing knot values in s */
323 long tknot_count
, /* number of t knots */
324 INREAL tknot
[], /* nondecreasing knot values in t */
325 long s_byte_stride
, /* s step size in memory bytes */
326 long t_byte_stride
, /* t step size in memory bytes */
327 INREAL ctlarray
[], /* pointer to first control point */
328 long sorder
, /* order of the spline in s parameter */
329 long torder
, /* order of the spline in t parameter */
330 long type
) /* description of range space */
332 Mapdesc
*mapdesc
= maplist
.locate( type
);
340 if( s_byte_stride
< 0 ) {
346 if( t_byte_stride
< 0 ) {
352 Knotvector sknotvector
, tknotvector
;
354 sknotvector
.init( sknot_count
, s_byte_stride
, sorder
, sknot
);
355 if( do_check_knots( &sknotvector
, "surface" ) ) return;
357 tknotvector
.init( tknot_count
, t_byte_stride
, torder
, tknot
);
358 if( do_check_knots( &tknotvector
, "surface" ) ) return;
360 O_nurbssurface
*o_nurbssurface
= new(o_nurbssurfacePool
) O_nurbssurface(type
);
361 o_nurbssurface
->bezier_patches
= new(quiltPool
) Quilt(mapdesc
);
363 o_nurbssurface
->bezier_patches
->toBezier( sknotvector
, tknotvector
,
364 ctlarray
, mapdesc
->getNcoords() );
365 THREAD( do_nurbssurface
, o_nurbssurface
, do_freenurbssurface
);
369 /*-----------------------------------------------------------------------------
372 *-----------------------------------------------------------------------------
375 NurbsTessellator::setnurbsproperty( long tag
, INREAL value
)
377 if( ! renderhints
.isProperty( tag
) ) {
380 Property
*prop
= new(propertyPool
) Property( tag
, value
);
381 THREAD( do_setnurbsproperty
, prop
, do_freenurbsproperty
);
385 /*-----------------------------------------------------------------------------
388 *-----------------------------------------------------------------------------
391 NurbsTessellator::setnurbsproperty( long type
, long tag
, INREAL value
)
393 Mapdesc
*mapdesc
= maplist
.locate( type
);
400 if( ! mapdesc
->isProperty( tag
) ) {
405 Property
*prop
= new(propertyPool
) Property( type
, tag
, value
);
406 THREAD( do_setnurbsproperty2
, prop
, do_freenurbsproperty
);
410 /*-----------------------------------------------------------------------------
413 *-----------------------------------------------------------------------------
417 NurbsTessellator::getnurbsproperty( long tag
, INREAL
*value
)
419 if( renderhints
.isProperty( tag
) ) {
420 *value
= renderhints
.getProperty( tag
);
426 /*-----------------------------------------------------------------------------
429 *-----------------------------------------------------------------------------
433 NurbsTessellator::getnurbsproperty( long type
, long tag
, INREAL
*value
)
435 Mapdesc
*mapdesc
= maplist
.locate( type
);
440 if( mapdesc
->isProperty( tag
) ) {
441 *value
= mapdesc
->getProperty( tag
);
447 /*--------------------------------------------------------------------------
448 * setnurbsproperty - accept a user supplied matrix as culling or sampling mat
449 *--------------------------------------------------------------------------
453 NurbsTessellator::setnurbsproperty( long type
, long purpose
, INREAL
*mat
)
455 // XXX - cannot be put in display list
456 Mapdesc
*mapdesc
= maplist
.locate( type
);
461 } else if( purpose
== N_BBOXSIZE
) {
462 mapdesc
->setBboxsize( mat
);
465 dprintf( "ERRORRORRORR!!!\n");
470 /*--------------------------------------------------------------------------
471 * setnurbsproperty - accept a user supplied matrix as culling or sampling mat
472 *--------------------------------------------------------------------------
476 NurbsTessellator::setnurbsproperty( long type
, long purpose
, INREAL
*mat
,
477 long rstride
, long cstride
)
479 // XXX - cannot be put in display list
480 Mapdesc
*mapdesc
= maplist
.locate( type
);
485 } else if( purpose
== N_CULLINGMATRIX
) {
486 mapdesc
->setCmat( mat
, rstride
, cstride
);
487 } else if( purpose
== N_SAMPLINGMATRIX
) {
488 mapdesc
->setSmat( mat
, rstride
, cstride
);
489 } else if( purpose
== N_BBOXMATRIX
) {
490 mapdesc
->setBmat( mat
, rstride
, cstride
);
493 dprintf( "ERRORRORRORR!!!\n");
499 NurbsTessellator::redefineMaps( void )
501 maplist
.initialize();
505 NurbsTessellator::defineMap( long type
, long rational
, long ncoords
)
507 maplist
.define( type
, (int) rational
, (int) ncoords
);
511 NurbsTessellator::discardRecording( void *_dl
)
513 delete (DisplayList
*) _dl
;
517 NurbsTessellator::beginRecording( void )
519 dl
= new DisplayList( this );
524 NurbsTessellator::endRecording( void )
531 NurbsTessellator::playRecording( void *_dl
)
535 ((DisplayList
*)_dl
)->play();