⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 patch.cc

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 CC
📖 第 1 页 / 共 2 页
字号:
/*
** 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-11 18:07:02 -0600 (Sat, 11 Mar 2006) $ $Revision: 1.1 $
 * $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/glu32/libnurbs/internals/patch.cc,v 1.1 2004/02/02 16:39:12 navaraf 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
 *--------------------------------------------------------------------------
 */

void
Patch::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;
    }
}

void
Patch::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 + -