📄 patch.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.*//* * patch.c++ * * $Date: 2006/03/14 15:08:52 $ $Revision: 1.4 $ * $Header: /home/krh/git/sync/mesa-cvs-repo/Mesa/src/glu/sgi/libnurbs/internals/patch.cc,v 1.4 2006/03/14 15:08:52 brianp Exp $ */#include <stdio.h>#include "glimports.h"#include "mystdio.h"#include "myassert.h"#include "mymath.h"#include "mystring.h"#include "patch.h"#include "mapdesc.h"#include "quilt.h"#include "nurbsconsts.h"#include "simplemath.h" //for glu_abs function in ::singleStep();/*-------------------------------------------------------------------------- * Patch - copy patch from quilt and transform control points *-------------------------------------------------------------------------- */Patch::Patch( Quilt_ptr geo, REAL *pta, REAL *ptb, Patch *n ){/* pspec[i].range is uninit here */ mapdesc = geo->mapdesc; cullval = mapdesc->isCulling() ? CULL_ACCEPT : CULL_TRIVIAL_ACCEPT; notInBbox = mapdesc->isBboxSubdividing() ? 1 : 0; needsSampling = mapdesc->isRangeSampling() ? 1 : 0; pspec[0].order = geo->qspec[0].order; pspec[1].order = geo->qspec[1].order; pspec[0].stride = pspec[1].order * MAXCOORDS; pspec[1].stride = MAXCOORDS; /* transform control points to sampling and culling spaces */ REAL *ps = geo->cpts; geo->select( pta, ptb ); ps += geo->qspec[0].offset; ps += geo->qspec[1].offset; ps += geo->qspec[0].index * geo->qspec[0].order * geo->qspec[0].stride; ps += geo->qspec[1].index * geo->qspec[1].order * geo->qspec[1].stride; if( needsSampling ) { mapdesc->xformSampling( ps, geo->qspec[0].order, geo->qspec[0].stride, geo->qspec[1].order, geo->qspec[1].stride, spts, pspec[0].stride, pspec[1].stride ); } if( cullval == CULL_ACCEPT ) { mapdesc->xformCulling( ps, geo->qspec[0].order, geo->qspec[0].stride, geo->qspec[1].order, geo->qspec[1].stride, cpts, pspec[0].stride, pspec[1].stride ); } if( notInBbox ) { mapdesc->xformBounding( ps, geo->qspec[0].order, geo->qspec[0].stride, geo->qspec[1].order, geo->qspec[1].stride, bpts, pspec[0].stride, pspec[1].stride ); } /* set scale range */ pspec[0].range[0] = geo->qspec[0].breakpoints[geo->qspec[0].index]; pspec[0].range[1] = geo->qspec[0].breakpoints[geo->qspec[0].index+1]; pspec[0].range[2] = pspec[0].range[1] - pspec[0].range[0]; pspec[1].range[0] = geo->qspec[1].breakpoints[geo->qspec[1].index]; pspec[1].range[1] = geo->qspec[1].breakpoints[geo->qspec[1].index+1]; pspec[1].range[2] = pspec[1].range[1] - pspec[1].range[0]; // may need to subdivide to match range of sub-patch if( pspec[0].range[0] != pta[0] ) { assert( pspec[0].range[0] < pta[0] ); Patch lower( *this, 0, pta[0], 0 ); *this = lower; } if( pspec[0].range[1] != ptb[0] ) { assert( pspec[0].range[1] > ptb[0] ); Patch upper( *this, 0, ptb[0], 0 ); } if( pspec[1].range[0] != pta[1] ) { assert( pspec[1].range[0] < pta[1] ); Patch lower( *this, 1, pta[1], 0 ); *this = lower; } if( pspec[1].range[1] != ptb[1] ) { assert( pspec[1].range[1] > ptb[1] ); Patch upper( *this, 1, ptb[1], 0 ); } checkBboxConstraint(); next = n;}/*-------------------------------------------------------------------------- * Patch - subdivide a patch along an isoparametric line *-------------------------------------------------------------------------- */Patch::Patch( Patch& upper, int param, REAL value, Patch *n ){ Patch& lower = *this; lower.cullval = upper.cullval; lower.mapdesc = upper.mapdesc; lower.notInBbox = upper.notInBbox; lower.needsSampling = upper.needsSampling; lower.pspec[0].order = upper.pspec[0].order; lower.pspec[1].order = upper.pspec[1].order; lower.pspec[0].stride = upper.pspec[0].stride; lower.pspec[1].stride = upper.pspec[1].stride; lower.next = n; /* reset scale range */ switch( param ) { case 0: { REAL d = (value-upper.pspec[0].range[0]) / upper.pspec[0].range[2]; if( needsSampling ) mapdesc->subdivide( upper.spts, lower.spts, d, pspec[1].order, pspec[1].stride, pspec[0].order, pspec[0].stride ); if( cullval == CULL_ACCEPT ) mapdesc->subdivide( upper.cpts, lower.cpts, d, pspec[1].order, pspec[1].stride, pspec[0].order, pspec[0].stride ); if( notInBbox ) mapdesc->subdivide( upper.bpts, lower.bpts, d, pspec[1].order, pspec[1].stride, pspec[0].order, pspec[0].stride ); lower.pspec[0].range[0] = upper.pspec[0].range[0]; lower.pspec[0].range[1] = value; lower.pspec[0].range[2] = value - upper.pspec[0].range[0]; upper.pspec[0].range[0] = value; upper.pspec[0].range[2] = upper.pspec[0].range[1] - value; lower.pspec[1].range[0] = upper.pspec[1].range[0]; lower.pspec[1].range[1] = upper.pspec[1].range[1]; lower.pspec[1].range[2] = upper.pspec[1].range[2]; break; } case 1: { REAL d = (value-upper.pspec[1].range[0]) / upper.pspec[1].range[2]; if( needsSampling ) mapdesc->subdivide( upper.spts, lower.spts, d, pspec[0].order, pspec[0].stride, pspec[1].order, pspec[1].stride ); if( cullval == CULL_ACCEPT ) mapdesc->subdivide( upper.cpts, lower.cpts, d, pspec[0].order, pspec[0].stride, pspec[1].order, pspec[1].stride ); if( notInBbox ) mapdesc->subdivide( upper.bpts, lower.bpts, d, pspec[0].order, pspec[0].stride, pspec[1].order, pspec[1].stride ); lower.pspec[0].range[0] = upper.pspec[0].range[0]; lower.pspec[0].range[1] = upper.pspec[0].range[1]; lower.pspec[0].range[2] = upper.pspec[0].range[2]; lower.pspec[1].range[0] = upper.pspec[1].range[0]; lower.pspec[1].range[1] = value; lower.pspec[1].range[2] = value - upper.pspec[1].range[0]; upper.pspec[1].range[0] = value; upper.pspec[1].range[2] = upper.pspec[1].range[1] - value; break; } } // inherit bounding box if( mapdesc->isBboxSubdividing() && ! notInBbox ) memcpy( lower.bb, upper.bb, sizeof( bb ) ); lower.checkBboxConstraint(); upper.checkBboxConstraint();}/*-------------------------------------------------------------------------- * clamp - clamp the sampling rate to a given maximum *-------------------------------------------------------------------------- */voidPatch::clamp( void ){ if( mapdesc->clampfactor != N_NOCLAMPING ) { pspec[0].clamp( mapdesc->clampfactor ); pspec[1].clamp( mapdesc->clampfactor ); }}void Patchspec::clamp( REAL clampfactor ){ if( sidestep[0] < minstepsize ) sidestep[0] = clampfactor * minstepsize; if( sidestep[1] < minstepsize ) sidestep[1] = clampfactor * minstepsize; if( stepsize < minstepsize ) stepsize = clampfactor * minstepsize;}void Patch::checkBboxConstraint( void ){ if( notInBbox && mapdesc->bboxTooBig( bpts, pspec[0].stride, pspec[1].stride, pspec[0].order, pspec[1].order, bb ) != 1 ) { notInBbox = 0; }}voidPatch::bbox( void ){ if( mapdesc->isBboxSubdividing() ) mapdesc->surfbbox( bb );}/*-------------------------------------------------------------------------- * getstepsize - compute the sampling density across the patch
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -