aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glu/sgi/libnurbs/internals/nurbsinterfac.cc
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/glu/sgi/libnurbs/internals/nurbsinterfac.cc')
-rw-r--r--mesalib/src/glu/sgi/libnurbs/internals/nurbsinterfac.cc537
1 files changed, 537 insertions, 0 deletions
diff --git a/mesalib/src/glu/sgi/libnurbs/internals/nurbsinterfac.cc b/mesalib/src/glu/sgi/libnurbs/internals/nurbsinterfac.cc
new file mode 100644
index 000000000..520bd419e
--- /dev/null
+++ b/mesalib/src/glu/sgi/libnurbs/internals/nurbsinterfac.cc
@@ -0,0 +1,537 @@
+/*
+** 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.
+*/
+
+/*
+ * nurbsinterfac.c++
+ *
+ */
+
+#include "glimports.h"
+#include "mystdio.h"
+#include "nurbsconsts.h"
+#include "nurbstess.h"
+#include "bufpool.h"
+#include "quilt.h"
+#include "displaylist.h"
+#include "knotvector.h"
+#include "mapdesc.h"
+
+#define THREAD( work, arg, cleanup ) \
+ if( dl ) {\
+ arg->save = 1;\
+ dl->append( (PFVS)&NurbsTessellator::work, (void *) arg, (PFVS)&NurbsTessellator::cleanup );\
+ } else {\
+ arg->save = 0;\
+ work( arg );\
+ }
+
+#define THREAD2( work ) \
+ if( dl ) {\
+ dl->append( (PFVS)&NurbsTessellator::work, 0, 0 );\
+ } else {\
+ work( );\
+ }
+
+NurbsTessellator::NurbsTessellator( BasicCurveEvaluator &c, BasicSurfaceEvaluator& e)
+ : maplist( backend ),
+ backend( c, e ),
+ subdivider( renderhints, backend ),
+ o_pwlcurvePool( sizeof( O_pwlcurve ), 32, "o_pwlcurvePool" ),
+ o_nurbscurvePool( sizeof( O_nurbscurve ), 32, "o_nurbscurvePool"),
+ o_curvePool( sizeof( O_curve ), 32, "o_curvePool" ),
+ o_trimPool( sizeof( O_trim ), 32, "o_trimPool" ),
+ o_surfacePool( sizeof( O_surface ), 1, "o_surfacePool" ),
+ o_nurbssurfacePool( sizeof( O_nurbssurface ), 4, "o_nurbssurfacePool" ),
+ propertyPool( sizeof( Property ), 32, "propertyPool" ),
+ quiltPool( sizeof( Quilt ), 32, "quiltPool" )
+{
+ dl = 0;
+ inSurface = 0;
+ inCurve = 0;
+ inTrim = 0;
+ playBack = 0;
+ jumpbuffer = newJumpbuffer();
+ subdivider.setJumpbuffer( jumpbuffer );
+}
+
+NurbsTessellator::~NurbsTessellator( void )
+{
+ if( inTrim ) {
+ do_nurbserror( 12 );
+ endtrim();
+ }
+
+ if( inSurface ) {
+ *nextNurbssurface = 0;
+ do_freeall();
+ }
+
+ if (jumpbuffer) {
+ deleteJumpbuffer(jumpbuffer);
+ jumpbuffer= 0;
+ }
+}
+
+/*-----------------------------------------------------------------------------
+ * bgnsurface - allocate and initialize an o_surface structure
+ *
+ * Client: GL user
+ *-----------------------------------------------------------------------------
+ */
+void
+NurbsTessellator::bgnsurface( long nuid )
+{
+ O_surface *o_surface = new(o_surfacePool) O_surface;
+ o_surface->nuid = nuid;
+ THREAD( do_bgnsurface, o_surface, do_freebgnsurface );
+}
+
+/*-----------------------------------------------------------------------------
+ * bgncurve - allocate an initialize an o_curve structure
+ *
+ * Client: GL user
+ *-----------------------------------------------------------------------------
+ */
+void
+NurbsTessellator::bgncurve( long nuid )
+{
+ O_curve *o_curve = new(o_curvePool) O_curve;
+ o_curve->nuid = nuid;
+ THREAD( do_bgncurve, o_curve, do_freebgncurve );
+}
+/*-----------------------------------------------------------------------------
+ * endcurve -
+ *
+ * Client:
+ *-----------------------------------------------------------------------------
+ */
+
+void
+NurbsTessellator::endcurve( void )
+{
+ THREAD2( do_endcurve );
+}
+
+/*-----------------------------------------------------------------------------
+ * endsurface - user level end of surface call
+ *
+ * Client: GL user
+ *-----------------------------------------------------------------------------
+ */
+void
+NurbsTessellator::endsurface( void )
+{
+ THREAD2( do_endsurface );
+}
+
+
+/*-----------------------------------------------------------------------------
+ * bgntrim - allocate and initialize a new trim loop structure (o_trim )
+ *
+ * Client: GL user
+ *-----------------------------------------------------------------------------
+ */
+void
+NurbsTessellator::bgntrim( void )
+{
+ O_trim *o_trim = new(o_trimPool) O_trim;
+ THREAD( do_bgntrim, o_trim, do_freebgntrim );
+}
+
+/*-----------------------------------------------------------------------------
+ * endtrim -
+ *
+ * Client: GL user
+ *-----------------------------------------------------------------------------
+ */
+void
+NurbsTessellator::endtrim( void )
+{
+ THREAD2( do_endtrim );
+}
+
+
+/*-----------------------------------------------------------------------------
+ * pwlcurve -
+ *
+ * count - number of points on curve
+ * array - array of points on curve
+ * byte_stride - distance between points in bytes
+ * type - valid data flag
+ *
+ * Client: Gl user
+ *-----------------------------------------------------------------------------
+ */
+void
+NurbsTessellator::pwlcurve( long count, INREAL array[], long byte_stride, long type )
+{
+ Mapdesc *mapdesc = maplist.locate( type );
+
+ if( mapdesc == 0 ) {
+ do_nurbserror( 35 );
+ isDataValid = 0;
+ return;
+ }
+
+ if ( (type != N_P2D) && (type != N_P2DR) ) {
+ do_nurbserror( 22 );
+ isDataValid = 0;
+ return;
+ }
+ if( count < 0 ) {
+ do_nurbserror( 33 );
+ isDataValid = 0;
+ return;
+ }
+ if( byte_stride < 0 ) {
+ do_nurbserror( 34 );
+ isDataValid = 0;
+ return;
+ }
+
+#ifdef NOTDEF
+ if( mapdesc->isRational() ) {
+ INREAL *p = array;
+ INREAL x = p[0]; INREAL y = p[1]; INREAL w = p[2];
+ p = (INREAL *) (((char *) p) + byte_stride);
+ for( long i = 1; i != count; i++ ) {
+ if( p[0] == x && p[1] == y && p[2] == w ) break;
+ x = p[0]; y = p[1]; w = p[2];
+ p = (INREAL *) (((char *) p) + byte_stride);
+ }
+ if( i != count ) {
+ do_nurbserror( 37 );
+ _glu_dprintf( "point %d (%f,%f)\n", i, x, y );
+ isDataValid = 0;
+ return;
+ }
+ } else {
+ INREAL *p = array;
+ INREAL x = p[0]; INREAL y = p[1];
+ p = (INREAL *) (((char *) p) + byte_stride);
+ for( long i = 1; i != count; i++ ) {
+ if( p[0] == x && p[1] == y ) break;
+ x = p[0]; y = p[1];
+ p = (INREAL *) (((char *) p) + byte_stride);
+ }
+ if( i != count ) {
+ do_nurbserror( 37 );
+ _glu_dprintf( "point %d (%f,%f)\n", i, x, y );
+ isDataValid = 0;
+ return;
+ }
+ }
+#endif
+
+ O_pwlcurve *o_pwlcurve = new(o_pwlcurvePool) O_pwlcurve( type, count, array, byte_stride, extTrimVertexPool.get((int)count) );
+ THREAD( do_pwlcurve, o_pwlcurve, do_freepwlcurve );
+}
+
+
+/*-----------------------------------------------------------------------------
+ * nurbscurve -
+ *
+ * Client: GL user
+ *-----------------------------------------------------------------------------
+ */
+void
+NurbsTessellator::nurbscurve(
+ long nknots, /* number of p knots */
+ INREAL knot[], /* nondecreasing knot values in p */
+ long byte_stride, /* distance in bytes between control points */
+ INREAL ctlarray[], /* pointer to first control point */
+ long order, /* order of spline */
+ long type ) /* description of range space */
+{
+
+ Mapdesc *mapdesc = maplist.locate( type );
+
+ if( mapdesc == 0 ) {
+ do_nurbserror( 35 );
+ isDataValid = 0;
+ return;
+ }
+
+ if( ctlarray == 0 ) {
+ do_nurbserror( 36 );
+ isDataValid = 0;
+ return;
+ }
+
+ if( byte_stride < 0 ) {
+ do_nurbserror( 34 );
+ isDataValid = 0;
+ return;
+ }
+
+ Knotvector knots;
+
+ knots.init( nknots, byte_stride, order, knot );
+ if( do_check_knots( &knots, "curve" ) ) return;
+
+ O_nurbscurve *o_nurbscurve = new(o_nurbscurvePool) O_nurbscurve(type);
+ o_nurbscurve->bezier_curves = new(quiltPool) Quilt(mapdesc);
+ o_nurbscurve->bezier_curves->toBezier( knots,ctlarray, mapdesc->getNcoords() );
+
+ THREAD( do_nurbscurve, o_nurbscurve, do_freenurbscurve );
+}
+
+
+/*-----------------------------------------------------------------------------
+ * nurbssurface -
+ *
+ * Client: User routine
+ *-----------------------------------------------------------------------------
+ */
+void
+NurbsTessellator::nurbssurface(
+ long sknot_count, /* number of s knots */
+ INREAL sknot[], /* nondecreasing knot values in s */
+ long tknot_count, /* number of t knots */
+ INREAL tknot[], /* nondecreasing knot values in t */
+ long s_byte_stride, /* s step size in memory bytes */
+ long t_byte_stride, /* t step size in memory bytes */
+ INREAL ctlarray[], /* pointer to first control point */
+ long sorder, /* order of the spline in s parameter */
+ long torder, /* order of the spline in t parameter */
+ long type) /* description of range space */
+{
+ Mapdesc *mapdesc = maplist.locate( type );
+
+ if( mapdesc == 0 ) {
+ do_nurbserror( 35 );
+ isDataValid = 0;
+ return;
+ }
+
+ if( s_byte_stride < 0 ) {
+ do_nurbserror( 34 );
+ isDataValid = 0;
+ return;
+ }
+
+ if( t_byte_stride < 0 ) {
+ do_nurbserror( 34 );
+ isDataValid = 0;
+ return;
+ }
+
+ Knotvector sknotvector, tknotvector;
+
+ sknotvector.init( sknot_count, s_byte_stride, sorder, sknot );
+ if( do_check_knots( &sknotvector, "surface" ) ) return;
+
+ tknotvector.init( tknot_count, t_byte_stride, torder, tknot );
+ if( do_check_knots( &tknotvector, "surface" ) ) return;
+
+ O_nurbssurface *o_nurbssurface = new(o_nurbssurfacePool) O_nurbssurface(type);
+ o_nurbssurface->bezier_patches = new(quiltPool) Quilt(mapdesc);
+
+ o_nurbssurface->bezier_patches->toBezier( sknotvector, tknotvector,
+ ctlarray, mapdesc->getNcoords() );
+ THREAD( do_nurbssurface, o_nurbssurface, do_freenurbssurface );
+}
+
+
+/*-----------------------------------------------------------------------------
+ * setnurbsproperty -
+ *
+ *-----------------------------------------------------------------------------
+ */
+void
+NurbsTessellator::setnurbsproperty( long tag, INREAL value )
+{
+ if( ! renderhints.isProperty( tag ) ) {
+ do_nurbserror( 26 );
+ } else {
+ Property *prop = new(propertyPool) Property( tag, value );
+ THREAD( do_setnurbsproperty, prop, do_freenurbsproperty );
+ }
+}
+
+/*-----------------------------------------------------------------------------
+ * setnurbsproperty -
+ *
+ *-----------------------------------------------------------------------------
+ */
+void
+NurbsTessellator::setnurbsproperty( long type, long tag, INREAL value )
+{
+ Mapdesc *mapdesc = maplist.locate( type );
+
+ if( mapdesc == 0 ) {
+ do_nurbserror( 35 );
+ return;
+ }
+
+ if( ! mapdesc->isProperty( tag ) ) {
+ do_nurbserror( 26 );
+ return;
+ }
+
+ Property *prop = new(propertyPool) Property( type, tag, value );
+ THREAD( do_setnurbsproperty2, prop, do_freenurbsproperty );
+}
+
+
+/*-----------------------------------------------------------------------------
+ * getnurbsproperty -
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+NurbsTessellator::getnurbsproperty( long tag, INREAL *value )
+{
+ if( renderhints.isProperty( tag ) ) {
+ *value = renderhints.getProperty( tag );
+ } else {
+ do_nurbserror( 26 );
+ }
+}
+
+/*-----------------------------------------------------------------------------
+ * getnurbsproperty -
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+NurbsTessellator::getnurbsproperty( long type, long tag, INREAL *value )
+{
+ Mapdesc *mapdesc = maplist.locate( type );
+
+ if( mapdesc == 0 )
+ do_nurbserror( 35 );
+
+ if( mapdesc->isProperty( tag ) ) {
+ *value = mapdesc->getProperty( tag );
+ } else {
+ do_nurbserror( 26 );
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * setnurbsproperty - accept a user supplied matrix as culling or sampling mat
+ *--------------------------------------------------------------------------
+ */
+
+void
+NurbsTessellator::setnurbsproperty( long type, long purpose, INREAL *mat )
+{
+ // XXX - cannot be put in display list
+ Mapdesc *mapdesc = maplist.locate( type );
+
+ if( mapdesc == 0 ) {
+ do_nurbserror( 35 );
+ isDataValid = 0;
+ } else if( purpose == N_BBOXSIZE ) {
+ mapdesc->setBboxsize( mat );
+ } else {
+#ifndef NDEBUG
+ _glu_dprintf( "ERRORRORRORR!!!\n");
+#endif
+ }
+}
+
+/*--------------------------------------------------------------------------
+ * setnurbsproperty - accept a user supplied matrix as culling or sampling mat
+ *--------------------------------------------------------------------------
+ */
+
+void
+NurbsTessellator::setnurbsproperty( long type, long purpose, INREAL *mat,
+ long rstride, long cstride )
+{
+ // XXX - cannot be put in display list
+ Mapdesc *mapdesc = maplist.locate( type );
+
+ if( mapdesc == 0 ) {
+ do_nurbserror( 35 );
+ isDataValid = 0;
+ } else if( purpose == N_CULLINGMATRIX ) {
+ mapdesc->setCmat( mat, rstride, cstride );
+ } else if( purpose == N_SAMPLINGMATRIX ) {
+ mapdesc->setSmat( mat, rstride, cstride );
+ } else if( purpose == N_BBOXMATRIX ) {
+ mapdesc->setBmat( mat, rstride, cstride );
+ } else {
+#ifndef NDEBUG
+ _glu_dprintf( "ERRORRORRORR!!!\n");
+#endif
+ }
+}
+
+void
+NurbsTessellator::redefineMaps( void )
+{
+ maplist.initialize();
+}
+
+void
+NurbsTessellator::defineMap( long type, long rational, long ncoords )
+{
+ maplist.define( type, (int) rational, (int) ncoords );
+}
+
+void
+NurbsTessellator::discardRecording( void *_dl )
+{
+ delete (DisplayList *) _dl;
+}
+
+void *
+NurbsTessellator::beginRecording( void )
+{
+ dl = new DisplayList( this );
+ return (void *) dl;
+}
+
+void
+NurbsTessellator::endRecording( void )
+{
+ dl->endList();
+ dl = 0;
+}
+
+void
+NurbsTessellator::playRecording( void *_dl )
+{
+ playBack = 1;
+ bgnrender();
+ ((DisplayList *)_dl)->play();
+ endrender();
+ playBack = 0;
+}
+