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 * arc.c++
37f220fa62Smrg *
38f220fa62Smrg */
39f220fa62Smrg
40f220fa62Smrg#include <stdio.h>
41f220fa62Smrg#include "glimports.h"
42f220fa62Smrg#include "mystdio.h"
43f220fa62Smrg#include "myassert.h"
44f220fa62Smrg#include "arc.h"
45f220fa62Smrg#include "bin.h"
46f220fa62Smrg#include "pwlarc.h"
47f220fa62Smrg#include "simplemath.h"
48f220fa62Smrg
49f220fa62Smrg/* local preprocessor definitions */
50f220fa62Smrg#define ZERO		0.00001/*0.000001*/
51f220fa62Smrg
52f220fa62Smrgconst int	Arc::bezier_tag = (1<<13);
53f220fa62Smrgconst int	Arc::arc_tag = (1<<3);
54f220fa62Smrgconst int	Arc::tail_tag = (1<<6);
55f220fa62Smrg
56f220fa62Smrg/*--------------------------------------------------------------------------
57f220fa62Smrg * makeSide - attach a pwl arc to an arc and mark it as a border arc
58f220fa62Smrg *--------------------------------------------------------------------------
59f220fa62Smrg */
60f220fa62Smrg
61f220fa62Smrgvoid
62f220fa62SmrgArc::makeSide( PwlArc *pwl, arc_side side )
63f220fa62Smrg{
64f220fa62Smrg    assert( pwl != 0);
65f220fa62Smrg    assert( pwlArc == 0 );
66f220fa62Smrg    assert( pwl->npts > 0 );
67f220fa62Smrg    assert( pwl->pts != 0);
68f220fa62Smrg    pwlArc = pwl;
69f220fa62Smrg    clearbezier();
70f220fa62Smrg    setside( side );
71f220fa62Smrg}
72f220fa62Smrg
73f220fa62Smrg
74f220fa62Smrg/*--------------------------------------------------------------------------
75f220fa62Smrg * numpts - count number of points on arc loop
76f220fa62Smrg *--------------------------------------------------------------------------
77f220fa62Smrg */
78f220fa62Smrg
79f220fa62Smrgint
80f220fa62SmrgArc::numpts( void )
81f220fa62Smrg{
82f220fa62Smrg    Arc_ptr jarc = this;
83f220fa62Smrg    int npts = 0;
84f220fa62Smrg    do {
85f220fa62Smrg	npts += jarc->pwlArc->npts;
86f220fa62Smrg	jarc = jarc->next;
87f220fa62Smrg    } while( jarc != this );
88f220fa62Smrg    return npts;
89f220fa62Smrg}
90f220fa62Smrg
91f220fa62Smrg/*--------------------------------------------------------------------------
92f220fa62Smrg * markverts - mark each point with id of arc
93f220fa62Smrg *--------------------------------------------------------------------------
94f220fa62Smrg */
95f220fa62Smrg
96f220fa62Smrgvoid
97f220fa62SmrgArc::markverts( void )
98f220fa62Smrg{
99f220fa62Smrg    Arc_ptr jarc = this;
100f220fa62Smrg
101f220fa62Smrg    do {
102f220fa62Smrg	TrimVertex *p = jarc->pwlArc->pts;
103f220fa62Smrg	for( int i=0; i<jarc->pwlArc->npts; i++ )
104f220fa62Smrg	    p[i].nuid = jarc->nuid;
105f220fa62Smrg	jarc = jarc->next;
106f220fa62Smrg    } while( jarc != this );
107f220fa62Smrg}
108f220fa62Smrg
109f220fa62Smrg/*--------------------------------------------------------------------------
110f220fa62Smrg * getextrema - find axis extrema on arc loop
111f220fa62Smrg *--------------------------------------------------------------------------
112f220fa62Smrg */
113f220fa62Smrg
114f220fa62Smrgvoid
115f220fa62SmrgArc::getextrema( Arc_ptr extrema[4] )
116f220fa62Smrg{
117f220fa62Smrg    REAL leftpt, botpt, rightpt, toppt;
118f220fa62Smrg
119f220fa62Smrg    extrema[0] = extrema[1] = extrema[2] = extrema[3] = this;
120f220fa62Smrg
121f220fa62Smrg    leftpt = rightpt = this->tail()[0];
122f220fa62Smrg    botpt  = toppt   = this->tail()[1];
123f220fa62Smrg
124f220fa62Smrg    for( Arc_ptr jarc = this->next; jarc != this; jarc = jarc->next ) {
125f220fa62Smrg	if ( jarc->tail()[0] <	leftpt ||
126f220fa62Smrg	    (jarc->tail()[0] <= leftpt && jarc->rhead()[0]<=leftpt))  {
127f220fa62Smrg	    leftpt = jarc->pwlArc->pts->param[0];
128f220fa62Smrg	    extrema[1] = jarc;
129f220fa62Smrg	}
130f220fa62Smrg	if ( jarc->tail()[0] >	rightpt ||
131f220fa62Smrg	    (jarc->tail()[0] >= rightpt && jarc->rhead()[0] >= rightpt)) {
132f220fa62Smrg	    rightpt = jarc->pwlArc->pts->param[0];
133f220fa62Smrg	    extrema[3] = jarc;
134f220fa62Smrg	}
135f220fa62Smrg	if ( jarc->tail()[1] <	botpt ||
136f220fa62Smrg	    (jarc->tail()[1] <= botpt && jarc->rhead()[1] <= botpt ))  {
137f220fa62Smrg	    botpt = jarc->pwlArc->pts->param[1];
138f220fa62Smrg	    extrema[2] = jarc;
139f220fa62Smrg	}
140f220fa62Smrg	if ( jarc->tail()[1] >	toppt ||
141f220fa62Smrg	    (jarc->tail()[1] >= toppt && jarc->rhead()[1] >= toppt))  {
142f220fa62Smrg	    toppt = jarc->pwlArc->pts->param[1];
143f220fa62Smrg	    extrema[0] = jarc;
144f220fa62Smrg	}
145f220fa62Smrg    }
146f220fa62Smrg}
147f220fa62Smrg
148f220fa62Smrg
149f220fa62Smrg/*-------------------------------------------------------------------------
150f220fa62Smrg * show - print to the stdout the vertices of a pwl arc
151f220fa62Smrg *-------------------------------------------------------------------------
152f220fa62Smrg */
153f220fa62Smrg
154f220fa62Smrgvoid
155f220fa62SmrgArc::show()
156f220fa62Smrg{
157f220fa62Smrg#ifndef NDEBUG
158f220fa62Smrg    _glu_dprintf( "\tPWLARC NP: %d FL: 1\n", pwlArc->npts );
159f220fa62Smrg    for( int i = 0; i < pwlArc->npts; i++ ) {
160f220fa62Smrg	 _glu_dprintf( "\t\tVERTEX %f %f\n", pwlArc->pts[i].param[0],
161f220fa62Smrg			pwlArc->pts[i].param[1] );
162f220fa62Smrg    }
163f220fa62Smrg#endif
164f220fa62Smrg}
165f220fa62Smrg
166f220fa62Smrg/*-------------------------------------------------------------------------
167f220fa62Smrg * print - print out the vertices of all pwl arcs on a loop
168f220fa62Smrg *-------------------------------------------------------------------------
169f220fa62Smrg */
170f220fa62Smrg
171f220fa62Smrgvoid
172f220fa62SmrgArc::print( void )
173f220fa62Smrg{
174f220fa62Smrg    Arc_ptr jarc = this;
175f220fa62Smrg
176f220fa62Smrg#ifndef NDEBUG
177f220fa62Smrg    _glu_dprintf( "BGNTRIM\n" );
178f220fa62Smrg#endif
179f220fa62Smrg    do {
180f220fa62Smrg	jarc->show( );
181f220fa62Smrg	jarc = jarc->next;
182f220fa62Smrg    } while (jarc != this);
183f220fa62Smrg#ifndef NDEBUG
184f220fa62Smrg    _glu_dprintf("ENDTRIM\n" );
185f220fa62Smrg#endif
186f220fa62Smrg}
187f220fa62Smrg
188f220fa62Smrg/*-------------------------------------------------------------------------
189f220fa62Smrg * isDisconnected - check if tail of arc and head of prev meet
190f220fa62Smrg *-------------------------------------------------------------------------
191f220fa62Smrg */
192f220fa62Smrg
193f220fa62Smrgint
194f220fa62SmrgArc::isDisconnected( void )
195f220fa62Smrg{
196f220fa62Smrg    if( pwlArc == 0 ) return 0;
197f220fa62Smrg    if( prev->pwlArc == 0 ) return 0;
198f220fa62Smrg
199f220fa62Smrg    REAL *p0 = tail();
200f220fa62Smrg    REAL *p1 = prev->rhead();
201f220fa62Smrg
202f220fa62Smrg    if( ((p0[0] - p1[0]) > ZERO) || ((p1[0] - p0[0]) > ZERO) ||
203f220fa62Smrg	((p0[1] - p1[1]) > ZERO) || ((p1[1] - p0[1]) > ZERO)  ) {
204f220fa62Smrg#ifndef NDEBUG
205f220fa62Smrg	_glu_dprintf( "x coord = %f %f %f\n", p0[0], p1[0], p0[0] - p1[0] );
206f220fa62Smrg	_glu_dprintf( "y coord = %f %f %f\n", p0[1], p1[1], p0[1] - p1[1] );
207f220fa62Smrg#endif
208f220fa62Smrg	return 1;
209f220fa62Smrg    } else {
210f220fa62Smrg	/* average two points together */
211f220fa62Smrg	p0[0] = p1[0] = (p1[0] + p0[0]) * 0.5;
212f220fa62Smrg	p0[1] = p1[1] = (p1[1] + p0[1]) * 0.5;
213f220fa62Smrg	return 0;
214f220fa62Smrg    }
215f220fa62Smrg}
216f220fa62Smrg
217f220fa62Smrg/*-------------------------------------------------------------------------
218f220fa62Smrg * neq_vert - assert that two 2D vertices are not equal
219f220fa62Smrg *-------------------------------------------------------------------------
220f220fa62Smrg */
221f220fa62Smrg
222f220fa62Smrginline static int
223f220fa62Smrgneq_vert( REAL	*v1, REAL *v2 )
224f220fa62Smrg{
225f220fa62Smrg     return ((v1[0] != v2[0]) || (v1[1] != v2[1] )) ? 1 : 0;
226f220fa62Smrg}
227f220fa62Smrg
228f220fa62Smrg/*-------------------------------------------------------------------------
229f220fa62Smrg * check - verify consistency of a loop, including
230f220fa62Smrg *		1) if pwl, no two consecutive vertices are identical
231f220fa62Smrg *		2) the circular link pointers are valid
232f220fa62Smrg *		3) the geometric info at the head and tail are consistent
233f220fa62Smrg *-------------------------------------------------------------------------
234f220fa62Smrg */
235f220fa62Smrg
236f220fa62Smrgint
237f220fa62SmrgArc::check( void )
238f220fa62Smrg{
239f220fa62Smrg    if( this == 0 ) return 1;
240f220fa62Smrg    Arc_ptr jarc = this;
241f220fa62Smrg    do {
242f220fa62Smrg	assert( (jarc->pwlArc != 0) || (jarc->bezierArc != 0) );
243f220fa62Smrg
244f220fa62Smrg	if (jarc->prev == 0 || jarc->next == 0) {
245f220fa62Smrg#ifndef NDEBUG
246f220fa62Smrg	    _glu_dprintf( "checkjarc:null next/prev pointer\n");
247f220fa62Smrg	    jarc->print( );
248f220fa62Smrg#endif
249f220fa62Smrg	    return 0;
250f220fa62Smrg	}
251f220fa62Smrg
252f220fa62Smrg	if (jarc->next->prev != jarc) {
253f220fa62Smrg#ifndef NDEBUG
254f220fa62Smrg	    _glu_dprintf( "checkjarc: pointer linkage screwed up\n");
255f220fa62Smrg	    jarc->print( );
256f220fa62Smrg#endif
257f220fa62Smrg	    return 0;
258f220fa62Smrg	}
259f220fa62Smrg
260f220fa62Smrg	if( jarc->pwlArc ) {
261f220fa62Smrg#ifndef NDEBUG
262f220fa62Smrg	    assert( jarc->pwlArc->npts >= 1 );
263f220fa62Smrg	    assert( jarc->pwlArc->npts < 100000 );
264f220fa62Smrg/*
265f220fa62Smrg	    for( int i=0; i < jarc->pwlArc->npts-1; i++ )
266f220fa62Smrg		assert( neq_vert( jarc->pwlArc->pts[i].param,
267f220fa62Smrg			     jarc->pwlArc->pts[i+1].param) );
268f220fa62Smrg*/
269f220fa62Smrg#endif
270f220fa62Smrg	    if( jarc->prev->pwlArc ) {
271f220fa62Smrg		if( jarc->tail()[1] != jarc->prev->rhead()[1] ) {
272f220fa62Smrg#ifndef NDEBUG
273f220fa62Smrg		    _glu_dprintf( "checkjarc: geometric linkage screwed up 1\n");
274f220fa62Smrg		    jarc->prev->show();
275f220fa62Smrg		    jarc->show();
276f220fa62Smrg#endif
277f220fa62Smrg		    return 0;
278f220fa62Smrg		}
279f220fa62Smrg		if( jarc->tail()[0] != jarc->prev->rhead()[0] ) {
280f220fa62Smrg
281f220fa62Smrg#ifndef NDEBUG
282f220fa62Smrg		    _glu_dprintf( "checkjarc: geometric linkage screwed up 2\n");
283f220fa62Smrg		    jarc->prev->show();
284f220fa62Smrg		    jarc->show();
285f220fa62Smrg#endif
286f220fa62Smrg		    return 0;
287f220fa62Smrg		}
288f220fa62Smrg	    }
289f220fa62Smrg	    if( jarc->next->pwlArc ) {
290f220fa62Smrg		if( jarc->next->tail()[0] != jarc->rhead()[0] ) {
291f220fa62Smrg#ifndef NDEBUG
292f220fa62Smrg			_glu_dprintf( "checkjarc: geometric linkage screwed up 3\n");
293f220fa62Smrg			jarc->show();
294f220fa62Smrg			jarc->next->show();
295f220fa62Smrg#endif
296f220fa62Smrg			return 0;
297f220fa62Smrg		}
298f220fa62Smrg		if( jarc->next->tail()[1] != jarc->rhead()[1] ) {
299f220fa62Smrg#ifndef NDEBUG
300f220fa62Smrg			_glu_dprintf( "checkjarc: geometric linkage screwed up 4\n");
301f220fa62Smrg			jarc->show();
302f220fa62Smrg			jarc->next->show();
303f220fa62Smrg#endif
304f220fa62Smrg			return 0;
305f220fa62Smrg		}
306f220fa62Smrg	    }
307f220fa62Smrg	    if( jarc->isbezier() ) {
308f220fa62Smrg		assert( jarc->pwlArc->npts == 2 );
309f220fa62Smrg		assert( (jarc->pwlArc->pts[0].param[0] == \
310f220fa62Smrg                        jarc->pwlArc->pts[1].param[0]) ||\
311f220fa62Smrg                        (jarc->pwlArc->pts[0].param[1] == \
312f220fa62Smrg                        jarc->pwlArc->pts[1].param[1]) );
313f220fa62Smrg	    }
314f220fa62Smrg	}
315f220fa62Smrg	jarc = jarc->next;
316f220fa62Smrg    } while (jarc != this);
317f220fa62Smrg    return 1;
318f220fa62Smrg}
319f220fa62Smrg
320f220fa62Smrg
321f220fa62Smrg#define TOL 0.00001
322f220fa62Smrg
323f220fa62Smrginline long tooclose( REAL x, REAL y )
324f220fa62Smrg{
325f220fa62Smrg    return (glu_abs(x-y) < TOL) ?  1 : 0;
326f220fa62Smrg}
327f220fa62Smrg
328f220fa62Smrg
329f220fa62Smrg/*--------------------------------------------------------------------------
330f220fa62Smrg * append - append a jordan arc to a circularly linked list
331f220fa62Smrg *--------------------------------------------------------------------------
332f220fa62Smrg */
333f220fa62Smrg
334f220fa62SmrgArc_ptr
335f220fa62SmrgArc::append( Arc_ptr jarc )
336f220fa62Smrg{
337f220fa62Smrg    if( jarc != 0 ) {
338f220fa62Smrg	next = jarc->next;
339f220fa62Smrg	prev = jarc;
340f220fa62Smrg	next->prev = prev->next = this;
341f220fa62Smrg    } else {
342f220fa62Smrg	next = prev = this;
343f220fa62Smrg    }
344f220fa62Smrg    return this;
345f220fa62Smrg}
346f220fa62Smrg
347