📄 nurbsinterfac.cc
字号:
/*** 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 *----------------------------------------------------------------------------- */voidNurbsTessellator::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 *----------------------------------------------------------------------------- */voidNurbsTessellator::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: *----------------------------------------------------------------------------- */voidNurbsTessellator::endcurve( void ){ THREAD2( do_endcurve );}/*----------------------------------------------------------------------------- * endsurface - user level end of surface call * * Client: GL user *----------------------------------------------------------------------------- */voidNurbsTessellator::endsurface( void ){ THREAD2( do_endsurface );}/*----------------------------------------------------------------------------- * bgntrim - allocate and initialize a new trim loop structure (o_trim ) * * Client: GL user *----------------------------------------------------------------------------- */voidNurbsTessellator::bgntrim( void ){ O_trim *o_trim = new(o_trimPool) O_trim; THREAD( do_bgntrim, o_trim, do_freebgntrim );}/*----------------------------------------------------------------------------- * endtrim - * * Client: GL user *----------------------------------------------------------------------------- */voidNurbsTessellator::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 *----------------------------------------------------------------------------- */voidNurbsTessellator::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 *----------------------------------------------------------------------------- */voidNurbsTessellator::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 *----------------------------------------------------------------------------- */voidNurbsTessellator::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 - * *----------------------------------------------------------------------------- */voidNurbsTessellator::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 - * *----------------------------------------------------------------------------- */voidNurbsTessellator::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 - * *----------------------------------------------------------------------------- */voidNurbsTessellator::getnurbsproperty( long tag, INREAL *value ){ if( renderhints.isProperty( tag ) ) { *value = renderhints.getProperty( tag ); } else { do_nurbserror( 26 ); }}/*----------------------------------------------------------------------------- * getnurbsproperty - * *----------------------------------------------------------------------------- */voidNurbsTessellator::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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -