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.
40 #include "glimports.h"
44 #include "nurbsconsts.h"
45 #include "nurbstess.h"
48 #include "knotvector.h"
53 NurbsTessellator::set_domain_distance_u_rate(REAL u_rate
)
55 subdivider
.set_domain_distance_u_rate(u_rate
);
59 NurbsTessellator::set_domain_distance_v_rate(REAL v_rate
)
61 subdivider
.set_domain_distance_v_rate(v_rate
);
65 NurbsTessellator::set_is_domain_distance_sampling(int flag
)
67 subdivider
.set_is_domain_distance_sampling(flag
);
71 NurbsTessellator::resetObjects( void )
77 NurbsTessellator::makeobj( int )
80 _glu_dprintf( "makeobj\n" );
85 NurbsTessellator::closeobj( void )
88 _glu_dprintf( "closeobj\n" );
93 NurbsTessellator::bgnrender( void )
96 _glu_dprintf( "bgnrender\n" );
101 NurbsTessellator::endrender( void )
104 _glu_dprintf( "endrender\n" );
108 /*-----------------------------------------------------------------------------
109 * do_freebgnsurface - free o_surface structure
111 * Client: do_freeall(), bgnsurface()
112 *-----------------------------------------------------------------------------
115 NurbsTessellator::do_freebgnsurface( O_surface
*o_surface
)
117 o_surface
->deleteMe( o_surfacePool
);
121 /*-----------------------------------------------------------------------------
122 * do_bgnsurface - begin the display of a surface
124 * Client: bgnsurface()
125 *-----------------------------------------------------------------------------
128 NurbsTessellator::do_bgnsurface( O_surface
*o_surface
)
136 if( ! playBack
) bgnrender();
139 isSurfaceModified
= 0;
142 currentSurface
= o_surface
;
143 nextTrim
= &( currentSurface
->o_trim
);
144 nextNurbssurface
= &( currentSurface
->o_nurbssurface
);
147 /*-----------------------------------------------------------------------------
148 * do_bgncurve - begin the display of a curve
151 *-----------------------------------------------------------------------------
154 NurbsTessellator::do_bgncurve( O_curve
*o_curve
)
162 currentCurve
= o_curve
;
163 currentCurve
->curvetype
= ct_none
;
166 if( *nextCurve
!= o_curve
) {
168 *nextCurve
= o_curve
;
171 if( ! playBack
) bgnrender();
174 nextCurve
= &(o_curve
->next
);
175 nextPwlcurve
= &(o_curve
->curve
.o_pwlcurve
);
176 nextNurbscurve
= &(o_curve
->curve
.o_nurbscurve
);
179 /*-----------------------------------------------------------------------------
183 *-----------------------------------------------------------------------------
187 NurbsTessellator::do_endcurve( void )
196 if (currentCurve
->curvetype
== ct_nurbscurve
)
202 if( ! isDataValid
) {
203 do_freecurveall( currentCurve
);
208 errval
= ::mysetjmp( jumpbuffer
);
210 if( currentCurve
->curvetype
== ct_nurbscurve
) {
211 subdivider
.beginQuilts();
212 for( O_nurbscurve
*n
= currentCurve
->curve
.o_nurbscurve
; n
!= 0; n
= n
->next
)
213 subdivider
.addQuilt( n
->bezier_curves
);
214 subdivider
.endQuilts();
215 subdivider
.drawCurves();
216 if( ! playBack
) endrender();
219 if( ! playBack
) endrender();
220 /*do_draw_pwlcurve( currentCurve->curve.o_pwlcurve ) */;
224 if( ! playBack
) endrender();
225 do_nurbserror( errval
);
227 do_freecurveall( currentCurve
);
232 /*-----------------------------------------------------------------------------
233 * do_endsurface - mark end of surface, display surface, free immediate data
236 *-----------------------------------------------------------------------------
239 NurbsTessellator::do_endsurface( void )
252 *nextNurbssurface
= 0;
254 if( ! isDataValid
) {
259 if( *nextTrim
!= 0 ) {
266 errval
= ::mysetjmp( jumpbuffer
);
270 subdivider
.beginTrims();
271 for( O_trim
*trim
= currentSurface
->o_trim
; trim
; trim
= trim
->next
) {
272 subdivider
.beginLoop();
273 for( O_curve
*curve
= trim
->o_curve
; curve
; curve
= curve
->next
) {
275 assert( curve
->curvetype
!= ct_none
);
276 if (curve
->curvetype
== ct_pwlcurve
) {
277 O_pwlcurve
*c
= curve
->curve
.o_pwlcurve
;
278 subdivider
.addArc( c
->npts
, c
->pts
, curve
->nuid
);
280 Quilt
*quilt
= curve
->curve
.o_nurbscurve
->bezier_curves
;
281 Quiltspec
*qspec
= quilt
->qspec
;
282 REAL
*cpts
= quilt
->cpts
+ qspec
->offset
;
283 REAL
*cptsend
= cpts
+ (qspec
->width
* qspec
->order
* qspec
->stride
);
284 for( ; cpts
!= cptsend
; cpts
+= qspec
->order
*qspec
->stride
)
285 subdivider
.addArc( cpts
, quilt
, curve
->nuid
);
288 subdivider
.endLoop();
290 subdivider
.endTrims();
293 subdivider
.beginQuilts();
294 for( O_nurbssurface
*n
= currentSurface
->o_nurbssurface
; n
; n
= n
->next
)
295 subdivider
.addQuilt( n
->bezier_patches
);
296 subdivider
.endQuilts();
297 subdivider
.drawSurfaces( currentSurface
->nuid
);
298 if( ! playBack
) endrender();
300 if( ! playBack
) endrender();
301 do_nurbserror( errval
);
308 /*-----------------------------------------------------------------------------
309 * do_freeall - free all data allocated in immediate mode
312 *-----------------------------------------------------------------------------
315 NurbsTessellator::do_freeall( void )
317 for( O_trim
*o_trim
= currentSurface
->o_trim
; o_trim
; ) {
318 O_trim
*next_o_trim
= o_trim
->next
;
319 for( O_curve
*curve
= o_trim
->o_curve
; curve
; ) {
320 O_curve
*next_o_curve
= curve
->next
;
321 do_freecurveall( curve
);
322 curve
= next_o_curve
;
324 if( o_trim
->save
== 0 ) do_freebgntrim( o_trim
);
325 o_trim
= next_o_trim
;
328 O_nurbssurface
*nurbss
, *next_nurbss
;
329 for( nurbss
= currentSurface
->o_nurbssurface
; nurbss
; nurbss
= next_nurbss
) {
330 next_nurbss
= nurbss
->next
;
331 if( nurbss
->save
== 0 )
332 do_freenurbssurface( nurbss
);
337 if( currentSurface
->save
== 0 ) do_freebgnsurface( currentSurface
);
341 NurbsTessellator::do_freecurveall( O_curve
*curve
)
343 assert( curve
->curvetype
!= ct_none
);
345 if( curve
->curvetype
== ct_nurbscurve
) {
346 O_nurbscurve
*ncurve
, *next_ncurve
;
347 for( ncurve
=curve
->curve
.o_nurbscurve
; ncurve
; ncurve
=next_ncurve
) {
348 next_ncurve
= ncurve
->next
;
349 if( ncurve
->save
== 0 )
350 do_freenurbscurve( ncurve
);
355 O_pwlcurve
*pcurve
, *next_pcurve
;
356 for( pcurve
=curve
->curve
.o_pwlcurve
; pcurve
; pcurve
=next_pcurve
) {
357 next_pcurve
= pcurve
->next
;
358 if( pcurve
->save
== 0 )
359 do_freepwlcurve( pcurve
);
364 if( curve
->save
== 0 )
365 do_freebgncurve( curve
);
369 /*-----------------------------------------------------------------------------
370 * do_freebgntrim - free the space allocated for a trim loop
373 *-----------------------------------------------------------------------------
376 NurbsTessellator::do_freebgntrim( O_trim
*o_trim
)
378 o_trim
->deleteMe( o_trimPool
);
382 /*-----------------------------------------------------------------------------
383 * do_bgntrim - link in a trim loop to the current trimmed surface description
386 *-----------------------------------------------------------------------------
389 NurbsTessellator::do_bgntrim( O_trim
*o_trim
)
404 if( *nextTrim
!= o_trim
) {
409 currentTrim
= o_trim
;
410 nextTrim
= &(o_trim
->next
);
411 nextCurve
= &(o_trim
->o_curve
);
415 /*-----------------------------------------------------------------------------
416 * do_endtrim - mark the end of the current trim loop
419 *-----------------------------------------------------------------------------
422 NurbsTessellator::do_endtrim( void )
430 if( currentTrim
->o_curve
== 0 ) {
437 if( *nextCurve
!= 0 ) {
443 /*-----------------------------------------------------------------------------
447 *-----------------------------------------------------------------------------
450 NurbsTessellator::do_freepwlcurve( O_pwlcurve
*o_pwlcurve
)
452 o_pwlcurve
->deleteMe( o_pwlcurvePool
);
456 NurbsTessellator::do_freebgncurve( O_curve
*o_curve
)
458 o_curve
->deleteMe( o_curvePool
);
461 /*-----------------------------------------------------------------------------
462 * do_pwlcurve - link in pwl trim loop to the current surface description
465 *-----------------------------------------------------------------------------
468 NurbsTessellator::do_pwlcurve( O_pwlcurve
*o_pwlcurve
)
472 if( o_pwlcurve
->save
== 0 )
473 do_freepwlcurve(o_pwlcurve
);
482 if( o_pwlcurve
->used
) {
487 o_pwlcurve
->used
= 1;
489 if( currentCurve
->curvetype
== ct_none
) {
490 currentCurve
->curvetype
= ct_pwlcurve
;
491 } else if( currentCurve
->curvetype
!= ct_pwlcurve
) {
497 if( *nextPwlcurve
!= o_pwlcurve
) {
499 *nextPwlcurve
= o_pwlcurve
;
501 nextPwlcurve
= &(o_pwlcurve
->next
);
503 if( o_pwlcurve
->owner
!= currentCurve
) {
505 o_pwlcurve
->owner
= currentCurve
;
513 /*-----------------------------------------------------------------------------
514 * do_freenurbscurve -
517 *-----------------------------------------------------------------------------
520 NurbsTessellator::do_freenurbscurve( O_nurbscurve
*o_nurbscurve
)
522 o_nurbscurve
->bezier_curves
->deleteMe( quiltPool
);
523 o_nurbscurve
->deleteMe( o_nurbscurvePool
);
527 /*-----------------------------------------------------------------------------
530 * Client: nurbscurve()
531 *-----------------------------------------------------------------------------
534 NurbsTessellator::do_nurbscurve( O_nurbscurve
*o_nurbscurve
)
541 if( o_nurbscurve
->used
) {
542 /* error - curve was already called in current surface */
547 o_nurbscurve
->used
= 1;
549 if( currentCurve
->curvetype
== ct_none
) {
550 currentCurve
->curvetype
= ct_nurbscurve
;
551 } else if( currentCurve
->curvetype
!= ct_nurbscurve
) {
557 if( *nextNurbscurve
!= o_nurbscurve
) {
559 *nextNurbscurve
= o_nurbscurve
;
562 nextNurbscurve
= &(o_nurbscurve
->next
);
564 if( o_nurbscurve
->owner
!= currentCurve
) {
566 o_nurbscurve
->owner
= currentCurve
;
569 if( o_nurbscurve
->owner
== 0 )
577 /*-----------------------------------------------------------------------------
578 * do_freenurbssurface -
581 *-----------------------------------------------------------------------------
585 NurbsTessellator::do_freenurbssurface( O_nurbssurface
*o_nurbssurface
)
587 o_nurbssurface
->bezier_patches
->deleteMe( quiltPool
);
588 o_nurbssurface
->deleteMe( o_nurbssurfacePool
);
591 /*-----------------------------------------------------------------------------
594 * Client: nurbssurface()
595 *-----------------------------------------------------------------------------
598 NurbsTessellator::do_nurbssurface( O_nurbssurface
*o_nurbssurface
)
605 if( o_nurbssurface
->used
) {
606 /* error - surface was already called in current block */
611 o_nurbssurface
->used
= 1;
613 if( *nextNurbssurface
!= o_nurbssurface
) {
614 isSurfaceModified
= 1;
615 *nextNurbssurface
= o_nurbssurface
;
618 if( o_nurbssurface
->owner
!= currentSurface
) {
619 isSurfaceModified
= 1;
620 o_nurbssurface
->owner
= currentSurface
;
622 nextNurbssurface
= &(o_nurbssurface
->next
);
629 /*-----------------------------------------------------------------------------
630 * do_freenurbsproperty
632 *-----------------------------------------------------------------------------
636 NurbsTessellator::do_freenurbsproperty( Property
*prop
)
638 prop
->deleteMe( propertyPool
);
642 /*-----------------------------------------------------------------------------
643 * do_setnurbsproperty -
645 *-----------------------------------------------------------------------------
649 NurbsTessellator::do_setnurbsproperty( Property
*prop
)
651 renderhints
.setProperty( prop
->tag
, prop
->value
);
652 if( prop
->save
== 0 )
653 do_freenurbsproperty( prop
);
657 NurbsTessellator::do_setnurbsproperty2( Property
*prop
)
659 Mapdesc
*mapdesc
= maplist
.find( prop
->type
);
661 mapdesc
->setProperty( prop
->tag
, prop
->value
);
662 if( prop
->save
== 0 )
663 do_freenurbsproperty( prop
);
667 NurbsTessellator::errorHandler( int )
672 NurbsTessellator::do_nurbserror( int msg
)
678 NurbsTessellator::do_check_knots( Knotvector
*knots
, char *msg
)
680 int status
= knots
->validate();
682 do_nurbserror( status
);
683 if( renderhints
.errorchecking
!= N_NOMSG
) knots
->show( msg
);