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

📄 subdivider.cc

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 CC
📖 第 1 页 / 共 2 页
字号:
		setArcTypeBezier();	    }        }    } }/*-------------------------------------------------------------------------- * samplingSplit - recursively subdivide patch, cull check each subpatch   *-------------------------------------------------------------------------- */voidSubdivider::samplingSplit(     Bin& source,     Patchlist& patchlist,     int subdivisions,     int param ){    if( ! source.isnonempty() ) return;    if( patchlist.cullCheck() == CULL_TRIVIAL_REJECT ) {	freejarcs( source );	return;    }    patchlist.getstepsize();    if( renderhints.display_method == N_OUTLINE_PATCH ) {        tessellation( source, patchlist );	outline( source );	freejarcs( source );	return;    }     //patchlist.clamp();    tessellation( source, patchlist );    if( patchlist.needsSamplingSubdivision() && (subdivisions > 0) ) {	if( ! patchlist.needsSubdivision( 0 ) )	    param = 1;	else if( ! patchlist.needsSubdivision( 1 ) )	    param = 0;	else	    param = 1 - param;	Bin left, right;	REAL mid = ( patchlist.pspec[param].range[0] +		     patchlist.pspec[param].range[1] ) * 0.5;	split( source, left, right, param, mid );	Patchlist subpatchlist( patchlist, param, mid );	samplingSplit( left, subpatchlist, subdivisions-1, param );	samplingSplit( right, patchlist, subdivisions-1, param );    } else {	setArcTypePwl();	setDegenerate();	nonSamplingSplit( source, patchlist, subdivisions, param );	setDegenerate();	setArcTypeBezier();    }}voidSubdivider::nonSamplingSplit(     Bin& source,     Patchlist& patchlist,     int subdivisions,     int param ){    if( patchlist.needsNonSamplingSubdivision() && (subdivisions > 0) ) {	param = 1 - param;	Bin left, right;	REAL mid = ( patchlist.pspec[param].range[0] +		     patchlist.pspec[param].range[1] ) * 0.5;	split( source, left, right, param, mid );	Patchlist subpatchlist( patchlist, param, mid );	if( left.isnonempty() )	    if( subpatchlist.cullCheck() == CULL_TRIVIAL_REJECT ) 		freejarcs( left );	    else	        nonSamplingSplit( left, subpatchlist, subdivisions-1, param );	if( right.isnonempty() ) 	    if( patchlist.cullCheck() == CULL_TRIVIAL_REJECT ) 		freejarcs( right );	    else	        nonSamplingSplit( right, patchlist, subdivisions-1, param );    } else {	// make bbox calls	patchlist.bbox();	backend.patch( patchlist.pspec[0].range[0], patchlist.pspec[0].range[1],		       patchlist.pspec[1].range[0], patchlist.pspec[1].range[1] );    	if( renderhints.display_method == N_OUTLINE_SUBDIV ) {	    outline( source );	    freejarcs( source );	} else {	    setArcTypePwl();	    setDegenerate();	    findIrregularS( source );	    monosplitInS( source, smbrkpts.start, smbrkpts.end );	}    }}/*-------------------------------------------------------------------------- * tessellation - set tessellation of interior and boundary of patch *-------------------------------------------------------------------------- */voidSubdivider::tessellation( Bin& bin, Patchlist &patchlist ){    // tessellate unsampled trim curves    tessellate( bin, patchlist.pspec[1].sidestep[1], patchlist.pspec[0].sidestep[1],	 patchlist.pspec[1].sidestep[0], patchlist.pspec[0].sidestep[0] );    // set interior sampling rates    slicer.setstriptessellation( patchlist.pspec[0].stepsize, patchlist.pspec[1].stepsize );    //added by zl: set the order which will be used in slicer.c++    slicer.set_ulinear( (patchlist.get_uorder() == 2));    slicer.set_vlinear( (patchlist.get_vorder() == 2));    // set boundary sampling rates    stepsizes[0] = patchlist.pspec[1].stepsize;    stepsizes[1] = patchlist.pspec[0].stepsize;    stepsizes[2] = patchlist.pspec[1].stepsize;    stepsizes[3] = patchlist.pspec[0].stepsize;}/*--------------------------------------------------------------------------- * monosplitInS - split a patch and a bin by an isoparametric line *--------------------------------------------------------------------------- */voidSubdivider::monosplitInS( Bin& source, int start, int end ){    if( source.isnonempty() ) {        if( start != end ) {	    int	i = start + (end - start) / 2;	    Bin left, right;	    split( source, left, right, 0, smbrkpts.pts[i] );	    monosplitInS( left, start, i );	    monosplitInS( right, i+1, end );        } else {	    if( renderhints.display_method == N_OUTLINE_SUBDIV_S ) {		outline( source );		freejarcs( source );	    } else {		setArcTypePwl();		setDegenerate();		findIrregularT( source );		monosplitInT( source, tmbrkpts.start, tmbrkpts.end );	    }        }    } }/*--------------------------------------------------------------------------- * monosplitInT - split a patch and a bin by an isoparametric line *--------------------------------------------------------------------------- */voidSubdivider::monosplitInT( Bin& source, int start, int end ){    if( source.isnonempty() ) {        if( start != end ) {	    int	i = start + (end - start) / 2;	    Bin left, right;	    split( source, left, right, 1, tmbrkpts.pts[i] );	    monosplitInT( left, start, i );	    monosplitInT( right, i+1, end );        } else {	    if( renderhints.display_method == N_OUTLINE_SUBDIV_ST ) {		outline( source );		freejarcs( source );	    } else {/*printf("*******render\n");source.show("source\n");*/		render( source );		freejarcs( source );	    }        }    } }/*---------------------------------------------------------------------------- * findIrregularS - determine points of non-monotonicity is s direction *---------------------------------------------------------------------------- */voidSubdivider::findIrregularS( Bin& bin ){    assert( bin.firstarc()->check() != 0 );    smbrkpts.grow( bin.numarcs() );    for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {	REAL *a = jarc->prev->tail();	REAL *b = jarc->tail();	REAL *c = jarc->head();	if( b[1] == a[1] && b[1] == c[1] ) continue;	//corrected code	if((b[1]<=a[1] && b[1] <= c[1]) ||	   (b[1]>=a[1] && b[1] >= c[1]))	  {	    //each arc (jarc, jarc->prev, jarc->next) is a 	    //monotone arc consisting of multiple line segements.	    //it may happen that jarc->prev and jarc->next are the same,	    //that is, jarc->prev and jarc form a closed loop.	    //In such case, a and c will be the same.            if(a[0]==c[0] && a[1] == c[1])	      {		if(jarc->pwlArc->npts >2)		  {		    c = jarc->pwlArc->pts[jarc->pwlArc->npts-2].param;		  }		else		  {		    assert(jarc->prev->pwlArc->npts>2);		    a = jarc->prev->pwlArc->pts[jarc->prev->pwlArc->npts-2].param;		  }		    	      }	    if(area(a,b,c) < 0)	      {		smbrkpts.add(b[0]);	      }	  }	/* old code, 	if( b[1] <= a[1] && b[1] <= c[1] ) {	    if( ! ccwTurn_tr( jarc->prev, jarc ) )                smbrkpts.add( b[0] );	} else if( b[1] >= a[1] && b[1] >= c[1] ) {	    if( ! ccwTurn_tl( jarc->prev, jarc ) )                smbrkpts.add( b[0] );        }	*/    }    smbrkpts.filter();} /*---------------------------------------------------------------------------- * findIrregularT - determine points of non-monotonicity in t direction *		     where one arc is parallel to the s axis. *---------------------------------------------------------------------------- */voidSubdivider::findIrregularT( Bin& bin ){    assert( bin.firstarc()->check() != 0 );    tmbrkpts.grow( bin.numarcs() );    for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {	REAL *a = jarc->prev->tail();	REAL *b = jarc->tail();	REAL *c = jarc->head();	if( b[0] == a[0] && b[0] == c[0] ) continue;	if( b[0] <= a[0] && b[0] <= c[0] ) {	    if( a[1] != b[1] && b[1] != c[1] ) continue; 	    if( ! ccwTurn_sr( jarc->prev, jarc ) )                tmbrkpts.add( b[1] );	} else if ( b[0] >= a[0] && b[0] >= c[0] ) {	    if( a[1] != b[1] && b[1] != c[1] ) continue; 	    if( ! ccwTurn_sl( jarc->prev, jarc ) )                tmbrkpts.add( b[1] );	}    }    tmbrkpts.filter( );}/*----------------------------------------------------------------------------- * makeBorderTrim - if no user input trimming data then create  * a trimming curve around the boundaries of the Quilt.  The curve consists of * four Jordan arcs, one for each side of the Quilt, connected, of course, * head to tail.  *----------------------------------------------------------------------------- */voidSubdivider::makeBorderTrim( const REAL *from, const REAL *to ){     REAL smin = from[0];    REAL smax = to[0];    REAL tmin = from[1];    REAL tmax = to[1];    pjarc = 0;    Arc_ptr jarc = new(arcpool) Arc( arc_bottom, 0 );    arctessellator.bezier( jarc, smin, smax, tmin, tmin );    initialbin.addarc( jarc  );    pjarc = jarc->append( pjarc );    jarc = new(arcpool) Arc( arc_right, 0 );    arctessellator.bezier( jarc, smax, smax, tmin, tmax );    initialbin.addarc( jarc  );    pjarc = jarc->append( pjarc );    jarc = new(arcpool) Arc( arc_top, 0 );    arctessellator.bezier( jarc, smax, smin, tmax, tmax );    initialbin.addarc( jarc  );    pjarc = jarc->append( pjarc );    jarc = new(arcpool) Arc( arc_left, 0 );    arctessellator.bezier( jarc, smin, smin, tmax, tmin );    initialbin.addarc( jarc  );    jarc->append( pjarc );    assert( jarc->check() != 0 );}/*---------------------------------------------------------------------------- * render - renders all monotone regions in a bin and frees the bin *---------------------------------------------------------------------------- */voidSubdivider::render( Bin& bin ){    bin.markall();#ifdef N_ISOLINE_S    slicer.setisolines( ( renderhints.display_method == N_ISOLINE_S ) ? 1 : 0 );#else    slicer.setisolines( 0 );#endif    for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {	if( jarc->ismarked() ) {	    assert( jarc->check( ) != 0 );	    Arc_ptr jarchead = jarc;	    do {		jarc->clearmark();		jarc = jarc->next;	    } while (jarc != jarchead);	    slicer.slice( jarc );	}    }}/*--------------------------------------------------------------------------- * outline - render the trimmed patch by outlining the boundary  *--------------------------------------------------------------------------- */voidSubdivider::outline( Bin& bin ){    bin.markall();    for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {	if( jarc->ismarked() ) {	    assert( jarc->check( ) != 0 );	    Arc_ptr jarchead = jarc;	    do {		slicer.outline( jarc );		jarc->clearmark();		jarc = jarc->prev;	    } while (jarc != jarchead);	}    }}/*--------------------------------------------------------------------------- * freejarcs - free all arcs in a bin *--------------------------------------------------------------------------- */voidSubdivider::freejarcs( Bin& bin ){    bin.adopt();	/* XXX - should not be necessary */    Arc_ptr jarc;    while( (jarc = bin.removearc()) != NULL ) {	if( jarc->pwlArc ) jarc->pwlArc->deleteMe( pwlarcpool ); jarc->pwlArc = 0;	if( jarc->bezierArc) jarc->bezierArc->deleteMe( bezierarcpool ); jarc->bezierArc = 0;	jarc->deleteMe( arcpool );    }}/*---------------------------------------------------------------------------- * tessellate - tessellate all Bezier arcs in a bin * 		   1) only accepts linear Bezier arcs as input  * 		   2) the Bezier arcs are stored in the pwlArc structure * 		   3) only vertical or horizontal lines work * 		-- should  * 		   1) represent Bezier arcs in BezierArc structure * 		      (this requires a multitude of changes to the code) * 		   2) accept high degree Bezier arcs (hard) * 		   3) map the curve onto the surface to determine tessellation * 		   4) work for curves of arbitrary geometry *---------------------------------------------------------------------------- */voidSubdivider::tessellate( Bin& bin, REAL rrate, REAL trate, REAL lrate, REAL brate ){    for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {	if( jarc->isbezier( ) ) {    	    assert( jarc->pwlArc->npts == 2 );		    TrimVertex  *pts = jarc->pwlArc->pts;    	    REAL s1 = pts[0].param[0];    	    REAL t1 = pts[0].param[1];    	    REAL s2 = pts[1].param[0];    	    REAL t2 = pts[1].param[1];	        	    jarc->pwlArc->deleteMe( pwlarcpool ); jarc->pwlArc = 0;	    	    switch( jarc->getside() ) {		case arc_left:		    assert( s1 == s2 );		    arctessellator.pwl_left( jarc, s1, t1, t2, lrate );		    break;		case arc_right:		    assert( s1 == s2 );		    arctessellator.pwl_right( jarc, s1, t1, t2, rrate );		    break;		case arc_top:		    assert( t1 == t2 );		    arctessellator.pwl_top( jarc, t1, s1, s2, trate );		    break;		case arc_bottom:		    assert( t1 == t2 );		    arctessellator.pwl_bottom( jarc, t1, s1, s2, brate );		    break;		case arc_none:		    (void) abort();		    break;	    }	    assert( ! jarc->isbezier() );    	    assert( jarc->check() != 0 );	}    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -