| /* |
| ** License Applicability. Except to the extent portions of this file are |
| ** made subject to an alternative license as permitted in the SGI Free |
| ** Software License B, Version 1.1 (the "License"), the contents of this |
| ** file are subject only to the provisions of the License. You may not use |
| ** this file except in compliance with the License. You may obtain a copy |
| ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 |
| ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: |
| ** |
| ** http://oss.sgi.com/projects/FreeB |
| ** |
| ** Note that, as provided in the License, the Software is distributed on an |
| ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS |
| ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND |
| ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A |
| ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. |
| ** |
| ** Original Code. The Original Code is: OpenGL Sample Implementation, |
| ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, |
| ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. |
| ** Copyright in any portions created by third parties is as indicated |
| ** elsewhere herein. All Rights Reserved. |
| ** |
| ** Additional Notice Provisions: The application programming interfaces |
| ** established by SGI in conjunction with the Original Code are The |
| ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released |
| ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version |
| ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X |
| ** Window System(R) (Version 1.3), released October 19, 1998. This software |
| ** was created using the OpenGL(R) version 1.2.1 Sample Implementation |
| ** published by SGI, but has not been independently verified as being |
| ** compliant with the OpenGL(R) version 1.2.1 Specification. |
| */ |
| |
| /* |
| * nurbstess.c++ |
| * |
| * $Date: 2012/03/29 17:22:17 $ $Revision: 1.1.1.1 $ |
| * $Header: /cvs/bao-parsec/pkgs/libs/mesa/src/src/glu/sgi/libnurbs/internals/nurbstess.cc,v 1.1.1.1 2012/03/29 17:22:17 uid42307 Exp $ |
| */ |
| |
| #include "glimports.h" |
| #include "myassert.h" |
| #include "mysetjmp.h" |
| #include "mystdio.h" |
| #include "nurbsconsts.h" |
| #include "nurbstess.h" |
| #include "bufpool.h" |
| #include "quilt.h" |
| #include "knotvector.h" |
| #include "mapdesc.h" |
| #include "maplist.h" |
| |
| void |
| NurbsTessellator::set_domain_distance_u_rate(REAL u_rate) |
| { |
| subdivider.set_domain_distance_u_rate(u_rate); |
| } |
| |
| void |
| NurbsTessellator::set_domain_distance_v_rate(REAL v_rate) |
| { |
| subdivider.set_domain_distance_v_rate(v_rate); |
| } |
| |
| void |
| NurbsTessellator::set_is_domain_distance_sampling(int flag) |
| { |
| subdivider.set_is_domain_distance_sampling(flag); |
| } |
| |
| void |
| NurbsTessellator::resetObjects( void ) |
| { |
| subdivider.clear(); |
| } |
| |
| void |
| NurbsTessellator::makeobj( int ) |
| { |
| #ifndef NDEBUG |
| _glu_dprintf( "makeobj\n" ); |
| #endif |
| } |
| |
| void |
| NurbsTessellator::closeobj( void ) |
| { |
| #ifndef NDEBUG |
| _glu_dprintf( "closeobj\n" ); |
| #endif |
| } |
| |
| void |
| NurbsTessellator::bgnrender( void ) |
| { |
| #ifndef NDEBUG |
| _glu_dprintf( "bgnrender\n" ); |
| #endif |
| } |
| |
| void |
| NurbsTessellator::endrender( void ) |
| { |
| #ifndef NDEBUG |
| _glu_dprintf( "endrender\n" ); |
| #endif |
| } |
| |
| /*----------------------------------------------------------------------------- |
| * do_freebgnsurface - free o_surface structure |
| * |
| * Client: do_freeall(), bgnsurface() |
| *----------------------------------------------------------------------------- |
| */ |
| void |
| NurbsTessellator::do_freebgnsurface( O_surface *o_surface ) |
| { |
| o_surface->deleteMe( o_surfacePool ); |
| } |
| |
| |
| /*----------------------------------------------------------------------------- |
| * do_bgnsurface - begin the display of a surface |
| * |
| * Client: bgnsurface() |
| *----------------------------------------------------------------------------- |
| */ |
| void |
| NurbsTessellator::do_bgnsurface( O_surface *o_surface ) |
| { |
| if( inSurface ) { |
| do_nurbserror( 27 ); |
| endsurface(); |
| } |
| inSurface = 1; |
| |
| if( ! playBack ) bgnrender(); |
| |
| isTrimModified = 0; |
| isSurfaceModified = 0; |
| isDataValid = 1; |
| numTrims = 0; |
| currentSurface = o_surface; |
| nextTrim = &( currentSurface->o_trim ); |
| nextNurbssurface = &( currentSurface->o_nurbssurface ); |
| } |
| |
| /*----------------------------------------------------------------------------- |
| * do_bgncurve - begin the display of a curve |
| * |
| * Client: bgncurve() |
| *----------------------------------------------------------------------------- |
| */ |
| void |
| NurbsTessellator::do_bgncurve( O_curve *o_curve ) |
| { |
| if ( inCurve ) { |
| do_nurbserror( 6 ); |
| endcurve(); |
| } |
| |
| inCurve = 1; |
| currentCurve = o_curve; |
| currentCurve->curvetype = ct_none; |
| |
| if( inTrim ) { |
| if( *nextCurve != o_curve ) { |
| isCurveModified = 1; |
| *nextCurve = o_curve; |
| } |
| } else { |
| if( ! playBack ) bgnrender(); |
| isDataValid = 1; |
| } |
| nextCurve = &(o_curve->next); |
| nextPwlcurve = &(o_curve->curve.o_pwlcurve); |
| nextNurbscurve = &(o_curve->curve.o_nurbscurve); |
| } |
| |
| /*----------------------------------------------------------------------------- |
| * do_endcurve - |
| * |
| * Client: endcurve() |
| *----------------------------------------------------------------------------- |
| */ |
| |
| void |
| NurbsTessellator::do_endcurve( void ) |
| { |
| if( ! inCurve ) { |
| do_nurbserror( 7 ); |
| return; |
| } |
| inCurve = 0; |
| |
| *nextCurve = 0; |
| if (currentCurve->curvetype == ct_nurbscurve) |
| *nextNurbscurve = 0; |
| else |
| *nextPwlcurve = 0; |
| |
| if ( ! inTrim ) { |
| if( ! isDataValid ) { |
| do_freecurveall( currentCurve ); |
| return; |
| } |
| |
| int errval; |
| errval = ::mysetjmp( jumpbuffer ); |
| if( errval == 0 ) { |
| if( currentCurve->curvetype == ct_nurbscurve ) { |
| subdivider.beginQuilts(); |
| for( O_nurbscurve *n = currentCurve->curve.o_nurbscurve; n != 0; n = n->next ) |
| subdivider.addQuilt( n->bezier_curves ); |
| subdivider.endQuilts(); |
| subdivider.drawCurves(); |
| if( ! playBack ) endrender(); |
| } else { |
| /* XXX */ |
| if( ! playBack ) endrender(); |
| /*do_draw_pwlcurve( currentCurve->curve.o_pwlcurve ) */; |
| do_nurbserror( 9 ); |
| } |
| } else { |
| if( ! playBack ) endrender(); |
| do_nurbserror( errval ); |
| } |
| do_freecurveall( currentCurve ); |
| resetObjects(); |
| } |
| } |
| |
| /*----------------------------------------------------------------------------- |
| * do_endsurface - mark end of surface, display surface, free immediate data |
| * |
| * Client: |
| *----------------------------------------------------------------------------- |
| */ |
| void |
| NurbsTessellator::do_endsurface( void ) |
| { |
| if( inTrim ) { |
| do_nurbserror( 12 ); |
| endtrim(); |
| } |
| |
| if( ! inSurface ) { |
| do_nurbserror( 13 ); |
| return; |
| } |
| inSurface = 0; |
| |
| *nextNurbssurface = 0; |
| |
| if( ! isDataValid ) { |
| do_freeall( ); |
| return; |
| } |
| |
| if( *nextTrim != 0 ) { |
| isTrimModified = 1; |
| *nextTrim = 0; |
| } |
| |
| int errval; |
| |
| errval = ::mysetjmp( jumpbuffer ); |
| if( errval == 0 ) { |
| if( numTrims > 0 ) { |
| |
| subdivider.beginTrims(); |
| for( O_trim *trim = currentSurface->o_trim; trim; trim = trim->next ) { |
| subdivider.beginLoop(); |
| for( O_curve *curve = trim->o_curve; curve; curve = curve->next ) { |
| curve->used = 0; |
| assert( curve->curvetype != ct_none ); |
| if (curve->curvetype == ct_pwlcurve) { |
| O_pwlcurve *c = curve->curve.o_pwlcurve; |
| subdivider.addArc( c->npts, c->pts, curve->nuid ); |
| } else { |
| Quilt *quilt = curve->curve.o_nurbscurve->bezier_curves; |
| Quiltspec *qspec = quilt->qspec; |
| REAL *cpts = quilt->cpts + qspec->offset; |
| REAL *cptsend = cpts + (qspec->width * qspec->order * qspec->stride); |
| for( ; cpts != cptsend; cpts += qspec->order*qspec->stride ) |
| subdivider.addArc( cpts, quilt, curve->nuid ); |
| } |
| } |
| subdivider.endLoop(); |
| } |
| subdivider.endTrims(); |
| } |
| |
| subdivider.beginQuilts(); |
| for( O_nurbssurface *n = currentSurface->o_nurbssurface; n; n = n->next ) |
| subdivider.addQuilt( n->bezier_patches ); |
| subdivider.endQuilts(); |
| subdivider.drawSurfaces( currentSurface->nuid ); |
| if( ! playBack ) endrender(); |
| } else { |
| if( ! playBack ) endrender(); |
| do_nurbserror( errval ); |
| } |
| |
| do_freeall( ); |
| resetObjects(); |
| } |
| |
| /*----------------------------------------------------------------------------- |
| * do_freeall - free all data allocated in immediate mode |
| * |
| * Client: |
| *----------------------------------------------------------------------------- |
| */ |
| void |
| NurbsTessellator::do_freeall( void ) |
| { |
| for( O_trim *o_trim = currentSurface->o_trim; o_trim; ) { |
| O_trim *next_o_trim = o_trim->next; |
| for( O_curve *curve = o_trim->o_curve; curve; ) { |
| O_curve *next_o_curve = curve->next; |
| do_freecurveall( curve ); |
| curve = next_o_curve; |
| } |
| if( o_trim->save == 0 ) do_freebgntrim( o_trim ); |
| o_trim = next_o_trim; |
| } |
| |
| O_nurbssurface *nurbss, *next_nurbss; |
| for( nurbss= currentSurface->o_nurbssurface; nurbss; nurbss = next_nurbss) { |
| next_nurbss = nurbss->next; |
| if( nurbss->save == 0 ) |
| do_freenurbssurface( nurbss ); |
| else |
| nurbss->used = 0; |
| } |
| |
| if( currentSurface->save == 0 ) do_freebgnsurface( currentSurface ); |
| } |
| |
| void |
| NurbsTessellator::do_freecurveall( O_curve *curve ) |
| { |
| assert( curve->curvetype != ct_none ); |
| |
| if( curve->curvetype == ct_nurbscurve ) { |
| O_nurbscurve *ncurve, *next_ncurve; |
| for( ncurve=curve->curve.o_nurbscurve; ncurve; ncurve=next_ncurve ) { |
| next_ncurve = ncurve->next; |
| if( ncurve->save == 0 ) |
| do_freenurbscurve( ncurve ); |
| else |
| ncurve->used = 0; |
| } |
| } else { |
| O_pwlcurve *pcurve, *next_pcurve; |
| for( pcurve=curve->curve.o_pwlcurve; pcurve; pcurve=next_pcurve ) { |
| next_pcurve = pcurve->next; |
| if( pcurve->save == 0 ) |
| do_freepwlcurve( pcurve ); |
| else |
| pcurve->used = 0; |
| } |
| } |
| if( curve->save == 0 ) |
| do_freebgncurve( curve ); |
| } |
| |
| |
| /*----------------------------------------------------------------------------- |
| * do_freebgntrim - free the space allocated for a trim loop |
| * |
| * Client: |
| *----------------------------------------------------------------------------- |
| */ |
| void |
| NurbsTessellator::do_freebgntrim( O_trim *o_trim ) |
| { |
| o_trim->deleteMe( o_trimPool ); |
| } |
| |
| |
| /*----------------------------------------------------------------------------- |
| * do_bgntrim - link in a trim loop to the current trimmed surface description |
| * |
| * Client: bgntrim() |
| *----------------------------------------------------------------------------- |
| */ |
| void |
| NurbsTessellator::do_bgntrim( O_trim *o_trim ) |
| { |
| |
| if( ! inSurface ) { |
| do_nurbserror( 15 ); |
| bgnsurface( 0 ); |
| inSurface = 2; |
| } |
| |
| if( inTrim ) { |
| do_nurbserror( 16 ); |
| endtrim(); |
| } |
| inTrim = 1; |
| |
| if( *nextTrim != o_trim ) { |
| isTrimModified = 1; |
| *nextTrim = o_trim; |
| } |
| |
| currentTrim = o_trim; |
| nextTrim = &(o_trim->next); |
| nextCurve = &(o_trim->o_curve); |
| } |
| |
| |
| /*----------------------------------------------------------------------------- |
| * do_endtrim - mark the end of the current trim loop |
| * |
| * Client: endtrim() |
| *----------------------------------------------------------------------------- |
| */ |
| void |
| NurbsTessellator::do_endtrim( void ) |
| { |
| if( ! inTrim ) { |
| do_nurbserror( 17 ); |
| return; |
| } |
| inTrim = 0; |
| |
| if( currentTrim->o_curve == 0 ) { |
| do_nurbserror( 18 ); |
| isDataValid = 0; |
| } |
| |
| numTrims++; |
| |
| if( *nextCurve != 0 ) { |
| isTrimModified = 1; |
| *nextCurve = 0; |
| } |
| } |
| |
| /*----------------------------------------------------------------------------- |
| * do_freepwlcurve - |
| * |
| * Client: |
| *----------------------------------------------------------------------------- |
| */ |
| void |
| NurbsTessellator::do_freepwlcurve( O_pwlcurve *o_pwlcurve ) |
| { |
| o_pwlcurve->deleteMe( o_pwlcurvePool ); |
| } |
| |
| void |
| NurbsTessellator::do_freebgncurve( O_curve *o_curve ) |
| { |
| o_curve->deleteMe( o_curvePool ); |
| } |
| |
| /*----------------------------------------------------------------------------- |
| * do_pwlcurve - link in pwl trim loop to the current surface description |
| * |
| * Client: pwlcurve() |
| *----------------------------------------------------------------------------- |
| */ |
| void |
| NurbsTessellator::do_pwlcurve( O_pwlcurve *o_pwlcurve ) |
| { |
| if( ! inTrim ) { |
| do_nurbserror( 19 ); |
| if( o_pwlcurve->save == 0 ) |
| do_freepwlcurve(o_pwlcurve ); |
| return; |
| } |
| |
| if( ! inCurve ) { |
| bgncurve( 0 ); |
| inCurve = 2; |
| } |
| |
| if( o_pwlcurve->used ) { |
| do_nurbserror( 20 ); |
| isDataValid = 0; |
| return; |
| } else |
| o_pwlcurve->used = 1; |
| |
| if( currentCurve->curvetype == ct_none ) { |
| currentCurve->curvetype = ct_pwlcurve; |
| } else if( currentCurve->curvetype != ct_pwlcurve ) { |
| do_nurbserror( 21 ); |
| isDataValid = 0; |
| return; |
| } |
| |
| if( *nextPwlcurve != o_pwlcurve ) { |
| isCurveModified = 1; |
| *nextPwlcurve = o_pwlcurve; |
| } |
| nextPwlcurve = &(o_pwlcurve->next); |
| |
| if( o_pwlcurve->owner != currentCurve ) { |
| isCurveModified = 1; |
| o_pwlcurve->owner = currentCurve; |
| } |
| |
| if( (inCurve == 2) ) |
| endcurve(); |
| } |
| |
| |
| /*----------------------------------------------------------------------------- |
| * do_freenurbscurve - |
| * |
| * Client: |
| *----------------------------------------------------------------------------- |
| */ |
| void |
| NurbsTessellator::do_freenurbscurve( O_nurbscurve *o_nurbscurve ) |
| { |
| o_nurbscurve->bezier_curves->deleteMe( quiltPool ); |
| o_nurbscurve->deleteMe( o_nurbscurvePool ); |
| } |
| |
| |
| /*----------------------------------------------------------------------------- |
| * do_nurbscurve - |
| * |
| * Client: nurbscurve() |
| *----------------------------------------------------------------------------- |
| */ |
| void |
| NurbsTessellator::do_nurbscurve( O_nurbscurve *o_nurbscurve ) |
| { |
| if ( ! inCurve ) { |
| bgncurve( 0 ); |
| inCurve = 2; |
| } |
| |
| if( o_nurbscurve->used ) { |
| /* error - curve was already called in current surface */ |
| do_nurbserror( 23 ); |
| isDataValid = 0; |
| return; |
| } else |
| o_nurbscurve->used = 1; |
| |
| if( currentCurve->curvetype == ct_none ) { |
| currentCurve->curvetype = ct_nurbscurve; |
| } else if( currentCurve->curvetype != ct_nurbscurve ) { |
| do_nurbserror( 24 ); |
| isDataValid = 0; |
| return; |
| } |
| |
| if( *nextNurbscurve != o_nurbscurve ) { |
| isCurveModified = 1; |
| *nextNurbscurve = o_nurbscurve; |
| } |
| |
| nextNurbscurve = &(o_nurbscurve->next); |
| |
| if( o_nurbscurve->owner != currentCurve ) { |
| isCurveModified = 1; |
| o_nurbscurve->owner = currentCurve; |
| } |
| |
| if( o_nurbscurve->owner == 0 ) |
| isCurveModified = 1; |
| |
| if( inCurve == 2 ) |
| endcurve(); |
| } |
| |
| |
| /*----------------------------------------------------------------------------- |
| * do_freenurbssurface - |
| * |
| * Client: |
| *----------------------------------------------------------------------------- |
| */ |
| |
| void |
| NurbsTessellator::do_freenurbssurface( O_nurbssurface *o_nurbssurface ) |
| { |
| o_nurbssurface->bezier_patches->deleteMe( quiltPool ); |
| o_nurbssurface->deleteMe( o_nurbssurfacePool ); |
| } |
| |
| /*----------------------------------------------------------------------------- |
| * do_nurbssurface - |
| * |
| * Client: nurbssurface() |
| *----------------------------------------------------------------------------- |
| */ |
| void |
| NurbsTessellator::do_nurbssurface( O_nurbssurface *o_nurbssurface ) |
| { |
| if( ! inSurface ) { |
| bgnsurface( 0 ); |
| inSurface = 2; |
| } |
| |
| if( o_nurbssurface->used ) { |
| /* error - surface was already called in current block */ |
| do_nurbserror( 25 ); |
| isDataValid = 0; |
| return; |
| } else |
| o_nurbssurface->used = 1; |
| |
| if( *nextNurbssurface != o_nurbssurface ) { |
| isSurfaceModified = 1; |
| *nextNurbssurface = o_nurbssurface; |
| } |
| |
| if( o_nurbssurface->owner != currentSurface ) { |
| isSurfaceModified = 1; |
| o_nurbssurface->owner = currentSurface; |
| } |
| nextNurbssurface = &(o_nurbssurface->next); |
| |
| if( inSurface == 2 ) |
| endsurface(); |
| } |
| |
| |
| /*----------------------------------------------------------------------------- |
| * do_freenurbsproperty |
| * |
| *----------------------------------------------------------------------------- |
| */ |
| |
| void |
| NurbsTessellator::do_freenurbsproperty( Property *prop ) |
| { |
| prop->deleteMe( propertyPool ); |
| } |
| |
| |
| /*----------------------------------------------------------------------------- |
| * do_setnurbsproperty - |
| * |
| *----------------------------------------------------------------------------- |
| */ |
| |
| void |
| NurbsTessellator::do_setnurbsproperty( Property *prop ) |
| { |
| renderhints.setProperty( prop->tag, prop->value ); |
| if( prop->save == 0 ) |
| do_freenurbsproperty( prop ); |
| } |
| |
| void |
| NurbsTessellator::do_setnurbsproperty2( Property *prop ) |
| { |
| Mapdesc *mapdesc = maplist.find( prop->type ); |
| |
| mapdesc->setProperty( prop->tag, prop->value ); |
| if( prop->save == 0 ) |
| do_freenurbsproperty( prop ); |
| } |
| |
| void |
| NurbsTessellator::errorHandler( int ) |
| { |
| } |
| |
| void |
| NurbsTessellator::do_nurbserror( int msg ) |
| { |
| errorHandler( msg ); |
| } |
| |
| int |
| NurbsTessellator::do_check_knots( Knotvector *knots, const char *msg ) |
| { |
| int status = knots->validate(); |
| if( status ) { |
| do_nurbserror( status ); |
| if( renderhints.errorchecking != N_NOMSG ) knots->show( msg ); |
| } |
| return status; |
| } |
| |
| |
| |
| |
| |