1f220fa62Smrg/*
2f220fa62Smrg** License Applicability. Except to the extent portions of this file are
3f220fa62Smrg** made subject to an alternative license as permitted in the SGI Free
4f220fa62Smrg** Software License B, Version 1.1 (the "License"), the contents of this
5f220fa62Smrg** file are subject only to the provisions of the License. You may not use
6f220fa62Smrg** this file except in compliance with the License. You may obtain a copy
7f220fa62Smrg** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8f220fa62Smrg** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
9f220fa62Smrg**
10f220fa62Smrg** http://oss.sgi.com/projects/FreeB
11f220fa62Smrg**
12f220fa62Smrg** Note that, as provided in the License, the Software is distributed on an
13f220fa62Smrg** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14f220fa62Smrg** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15f220fa62Smrg** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16f220fa62Smrg** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
17f220fa62Smrg**
18f220fa62Smrg** Original Code. The Original Code is: OpenGL Sample Implementation,
19f220fa62Smrg** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20f220fa62Smrg** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21f220fa62Smrg** Copyright in any portions created by third parties is as indicated
22f220fa62Smrg** elsewhere herein. All Rights Reserved.
23f220fa62Smrg**
24f220fa62Smrg** Additional Notice Provisions: The application programming interfaces
25f220fa62Smrg** established by SGI in conjunction with the Original Code are The
26f220fa62Smrg** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27f220fa62Smrg** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28f220fa62Smrg** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29f220fa62Smrg** Window System(R) (Version 1.3), released October 19, 1998. This software
30f220fa62Smrg** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31f220fa62Smrg** published by SGI, but has not been independently verified as being
32f220fa62Smrg** compliant with the OpenGL(R) version 1.2.1 Specification.
33f220fa62Smrg*/
34f220fa62Smrg
35f220fa62Smrg/*
36f220fa62Smrg * ccw.c++
37f220fa62Smrg *
38f220fa62Smrg */
39f220fa62Smrg
40f220fa62Smrg#include "glimports.h"
41f220fa62Smrg#include "mystdio.h"
42f220fa62Smrg#include "myassert.h"
43f220fa62Smrg#include "subdivider.h"
44f220fa62Smrg#include "types.h"
45f220fa62Smrg#include "arc.h"
46f220fa62Smrg#include "trimvertex.h"
47f220fa62Smrg#include "simplemath.h"
48f220fa62Smrg
49f220fa62Smrginline int
50f220fa62SmrgSubdivider::bbox( TrimVertex *a, TrimVertex *b, TrimVertex *c, int p )
51f220fa62Smrg{
52f220fa62Smrg    return bbox( a->param[p], b->param[p], c->param[p],
53f220fa62Smrg	         a->param[1-p], b->param[1-p], c->param[1-p] );
54f220fa62Smrg}
55f220fa62Smrg
56f220fa62Smrgint
57f220fa62SmrgSubdivider::ccwTurn_sr( Arc_ptr j1, Arc_ptr j2 ) // dir = 1
58f220fa62Smrg{
59e7980a23Smrg    TrimVertex *v1	= &j1->pwlArc->pts[j1->pwlArc->npts-1];
60e7980a23Smrg    TrimVertex *v1last	= &j1->pwlArc->pts[0];
61e7980a23Smrg    TrimVertex *v2	= &j2->pwlArc->pts[0];
62e7980a23Smrg    TrimVertex *v2last	= &j2->pwlArc->pts[j2->pwlArc->npts-1];
63e7980a23Smrg    TrimVertex *v1next	= v1-1;
64e7980a23Smrg    TrimVertex *v2next	= v2+1;
65f220fa62Smrg    int sgn;
66f220fa62Smrg
67f220fa62Smrg    assert( v1 != v1last );
68f220fa62Smrg    assert( v2 != v2last );
69f220fa62Smrg
70f220fa62Smrg#ifndef NDEBUG
71f220fa62Smrg    _glu_dprintf( "arc_ccw_turn, p = %d\n", 0 );
72f220fa62Smrg#endif
73f220fa62Smrg
74f220fa62Smrg    // the arcs lie on the line (0 == v1->param[0])
75f220fa62Smrg    if( v1->param[0] == v1next->param[0] && v2->param[0] == v2next->param[0] )
76f220fa62Smrg	return 0;
77f220fa62Smrg
78f220fa62Smrg    if( v2next->param[0] < v2->param[0] || v1next->param[0] < v1->param[0] )
79f220fa62Smrg	::mylongjmp( jumpbuffer, 28 );
80f220fa62Smrg
81f220fa62Smrg    if( v1->param[1] < v2->param[1] )
82f220fa62Smrg	return 0;
83f220fa62Smrg    else if( v1->param[1] > v2->param[1] )
84f220fa62Smrg	return 1;
85f220fa62Smrg
86f220fa62Smrg    while( 1 ) {
87f220fa62Smrg	if( v1next->param[0] < v2next->param[0] ) {
88f220fa62Smrg#ifndef NDEBUG
89f220fa62Smrg	    _glu_dprintf( "case a\n" );
90f220fa62Smrg#endif
91f220fa62Smrg	    assert( v1->param[0] <= v1next->param[0] );
92f220fa62Smrg	    assert( v2->param[0] <= v1next->param[0] );
93f220fa62Smrg	    switch( bbox( v2, v2next, v1next, 1 ) ) {
94f220fa62Smrg		case -1:
95f220fa62Smrg		    return 0;
96f220fa62Smrg		case 0:
97f220fa62Smrg		   sgn = ccw( v1next, v2, v2next );
98f220fa62Smrg		   if( sgn != -1 ) {
99f220fa62Smrg			return sgn;
100f220fa62Smrg		   } else {
101f220fa62Smrg#ifdef DEBUG
102f220fa62Smrg			_glu_dprintf( "decr\n" );
103f220fa62Smrg#endif
104f220fa62Smrg			v1 = v1next--;
105f220fa62Smrg			if( v1 == v1last ) {
106f220fa62Smrg#ifdef DEBUG
107f220fa62Smrg			    _glu_dprintf( "no good results\n" );
108f220fa62Smrg#endif
109f220fa62Smrg			    return 0; // ill-conditioned, guess answer
110f220fa62Smrg			}
111f220fa62Smrg		    }
112f220fa62Smrg		    break;
113f220fa62Smrg		case 1:
114f220fa62Smrg		    return 1;
115f220fa62Smrg	    }
116f220fa62Smrg	} else if( v1next->param[0] > v2next->param[0] ) {
117f220fa62Smrg#ifndef NDEBUG
118f220fa62Smrg	    _glu_dprintf( "case b\n" );
119f220fa62Smrg#endif
120f220fa62Smrg	    assert( v1->param[0] <= v2next->param[0] );
121f220fa62Smrg	    assert( v2->param[0] <= v2next->param[0] );
122f220fa62Smrg	    switch( bbox( v1, v1next, v2next, 1 ) ) {
123f220fa62Smrg		case -1:
124f220fa62Smrg		    return 1;
125f220fa62Smrg		case 0:
126f220fa62Smrg		   sgn = ccw( v1next, v1, v2next );
127f220fa62Smrg		   if( sgn != -1 ) {
128f220fa62Smrg			return sgn;
129f220fa62Smrg		   } else {
130f220fa62Smrg#ifdef DEBUG
131f220fa62Smrg			_glu_dprintf( "incr\n" );
132f220fa62Smrg#endif
133f220fa62Smrg			v2 = v2next++;
134f220fa62Smrg			if( v2 == v2last ) {
135f220fa62Smrg#ifdef DEBUG
136f220fa62Smrg			    _glu_dprintf( "no good results\n" );
137f220fa62Smrg#endif
138f220fa62Smrg			    return 0; // ill-conditioned, guess answer
139f220fa62Smrg			}
140f220fa62Smrg		    }
141f220fa62Smrg		    break;
142f220fa62Smrg		case 1:
143f220fa62Smrg		    return 0;
144f220fa62Smrg	    }
145f220fa62Smrg	} else {
146f220fa62Smrg#ifndef NDEBUG
147f220fa62Smrg	    _glu_dprintf( "case ab\n" );
148f220fa62Smrg#endif
149f220fa62Smrg	    if( v1next->param[1] < v2next->param[1] )
150f220fa62Smrg		return 0;
151f220fa62Smrg	    else if( v1next->param[1] > v2next->param[1] )
152f220fa62Smrg		return 1;
153f220fa62Smrg	    else {
154f220fa62Smrg#ifdef DEBUG
155f220fa62Smrg		_glu_dprintf( "incr\n" );
156f220fa62Smrg#endif
157f220fa62Smrg		v2 = v2next++;
158f220fa62Smrg		if( v2 == v2last ) {
159f220fa62Smrg#ifdef DEBUG
160f220fa62Smrg		    _glu_dprintf( "no good results\n" );
161f220fa62Smrg#endif
162f220fa62Smrg		    return 0; // ill-conditioned, guess answer
163f220fa62Smrg		}
164f220fa62Smrg	    }
165f220fa62Smrg	}
166f220fa62Smrg    }
167f220fa62Smrg}
168f220fa62Smrg
169f220fa62Smrgint
170f220fa62SmrgSubdivider::ccwTurn_sl( Arc_ptr j1, Arc_ptr j2 ) // dir = 0
171f220fa62Smrg{
172e7980a23Smrg    TrimVertex *v1	= &j1->pwlArc->pts[j1->pwlArc->npts-1];
173e7980a23Smrg    TrimVertex *v1last	= &j1->pwlArc->pts[0];
174e7980a23Smrg    TrimVertex *v2	= &j2->pwlArc->pts[0];
175e7980a23Smrg    TrimVertex *v2last	= &j2->pwlArc->pts[j2->pwlArc->npts-1];
176e7980a23Smrg    TrimVertex *v1next	= v1-1;
177e7980a23Smrg    TrimVertex *v2next	= v2+1;
178f220fa62Smrg    int sgn;
179f220fa62Smrg
180f220fa62Smrg    assert( v1 != v1last );
181f220fa62Smrg    assert( v2 != v2last );
182f220fa62Smrg
183f220fa62Smrg#ifndef NDEBUG
184f220fa62Smrg    _glu_dprintf( "arc_ccw_turn, p = %d\n", 0 );
185f220fa62Smrg#endif
186f220fa62Smrg
187f220fa62Smrg    // the arcs lie on the line (0 == v1->param[0])
188f220fa62Smrg    if( v1->param[0] == v1next->param[0] && v2->param[0] == v2next->param[0] )
189f220fa62Smrg	return 0;
190f220fa62Smrg
191f220fa62Smrg    if( v2next->param[0] > v2->param[0] || v1next->param[0] > v1->param[0] )
192f220fa62Smrg	::mylongjmp( jumpbuffer, 28 );
193f220fa62Smrg
194f220fa62Smrg    if( v1->param[1] < v2->param[1] )
195f220fa62Smrg	return 1;
196f220fa62Smrg    else if( v1->param[1] > v2->param[1] )
197f220fa62Smrg	return 0;
198f220fa62Smrg
199f220fa62Smrg    while( 1 ) {
200f220fa62Smrg	if( v1next->param[0] > v2next->param[0] ) {
201f220fa62Smrg#ifndef NDEBUG
202f220fa62Smrg	    _glu_dprintf( "case c\n" );
203f220fa62Smrg#endif
204f220fa62Smrg	    assert( v1->param[0] >= v1next->param[0] );
205f220fa62Smrg	    assert( v2->param[0] >= v1next->param[0] );
206f220fa62Smrg	    switch( bbox( v2next, v2, v1next, 1 ) ) {
207f220fa62Smrg		case -1:
208f220fa62Smrg		    return 1;
209f220fa62Smrg		case 0:
210f220fa62Smrg		    sgn = ccw( v1next, v2, v2next );
211f220fa62Smrg		    if( sgn != -1 )
212f220fa62Smrg			return sgn;
213f220fa62Smrg		    else {
214f220fa62Smrg			v1 = v1next--;
215f220fa62Smrg#ifdef DEBUG
216f220fa62Smrg			_glu_dprintf( "decr\n" );
217f220fa62Smrg#endif
218f220fa62Smrg			if( v1 == v1last ) {
219f220fa62Smrg#ifdef DEBUG
220f220fa62Smrg			    _glu_dprintf( "no good results\n" );
221f220fa62Smrg#endif
222f220fa62Smrg			    return 0; // ill-conditioned, guess answer
223f220fa62Smrg			}
224f220fa62Smrg		    }
225f220fa62Smrg		    break;
226f220fa62Smrg		case 1:
227f220fa62Smrg		    return 0;
228f220fa62Smrg	    }
229f220fa62Smrg	} else if( v1next->param[0] < v2next->param[0] ) {
230f220fa62Smrg#ifndef NDEBUG
231f220fa62Smrg	    _glu_dprintf( "case d\n" );
232f220fa62Smrg#endif
233f220fa62Smrg	    assert( v1->param[0] >= v2next->param[0] );
234f220fa62Smrg	    assert( v2->param[0] >= v2next->param[0] );
235f220fa62Smrg	    switch( bbox( v1next, v1, v2next, 1 ) ) {
236f220fa62Smrg		case -1:
237f220fa62Smrg		    return 0;
238f220fa62Smrg		case 0:
239f220fa62Smrg		    sgn = ccw( v1next, v1, v2next );
240f220fa62Smrg		    if( sgn != -1 )
241f220fa62Smrg			return sgn;
242f220fa62Smrg		    else {
243f220fa62Smrg			v2 = v2next++;
244f220fa62Smrg#ifdef DEBUG
245f220fa62Smrg			_glu_dprintf( "incr\n" );
246f220fa62Smrg#endif
247f220fa62Smrg			if( v2 == v2last ) {
248f220fa62Smrg#ifdef DEBUG
249f220fa62Smrg			    _glu_dprintf( "no good results\n" );
250f220fa62Smrg#endif
251f220fa62Smrg			    return 0; // ill-conditioned, guess answer
252f220fa62Smrg			}
253f220fa62Smrg		    }
254f220fa62Smrg		    break;
255f220fa62Smrg		case 1:
256f220fa62Smrg		    return 1;
257f220fa62Smrg	    }
258f220fa62Smrg	} else {
259f220fa62Smrg#ifdef DEBUG
260f220fa62Smrg	    _glu_dprintf( "case cd\n" );
261f220fa62Smrg#endif
262f220fa62Smrg	    if( v1next->param[1] < v2next->param[1] )
263f220fa62Smrg		return 1;
264f220fa62Smrg	    else if( v1next->param[1] > v2next->param[1] )
265f220fa62Smrg		return 0;
266f220fa62Smrg	    else {
267f220fa62Smrg		v2 = v2next++;
268f220fa62Smrg#ifdef DEBUG
269f220fa62Smrg		_glu_dprintf( "incr\n" );
270f220fa62Smrg#endif
271f220fa62Smrg		if( v2 == v2last ) {
272f220fa62Smrg#ifdef DEBUG
273f220fa62Smrg		    _glu_dprintf( "no good results\n" );
274f220fa62Smrg#endif
275f220fa62Smrg		    return 0; // ill-conditioned, guess answer
276f220fa62Smrg		}
277f220fa62Smrg	    }
278f220fa62Smrg	}
279f220fa62Smrg    }
280f220fa62Smrg}
281f220fa62Smrg
282f220fa62Smrgint
283f220fa62SmrgSubdivider::ccwTurn_tr( Arc_ptr j1, Arc_ptr j2 ) // dir = 1
284f220fa62Smrg{
285e7980a23Smrg    TrimVertex *v1	= &j1->pwlArc->pts[j1->pwlArc->npts-1];
286e7980a23Smrg    TrimVertex *v1last	= &j1->pwlArc->pts[0];
287e7980a23Smrg    TrimVertex *v2	= &j2->pwlArc->pts[0];
288e7980a23Smrg    TrimVertex *v2last	= &j2->pwlArc->pts[j2->pwlArc->npts-1];
289e7980a23Smrg    TrimVertex *v1next	= v1-1;
290e7980a23Smrg    TrimVertex *v2next	= v2+1;
291f220fa62Smrg    int sgn;
292f220fa62Smrg
293f220fa62Smrg    assert( v1 != v1last );
294f220fa62Smrg    assert( v2 != v2last );
295f220fa62Smrg
296f220fa62Smrg#ifndef NDEBUG
297f220fa62Smrg    _glu_dprintf( "arc_ccw_turn, p = %d\n", 1 );
298f220fa62Smrg#endif
299f220fa62Smrg
300f220fa62Smrg    // the arcs lie on the line (1 == v1->param[1])
301f220fa62Smrg    if( v1->param[1] == v1next->param[1] && v2->param[1] == v2next->param[1] )
302f220fa62Smrg	return 0;
303f220fa62Smrg
304f220fa62Smrg    if( v2next->param[1] < v2->param[1] || v1next->param[1] < v1->param[1] )
305f220fa62Smrg	::mylongjmp( jumpbuffer, 28 );
306f220fa62Smrg
307f220fa62Smrg    if( v1->param[0] < v2->param[0] )
308f220fa62Smrg	return 1;
309f220fa62Smrg    else if( v1->param[0] > v2->param[0] )
310f220fa62Smrg	return 0;
311f220fa62Smrg
312f220fa62Smrg    while( 1 ) {
313f220fa62Smrg	if( v1next->param[1] < v2next->param[1] ) {
314f220fa62Smrg#ifndef NDEBUG
315f220fa62Smrg	    _glu_dprintf( "case a\n" );
316f220fa62Smrg#endif
317f220fa62Smrg	    assert( v1->param[1] <= v1next->param[1] );
318f220fa62Smrg	    assert( v2->param[1] <= v1next->param[1] );
319f220fa62Smrg	    switch( bbox( v2, v2next, v1next, 0 ) ) {
320f220fa62Smrg		case -1:
321f220fa62Smrg		    return 1;
322f220fa62Smrg		case 0:
323f220fa62Smrg		   sgn = ccw( v1next, v2, v2next );
324f220fa62Smrg		   if( sgn != -1 ) {
325f220fa62Smrg			return sgn;
326f220fa62Smrg		   } else {
327f220fa62Smrg#ifdef DEBUG
328f220fa62Smrg			_glu_dprintf( "decr\n" );
329f220fa62Smrg#endif
330f220fa62Smrg			v1 = v1next--;
331f220fa62Smrg			if( v1 == v1last ) {
332f220fa62Smrg#ifdef DEBUG
333f220fa62Smrg			    _glu_dprintf( "no good results\n" );
334f220fa62Smrg#endif
335f220fa62Smrg			    return 0; // ill-conditioned, guess answer
336f220fa62Smrg			}
337f220fa62Smrg		    }
338f220fa62Smrg		    break;
339f220fa62Smrg		case 1:
340f220fa62Smrg		    return 0;
341f220fa62Smrg	    }
342f220fa62Smrg	} else if( v1next->param[1] > v2next->param[1] ) {
343f220fa62Smrg#ifndef NDEBUG
344f220fa62Smrg	    _glu_dprintf( "case b\n" );
345f220fa62Smrg#endif
346f220fa62Smrg	    assert( v1->param[1] <= v2next->param[1] );
347f220fa62Smrg	    assert( v2->param[1] <= v2next->param[1] );
348f220fa62Smrg	    switch( bbox( v1, v1next, v2next, 0 ) ) {
349f220fa62Smrg		case -1:
350f220fa62Smrg		    return 0;
351f220fa62Smrg		case 0:
352f220fa62Smrg		   sgn = ccw( v1next, v1, v2next );
353f220fa62Smrg		   if( sgn != -1 ) {
354f220fa62Smrg			return sgn;
355f220fa62Smrg		   } else {
356f220fa62Smrg#ifdef DEBUG
357f220fa62Smrg			_glu_dprintf( "incr\n" );
358f220fa62Smrg#endif
359f220fa62Smrg			v2 = v2next++;
360f220fa62Smrg			if( v2 == v2last ) {
361f220fa62Smrg#ifdef DEBUG
362f220fa62Smrg			    _glu_dprintf( "no good results\n" );
363f220fa62Smrg#endif
364f220fa62Smrg			    return 0; // ill-conditioned, guess answer
365f220fa62Smrg			}
366f220fa62Smrg		    }
367f220fa62Smrg		    break;
368f220fa62Smrg		case 1:
369f220fa62Smrg		    return 1;
370f220fa62Smrg	    }
371f220fa62Smrg	} else {
372f220fa62Smrg#ifdef DEBUG
373f220fa62Smrg	    _glu_dprintf( "case ab\n" );
374f220fa62Smrg#endif
375f220fa62Smrg	    if( v1next->param[0] < v2next->param[0] )
376f220fa62Smrg		return 1;
377f220fa62Smrg	    else if( v1next->param[0] > v2next->param[0] )
378f220fa62Smrg		return 0;
379f220fa62Smrg	    else {
380f220fa62Smrg#ifdef DEBUG
381f220fa62Smrg		_glu_dprintf( "incr\n" );
382f220fa62Smrg#endif
383f220fa62Smrg		v2 = v2next++;
384f220fa62Smrg		if( v2 == v2last ) {
385f220fa62Smrg#ifdef DEBUG
386f220fa62Smrg		    _glu_dprintf( "no good results\n" );
387f220fa62Smrg#endif
388f220fa62Smrg		    return 0; // ill-conditioned, guess answer
389f220fa62Smrg		}
390f220fa62Smrg	    }
391f220fa62Smrg	}
392f220fa62Smrg    }
393f220fa62Smrg}
394f220fa62Smrg
395f220fa62Smrgint
396f220fa62SmrgSubdivider::ccwTurn_tl( Arc_ptr j1, Arc_ptr j2 )
397f220fa62Smrg{
398e7980a23Smrg    TrimVertex *v1	= &j1->pwlArc->pts[j1->pwlArc->npts-1];
399e7980a23Smrg    TrimVertex *v1last	= &j1->pwlArc->pts[0];
400e7980a23Smrg    TrimVertex *v2	= &j2->pwlArc->pts[0];
401e7980a23Smrg    TrimVertex *v2last	= &j2->pwlArc->pts[j2->pwlArc->npts-1];
402e7980a23Smrg    TrimVertex *v1next	= v1-1;
403e7980a23Smrg    TrimVertex *v2next	= v2+1;
404f220fa62Smrg    int sgn;
405f220fa62Smrg
406f220fa62Smrg    assert( v1 != v1last );
407f220fa62Smrg    assert( v2 != v2last );
408f220fa62Smrg
409f220fa62Smrg#ifndef NDEBUG
410f220fa62Smrg    _glu_dprintf( "arc_ccw_turn, p = %d\n", 1 );
411f220fa62Smrg#endif
412f220fa62Smrg
413f220fa62Smrg    // the arcs lie on the line (1 == v1->param[1])
414f220fa62Smrg    if( v1->param[1] == v1next->param[1] && v2->param[1] == v2next->param[1] )
415f220fa62Smrg	return 0;
416f220fa62Smrg
417f220fa62Smrg    if( v2next->param[1] > v2->param[1] || v1next->param[1] > v1->param[1] )
418f220fa62Smrg	::mylongjmp( jumpbuffer, 28 );
419f220fa62Smrg
420f220fa62Smrg    if( v1->param[0] < v2->param[0] )
421f220fa62Smrg	return 0;
422f220fa62Smrg    else if( v1->param[0] > v2->param[0] )
423f220fa62Smrg	return 1;
424f220fa62Smrg
425f220fa62Smrg    while( 1 ) {
426f220fa62Smrg	if( v1next->param[1] > v2next->param[1] ) {
427f220fa62Smrg#ifndef NDEBUG
428f220fa62Smrg	    _glu_dprintf( "case c\n" );
429f220fa62Smrg#endif
430f220fa62Smrg	    assert( v1->param[1] >= v1next->param[1] );
431f220fa62Smrg	    assert( v2->param[1] >= v1next->param[1] );
432f220fa62Smrg	    switch( bbox( v2next, v2, v1next, 0 ) ) {
433f220fa62Smrg		case -1:
434f220fa62Smrg		    return 0;
435f220fa62Smrg		case 0:
436f220fa62Smrg		    sgn = ccw( v1next, v2, v2next );
437f220fa62Smrg		    if( sgn != -1 )
438f220fa62Smrg			return sgn;
439f220fa62Smrg		    else {
440f220fa62Smrg			v1 = v1next--;
441f220fa62Smrg#ifdef DEBUG
442f220fa62Smrg			_glu_dprintf( "decr\n" );
443f220fa62Smrg#endif
444f220fa62Smrg			if( v1 == v1last ) {
445f220fa62Smrg#ifdef DEBUG
446f220fa62Smrg			    _glu_dprintf( "no good results\n" );
447f220fa62Smrg#endif
448f220fa62Smrg			    return 0; // ill-conditioned, guess answer
449f220fa62Smrg			}
450f220fa62Smrg		    }
451f220fa62Smrg		    break;
452f220fa62Smrg		case 1:
453f220fa62Smrg		    return 1;
454f220fa62Smrg	    }
455f220fa62Smrg	} else if( v1next->param[1] < v2next->param[1] ) {
456f220fa62Smrg#ifndef NDEBUG
457f220fa62Smrg	    _glu_dprintf( "case d\n" );
458f220fa62Smrg	    assert( v1->param[1] >= v2next->param[1] );
459f220fa62Smrg	    assert( v2->param[1] >= v2next->param[1] );
460f220fa62Smrg#endif
461f220fa62Smrg	    switch( bbox( v1next, v1, v2next, 0 ) ) {
462f220fa62Smrg		case -1:
463f220fa62Smrg		    return 1;
464f220fa62Smrg		case 0:
465f220fa62Smrg		    sgn = ccw( v1next, v1, v2next );
466f220fa62Smrg		    if( sgn != -1 )
467f220fa62Smrg			return sgn;
468f220fa62Smrg		    else {
469f220fa62Smrg			v2 = v2next++;
470f220fa62Smrg#ifdef DEBUG
471f220fa62Smrg			_glu_dprintf( "incr\n" );
472f220fa62Smrg#endif
473f220fa62Smrg			if( v2 == v2last ) {
474f220fa62Smrg#ifdef DEBUG
475f220fa62Smrg			    _glu_dprintf( "no good results\n" );
476f220fa62Smrg#endif
477f220fa62Smrg			    return 0; // ill-conditioned, guess answer
478f220fa62Smrg			}
479f220fa62Smrg		    }
480f220fa62Smrg		    break;
481f220fa62Smrg		case 1:
482f220fa62Smrg		    return 0;
483f220fa62Smrg	    }
484f220fa62Smrg	} else {
485f220fa62Smrg#ifdef DEBUG
486f220fa62Smrg	    _glu_dprintf( "case cd\n" );
487f220fa62Smrg#endif
488f220fa62Smrg	    if( v1next->param[0] < v2next->param[0] )
489f220fa62Smrg		return 0;
490f220fa62Smrg	    else if( v1next->param[0] > v2next->param[0] )
491f220fa62Smrg		return 1;
492f220fa62Smrg	    else {
493f220fa62Smrg		v2 = v2next++;
494f220fa62Smrg#ifdef DEBUG
495f220fa62Smrg		_glu_dprintf( "incr\n" );
496f220fa62Smrg#endif
497f220fa62Smrg		if( v2 == v2last ) {
498f220fa62Smrg#ifdef DEBUG
499f220fa62Smrg		    _glu_dprintf( "no good results\n" );
500f220fa62Smrg#endif
501f220fa62Smrg		    return 0; // ill-conditioned, guess answer
502f220fa62Smrg		}
503f220fa62Smrg	    }
504f220fa62Smrg	}
505f220fa62Smrg    }
506f220fa62Smrg}
507f220fa62Smrg
508f220fa62Smrg
509f220fa62Smrg#ifndef NDEBUG
510f220fa62Smrgint
511e7980a23SmrgSubdivider::bbox( REAL sa, REAL sb, REAL sc, REAL ta, REAL tb, REAL tc )
512f220fa62Smrg#else
513f220fa62Smrgint
514e7980a23SmrgSubdivider::bbox( REAL sa, REAL sb, REAL sc, REAL   , REAL   , REAL    )
515f220fa62Smrg#endif
516f220fa62Smrg{
517f220fa62Smrg#ifndef NDEBUG
518f220fa62Smrg    assert( tc >= ta );
519f220fa62Smrg    assert( tc <= tb );
520f220fa62Smrg#endif
521f220fa62Smrg
522f220fa62Smrg    if( sa < sb ) {
523f220fa62Smrg	if( sc <= sa ) {
524f220fa62Smrg	    return -1;
525f220fa62Smrg	} else if( sb <= sc ) {
526f220fa62Smrg	    return 1;
527f220fa62Smrg	} else {
528f220fa62Smrg	    return 0;
529f220fa62Smrg	}
530f220fa62Smrg    } else if( sa > sb ) {
531f220fa62Smrg	if( sc >= sa ) {
532f220fa62Smrg	    return 1;
533f220fa62Smrg	} else if( sb >= sc ) {
534f220fa62Smrg	    return -1;
535f220fa62Smrg	} else {
536f220fa62Smrg	    return 0;
537f220fa62Smrg	}
538f220fa62Smrg    } else {
539f220fa62Smrg	if( sc > sa ) {
540f220fa62Smrg	    return 1;
541f220fa62Smrg	} else if( sb > sc ) {
542f220fa62Smrg	    return -1;
543f220fa62Smrg	} else {
544f220fa62Smrg	    return 0;
545f220fa62Smrg	}
546f220fa62Smrg    }
547f220fa62Smrg}
548f220fa62Smrg
549f220fa62Smrg/*----------------------------------------------------------------------------
550f220fa62Smrg * ccw - determine how three points are oriented by computing their
551f220fa62Smrg *	 determinant.
552f220fa62Smrg *	 Return 1 if the vertices are ccw oriented,
553f220fa62Smrg *		0 if they are cw oriented, or
554f220fa62Smrg *		-1 if the computation is ill-conditioned.
555f220fa62Smrg *----------------------------------------------------------------------------
556f220fa62Smrg */
557f220fa62Smrgint
558f220fa62SmrgSubdivider::ccw( TrimVertex *a, TrimVertex *b, TrimVertex *c )
559f220fa62Smrg{
560f220fa62Smrg    REAL d = det3( a, b, c );
561f220fa62Smrg    if( glu_abs(d) < 0.0001 ) return -1;
562f220fa62Smrg    return (d < 0.0) ? 0 : 1;
563f220fa62Smrg}
564