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 * intersect.c++ 37f220fa62Smrg * 38f220fa62Smrg */ 39f220fa62Smrg 40f220fa62Smrg#include "glimports.h" 41f220fa62Smrg#include "myassert.h" 42f220fa62Smrg#include "mystdio.h" 43f220fa62Smrg#include "subdivider.h" 44f220fa62Smrg#include "arc.h" 45f220fa62Smrg#include "bin.h" 46f220fa62Smrg#include "backend.h" 47f220fa62Smrg#include "trimvertpool.h" 48f220fa62Smrg 49f220fa62Smrg/*#define NOTDEF*/ 50f220fa62Smrg 51f220fa62Smrgenum i_result { INTERSECT_VERTEX, INTERSECT_EDGE }; 52f220fa62Smrg 53f220fa62Smrg/* local functions */ 54f220fa62Smrg#ifndef NDEBUG // for asserts only 55f220fa62Smrgstatic int arc_classify( Arc_ptr, int, REAL ); 56f220fa62Smrg#endif 57f220fa62Smrgstatic enum i_result pwlarc_intersect( PwlArc *, int, REAL, int, int[3] ); 58f220fa62Smrg 59f220fa62Smrg 60f220fa62Smrgvoid 61f220fa62SmrgSubdivider::partition( Bin & bin, Bin & left, Bin & intersections, 62f220fa62Smrg Bin & right, Bin & unknown, int param, REAL value ) 63f220fa62Smrg{ 64f220fa62Smrg Bin headonleft, headonright, tailonleft, tailonright; 65f220fa62Smrg 66f220fa62Smrg for( Arc_ptr jarc = bin.removearc(); jarc; jarc = bin.removearc() ) { 67f220fa62Smrg 68f220fa62Smrg REAL tdiff = jarc->tail()[param] - value; 69f220fa62Smrg REAL hdiff = jarc->head()[param] - value; 70f220fa62Smrg 71f220fa62Smrg if( tdiff > 0.0 ) { 72f220fa62Smrg if( hdiff > 0.0 ) { 73f220fa62Smrg right.addarc( jarc ); 74f220fa62Smrg } else if( hdiff == 0.0 ) { 75f220fa62Smrg tailonright.addarc( jarc ); 76f220fa62Smrg } else { 77f220fa62Smrg Arc_ptr jtemp; 78f220fa62Smrg switch( arc_split(jarc, param, value, 0) ) { 79f220fa62Smrg case 2: 80f220fa62Smrg tailonright.addarc( jarc ); 81f220fa62Smrg headonleft.addarc( jarc->next ); 82f220fa62Smrg break; 83f220fa62Smrg case 31: 84f220fa62Smrg assert( jarc->head()[param] > value ); 85f220fa62Smrg right.addarc( jarc ); 86f220fa62Smrg tailonright.addarc( jtemp = jarc->next ); 87f220fa62Smrg headonleft.addarc( jtemp->next ); 88f220fa62Smrg break; 89f220fa62Smrg case 32: 90f220fa62Smrg assert( jarc->head()[param] <= value ); 91f220fa62Smrg tailonright .addarc( jarc ); 92f220fa62Smrg headonleft.addarc( jtemp = jarc->next ); 93f220fa62Smrg left.addarc( jtemp->next ); 94f220fa62Smrg break; 95f220fa62Smrg case 4: 96f220fa62Smrg right.addarc( jarc ); 97f220fa62Smrg tailonright.addarc( jtemp = jarc->next ); 98f220fa62Smrg headonleft.addarc( jtemp = jtemp->next ); 99f220fa62Smrg left.addarc( jtemp->next ); 100f220fa62Smrg } 101f220fa62Smrg } 102f220fa62Smrg } else if( tdiff == 0.0 ) { 103f220fa62Smrg if( hdiff > 0.0 ) { 104f220fa62Smrg headonright.addarc( jarc ); 105f220fa62Smrg } else if( hdiff == 0.0 ) { 106f220fa62Smrg unknown.addarc( jarc ); 107f220fa62Smrg } else { 108f220fa62Smrg headonleft.addarc( jarc ); 109f220fa62Smrg } 110f220fa62Smrg } else { 111f220fa62Smrg if( hdiff > 0.0 ) { 112f220fa62Smrg Arc_ptr jtemp; 113f220fa62Smrg switch( arc_split(jarc, param, value, 1) ) { 114f220fa62Smrg case 2: 115f220fa62Smrg tailonleft.addarc( jarc ); 116f220fa62Smrg headonright.addarc( jarc->next ); 117f220fa62Smrg break; 118f220fa62Smrg case 31: 119f220fa62Smrg assert( jarc->head()[param] < value ); 120f220fa62Smrg left.addarc( jarc ); 121f220fa62Smrg tailonleft.addarc( jtemp = jarc->next ); 122f220fa62Smrg headonright.addarc( jtemp->next ); 123f220fa62Smrg break; 124f220fa62Smrg case 32: 125f220fa62Smrg assert( jarc->head()[param] >= value ); 126f220fa62Smrg tailonleft.addarc( jarc ); 127f220fa62Smrg headonright.addarc( jtemp = jarc->next ); 128f220fa62Smrg right.addarc( jtemp->next ); 129f220fa62Smrg break; 130f220fa62Smrg case 4: 131f220fa62Smrg left.addarc( jarc ); 132f220fa62Smrg tailonleft.addarc( jtemp = jarc->next ); 133f220fa62Smrg headonright.addarc( jtemp = jtemp->next ); 134f220fa62Smrg right.addarc( jtemp->next ); 135f220fa62Smrg } 136f220fa62Smrg } else if( hdiff == 0.0 ) { 137f220fa62Smrg tailonleft.addarc( jarc ); 138f220fa62Smrg } else { 139f220fa62Smrg left.addarc( jarc ); 140f220fa62Smrg } 141f220fa62Smrg } 142f220fa62Smrg } 143f220fa62Smrg if( param == 0 ) { 144f220fa62Smrg classify_headonleft_s( headonleft, intersections, left, value ); 145f220fa62Smrg classify_tailonleft_s( tailonleft, intersections, left, value ); 146f220fa62Smrg classify_headonright_s( headonright, intersections, right, value ); 147f220fa62Smrg classify_tailonright_s( tailonright, intersections, right, value ); 148f220fa62Smrg } else { 149f220fa62Smrg classify_headonleft_t( headonleft, intersections, left, value ); 150f220fa62Smrg classify_tailonleft_t( tailonleft, intersections, left, value ); 151f220fa62Smrg classify_headonright_t( headonright, intersections, right, value ); 152f220fa62Smrg classify_tailonright_t( tailonright, intersections, right, value ); 153f220fa62Smrg } 154f220fa62Smrg} 155f220fa62Smrg 156f220fa62Smrginline static void 157f220fa62Smrgvert_interp( TrimVertex *n, TrimVertex *l, TrimVertex *r, int p, REAL val ) 158f220fa62Smrg{ 159f220fa62Smrg assert( val > l->param[p]); 160f220fa62Smrg assert( val < r->param[p]); 161f220fa62Smrg 162f220fa62Smrg n->nuid = l->nuid; 163f220fa62Smrg 164f220fa62Smrg n->param[p] = val; 165f220fa62Smrg if( l->param[1-p] != r->param[1-p] ) { 166f220fa62Smrg REAL ratio = (val - l->param[p]) / (r->param[p] - l->param[p]); 167f220fa62Smrg n->param[1-p] = l->param[1-p] + 168f220fa62Smrg ratio * (r->param[1-p] - l->param[1-p]); 169f220fa62Smrg } else { 170f220fa62Smrg n->param[1-p] = l->param[1-p]; 171f220fa62Smrg } 172f220fa62Smrg} 173f220fa62Smrg 174f220fa62Smrgint 175f220fa62SmrgSubdivider::arc_split( Arc_ptr jarc, int param, REAL value, int dir ) 176f220fa62Smrg{ 177f220fa62Smrg int maxvertex = jarc->pwlArc->npts; 178f220fa62Smrg Arc_ptr jarc1; 179f220fa62Smrg TrimVertex* v = jarc->pwlArc->pts; 180f220fa62Smrg 181f220fa62Smrg int loc[3]; 182f220fa62Smrg switch( pwlarc_intersect( jarc->pwlArc, param, value, dir, loc ) ) { 183f220fa62Smrg 184f220fa62Smrg // When the parameter value lands on a vertex, life is sweet 185f220fa62Smrg case INTERSECT_VERTEX: { 186f220fa62Smrg jarc1 = new(arcpool) Arc( jarc, new( pwlarcpool) PwlArc( maxvertex-loc[1], &v[loc[1]] ) ); 187f220fa62Smrg jarc->pwlArc->npts = loc[1] + 1; 188f220fa62Smrg jarc1->next = jarc->next; 189f220fa62Smrg jarc1->next->prev = jarc1; 190f220fa62Smrg jarc->next = jarc1; 191f220fa62Smrg jarc1->prev = jarc; 192f220fa62Smrg assert(jarc->check() != 0); 193f220fa62Smrg return 2; 194f220fa62Smrg } 195f220fa62Smrg 196f220fa62Smrg // When the parameter value intersects an edge, we have to 197f220fa62Smrg // interpolate a new vertex. There are special cases 198f220fa62Smrg // if the new vertex is adjacent to one or both of the 199f220fa62Smrg // endpoints of the arc. 200f220fa62Smrg case INTERSECT_EDGE: { 201f220fa62Smrg int i, j; 202f220fa62Smrg if( dir == 0 ) { 203f220fa62Smrg i = loc[0]; 204f220fa62Smrg j = loc[2]; 205f220fa62Smrg } else { 206f220fa62Smrg i = loc[2]; 207f220fa62Smrg j = loc[0]; 208f220fa62Smrg } 209f220fa62Smrg 210f220fa62Smrg#ifndef NOTDEF 211f220fa62Smrg // The split is between vertices at index j and i, in that 212f220fa62Smrg // order (j < i) 213f220fa62Smrg 214f220fa62Smrg // JEB: This code is my idea of how to do the split without 215f220fa62Smrg // increasing the number of links. I'm doing this so that 216f220fa62Smrg // the is_rect routine can recognize rectangles created by 217f220fa62Smrg // subdivision. In exchange for simplifying the curve list, 218f220fa62Smrg // however, it costs in allocated space and vertex copies. 219f220fa62Smrg 220f220fa62Smrg TrimVertex *newjunk = trimvertexpool.get(maxvertex -i+1 /*-j*/); 221f220fa62Smrg int k; 222f220fa62Smrg for(k=0; k<maxvertex-i; k++) 223f220fa62Smrg { 224f220fa62Smrg newjunk[k+1] = v[i+k]; 225f220fa62Smrg newjunk[k+1].nuid = jarc->nuid; 226f220fa62Smrg } 227f220fa62Smrg 228f220fa62Smrg TrimVertex *vcopy = trimvertexpool.get(maxvertex); 229f220fa62Smrg for(k=0; k<maxvertex; k++) 230f220fa62Smrg { 231f220fa62Smrg vcopy[k].param[0] = v[k].param[0]; 232f220fa62Smrg vcopy[k].param[1] = v[k].param[1]; 233f220fa62Smrg } 234f220fa62Smrg jarc->pwlArc->pts=vcopy; 235f220fa62Smrg 236f220fa62Smrg v[i].nuid = jarc->nuid; 237f220fa62Smrg v[j].nuid = jarc->nuid; 238f220fa62Smrg vert_interp( &newjunk[0], &v[loc[0]], &v[loc[2]], param, value ); 239f220fa62Smrg 240f220fa62Smrg if( showingDegenerate() ) 241f220fa62Smrg backend.triangle( &v[i], &newjunk[0], &v[j] ); 242f220fa62Smrg 243f220fa62Smrg vcopy[j+1].param[0]=newjunk[0].param[0]; 244f220fa62Smrg vcopy[j+1].param[1]=newjunk[0].param[1]; 245f220fa62Smrg 246f220fa62Smrg 247f220fa62Smrg jarc1 = new(arcpool) Arc( jarc, 248f220fa62Smrg new(pwlarcpool) PwlArc(maxvertex-i+1 , newjunk ) ); 249f220fa62Smrg 250f220fa62Smrg jarc->pwlArc->npts = j+2; 251f220fa62Smrg jarc1->next = jarc->next; 252f220fa62Smrg jarc1->next->prev = jarc1; 253f220fa62Smrg jarc->next = jarc1; 254f220fa62Smrg jarc1->prev = jarc; 255f220fa62Smrg assert(jarc->check() != 0); 256f220fa62Smrg 257f220fa62Smrg return 2; 258f220fa62Smrg#endif //not NOTDEF 259f220fa62Smrg // JEB: This is the original version: 260f220fa62Smrg#ifdef NOTDEF 261f220fa62Smrg Arc_ptr jarc2, jarc3; 262f220fa62Smrg 263f220fa62Smrg TrimVertex *newjunk = trimvertexpool.get(3); 264f220fa62Smrg v[i].nuid = jarc->nuid; 265f220fa62Smrg v[j].nuid = jarc->nuid; 266f220fa62Smrg newjunk[0] = v[j]; 267f220fa62Smrg newjunk[2] = v[i]; 268f220fa62Smrg vert_interp( &newjunk[1], &v[loc[0]], &v[loc[2]], param, value ); 269f220fa62Smrg 270f220fa62Smrg if( showingDegenerate() ) 271f220fa62Smrg backend.triangle( &newjunk[2], &newjunk[1], &newjunk[0] ); 272f220fa62Smrg 273f220fa62Smrg // New vertex adjacent to both endpoints 274f220fa62Smrg if (maxvertex == 2) { 275f220fa62Smrg jarc1 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk+1 ) ); 276f220fa62Smrg jarc->pwlArc->npts = 2; 277f220fa62Smrg jarc->pwlArc->pts = newjunk; 278f220fa62Smrg jarc1->next = jarc->next; 279f220fa62Smrg jarc1->next->prev = jarc1; 280f220fa62Smrg jarc->next = jarc1; 281f220fa62Smrg jarc1->prev = jarc; 282f220fa62Smrg assert(jarc->check() != 0); 283f220fa62Smrg 284f220fa62Smrg return 2; 285f220fa62Smrg 286f220fa62Smrg // New vertex adjacent to ending point of arc 287f220fa62Smrg } else if (maxvertex - j == 2) { 288f220fa62Smrg jarc1 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk ) ); 289f220fa62Smrg jarc2 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk+1 ) ); 290f220fa62Smrg jarc->pwlArc->npts = maxvertex-1; 291f220fa62Smrg jarc2->next = jarc->next; 292f220fa62Smrg jarc2->next->prev = jarc2; 293f220fa62Smrg jarc->next = jarc1; 294f220fa62Smrg jarc1->prev = jarc; 295f220fa62Smrg jarc1->next = jarc2; 296f220fa62Smrg jarc2->prev = jarc1; 297f220fa62Smrg assert(jarc->check() != 0); 298f220fa62Smrg return 31; 299f220fa62Smrg 300f220fa62Smrg // New vertex adjacent to starting point of arc 301f220fa62Smrg } else if (i == 1) { 302f220fa62Smrg jarc1 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk+1 ) ); 303f220fa62Smrg jarc2 = new(arcpool) Arc( jarc, 304f220fa62Smrg new(pwlarcpool) PwlArc( maxvertex-1, &jarc->pwlArc->pts[1] ) ); 305f220fa62Smrg jarc->pwlArc->npts = 2; 306f220fa62Smrg jarc->pwlArc->pts = newjunk; 307f220fa62Smrg jarc2->next = jarc->next; 308f220fa62Smrg jarc2->next->prev = jarc2; 309f220fa62Smrg jarc->next = jarc1; 310f220fa62Smrg jarc1->prev = jarc; 311f220fa62Smrg jarc1->next = jarc2; 312f220fa62Smrg jarc2->prev = jarc1; 313f220fa62Smrg assert(jarc->check() != 0); 314f220fa62Smrg return 32; 315f220fa62Smrg 316f220fa62Smrg // It's somewhere in the middle 317f220fa62Smrg } else { 318f220fa62Smrg jarc1 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk ) ); 319f220fa62Smrg jarc2 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk+1 ) ); 320f220fa62Smrg jarc3 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( maxvertex-i, v+i ) ); 321f220fa62Smrg jarc->pwlArc->npts = j + 1; 322f220fa62Smrg jarc3->next = jarc->next; 323f220fa62Smrg jarc3->next->prev = jarc3; 324f220fa62Smrg jarc->next = jarc1; 325f220fa62Smrg jarc1->prev = jarc; 326f220fa62Smrg jarc1->next = jarc2; 327f220fa62Smrg jarc2->prev = jarc1; 328f220fa62Smrg jarc2->next = jarc3; 329f220fa62Smrg jarc3->prev = jarc2; 330f220fa62Smrg assert(jarc->check() != 0); 331f220fa62Smrg return 4; 332f220fa62Smrg } 333f220fa62Smrg#endif // NOTDEF 334f220fa62Smrg } 335f220fa62Smrg default: 336f220fa62Smrg return -1; //picked -1 since it's not used 337f220fa62Smrg } 338f220fa62Smrg} 339f220fa62Smrg 340f220fa62Smrg/*---------------------------------------------------------------------------- 341f220fa62Smrg * pwlarc_intersect - find intersection of pwlArc and isoparametric line 342f220fa62Smrg *---------------------------------------------------------------------------- 343f220fa62Smrg */ 344f220fa62Smrg 345f220fa62Smrgstatic enum i_result 346f220fa62Smrgpwlarc_intersect( 347f220fa62Smrg PwlArc *pwlArc, 348f220fa62Smrg int param, 349f220fa62Smrg REAL value, 350f220fa62Smrg int dir, 351f220fa62Smrg int loc[3] ) 352f220fa62Smrg{ 353f220fa62Smrg assert( pwlArc->npts > 0 ); 354f220fa62Smrg 355f220fa62Smrg if( dir ) { 356f220fa62Smrg TrimVertex *v = pwlArc->pts; 357f220fa62Smrg int imin = 0; 358f220fa62Smrg int imax = pwlArc->npts - 1; 359f220fa62Smrg assert( value > v[imin].param[param] ); 360f220fa62Smrg assert( value < v[imax].param[param] ); 361f220fa62Smrg while( (imax - imin) > 1 ) { 362f220fa62Smrg int imid = (imax + imin)/2; 363f220fa62Smrg if( v[imid].param[param] > value ) 364f220fa62Smrg imax = imid; 365f220fa62Smrg else if( v[imid].param[param] < value ) 366f220fa62Smrg imin = imid; 367f220fa62Smrg else { 368f220fa62Smrg loc[1] = imid; 369f220fa62Smrg return INTERSECT_VERTEX; 370f220fa62Smrg } 371f220fa62Smrg } 372f220fa62Smrg loc[0] = imin; 373f220fa62Smrg loc[2] = imax; 374f220fa62Smrg return INTERSECT_EDGE; 375f220fa62Smrg } else { 376f220fa62Smrg TrimVertex *v = pwlArc->pts; 377f220fa62Smrg int imax = 0; 378f220fa62Smrg int imin = pwlArc->npts - 1; 379f220fa62Smrg assert( value > v[imin].param[param] ); 380f220fa62Smrg assert( value < v[imax].param[param] ); 381f220fa62Smrg while( (imin - imax) > 1 ) { 382f220fa62Smrg int imid = (imax + imin)/2; 383f220fa62Smrg if( v[imid].param[param] > value ) 384f220fa62Smrg imax = imid; 385f220fa62Smrg else if( v[imid].param[param] < value ) 386f220fa62Smrg imin = imid; 387f220fa62Smrg else { 388f220fa62Smrg loc[1] = imid; 389f220fa62Smrg return INTERSECT_VERTEX; 390f220fa62Smrg } 391f220fa62Smrg } 392f220fa62Smrg loc[0] = imin; 393f220fa62Smrg loc[2] = imax; 394f220fa62Smrg return INTERSECT_EDGE; 395f220fa62Smrg } 396f220fa62Smrg} 397f220fa62Smrg 398f220fa62Smrg/*---------------------------------------------------------------------------- 399f220fa62Smrg * arc_classify - determine which side of a line a jarc lies 400f220fa62Smrg *---------------------------------------------------------------------------- 401f220fa62Smrg */ 402f220fa62Smrg 403f220fa62Smrg#ifndef NDEBUG // for asserts only 404f220fa62Smrgstatic int 405f220fa62Smrgarc_classify( Arc_ptr jarc, int param, REAL value ) 406f220fa62Smrg{ 407f220fa62Smrg REAL tdiff, hdiff; 408f220fa62Smrg if( param == 0 ) { 409f220fa62Smrg tdiff = jarc->tail()[0] - value; 410f220fa62Smrg hdiff = jarc->head()[0] - value; 411f220fa62Smrg } else { 412f220fa62Smrg tdiff = jarc->tail()[1] - value; 413f220fa62Smrg hdiff = jarc->head()[1] - value; 414f220fa62Smrg } 415f220fa62Smrg 416f220fa62Smrg if( tdiff > 0.0 ) { 417f220fa62Smrg if( hdiff > 0.0 ) { 418f220fa62Smrg return 0x11; 419f220fa62Smrg } else if( hdiff == 0.0 ) { 420f220fa62Smrg return 0x12; 421f220fa62Smrg } else { 422f220fa62Smrg return 0x10; 423f220fa62Smrg } 424f220fa62Smrg } else if( tdiff == 0.0 ) { 425f220fa62Smrg if( hdiff > 0.0 ) { 426f220fa62Smrg return 0x21; 427f220fa62Smrg } else if( hdiff == 0.0 ) { 428f220fa62Smrg return 0x22; 429f220fa62Smrg } else { 430f220fa62Smrg return 0x20; 431f220fa62Smrg } 432f220fa62Smrg } else { 433f220fa62Smrg if( hdiff > 0.0 ) { 434f220fa62Smrg return 0x01; 435f220fa62Smrg } else if( hdiff == 0.0 ) { 436f220fa62Smrg return 0x02; 437f220fa62Smrg } else { 438f220fa62Smrg return 0; 439f220fa62Smrg } 440f220fa62Smrg } 441f220fa62Smrg} 442f220fa62Smrg#endif 443f220fa62Smrg 444f220fa62Smrgvoid 445f220fa62SmrgSubdivider::classify_tailonleft_s( Bin& bin, Bin& in, Bin& out, REAL val ) 446f220fa62Smrg{ 447f220fa62Smrg /* tail at left, head on line */ 448f220fa62Smrg Arc_ptr j; 449f220fa62Smrg 450f220fa62Smrg while( (j = bin.removearc()) != NULL ) { 451f220fa62Smrg assert( arc_classify( j, 0, val ) == 0x02 ); 452f220fa62Smrg j->clearitail(); 453f220fa62Smrg 454f220fa62Smrg REAL diff = j->next->head()[0] - val; 455f220fa62Smrg if( diff > 0.0 ) { 456f220fa62Smrg in.addarc( j ); 457f220fa62Smrg } else if( diff < 0.0 ) { 458f220fa62Smrg if( ccwTurn_sl( j, j->next ) ) 459f220fa62Smrg out.addarc( j ); 460f220fa62Smrg else 461f220fa62Smrg in.addarc( j ); 462f220fa62Smrg } else { 463f220fa62Smrg if( j->next->tail()[1] > j->next->head()[1] ) 464f220fa62Smrg in.addarc(j); 465f220fa62Smrg else 466f220fa62Smrg out.addarc(j); 467f220fa62Smrg } 468f220fa62Smrg } 469f220fa62Smrg} 470f220fa62Smrg 471f220fa62Smrgvoid 472f220fa62SmrgSubdivider::classify_tailonleft_t( Bin& bin, Bin& in, Bin& out, REAL val ) 473f220fa62Smrg{ 474f220fa62Smrg /* tail at left, head on line */ 475f220fa62Smrg Arc_ptr j; 476f220fa62Smrg 477f220fa62Smrg while( (j = bin.removearc()) != NULL ) { 478f220fa62Smrg assert( arc_classify( j, 1, val ) == 0x02 ); 479f220fa62Smrg j->clearitail(); 480f220fa62Smrg 481f220fa62Smrg REAL diff = j->next->head()[1] - val; 482f220fa62Smrg if( diff > 0.0 ) { 483f220fa62Smrg in.addarc( j ); 484f220fa62Smrg } else if( diff < 0.0 ) { 485f220fa62Smrg if( ccwTurn_tl( j, j->next ) ) 486f220fa62Smrg out.addarc( j ); 487f220fa62Smrg else 488f220fa62Smrg in.addarc( j ); 489f220fa62Smrg } else { 490f220fa62Smrg if (j->next->tail()[0] > j->next->head()[0] ) 491f220fa62Smrg out.addarc( j ); 492f220fa62Smrg else 493f220fa62Smrg in.addarc( j ); 494f220fa62Smrg } 495f220fa62Smrg } 496f220fa62Smrg} 497f220fa62Smrg 498f220fa62Smrgvoid 499f220fa62SmrgSubdivider::classify_headonleft_s( Bin& bin, Bin& in, Bin& out, REAL val ) 500f220fa62Smrg{ 501f220fa62Smrg /* tail on line, head at left */ 502f220fa62Smrg Arc_ptr j; 503f220fa62Smrg 504f220fa62Smrg while( (j = bin.removearc()) != NULL ) { 505f220fa62Smrg assert( arc_classify( j, 0, val ) == 0x20 ); 506f220fa62Smrg 507f220fa62Smrg j->setitail(); 508f220fa62Smrg 509f220fa62Smrg REAL diff = j->prev->tail()[0] - val; 510f220fa62Smrg if( diff > 0.0 ) { 511f220fa62Smrg out.addarc( j ); 512f220fa62Smrg } else if( diff < 0.0 ) { 513f220fa62Smrg if( ccwTurn_sl( j->prev, j ) ) 514f220fa62Smrg out.addarc( j ); 515f220fa62Smrg else 516f220fa62Smrg in.addarc( j ); 517f220fa62Smrg } else { 518f220fa62Smrg if( j->prev->tail()[1] > j->prev->head()[1] ) 519f220fa62Smrg in.addarc( j ); 520f220fa62Smrg else 521f220fa62Smrg out.addarc( j ); 522f220fa62Smrg } 523f220fa62Smrg } 524f220fa62Smrg} 525f220fa62Smrg 526f220fa62Smrgvoid 527f220fa62SmrgSubdivider::classify_headonleft_t( Bin& bin, Bin& in, Bin& out, REAL val ) 528f220fa62Smrg{ 529f220fa62Smrg /* tail on line, head at left */ 530f220fa62Smrg Arc_ptr j; 531f220fa62Smrg 532f220fa62Smrg while( (j = bin.removearc()) != NULL ) { 533f220fa62Smrg assert( arc_classify( j, 1, val ) == 0x20 ); 534f220fa62Smrg j->setitail(); 535f220fa62Smrg 536f220fa62Smrg REAL diff = j->prev->tail()[1] - val; 537f220fa62Smrg if( diff > 0.0 ) { 538f220fa62Smrg out.addarc( j ); 539f220fa62Smrg } else if( diff < 0.0 ) { 540f220fa62Smrg if( ccwTurn_tl( j->prev, j ) ) 541f220fa62Smrg out.addarc( j ); 542f220fa62Smrg else 543f220fa62Smrg in.addarc( j ); 544f220fa62Smrg } else { 545f220fa62Smrg if( j->prev->tail()[0] > j->prev->head()[0] ) 546f220fa62Smrg out.addarc( j ); 547f220fa62Smrg else 548f220fa62Smrg in.addarc( j ); 549f220fa62Smrg } 550f220fa62Smrg } 551f220fa62Smrg} 552f220fa62Smrg 553f220fa62Smrg 554f220fa62Smrgvoid 555f220fa62SmrgSubdivider::classify_tailonright_s( Bin& bin, Bin& in, Bin& out, REAL val ) 556f220fa62Smrg{ 557f220fa62Smrg /* tail at right, head on line */ 558f220fa62Smrg Arc_ptr j; 559f220fa62Smrg 560f220fa62Smrg while( (j = bin.removearc()) != NULL ) { 561f220fa62Smrg assert( arc_classify( j, 0, val ) == 0x12); 562f220fa62Smrg 563f220fa62Smrg j->clearitail(); 564f220fa62Smrg 565f220fa62Smrg REAL diff = j->next->head()[0] - val; 566f220fa62Smrg if( diff > 0.0 ) { 567f220fa62Smrg if( ccwTurn_sr( j, j->next ) ) 568f220fa62Smrg out.addarc( j ); 569f220fa62Smrg else 570f220fa62Smrg in.addarc( j ); 571f220fa62Smrg } else if( diff < 0.0 ) { 572f220fa62Smrg in.addarc( j ); 573f220fa62Smrg } else { 574f220fa62Smrg if( j->next->tail()[1] > j->next->head()[1] ) 575f220fa62Smrg out.addarc( j ); 576f220fa62Smrg else 577f220fa62Smrg in.addarc( j ); 578f220fa62Smrg } 579f220fa62Smrg } 580f220fa62Smrg} 581f220fa62Smrg 582f220fa62Smrgvoid 583f220fa62SmrgSubdivider::classify_tailonright_t( Bin& bin, Bin& in, Bin& out, REAL val ) 584f220fa62Smrg{ 585f220fa62Smrg /* tail at right, head on line */ 586f220fa62Smrg Arc_ptr j; 587f220fa62Smrg 588f220fa62Smrg while( (j = bin.removearc()) != NULL ) { 589f220fa62Smrg assert( arc_classify( j, 1, val ) == 0x12); 590f220fa62Smrg 591f220fa62Smrg j->clearitail(); 592f220fa62Smrg 593f220fa62Smrg REAL diff = j->next->head()[1] - val; 594f220fa62Smrg if( diff > 0.0 ) { 595f220fa62Smrg if( ccwTurn_tr( j, j->next ) ) 596f220fa62Smrg out.addarc( j ); 597f220fa62Smrg else 598f220fa62Smrg in.addarc( j ); 599f220fa62Smrg } else if( diff < 0.0 ) { 600f220fa62Smrg in.addarc( j ); 601f220fa62Smrg } else { 602f220fa62Smrg if( j->next->tail()[0] > j->next->head()[0] ) 603f220fa62Smrg in.addarc( j ); 604f220fa62Smrg else 605f220fa62Smrg out.addarc( j ); 606f220fa62Smrg } 607f220fa62Smrg } 608f220fa62Smrg} 609f220fa62Smrg 610f220fa62Smrgvoid 611f220fa62SmrgSubdivider::classify_headonright_s( Bin& bin, Bin& in, Bin& out, REAL val ) 612f220fa62Smrg{ 613f220fa62Smrg /* tail on line, head at right */ 614f220fa62Smrg Arc_ptr j; 615f220fa62Smrg 616f220fa62Smrg while( (j = bin.removearc()) != NULL ) { 617f220fa62Smrg assert( arc_classify( j, 0, val ) == 0x21 ); 618f220fa62Smrg 619f220fa62Smrg j->setitail(); 620f220fa62Smrg 621f220fa62Smrg REAL diff = j->prev->tail()[0] - val; 622f220fa62Smrg if( diff > 0.0 ) { 623f220fa62Smrg if( ccwTurn_sr( j->prev, j ) ) 624f220fa62Smrg out.addarc( j ); 625f220fa62Smrg else 626f220fa62Smrg in.addarc( j ); 627f220fa62Smrg } else if( diff < 0.0 ) { 628f220fa62Smrg out.addarc( j ); 629f220fa62Smrg } else { 630f220fa62Smrg if( j->prev->tail()[1] > j->prev->head()[1] ) 631f220fa62Smrg out.addarc( j ); 632f220fa62Smrg else 633f220fa62Smrg in.addarc( j ); 634f220fa62Smrg } 635f220fa62Smrg } 636f220fa62Smrg} 637f220fa62Smrg 638f220fa62Smrgvoid 639f220fa62SmrgSubdivider::classify_headonright_t( Bin& bin, Bin& in, Bin& out, REAL val ) 640f220fa62Smrg{ 641f220fa62Smrg /* tail on line, head at right */ 642f220fa62Smrg Arc_ptr j; 643f220fa62Smrg 644f220fa62Smrg while( (j = bin.removearc()) != NULL ) { 645f220fa62Smrg assert( arc_classify( j, 1, val ) == 0x21 ); 646f220fa62Smrg 647f220fa62Smrg j->setitail(); 648f220fa62Smrg 649f220fa62Smrg REAL diff = j->prev->tail()[1] - val; 650f220fa62Smrg if( diff > 0.0 ) { 651f220fa62Smrg if( ccwTurn_tr( j->prev, j ) ) 652f220fa62Smrg out.addarc( j ); 653f220fa62Smrg else 654f220fa62Smrg in.addarc( j ); 655f220fa62Smrg } else if( diff < 0.0 ) { 656f220fa62Smrg out.addarc( j ); 657f220fa62Smrg } else { 658f220fa62Smrg if( j->prev->tail()[0] > j->prev->head()[0] ) 659f220fa62Smrg in.addarc( j ); 660f220fa62Smrg else 661f220fa62Smrg out.addarc( j ); 662f220fa62Smrg } 663f220fa62Smrg } 664f220fa62Smrg} 665f220fa62Smrg 666