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