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