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/nurbstess.cc,v 1.1 2001/03/17 00:25:41 brianp Exp $
42 #include "glimports.h"
46 #include "nurbsconsts.h"
47 #include "nurbstess.h"
50 #include "knotvector.h"
55 NurbsTessellator::set_domain_distance_u_rate(REAL u_rate
)
57 subdivider
.set_domain_distance_u_rate(u_rate
);
61 NurbsTessellator::set_domain_distance_v_rate(REAL v_rate
)
63 subdivider
.set_domain_distance_v_rate(v_rate
);
67 NurbsTessellator::set_is_domain_distance_sampling(int flag
)
69 subdivider
.set_is_domain_distance_sampling(flag
);
73 NurbsTessellator::resetObjects( void )
79 NurbsTessellator::makeobj( int )
82 dprintf( "makeobj\n" );
87 NurbsTessellator::closeobj( void )
90 dprintf( "closeobj\n" );
95 NurbsTessellator::bgnrender( void )
98 dprintf( "bgnrender\n" );
103 NurbsTessellator::endrender( void )
106 dprintf( "endrender\n" );
110 /*-----------------------------------------------------------------------------
111 * do_freebgnsurface - free o_surface structure
113 * Client: do_freeall(), bgnsurface()
114 *-----------------------------------------------------------------------------
117 NurbsTessellator::do_freebgnsurface( O_surface
*o_surface
)
119 o_surface
->deleteMe( o_surfacePool
);
123 /*-----------------------------------------------------------------------------
124 * do_bgnsurface - begin the display of a surface
126 * Client: bgnsurface()
127 *-----------------------------------------------------------------------------
130 NurbsTessellator::do_bgnsurface( O_surface
*o_surface
)
138 if( ! playBack
) bgnrender();
141 isSurfaceModified
= 0;
144 currentSurface
= o_surface
;
145 nextTrim
= &( currentSurface
->o_trim
);
146 nextNurbssurface
= &( currentSurface
->o_nurbssurface
);
149 /*-----------------------------------------------------------------------------
150 * do_bgncurve - begin the display of a curve
153 *-----------------------------------------------------------------------------
156 NurbsTessellator::do_bgncurve( O_curve
*o_curve
)
164 currentCurve
= o_curve
;
165 currentCurve
->curvetype
= ct_none
;
168 if( *nextCurve
!= o_curve
) {
170 *nextCurve
= o_curve
;
173 if( ! playBack
) bgnrender();
176 nextCurve
= &(o_curve
->next
);
177 nextPwlcurve
= &(o_curve
->curve
.o_pwlcurve
);
178 nextNurbscurve
= &(o_curve
->curve
.o_nurbscurve
);
181 /*-----------------------------------------------------------------------------
185 *-----------------------------------------------------------------------------
189 NurbsTessellator::do_endcurve( void )
198 if (currentCurve
->curvetype
== ct_nurbscurve
)
204 if( ! isDataValid
) {
205 do_freecurveall( currentCurve
);
210 errval
= ::mysetjmp( jumpbuffer
);
212 if( currentCurve
->curvetype
== ct_nurbscurve
) {
213 subdivider
.beginQuilts();
214 for( O_nurbscurve
*n
= currentCurve
->curve
.o_nurbscurve
; n
!= 0; n
= n
->next
)
215 subdivider
.addQuilt( n
->bezier_curves
);
216 subdivider
.endQuilts();
217 subdivider
.drawCurves();
218 if( ! playBack
) endrender();
221 if( ! playBack
) endrender();
222 /*do_draw_pwlcurve( currentCurve->curve.o_pwlcurve ) */;
226 if( ! playBack
) endrender();
227 do_nurbserror( errval
);
229 do_freecurveall( currentCurve
);
234 /*-----------------------------------------------------------------------------
235 * do_endsurface - mark end of surface, display surface, free immediate data
238 *-----------------------------------------------------------------------------
241 NurbsTessellator::do_endsurface( void )
254 *nextNurbssurface
= 0;
256 if( ! isDataValid
) {
261 if( *nextTrim
!= 0 ) {
268 errval
= ::mysetjmp( jumpbuffer
);
272 subdivider
.beginTrims();
273 for( O_trim
*trim
= currentSurface
->o_trim
; trim
; trim
= trim
->next
) {
274 subdivider
.beginLoop();
275 for( O_curve
*curve
= trim
->o_curve
; curve
; curve
= curve
->next
) {
277 assert( curve
->curvetype
!= ct_none
);
278 if (curve
->curvetype
== ct_pwlcurve
) {
279 O_pwlcurve
*c
= curve
->curve
.o_pwlcurve
;
280 subdivider
.addArc( c
->npts
, c
->pts
, curve
->nuid
);
282 Quilt
*quilt
= curve
->curve
.o_nurbscurve
->bezier_curves
;
283 Quiltspec
*qspec
= quilt
->qspec
;
284 REAL
*cpts
= quilt
->cpts
+ qspec
->offset
;
285 REAL
*cptsend
= cpts
+ (qspec
->width
* qspec
->order
* qspec
->stride
);
286 for( ; cpts
!= cptsend
; cpts
+= qspec
->order
*qspec
->stride
)
287 subdivider
.addArc( cpts
, quilt
, curve
->nuid
);
290 subdivider
.endLoop();
292 subdivider
.endTrims();
295 subdivider
.beginQuilts();
296 for( O_nurbssurface
*n
= currentSurface
->o_nurbssurface
; n
; n
= n
->next
)
297 subdivider
.addQuilt( n
->bezier_patches
);
298 subdivider
.endQuilts();
299 subdivider
.drawSurfaces( currentSurface
->nuid
);
300 if( ! playBack
) endrender();
302 if( ! playBack
) endrender();
303 do_nurbserror( errval
);
310 /*-----------------------------------------------------------------------------
311 * do_freeall - free all data allocated in immediate mode
314 *-----------------------------------------------------------------------------
317 NurbsTessellator::do_freeall( void )
319 for( O_trim
*o_trim
= currentSurface
->o_trim
; o_trim
; ) {
320 O_trim
*next_o_trim
= o_trim
->next
;
321 for( O_curve
*curve
= o_trim
->o_curve
; curve
; ) {
322 O_curve
*next_o_curve
= curve
->next
;
323 do_freecurveall( curve
);
324 curve
= next_o_curve
;
326 if( o_trim
->save
== 0 ) do_freebgntrim( o_trim
);
327 o_trim
= next_o_trim
;
330 O_nurbssurface
*nurbss
, *next_nurbss
;
331 for( nurbss
= currentSurface
->o_nurbssurface
; nurbss
; nurbss
= next_nurbss
) {
332 next_nurbss
= nurbss
->next
;
333 if( nurbss
->save
== 0 )
334 do_freenurbssurface( nurbss
);
339 if( currentSurface
->save
== 0 ) do_freebgnsurface( currentSurface
);
343 NurbsTessellator::do_freecurveall( O_curve
*curve
)
345 assert( curve
->curvetype
!= ct_none
);
347 if( curve
->curvetype
== ct_nurbscurve
) {
348 O_nurbscurve
*ncurve
, *next_ncurve
;
349 for( ncurve
=curve
->curve
.o_nurbscurve
; ncurve
; ncurve
=next_ncurve
) {
350 next_ncurve
= ncurve
->next
;
351 if( ncurve
->save
== 0 )
352 do_freenurbscurve( ncurve
);
357 O_pwlcurve
*pcurve
, *next_pcurve
;
358 for( pcurve
=curve
->curve
.o_pwlcurve
; pcurve
; pcurve
=next_pcurve
) {
359 next_pcurve
= pcurve
->next
;
360 if( pcurve
->save
== 0 )
361 do_freepwlcurve( pcurve
);
366 if( curve
->save
== 0 )
367 do_freebgncurve( curve
);
371 /*-----------------------------------------------------------------------------
372 * do_freebgntrim - free the space allocated for a trim loop
375 *-----------------------------------------------------------------------------
378 NurbsTessellator::do_freebgntrim( O_trim
*o_trim
)
380 o_trim
->deleteMe( o_trimPool
);
384 /*-----------------------------------------------------------------------------
385 * do_bgntrim - link in a trim loop to the current trimmed surface description
388 *-----------------------------------------------------------------------------
391 NurbsTessellator::do_bgntrim( O_trim
*o_trim
)
406 if( *nextTrim
!= o_trim
) {
411 currentTrim
= o_trim
;
412 nextTrim
= &(o_trim
->next
);
413 nextCurve
= &(o_trim
->o_curve
);
417 /*-----------------------------------------------------------------------------
418 * do_endtrim - mark the end of the current trim loop
421 *-----------------------------------------------------------------------------
424 NurbsTessellator::do_endtrim( void )
432 if( currentTrim
->o_curve
== 0 ) {
439 if( *nextCurve
!= 0 ) {
445 /*-----------------------------------------------------------------------------
449 *-----------------------------------------------------------------------------
452 NurbsTessellator::do_freepwlcurve( O_pwlcurve
*o_pwlcurve
)
454 o_pwlcurve
->deleteMe( o_pwlcurvePool
);
458 NurbsTessellator::do_freebgncurve( O_curve
*o_curve
)
460 o_curve
->deleteMe( o_curvePool
);
463 /*-----------------------------------------------------------------------------
464 * do_pwlcurve - link in pwl trim loop to the current surface description
467 *-----------------------------------------------------------------------------
470 NurbsTessellator::do_pwlcurve( O_pwlcurve
*o_pwlcurve
)
474 if( o_pwlcurve
->save
== 0 )
475 do_freepwlcurve(o_pwlcurve
);
484 if( o_pwlcurve
->used
) {
489 o_pwlcurve
->used
= 1;
491 if( currentCurve
->curvetype
== ct_none
) {
492 currentCurve
->curvetype
= ct_pwlcurve
;
493 } else if( currentCurve
->curvetype
!= ct_pwlcurve
) {
499 if( *nextPwlcurve
!= o_pwlcurve
) {
501 *nextPwlcurve
= o_pwlcurve
;
503 nextPwlcurve
= &(o_pwlcurve
->next
);
505 if( o_pwlcurve
->owner
!= currentCurve
) {
507 o_pwlcurve
->owner
= currentCurve
;
515 /*-----------------------------------------------------------------------------
516 * do_freenurbscurve -
519 *-----------------------------------------------------------------------------
522 NurbsTessellator::do_freenurbscurve( O_nurbscurve
*o_nurbscurve
)
524 o_nurbscurve
->bezier_curves
->deleteMe( quiltPool
);
525 o_nurbscurve
->deleteMe( o_nurbscurvePool
);
529 /*-----------------------------------------------------------------------------
532 * Client: nurbscurve()
533 *-----------------------------------------------------------------------------
536 NurbsTessellator::do_nurbscurve( O_nurbscurve
*o_nurbscurve
)
543 if( o_nurbscurve
->used
) {
544 /* error - curve was already called in current surface */
549 o_nurbscurve
->used
= 1;
551 if( currentCurve
->curvetype
== ct_none
) {
552 currentCurve
->curvetype
= ct_nurbscurve
;
553 } else if( currentCurve
->curvetype
!= ct_nurbscurve
) {
559 if( *nextNurbscurve
!= o_nurbscurve
) {
561 *nextNurbscurve
= o_nurbscurve
;
564 nextNurbscurve
= &(o_nurbscurve
->next
);
566 if( o_nurbscurve
->owner
!= currentCurve
) {
568 o_nurbscurve
->owner
= currentCurve
;
571 if( o_nurbscurve
->owner
== 0 )
579 /*-----------------------------------------------------------------------------
580 * do_freenurbssurface -
583 *-----------------------------------------------------------------------------
587 NurbsTessellator::do_freenurbssurface( O_nurbssurface
*o_nurbssurface
)
589 o_nurbssurface
->bezier_patches
->deleteMe( quiltPool
);
590 o_nurbssurface
->deleteMe( o_nurbssurfacePool
);
593 /*-----------------------------------------------------------------------------
596 * Client: nurbssurface()
597 *-----------------------------------------------------------------------------
600 NurbsTessellator::do_nurbssurface( O_nurbssurface
*o_nurbssurface
)
607 if( o_nurbssurface
->used
) {
608 /* error - surface was already called in current block */
613 o_nurbssurface
->used
= 1;
615 if( *nextNurbssurface
!= o_nurbssurface
) {
616 isSurfaceModified
= 1;
617 *nextNurbssurface
= o_nurbssurface
;
620 if( o_nurbssurface
->owner
!= currentSurface
) {
621 isSurfaceModified
= 1;
622 o_nurbssurface
->owner
= currentSurface
;
624 nextNurbssurface
= &(o_nurbssurface
->next
);
631 /*-----------------------------------------------------------------------------
632 * do_freenurbsproperty
634 *-----------------------------------------------------------------------------
638 NurbsTessellator::do_freenurbsproperty( Property
*prop
)
640 prop
->deleteMe( propertyPool
);
644 /*-----------------------------------------------------------------------------
645 * do_setnurbsproperty -
647 *-----------------------------------------------------------------------------
651 NurbsTessellator::do_setnurbsproperty( Property
*prop
)
653 renderhints
.setProperty( prop
->tag
, prop
->value
);
654 if( prop
->save
== 0 )
655 do_freenurbsproperty( prop
);
659 NurbsTessellator::do_setnurbsproperty2( Property
*prop
)
661 Mapdesc
*mapdesc
= maplist
.find( prop
->type
);
663 mapdesc
->setProperty( prop
->tag
, prop
->value
);
664 if( prop
->save
== 0 )
665 do_freenurbsproperty( prop
);
669 NurbsTessellator::errorHandler( int )
674 NurbsTessellator::do_nurbserror( int msg
)
680 NurbsTessellator::do_check_knots( Knotvector
*knots
, char *msg
)
682 int status
= knots
->validate();
684 do_nurbserror( status
);
685 if( renderhints
.errorchecking
!= N_NOMSG
) knots
->show( msg
);