1c2c66affSColin Finck /*
2c2c66affSColin Finck ** License Applicability. Except to the extent portions of this file are
3c2c66affSColin Finck ** made subject to an alternative license as permitted in the SGI Free
4c2c66affSColin Finck ** Software License B, Version 1.1 (the "License"), the contents of this
5c2c66affSColin Finck ** file are subject only to the provisions of the License. You may not use
6c2c66affSColin Finck ** this file except in compliance with the License. You may obtain a copy
7c2c66affSColin Finck ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8c2c66affSColin Finck ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
9c2c66affSColin Finck **
10c2c66affSColin Finck ** http://oss.sgi.com/projects/FreeB
11c2c66affSColin Finck **
12c2c66affSColin Finck ** Note that, as provided in the License, the Software is distributed on an
13c2c66affSColin Finck ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14c2c66affSColin Finck ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15c2c66affSColin Finck ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16c2c66affSColin Finck ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
17c2c66affSColin Finck **
18c2c66affSColin Finck ** Original Code. The Original Code is: OpenGL Sample Implementation,
19c2c66affSColin Finck ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20c2c66affSColin Finck ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21c2c66affSColin Finck ** Copyright in any portions created by third parties is as indicated
22c2c66affSColin Finck ** elsewhere herein. All Rights Reserved.
23c2c66affSColin Finck **
24c2c66affSColin Finck ** Additional Notice Provisions: The application programming interfaces
25c2c66affSColin Finck ** established by SGI in conjunction with the Original Code are The
26c2c66affSColin Finck ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27c2c66affSColin Finck ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28c2c66affSColin Finck ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29c2c66affSColin Finck ** Window System(R) (Version 1.3), released October 19, 1998. This software
30c2c66affSColin Finck ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31c2c66affSColin Finck ** published by SGI, but has not been independently verified as being
32c2c66affSColin Finck ** compliant with the OpenGL(R) version 1.2.1 Specification.
33c2c66affSColin Finck */
34c2c66affSColin Finck 
35c2c66affSColin Finck /*
36c2c66affSColin Finck  * subdivider.cxx
37c2c66affSColin Finck  *
38c2c66affSColin Finck  */
39c2c66affSColin Finck 
40c2c66affSColin Finck //#include "glimports.h"
41c2c66affSColin Finck //#include "myassert.h"
42c2c66affSColin Finck //#include "mystdio.h"
43c2c66affSColin Finck #include "subdivider.h"
44c2c66affSColin Finck //#include "arc.h"
45c2c66affSColin Finck #include "bezierarc.h"
46c2c66affSColin Finck //#include "bin.h"
47c2c66affSColin Finck #include "renderhints.h"
48c2c66affSColin Finck #include "backend.h"
49c2c66affSColin Finck //#include "mapdesc.h"
50c2c66affSColin Finck #include "quilt.h"
51c2c66affSColin Finck #include "patchlist.h"
52c2c66affSColin Finck //#include "patch.h"
53c2c66affSColin Finck //#include "nurbsconsts.h"
54c2c66affSColin Finck //#include "trimvertpool.h"
55c2c66affSColin Finck #include "simplemath.h"
56c2c66affSColin Finck 
57c2c66affSColin Finck #include "polyUtil.h" //for function area()
58c2c66affSColin Finck 
59c2c66affSColin Finck //#define  PARTITION_TEST
60c2c66affSColin Finck #ifdef PARTITION_TEST
61c2c66affSColin Finck #include "partitionY.h"
62c2c66affSColin Finck #include "monoTriangulation.h"
63c2c66affSColin Finck #include "dataTransform.h"
64c2c66affSColin Finck #include "monoChain.h"
65c2c66affSColin Finck 
66c2c66affSColin Finck #endif
67c2c66affSColin Finck 
68c2c66affSColin Finck 
69c2c66affSColin Finck #define OPTIMIZE_UNTRIMED_CASE
70c2c66affSColin Finck 
71c2c66affSColin Finck 
72c2c66affSColin Finck Bin*
makePatchBoundary(const REAL * from,const REAL * to)73c2c66affSColin Finck Subdivider::makePatchBoundary( const REAL *from, const REAL *to )
74c2c66affSColin Finck {
75c2c66affSColin Finck     Bin* ret = new Bin();
76c2c66affSColin Finck     REAL smin = from[0];
77c2c66affSColin Finck     REAL smax = to[0];
78c2c66affSColin Finck     REAL tmin = from[1];
79c2c66affSColin Finck     REAL tmax = to[1];
80c2c66affSColin Finck 
81c2c66affSColin Finck     pjarc = 0;
82c2c66affSColin Finck 
83c2c66affSColin Finck     Arc_ptr jarc = new(arcpool) Arc( arc_bottom, 0 );
84c2c66affSColin Finck     arctessellator.bezier( jarc, smin, smax, tmin, tmin );
85c2c66affSColin Finck     ret->addarc( jarc  );
86c2c66affSColin Finck     pjarc = jarc->append( pjarc );
87c2c66affSColin Finck 
88c2c66affSColin Finck     jarc = new(arcpool) Arc( arc_right, 0 );
89c2c66affSColin Finck     arctessellator.bezier( jarc, smax, smax, tmin, tmax );
90c2c66affSColin Finck     ret->addarc( jarc  );
91c2c66affSColin Finck     pjarc = jarc->append( pjarc );
92c2c66affSColin Finck 
93c2c66affSColin Finck     jarc = new(arcpool) Arc( arc_top, 0 );
94c2c66affSColin Finck     arctessellator.bezier( jarc, smax, smin, tmax, tmax );
95c2c66affSColin Finck     ret->addarc( jarc  );
96c2c66affSColin Finck     pjarc = jarc->append( pjarc );
97c2c66affSColin Finck 
98c2c66affSColin Finck     jarc = new(arcpool) Arc( arc_left, 0 );
99c2c66affSColin Finck     arctessellator.bezier( jarc, smin, smin, tmax, tmin );
100c2c66affSColin Finck     ret->addarc( jarc  );
101c2c66affSColin Finck     jarc->append( pjarc );
102c2c66affSColin Finck 
103c2c66affSColin Finck     assert( jarc->check() != 0 );
104c2c66affSColin Finck     return ret;
105c2c66affSColin Finck }
106c2c66affSColin Finck 
107c2c66affSColin Finck /*---------------------------------------------------------------------------
108c2c66affSColin Finck  * Subdivider - construct a subdivider
109c2c66affSColin Finck  *---------------------------------------------------------------------------
110c2c66affSColin Finck  */
111c2c66affSColin Finck 
Subdivider(Renderhints & r,Backend & b)112c2c66affSColin Finck Subdivider::Subdivider( Renderhints& r, Backend& b )
113c2c66affSColin Finck 	: slicer( b ),
114c2c66affSColin Finck 	  arctessellator( trimvertexpool, pwlarcpool ),
115c2c66affSColin Finck 	  arcpool( sizeof( Arc), 1, "arcpool" ),
116c2c66affSColin Finck  	  bezierarcpool( sizeof( BezierArc ), 1, "Bezarcpool" ),
117c2c66affSColin Finck 	  pwlarcpool( sizeof( PwlArc ), 1, "Pwlarcpool" ),
118c2c66affSColin Finck 	  renderhints( r ),
119c2c66affSColin Finck 	  backend( b )
120c2c66affSColin Finck {
121c2c66affSColin Finck }
122c2c66affSColin Finck 
123c2c66affSColin Finck void
setJumpbuffer(JumpBuffer * j)124c2c66affSColin Finck Subdivider::setJumpbuffer( JumpBuffer *j )
125c2c66affSColin Finck {
126c2c66affSColin Finck     jumpbuffer = j;
127c2c66affSColin Finck }
128c2c66affSColin Finck 
129c2c66affSColin Finck /*---------------------------------------------------------------------------
130c2c66affSColin Finck  * clear - reset all state after possible error condition
131c2c66affSColin Finck  *---------------------------------------------------------------------------
132c2c66affSColin Finck  */
133c2c66affSColin Finck 
134c2c66affSColin Finck void
clear(void)135c2c66affSColin Finck Subdivider::clear( void )
136c2c66affSColin Finck {
137c2c66affSColin Finck     trimvertexpool.clear();
138c2c66affSColin Finck     arcpool.clear();
139c2c66affSColin Finck     pwlarcpool.clear();
140c2c66affSColin Finck     bezierarcpool.clear();
141c2c66affSColin Finck }
142c2c66affSColin Finck 
143c2c66affSColin Finck /*---------------------------------------------------------------------------
144c2c66affSColin Finck  * ~Subdivider - destroy a subdivider
145c2c66affSColin Finck  *---------------------------------------------------------------------------
146c2c66affSColin Finck  */
147c2c66affSColin Finck 
~Subdivider(void)148c2c66affSColin Finck Subdivider::~Subdivider( void )
149c2c66affSColin Finck {
150c2c66affSColin Finck }
151c2c66affSColin Finck 
152c2c66affSColin Finck /*---------------------------------------------------------------------------
153c2c66affSColin Finck  * addArc - add a bezier arc to a trim loop and to a bin
154c2c66affSColin Finck  *---------------------------------------------------------------------------
155c2c66affSColin Finck  */
156c2c66affSColin Finck void
addArc(REAL * cpts,Quilt * quilt,long _nuid)157c2c66affSColin Finck Subdivider::addArc( REAL *cpts, Quilt *quilt, long _nuid )
158c2c66affSColin Finck {
159c2c66affSColin Finck     BezierArc *bezierArc = new(bezierarcpool) BezierArc;
160c2c66affSColin Finck     Arc *jarc  		= new(arcpool) Arc( arc_none, _nuid );
161c2c66affSColin Finck     jarc->pwlArc	= 0;
162c2c66affSColin Finck     jarc->bezierArc	= bezierArc;
163c2c66affSColin Finck     bezierArc->order	= quilt->qspec->order;
164c2c66affSColin Finck     bezierArc->stride	= quilt->qspec->stride;
165c2c66affSColin Finck     bezierArc->mapdesc	= quilt->mapdesc;
166c2c66affSColin Finck     bezierArc->cpts	= cpts;
167c2c66affSColin Finck     initialbin.addarc( jarc );
168c2c66affSColin Finck     pjarc		= jarc->append( pjarc );
169c2c66affSColin Finck }
170c2c66affSColin Finck 
171c2c66affSColin Finck /*---------------------------------------------------------------------------
172c2c66affSColin Finck  * addArc - add a pwl arc to a trim loop and to a bin
173c2c66affSColin Finck  *---------------------------------------------------------------------------
174c2c66affSColin Finck  */
175c2c66affSColin Finck 
176c2c66affSColin Finck void
addArc(int npts,TrimVertex * pts,long _nuid)177c2c66affSColin Finck Subdivider::addArc( int npts, TrimVertex *pts, long _nuid )
178c2c66affSColin Finck {
179c2c66affSColin Finck     Arc *jarc 		= new(arcpool) Arc( arc_none, _nuid );
180c2c66affSColin Finck     jarc->pwlArc	= new(pwlarcpool) PwlArc( npts, pts );
181c2c66affSColin Finck     initialbin.addarc( jarc  );
182c2c66affSColin Finck     pjarc		= jarc->append( pjarc );
183c2c66affSColin Finck }
184c2c66affSColin Finck 
185c2c66affSColin Finck void
beginQuilts(void)186c2c66affSColin Finck Subdivider::beginQuilts( void )
187c2c66affSColin Finck {
188c2c66affSColin Finck     qlist = 0;
189c2c66affSColin Finck }
190c2c66affSColin Finck 
191c2c66affSColin Finck void
addQuilt(Quilt * quilt)192c2c66affSColin Finck Subdivider::addQuilt( Quilt *quilt )
193c2c66affSColin Finck {
194c2c66affSColin Finck     quilt->next = qlist;
195c2c66affSColin Finck     qlist = quilt;
196c2c66affSColin Finck }
197c2c66affSColin Finck 
198c2c66affSColin Finck /*---------------------------------------------------------------------------
199c2c66affSColin Finck  * drawSurfaces - main entry point for surface tessellation
200c2c66affSColin Finck  *---------------------------------------------------------------------------
201c2c66affSColin Finck  */
202c2c66affSColin Finck 
203c2c66affSColin Finck void
drawSurfaces(long nuid)204c2c66affSColin Finck Subdivider::drawSurfaces( long nuid )
205c2c66affSColin Finck {
206c2c66affSColin Finck     renderhints.init( );
207c2c66affSColin Finck 
208c2c66affSColin Finck     if (qlist == NULL)
209c2c66affSColin Finck       {
210c2c66affSColin Finck 	//initialbin could be nonempty due to some errors
211c2c66affSColin Finck 	freejarcs(initialbin);
212c2c66affSColin Finck 	return;
213c2c66affSColin Finck       }
214c2c66affSColin Finck 
215c2c66affSColin Finck     for( Quilt *q = qlist; q; q = q->next ) {
216c2c66affSColin Finck 	if( q->isCulled( ) == CULL_TRIVIAL_REJECT ) {
217c2c66affSColin Finck 	    freejarcs( initialbin );
218c2c66affSColin Finck 	    return;
219c2c66affSColin Finck 	}
220c2c66affSColin Finck     }
221c2c66affSColin Finck 
222c2c66affSColin Finck 
223c2c66affSColin Finck     REAL from[2], to[2];
224c2c66affSColin Finck     qlist->getRange( from, to, spbrkpts, tpbrkpts );
225c2c66affSColin Finck #ifdef OPTIMIZE_UNTRIMED_CASE
226c2c66affSColin Finck     //perform optimization only when the samplng method is
227c2c66affSColin Finck     //DOMAIN_DISTANCE and the display methdo is either
228c2c66affSColin Finck     //fill or outline_polygon.
229c2c66affSColin Finck     int optimize = (is_domain_distance_sampling && (renderhints.display_method != N_OUTLINE_PATCH));
230c2c66affSColin Finck #endif
231c2c66affSColin Finck 
232c2c66affSColin Finck     if( ! initialbin.isnonempty() ) {
233c2c66affSColin Finck #ifdef OPTIMIZE_UNTRIMED_CASE
234c2c66affSColin Finck         if(! optimize )
235c2c66affSColin Finck 	  {
236c2c66affSColin Finck 
237c2c66affSColin Finck 	  makeBorderTrim( from, to );
238c2c66affSColin Finck 	  }
239c2c66affSColin Finck #else
240c2c66affSColin Finck 	makeBorderTrim( from, to );
241c2c66affSColin Finck #endif
242c2c66affSColin Finck     } else {
243c2c66affSColin Finck 	REAL rate[2];
244c2c66affSColin Finck 	qlist->findRates( spbrkpts, tpbrkpts, rate );
245c2c66affSColin Finck 
246c2c66affSColin Finck     	if( decompose( initialbin, min(rate[0], rate[1]) ) )
247c2c66affSColin Finck 	    mylongjmp( jumpbuffer, 31 );
248c2c66affSColin Finck     }
249c2c66affSColin Finck 
250c2c66affSColin Finck     backend.bgnsurf( renderhints.wiretris, renderhints.wirequads, nuid );
251c2c66affSColin Finck 
252c2c66affSColin Finck #ifdef PARTITION_TEST
253c2c66affSColin Finck  if(    initialbin.isnonempty() && spbrkpts.end-2 == spbrkpts.start &&
254c2c66affSColin Finck 	tpbrkpts.end-2 == tpbrkpts.start)
255c2c66affSColin Finck {
256c2c66affSColin Finck     for(int i=spbrkpts.start; i<spbrkpts.end-1; i++){
257c2c66affSColin Finck       for(int j=tpbrkpts.start; j<tpbrkpts.end-1; j++){
258c2c66affSColin Finck 	Real pta[2], ptb[2];
259c2c66affSColin Finck 	pta[0] = spbrkpts.pts[i];
260c2c66affSColin Finck 	ptb[0] = spbrkpts.pts[i+1];
261c2c66affSColin Finck 	pta[1] = tpbrkpts.pts[j];
262c2c66affSColin Finck 	ptb[1] = tpbrkpts.pts[j+1];
263c2c66affSColin Finck 	qlist->downloadAll(pta, ptb, backend);
264c2c66affSColin Finck 
265c2c66affSColin Finck 	directedLine *poly;
266c2c66affSColin Finck 
267c2c66affSColin Finck 	  {
268c2c66affSColin Finck 
269c2c66affSColin Finck 	    poly = bin_to_DLineLoops(initialbin);
270c2c66affSColin Finck 
271c2c66affSColin Finck 	    poly=poly->deleteDegenerateLinesAllPolygons();
272c2c66affSColin Finck 
273c2c66affSColin Finck     sampledLine* retSampledLines;
274c2c66affSColin Finck //printf("before MC_partition\n");
275c2c66affSColin Finck 	    poly = MC_partitionY(poly, &retSampledLines);
276c2c66affSColin Finck //printf("after MC_partition\n");
277c2c66affSColin Finck 
278c2c66affSColin Finck 	  }
279c2c66affSColin Finck 
280c2c66affSColin Finck 
281c2c66affSColin Finck 	{
282c2c66affSColin Finck 	  primStream pStream(5000,5000);
283c2c66affSColin Finck 	  directedLine* temp;
284c2c66affSColin Finck 
285c2c66affSColin Finck 	  for(temp=poly; temp != NULL; temp=temp->getNextPolygon())
286c2c66affSColin Finck 
287c2c66affSColin Finck 	    monoTriangulation(temp, &pStream);
288c2c66affSColin Finck 
289c2c66affSColin Finck 	  slicer.evalStream(&pStream);
290c2c66affSColin Finck 
291c2c66affSColin Finck 	}
292c2c66affSColin Finck 	//need to clean up space
293c2c66affSColin Finck       }
294c2c66affSColin Finck     }
295c2c66affSColin Finck     freejarcs( initialbin );
296c2c66affSColin Finck     backend.endsurf();
297c2c66affSColin Finck     return;
298c2c66affSColin Finck 
299c2c66affSColin Finck     /*
300c2c66affSColin Finck     printf("num_polygons=%i\n", poly->numPolygons());
301c2c66affSColin Finck     printf("num_edges=%i\n", poly->numEdgesAllPolygons());
302c2c66affSColin Finck     poly->writeAllPolygons("zloutputFile");
303c2c66affSColin Finck     return;
304c2c66affSColin Finck     {
305c2c66affSColin Finck       primStream pStream(20,20);
306c2c66affSColin Finck       for(directedLine* tempD = poly; tempD != NULL; tempD = tempD->getNextPolygon())
307c2c66affSColin Finck 	monoTriangulation(tempD, &pStream);
308c2c66affSColin Finck     }
309c2c66affSColin Finck     return;
310c2c66affSColin Finck     */
311c2c66affSColin Finck }
312c2c66affSColin Finck #endif //PARTITION_TEST
313c2c66affSColin Finck 
314c2c66affSColin Finck 
315c2c66affSColin Finck #ifdef OPTIMIZE_UNTRIMED_CASE
316c2c66affSColin Finck     if( (!initialbin.isnonempty())  && optimize )
317c2c66affSColin Finck       {
318c2c66affSColin Finck 	int i,j;
319c2c66affSColin Finck 	int num_u_steps;
320c2c66affSColin Finck         int num_v_steps;
321c2c66affSColin Finck 	for(i=spbrkpts.start; i<spbrkpts.end-1; i++){
322c2c66affSColin Finck 	  for(j=tpbrkpts.start; j<tpbrkpts.end-1; j++){
323c2c66affSColin Finck 	    Real pta[2], ptb[2];
324c2c66affSColin Finck 	    pta[0] = spbrkpts.pts[i];
325c2c66affSColin Finck 	    ptb[0] = spbrkpts.pts[i+1];
326c2c66affSColin Finck 	    pta[1] = tpbrkpts.pts[j];
327c2c66affSColin Finck 	    ptb[1] = tpbrkpts.pts[j+1];
328c2c66affSColin Finck 	    qlist->downloadAll(pta, ptb, backend);
329c2c66affSColin Finck 
330c2c66affSColin Finck             num_u_steps = (int) (domain_distance_u_rate * (ptb[0]-pta[0]));
331c2c66affSColin Finck             num_v_steps = (int) (domain_distance_v_rate * (ptb[1]-pta[1]));
332c2c66affSColin Finck 
333c2c66affSColin Finck             if(num_u_steps <= 0) num_u_steps = 1;
334c2c66affSColin Finck             if(num_v_steps <= 0) num_v_steps = 1;
335c2c66affSColin Finck 
336c2c66affSColin Finck 	    backend.surfgrid(pta[0], ptb[0], num_u_steps,
337c2c66affSColin Finck 			     ptb[1], pta[1], num_v_steps);
338c2c66affSColin Finck 	    backend.surfmesh(0,0,num_u_steps,num_v_steps);
339c2c66affSColin Finck 
340c2c66affSColin Finck 
341c2c66affSColin Finck 
342c2c66affSColin Finck 	    continue;
343c2c66affSColin Finck 	    /* the following is left for reference purpose, don't delete
344c2c66affSColin Finck 	    {
345c2c66affSColin Finck 	    Bin* tempSource;
346c2c66affSColin Finck 	      Patchlist patchlist(qlist, pta, ptb);
347c2c66affSColin Finck 	      patchlist.getstepsize();
348c2c66affSColin Finck 
349c2c66affSColin Finck 	      tempSource=makePatchBoundary(pta, ptb);
350c2c66affSColin Finck 
351c2c66affSColin Finck 	      tessellation(*tempSource, patchlist);
352c2c66affSColin Finck 
353c2c66affSColin Finck 	      render(*tempSource);
354c2c66affSColin Finck 	      delete tempSource;
355c2c66affSColin Finck 	    }
356c2c66affSColin Finck 	    */
357c2c66affSColin Finck 	  }
358c2c66affSColin Finck 	}
359c2c66affSColin Finck       }
360c2c66affSColin Finck     else
361c2c66affSColin Finck       subdivideInS( initialbin );
362c2c66affSColin Finck #else
363c2c66affSColin Finck 
364c2c66affSColin Finck     subdivideInS( initialbin );
365c2c66affSColin Finck #endif
366c2c66affSColin Finck 
367c2c66affSColin Finck     backend.endsurf();
368c2c66affSColin Finck 
369c2c66affSColin Finck }
370c2c66affSColin Finck 
371c2c66affSColin Finck void
subdivideInS(Bin & source)372c2c66affSColin Finck Subdivider::subdivideInS( Bin& source )
373c2c66affSColin Finck {
374c2c66affSColin Finck     if( renderhints.display_method == N_OUTLINE_PARAM ) {
375c2c66affSColin Finck 	outline( source );
376c2c66affSColin Finck 	freejarcs( source );
377c2c66affSColin Finck     } else {
378c2c66affSColin Finck 	setArcTypeBezier();
379c2c66affSColin Finck 	setNonDegenerate();
380c2c66affSColin Finck 	splitInS( source, spbrkpts.start, spbrkpts.end );
381c2c66affSColin Finck     }
382c2c66affSColin Finck }
383c2c66affSColin Finck 
384c2c66affSColin Finck 
385c2c66affSColin Finck /*---------------------------------------------------------------------------
386c2c66affSColin Finck  * splitInS - split a patch and a bin by an isoparametric line
387c2c66affSColin Finck  *---------------------------------------------------------------------------
388c2c66affSColin Finck  */
389c2c66affSColin Finck 
390c2c66affSColin Finck void
splitInS(Bin & source,int start,int end)391c2c66affSColin Finck Subdivider::splitInS( Bin& source, int start, int end )
392c2c66affSColin Finck {
393c2c66affSColin Finck     if( source.isnonempty() ) {
394c2c66affSColin Finck         if( start != end ) {
395c2c66affSColin Finck 	    int	i = start + (end - start) / 2;
396c2c66affSColin Finck 	    Bin left, right;
397c2c66affSColin Finck 	    split( source, left, right, 0, spbrkpts.pts[i] );
398c2c66affSColin Finck 	    splitInS( left, start, i );
399c2c66affSColin Finck 	    splitInS( right, i+1, end );
400c2c66affSColin Finck         } else {
401c2c66affSColin Finck 	    if( start == spbrkpts.start || start == spbrkpts.end ) {
402c2c66affSColin Finck 		freejarcs( source );
403c2c66affSColin Finck 	    } else if( renderhints.display_method == N_OUTLINE_PARAM_S ) {
404c2c66affSColin Finck 		outline( source );
405c2c66affSColin Finck 		freejarcs( source );
406c2c66affSColin Finck 	    } else {
407c2c66affSColin Finck 		setArcTypeBezier();
408c2c66affSColin Finck 		setNonDegenerate();
409c2c66affSColin Finck 		s_index = start;
410c2c66affSColin Finck 		splitInT( source, tpbrkpts.start, tpbrkpts.end );
411c2c66affSColin Finck 	    }
412c2c66affSColin Finck         }
413c2c66affSColin Finck     }
414c2c66affSColin Finck }
415c2c66affSColin Finck 
416c2c66affSColin Finck /*---------------------------------------------------------------------------
417c2c66affSColin Finck  * splitInT - split a patch and a bin by an isoparametric line
418c2c66affSColin Finck  *---------------------------------------------------------------------------
419c2c66affSColin Finck  */
420c2c66affSColin Finck 
421c2c66affSColin Finck void
splitInT(Bin & source,int start,int end)422c2c66affSColin Finck Subdivider::splitInT( Bin& source, int start, int end )
423c2c66affSColin Finck {
424c2c66affSColin Finck     if( source.isnonempty() ) {
425c2c66affSColin Finck         if( start != end ) {
426c2c66affSColin Finck 	    int	i = start + (end - start) / 2;
427c2c66affSColin Finck 	    Bin left, right;
428c2c66affSColin Finck 	    split( source, left, right, 1, tpbrkpts.pts[i] );
429c2c66affSColin Finck 	    splitInT( left, start, i );
430c2c66affSColin Finck 	    splitInT( right, i+1, end );
431c2c66affSColin Finck         } else {
432c2c66affSColin Finck 	    if( start == tpbrkpts.start || start == tpbrkpts.end ) {
433c2c66affSColin Finck 		freejarcs( source );
434c2c66affSColin Finck 	    } else if( renderhints.display_method == N_OUTLINE_PARAM_ST ) {
435c2c66affSColin Finck 		outline( source );
436c2c66affSColin Finck 		freejarcs( source );
437c2c66affSColin Finck 	    } else {
438c2c66affSColin Finck 		t_index = start;
439c2c66affSColin Finck 		setArcTypeBezier();
440c2c66affSColin Finck 		setDegenerate();
441c2c66affSColin Finck 
442c2c66affSColin Finck 		REAL pta[2], ptb[2];
443c2c66affSColin Finck 		pta[0] = spbrkpts.pts[s_index-1];
444c2c66affSColin Finck 		pta[1] = tpbrkpts.pts[t_index-1];
445c2c66affSColin Finck 
446c2c66affSColin Finck 		ptb[0] = spbrkpts.pts[s_index];
447c2c66affSColin Finck 		ptb[1] = tpbrkpts.pts[t_index];
448c2c66affSColin Finck 		qlist->downloadAll( pta, ptb, backend );
449c2c66affSColin Finck 
450c2c66affSColin Finck 		Patchlist patchlist( qlist, pta, ptb );
451c2c66affSColin Finck /*
452c2c66affSColin Finck printf("-------samplingSplit-----\n");
453c2c66affSColin Finck source.show("samplingSplit source");
454c2c66affSColin Finck */
455c2c66affSColin Finck 		samplingSplit( source, patchlist, renderhints.maxsubdivisions, 0 );
456c2c66affSColin Finck 		setNonDegenerate();
457c2c66affSColin Finck 		setArcTypeBezier();
458c2c66affSColin Finck 	    }
459c2c66affSColin Finck         }
460c2c66affSColin Finck     }
461c2c66affSColin Finck }
462c2c66affSColin Finck 
463c2c66affSColin Finck /*--------------------------------------------------------------------------
464c2c66affSColin Finck  * samplingSplit - recursively subdivide patch, cull check each subpatch
465c2c66affSColin Finck  *--------------------------------------------------------------------------
466c2c66affSColin Finck  */
467c2c66affSColin Finck 
468c2c66affSColin Finck void
samplingSplit(Bin & source,Patchlist & patchlist,int subdivisions,int param)469c2c66affSColin Finck Subdivider::samplingSplit(
470c2c66affSColin Finck     Bin& source,
471c2c66affSColin Finck     Patchlist& patchlist,
472c2c66affSColin Finck     int subdivisions,
473c2c66affSColin Finck     int param )
474c2c66affSColin Finck {
475c2c66affSColin Finck     if( ! source.isnonempty() ) return;
476c2c66affSColin Finck 
477c2c66affSColin Finck     if( patchlist.cullCheck() == CULL_TRIVIAL_REJECT ) {
478c2c66affSColin Finck 	freejarcs( source );
479c2c66affSColin Finck 	return;
480c2c66affSColin Finck     }
481c2c66affSColin Finck 
482c2c66affSColin Finck     patchlist.getstepsize();
483c2c66affSColin Finck 
484c2c66affSColin Finck     if( renderhints.display_method == N_OUTLINE_PATCH ) {
485c2c66affSColin Finck         tessellation( source, patchlist );
486c2c66affSColin Finck 	outline( source );
487c2c66affSColin Finck 	freejarcs( source );
488c2c66affSColin Finck 	return;
489c2c66affSColin Finck     }
490c2c66affSColin Finck 
491c2c66affSColin Finck     //patchlist.clamp();
492c2c66affSColin Finck 
493c2c66affSColin Finck     tessellation( source, patchlist );
494c2c66affSColin Finck 
495c2c66affSColin Finck     if( patchlist.needsSamplingSubdivision() && (subdivisions > 0) ) {
496c2c66affSColin Finck 	if( ! patchlist.needsSubdivision( 0 ) )
497c2c66affSColin Finck 	    param = 1;
498c2c66affSColin Finck 	else if( ! patchlist.needsSubdivision( 1 ) )
499c2c66affSColin Finck 	    param = 0;
500c2c66affSColin Finck 	else
501c2c66affSColin Finck 	    param = 1 - param;
502c2c66affSColin Finck 
503c2c66affSColin Finck 	Bin left, right;
504c2c66affSColin Finck 	REAL mid = ( patchlist.pspec[param].range[0] +
505c2c66affSColin Finck 		     patchlist.pspec[param].range[1] ) * 0.5;
506c2c66affSColin Finck 	split( source, left, right, param, mid );
507c2c66affSColin Finck 	Patchlist subpatchlist( patchlist, param, mid );
508c2c66affSColin Finck 	samplingSplit( left, subpatchlist, subdivisions-1, param );
509c2c66affSColin Finck 	samplingSplit( right, patchlist, subdivisions-1, param );
510c2c66affSColin Finck     } else {
511c2c66affSColin Finck 	setArcTypePwl();
512c2c66affSColin Finck 	setDegenerate();
513c2c66affSColin Finck 	nonSamplingSplit( source, patchlist, subdivisions, param );
514c2c66affSColin Finck 	setDegenerate();
515c2c66affSColin Finck 	setArcTypeBezier();
516c2c66affSColin Finck     }
517c2c66affSColin Finck }
518c2c66affSColin Finck 
519c2c66affSColin Finck void
nonSamplingSplit(Bin & source,Patchlist & patchlist,int subdivisions,int param)520c2c66affSColin Finck Subdivider::nonSamplingSplit(
521c2c66affSColin Finck     Bin& source,
522c2c66affSColin Finck     Patchlist& patchlist,
523c2c66affSColin Finck     int subdivisions,
524c2c66affSColin Finck     int param )
525c2c66affSColin Finck {
526c2c66affSColin Finck     if( patchlist.needsNonSamplingSubdivision() && (subdivisions > 0) ) {
527c2c66affSColin Finck 	param = 1 - param;
528c2c66affSColin Finck 
529c2c66affSColin Finck 	Bin left, right;
530c2c66affSColin Finck 	REAL mid = ( patchlist.pspec[param].range[0] +
531c2c66affSColin Finck 		     patchlist.pspec[param].range[1] ) * 0.5;
532c2c66affSColin Finck 	split( source, left, right, param, mid );
533c2c66affSColin Finck 	Patchlist subpatchlist( patchlist, param, mid );
534c2c66affSColin Finck 	if( left.isnonempty() ) {
535c2c66affSColin Finck 	    if( subpatchlist.cullCheck() == CULL_TRIVIAL_REJECT )
536c2c66affSColin Finck 		freejarcs( left );
537c2c66affSColin Finck 	    else
538c2c66affSColin Finck 	        nonSamplingSplit( left, subpatchlist, subdivisions-1, param );
539c2c66affSColin Finck 	}
540c2c66affSColin Finck 	if( right.isnonempty() ) {
541c2c66affSColin Finck 	    if( patchlist.cullCheck() == CULL_TRIVIAL_REJECT )
542c2c66affSColin Finck 		freejarcs( right );
543c2c66affSColin Finck 	    else
544c2c66affSColin Finck 	        nonSamplingSplit( right, patchlist, subdivisions-1, param );
545c2c66affSColin Finck 	}
546c2c66affSColin Finck 
547c2c66affSColin Finck     } else {
548c2c66affSColin Finck 	// make bbox calls
549c2c66affSColin Finck 	patchlist.bbox();
550c2c66affSColin Finck 	backend.patch( patchlist.pspec[0].range[0], patchlist.pspec[0].range[1],
551c2c66affSColin Finck 		       patchlist.pspec[1].range[0], patchlist.pspec[1].range[1] );
552c2c66affSColin Finck 
553c2c66affSColin Finck 	if( renderhints.display_method == N_OUTLINE_SUBDIV ) {
554c2c66affSColin Finck 	    outline( source );
555c2c66affSColin Finck 	    freejarcs( source );
556c2c66affSColin Finck 	} else {
557c2c66affSColin Finck 	    setArcTypePwl();
558c2c66affSColin Finck 	    setDegenerate();
559c2c66affSColin Finck 	    findIrregularS( source );
560c2c66affSColin Finck 	    monosplitInS( source, smbrkpts.start, smbrkpts.end );
561c2c66affSColin Finck 	}
562c2c66affSColin Finck     }
563c2c66affSColin Finck }
564c2c66affSColin Finck 
565c2c66affSColin Finck /*--------------------------------------------------------------------------
566c2c66affSColin Finck  * tessellation - set tessellation of interior and boundary of patch
567c2c66affSColin Finck  *--------------------------------------------------------------------------
568c2c66affSColin Finck  */
569c2c66affSColin Finck 
570c2c66affSColin Finck void
tessellation(Bin & bin,Patchlist & patchlist)571c2c66affSColin Finck Subdivider::tessellation( Bin& bin, Patchlist &patchlist )
572c2c66affSColin Finck {
573c2c66affSColin Finck     // tessellate unsampled trim curves
574c2c66affSColin Finck     tessellate( bin, patchlist.pspec[1].sidestep[1], patchlist.pspec[0].sidestep[1],
575c2c66affSColin Finck 	 patchlist.pspec[1].sidestep[0], patchlist.pspec[0].sidestep[0] );
576c2c66affSColin Finck 
577c2c66affSColin Finck     // set interior sampling rates
578c2c66affSColin Finck     slicer.setstriptessellation( patchlist.pspec[0].stepsize, patchlist.pspec[1].stepsize );
579c2c66affSColin Finck 
580c2c66affSColin Finck     //added by zl: set the order which will be used in slicer.c++
581c2c66affSColin Finck     slicer.set_ulinear( (patchlist.get_uorder() == 2));
582c2c66affSColin Finck     slicer.set_vlinear( (patchlist.get_vorder() == 2));
583c2c66affSColin Finck 
584c2c66affSColin Finck     // set boundary sampling rates
585c2c66affSColin Finck     stepsizes[0] = patchlist.pspec[1].stepsize;
586c2c66affSColin Finck     stepsizes[1] = patchlist.pspec[0].stepsize;
587c2c66affSColin Finck     stepsizes[2] = patchlist.pspec[1].stepsize;
588c2c66affSColin Finck     stepsizes[3] = patchlist.pspec[0].stepsize;
589c2c66affSColin Finck }
590c2c66affSColin Finck 
591c2c66affSColin Finck /*---------------------------------------------------------------------------
592c2c66affSColin Finck  * monosplitInS - split a patch and a bin by an isoparametric line
593c2c66affSColin Finck  *---------------------------------------------------------------------------
594c2c66affSColin Finck  */
595c2c66affSColin Finck 
596c2c66affSColin Finck void
monosplitInS(Bin & source,int start,int end)597c2c66affSColin Finck Subdivider::monosplitInS( Bin& source, int start, int end )
598c2c66affSColin Finck {
599c2c66affSColin Finck     if( source.isnonempty() ) {
600c2c66affSColin Finck         if( start != end ) {
601c2c66affSColin Finck 	    int	i = start + (end - start) / 2;
602c2c66affSColin Finck 	    Bin left, right;
603c2c66affSColin Finck 	    split( source, left, right, 0, smbrkpts.pts[i] );
604c2c66affSColin Finck 	    monosplitInS( left, start, i );
605c2c66affSColin Finck 	    monosplitInS( right, i+1, end );
606c2c66affSColin Finck         } else {
607c2c66affSColin Finck 	    if( renderhints.display_method == N_OUTLINE_SUBDIV_S ) {
608c2c66affSColin Finck 		outline( source );
609c2c66affSColin Finck 		freejarcs( source );
610c2c66affSColin Finck 	    } else {
611c2c66affSColin Finck 		setArcTypePwl();
612c2c66affSColin Finck 		setDegenerate();
613c2c66affSColin Finck 		findIrregularT( source );
614c2c66affSColin Finck 		monosplitInT( source, tmbrkpts.start, tmbrkpts.end );
615c2c66affSColin Finck 	    }
616c2c66affSColin Finck         }
617c2c66affSColin Finck     }
618c2c66affSColin Finck }
619c2c66affSColin Finck 
620c2c66affSColin Finck /*---------------------------------------------------------------------------
621c2c66affSColin Finck  * monosplitInT - split a patch and a bin by an isoparametric line
622c2c66affSColin Finck  *---------------------------------------------------------------------------
623c2c66affSColin Finck  */
624c2c66affSColin Finck 
625c2c66affSColin Finck void
monosplitInT(Bin & source,int start,int end)626c2c66affSColin Finck Subdivider::monosplitInT( Bin& source, int start, int end )
627c2c66affSColin Finck {
628c2c66affSColin Finck     if( source.isnonempty() ) {
629c2c66affSColin Finck         if( start != end ) {
630c2c66affSColin Finck 	    int	i = start + (end - start) / 2;
631c2c66affSColin Finck 	    Bin left, right;
632c2c66affSColin Finck 	    split( source, left, right, 1, tmbrkpts.pts[i] );
633c2c66affSColin Finck 	    monosplitInT( left, start, i );
634c2c66affSColin Finck 	    monosplitInT( right, i+1, end );
635c2c66affSColin Finck         } else {
636c2c66affSColin Finck 	    if( renderhints.display_method == N_OUTLINE_SUBDIV_ST ) {
637c2c66affSColin Finck 		outline( source );
638c2c66affSColin Finck 		freejarcs( source );
639c2c66affSColin Finck 	    } else {
640c2c66affSColin Finck /*
641c2c66affSColin Finck printf("*******render\n");
642c2c66affSColin Finck source.show("source\n");
643c2c66affSColin Finck */
644c2c66affSColin Finck 		render( source );
645c2c66affSColin Finck 		freejarcs( source );
646c2c66affSColin Finck 	    }
647c2c66affSColin Finck         }
648c2c66affSColin Finck     }
649c2c66affSColin Finck }
650c2c66affSColin Finck 
651c2c66affSColin Finck 
652c2c66affSColin Finck /*----------------------------------------------------------------------------
653c2c66affSColin Finck  * findIrregularS - determine points of non-monotonicity is s direction
654c2c66affSColin Finck  *----------------------------------------------------------------------------
655c2c66affSColin Finck  */
656c2c66affSColin Finck 
657c2c66affSColin Finck void
findIrregularS(Bin & bin)658c2c66affSColin Finck Subdivider::findIrregularS( Bin& bin )
659c2c66affSColin Finck {
660c2c66affSColin Finck     assert( bin.firstarc()->check() != 0 );
661c2c66affSColin Finck 
662c2c66affSColin Finck     smbrkpts.grow( bin.numarcs() );
663c2c66affSColin Finck 
664c2c66affSColin Finck     for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {
665c2c66affSColin Finck 	REAL *a = jarc->prev->tail();
666c2c66affSColin Finck 	REAL *b = jarc->tail();
667c2c66affSColin Finck 	REAL *c = jarc->head();
668c2c66affSColin Finck 
669c2c66affSColin Finck 	if( b[1] == a[1] && b[1] == c[1] ) continue;
670c2c66affSColin Finck 
671c2c66affSColin Finck 	//corrected code
672c2c66affSColin Finck 	if((b[1]<=a[1] && b[1] <= c[1]) ||
673c2c66affSColin Finck 	   (b[1]>=a[1] && b[1] >= c[1]))
674c2c66affSColin Finck 	  {
675c2c66affSColin Finck 	    //each arc (jarc, jarc->prev, jarc->next) is a
676c2c66affSColin Finck 	    //monotone arc consisting of multiple line segements.
677c2c66affSColin Finck 	    //it may happen that jarc->prev and jarc->next are the same,
678c2c66affSColin Finck 	    //that is, jarc->prev and jarc form a closed loop.
679c2c66affSColin Finck 	    //In such case, a and c will be the same.
680c2c66affSColin Finck             if(a[0]==c[0] && a[1] == c[1])
681c2c66affSColin Finck 	      {
682c2c66affSColin Finck 		if(jarc->pwlArc->npts >2)
683c2c66affSColin Finck 		  {
684c2c66affSColin Finck 		    c = jarc->pwlArc->pts[jarc->pwlArc->npts-2].param;
685c2c66affSColin Finck 		  }
686c2c66affSColin Finck 		else
687c2c66affSColin Finck 		  {
688c2c66affSColin Finck 		    assert(jarc->prev->pwlArc->npts>2);
689c2c66affSColin Finck 		    a = jarc->prev->pwlArc->pts[jarc->prev->pwlArc->npts-2].param;
690c2c66affSColin Finck 		  }
691c2c66affSColin Finck 
692c2c66affSColin Finck 	      }
693c2c66affSColin Finck 	    if(area(a,b,c) < 0)
694c2c66affSColin Finck 	      {
695c2c66affSColin Finck 		smbrkpts.add(b[0]);
696c2c66affSColin Finck 	      }
697c2c66affSColin Finck 
698c2c66affSColin Finck 	  }
699c2c66affSColin Finck 
700c2c66affSColin Finck 	/* old code,
701c2c66affSColin Finck 	if( b[1] <= a[1] && b[1] <= c[1] ) {
702c2c66affSColin Finck 	    if( ! ccwTurn_tr( jarc->prev, jarc ) )
703c2c66affSColin Finck                 smbrkpts.add( b[0] );
704c2c66affSColin Finck 	} else if( b[1] >= a[1] && b[1] >= c[1] ) {
705c2c66affSColin Finck 	    if( ! ccwTurn_tl( jarc->prev, jarc ) )
706c2c66affSColin Finck                 smbrkpts.add( b[0] );
707c2c66affSColin Finck         }
708c2c66affSColin Finck 	*/
709c2c66affSColin Finck 
710c2c66affSColin Finck     }
711c2c66affSColin Finck 
712c2c66affSColin Finck     smbrkpts.filter();
713c2c66affSColin Finck }
714c2c66affSColin Finck 
715c2c66affSColin Finck /*----------------------------------------------------------------------------
716c2c66affSColin Finck  * findIrregularT - determine points of non-monotonicity in t direction
717c2c66affSColin Finck  *		     where one arc is parallel to the s axis.
718c2c66affSColin Finck  *----------------------------------------------------------------------------
719c2c66affSColin Finck  */
720c2c66affSColin Finck 
721c2c66affSColin Finck void
findIrregularT(Bin & bin)722c2c66affSColin Finck Subdivider::findIrregularT( Bin& bin )
723c2c66affSColin Finck {
724c2c66affSColin Finck     assert( bin.firstarc()->check() != 0 );
725c2c66affSColin Finck 
726c2c66affSColin Finck     tmbrkpts.grow( bin.numarcs() );
727c2c66affSColin Finck 
728c2c66affSColin Finck     for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {
729c2c66affSColin Finck 	REAL *a = jarc->prev->tail();
730c2c66affSColin Finck 	REAL *b = jarc->tail();
731c2c66affSColin Finck 	REAL *c = jarc->head();
732c2c66affSColin Finck 
733c2c66affSColin Finck 	if( b[0] == a[0] && b[0] == c[0] ) continue;
734c2c66affSColin Finck 
735c2c66affSColin Finck 	if( b[0] <= a[0] && b[0] <= c[0] ) {
736c2c66affSColin Finck 	    if( a[1] != b[1] && b[1] != c[1] ) continue;
737c2c66affSColin Finck 	    if( ! ccwTurn_sr( jarc->prev, jarc ) )
738c2c66affSColin Finck                 tmbrkpts.add( b[1] );
739c2c66affSColin Finck 	} else if ( b[0] >= a[0] && b[0] >= c[0] ) {
740c2c66affSColin Finck 	    if( a[1] != b[1] && b[1] != c[1] ) continue;
741c2c66affSColin Finck 	    if( ! ccwTurn_sl( jarc->prev, jarc ) )
742c2c66affSColin Finck                 tmbrkpts.add( b[1] );
743c2c66affSColin Finck 	}
744c2c66affSColin Finck     }
745c2c66affSColin Finck     tmbrkpts.filter( );
746c2c66affSColin Finck }
747c2c66affSColin Finck 
748c2c66affSColin Finck /*-----------------------------------------------------------------------------
749c2c66affSColin Finck  * makeBorderTrim - if no user input trimming data then create
750c2c66affSColin Finck  * a trimming curve around the boundaries of the Quilt.  The curve consists of
751c2c66affSColin Finck  * four Jordan arcs, one for each side of the Quilt, connected, of course,
752c2c66affSColin Finck  * head to tail.
753c2c66affSColin Finck  *-----------------------------------------------------------------------------
754c2c66affSColin Finck  */
755c2c66affSColin Finck 
756c2c66affSColin Finck void
makeBorderTrim(const REAL * from,const REAL * to)757c2c66affSColin Finck Subdivider::makeBorderTrim( const REAL *from, const REAL *to )
758c2c66affSColin Finck {
759c2c66affSColin Finck     REAL smin = from[0];
760c2c66affSColin Finck     REAL smax = to[0];
761c2c66affSColin Finck     REAL tmin = from[1];
762c2c66affSColin Finck     REAL tmax = to[1];
763c2c66affSColin Finck 
764c2c66affSColin Finck     pjarc = 0;
765c2c66affSColin Finck 
766c2c66affSColin Finck     Arc_ptr jarc = new(arcpool) Arc( arc_bottom, 0 );
767c2c66affSColin Finck     arctessellator.bezier( jarc, smin, smax, tmin, tmin );
768c2c66affSColin Finck     initialbin.addarc( jarc  );
769c2c66affSColin Finck     pjarc = jarc->append( pjarc );
770c2c66affSColin Finck 
771c2c66affSColin Finck     jarc = new(arcpool) Arc( arc_right, 0 );
772c2c66affSColin Finck     arctessellator.bezier( jarc, smax, smax, tmin, tmax );
773c2c66affSColin Finck     initialbin.addarc( jarc  );
774c2c66affSColin Finck     pjarc = jarc->append( pjarc );
775c2c66affSColin Finck 
776c2c66affSColin Finck     jarc = new(arcpool) Arc( arc_top, 0 );
777c2c66affSColin Finck     arctessellator.bezier( jarc, smax, smin, tmax, tmax );
778c2c66affSColin Finck     initialbin.addarc( jarc  );
779c2c66affSColin Finck     pjarc = jarc->append( pjarc );
780c2c66affSColin Finck 
781c2c66affSColin Finck     jarc = new(arcpool) Arc( arc_left, 0 );
782c2c66affSColin Finck     arctessellator.bezier( jarc, smin, smin, tmax, tmin );
783c2c66affSColin Finck     initialbin.addarc( jarc  );
784c2c66affSColin Finck     jarc->append( pjarc );
785c2c66affSColin Finck 
786c2c66affSColin Finck     assert( jarc->check() != 0 );
787c2c66affSColin Finck }
788c2c66affSColin Finck 
789c2c66affSColin Finck /*----------------------------------------------------------------------------
790c2c66affSColin Finck  * render - renders all monotone regions in a bin and frees the bin
791c2c66affSColin Finck  *----------------------------------------------------------------------------
792c2c66affSColin Finck  */
793c2c66affSColin Finck 
794c2c66affSColin Finck void
render(Bin & bin)795c2c66affSColin Finck Subdivider::render( Bin& bin )
796c2c66affSColin Finck {
797c2c66affSColin Finck     bin.markall();
798c2c66affSColin Finck 
799c2c66affSColin Finck #ifdef N_ISOLINE_S
800c2c66affSColin Finck     slicer.setisolines( ( renderhints.display_method == N_ISOLINE_S ) ? 1 : 0 );
801c2c66affSColin Finck #else
802c2c66affSColin Finck     slicer.setisolines( 0 );
803c2c66affSColin Finck #endif
804c2c66affSColin Finck 
805c2c66affSColin Finck     for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {
806c2c66affSColin Finck 	if( jarc->ismarked() ) {
807c2c66affSColin Finck 	    assert( jarc->check( ) != 0 );
808c2c66affSColin Finck 	    Arc_ptr jarchead = jarc;
809c2c66affSColin Finck 	    do {
810c2c66affSColin Finck 		jarc->clearmark();
811c2c66affSColin Finck 		jarc = jarc->next;
812c2c66affSColin Finck 	    } while (jarc != jarchead);
813c2c66affSColin Finck 	    slicer.slice( jarc );
814c2c66affSColin Finck 	}
815c2c66affSColin Finck     }
816c2c66affSColin Finck }
817c2c66affSColin Finck 
818c2c66affSColin Finck /*---------------------------------------------------------------------------
819c2c66affSColin Finck  * outline - render the trimmed patch by outlining the boundary
820c2c66affSColin Finck  *---------------------------------------------------------------------------
821c2c66affSColin Finck  */
822c2c66affSColin Finck 
823c2c66affSColin Finck void
outline(Bin & bin)824c2c66affSColin Finck Subdivider::outline( Bin& bin )
825c2c66affSColin Finck {
826c2c66affSColin Finck     bin.markall();
827c2c66affSColin Finck     for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {
828c2c66affSColin Finck 	if( jarc->ismarked() ) {
829c2c66affSColin Finck 	    assert( jarc->check( ) != 0 );
830c2c66affSColin Finck 	    Arc_ptr jarchead = jarc;
831c2c66affSColin Finck 	    do {
832c2c66affSColin Finck 		slicer.outline( jarc );
833c2c66affSColin Finck 		jarc->clearmark();
834c2c66affSColin Finck 		jarc = jarc->prev;
835c2c66affSColin Finck 	    } while (jarc != jarchead);
836c2c66affSColin Finck 	}
837c2c66affSColin Finck     }
838c2c66affSColin Finck }
839c2c66affSColin Finck 
840c2c66affSColin Finck /*---------------------------------------------------------------------------
841c2c66affSColin Finck  * freejarcs - free all arcs in a bin
842c2c66affSColin Finck  *---------------------------------------------------------------------------
843c2c66affSColin Finck  */
844c2c66affSColin Finck 
845c2c66affSColin Finck void
freejarcs(Bin & bin)846c2c66affSColin Finck Subdivider::freejarcs( Bin& bin )
847c2c66affSColin Finck {
848c2c66affSColin Finck     bin.adopt();	/* XXX - should not be necessary */
849c2c66affSColin Finck 
850c2c66affSColin Finck     Arc_ptr jarc;
851c2c66affSColin Finck     while( (jarc = bin.removearc()) != NULL ) {
852*95269bc8STimo Kreuzer 	if( jarc->pwlArc ) jarc->pwlArc->deleteMe( pwlarcpool );
853*95269bc8STimo Kreuzer     jarc->pwlArc = 0;
854*95269bc8STimo Kreuzer 	if( jarc->bezierArc) jarc->bezierArc->deleteMe( bezierarcpool );
855*95269bc8STimo Kreuzer     jarc->bezierArc = 0;
856c2c66affSColin Finck 	jarc->deleteMe( arcpool );
857c2c66affSColin Finck     }
858c2c66affSColin Finck }
859c2c66affSColin Finck 
860c2c66affSColin Finck /*----------------------------------------------------------------------------
861c2c66affSColin Finck  * tessellate - tessellate all Bezier arcs in a bin
862c2c66affSColin Finck  * 		   1) only accepts linear Bezier arcs as input
863c2c66affSColin Finck  * 		   2) the Bezier arcs are stored in the pwlArc structure
864c2c66affSColin Finck  * 		   3) only vertical or horizontal lines work
865c2c66affSColin Finck  * 		-- should
866c2c66affSColin Finck  * 		   1) represent Bezier arcs in BezierArc structure
867c2c66affSColin Finck  * 		      (this requires a multitude of changes to the code)
868c2c66affSColin Finck  * 		   2) accept high degree Bezier arcs (hard)
869c2c66affSColin Finck  * 		   3) map the curve onto the surface to determine tessellation
870c2c66affSColin Finck  * 		   4) work for curves of arbitrary geometry
871c2c66affSColin Finck  *----------------------------------------------------------------------------
872c2c66affSColin Finck  */
873c2c66affSColin Finck 
874c2c66affSColin Finck 
875c2c66affSColin Finck void
tessellate(Bin & bin,REAL rrate,REAL trate,REAL lrate,REAL brate)876c2c66affSColin Finck Subdivider::tessellate( Bin& bin, REAL rrate, REAL trate, REAL lrate, REAL brate )
877c2c66affSColin Finck {
878c2c66affSColin Finck     for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {
879c2c66affSColin Finck 	if( jarc->isbezier( ) ) {
880c2c66affSColin Finck     	    assert( jarc->pwlArc->npts == 2 );
881c2c66affSColin Finck 	    TrimVertex  *pts = jarc->pwlArc->pts;
882c2c66affSColin Finck     	    REAL s1 = pts[0].param[0];
883c2c66affSColin Finck     	    REAL t1 = pts[0].param[1];
884c2c66affSColin Finck     	    REAL s2 = pts[1].param[0];
885c2c66affSColin Finck     	    REAL t2 = pts[1].param[1];
886c2c66affSColin Finck 
887c2c66affSColin Finck     	    jarc->pwlArc->deleteMe( pwlarcpool ); jarc->pwlArc = 0;
888c2c66affSColin Finck 
889c2c66affSColin Finck 	    switch( jarc->getside() ) {
890c2c66affSColin Finck 		case arc_left:
891c2c66affSColin Finck 		    assert( s1 == s2 );
892c2c66affSColin Finck 		    arctessellator.pwl_left( jarc, s1, t1, t2, lrate );
893c2c66affSColin Finck 		    break;
894c2c66affSColin Finck 		case arc_right:
895c2c66affSColin Finck 		    assert( s1 == s2 );
896c2c66affSColin Finck 		    arctessellator.pwl_right( jarc, s1, t1, t2, rrate );
897c2c66affSColin Finck 		    break;
898c2c66affSColin Finck 		case arc_top:
899c2c66affSColin Finck 		    assert( t1 == t2 );
900c2c66affSColin Finck 		    arctessellator.pwl_top( jarc, t1, s1, s2, trate );
901c2c66affSColin Finck 		    break;
902c2c66affSColin Finck 		case arc_bottom:
903c2c66affSColin Finck 		    assert( t1 == t2 );
904c2c66affSColin Finck 		    arctessellator.pwl_bottom( jarc, t1, s1, s2, brate );
905c2c66affSColin Finck 		    break;
906c2c66affSColin Finck 		case arc_none:
907c2c66affSColin Finck 		    (void) abort();
908c2c66affSColin Finck 		    break;
909c2c66affSColin Finck 	    }
910c2c66affSColin Finck 	    assert( ! jarc->isbezier() );
911c2c66affSColin Finck     	    assert( jarc->check() != 0 );
912c2c66affSColin Finck 	}
913c2c66affSColin Finck     }
914c2c66affSColin Finck }
915