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 * mesher.c++ 37f220fa62Smrg * 38f220fa62Smrg */ 39f220fa62Smrg 40f220fa62Smrg#include "glimports.h" 41f220fa62Smrg#include "myassert.h" 42f220fa62Smrg#include "mystdio.h" 43f220fa62Smrg#include "gridvertex.h" 44f220fa62Smrg#include "gridtrimvertex.h" 45f220fa62Smrg#include "jarcloc.h" 46f220fa62Smrg#include "gridline.h" 47f220fa62Smrg#include "trimline.h" 48f220fa62Smrg#include "uarray.h" 49f220fa62Smrg#include "backend.h" 50f220fa62Smrg#include "mesher.h" 51f220fa62Smrg 52f220fa62Smrg 53f220fa62Smrgconst float Mesher::ZERO = 0.0; 54f220fa62Smrg 55f220fa62SmrgMesher::Mesher( Backend& b ) 56f220fa62Smrg : backend( b ), 57f220fa62Smrg p( sizeof( GridTrimVertex ), 100, "GridTrimVertexPool" ) 58f220fa62Smrg{ 59f220fa62Smrg stacksize = 0; 60f220fa62Smrg vdata = 0; 61f220fa62Smrg last[0] = 0; 62f220fa62Smrg last[1] = 0; 63f220fa62Smrg itop = 0; 64f220fa62Smrg lastedge = 0; //needed to prevent purify UMR 65f220fa62Smrg} 66f220fa62Smrg 67f220fa62SmrgMesher::~Mesher( void ) 68f220fa62Smrg{ 69f220fa62Smrg if( vdata ) delete[] vdata; 70f220fa62Smrg} 71f220fa62Smrg 72f220fa62Smrgvoid 73f220fa62SmrgMesher::init( unsigned int npts ) 74f220fa62Smrg{ 75f220fa62Smrg p.clear(); 76f220fa62Smrg if( stacksize < npts ) { 77f220fa62Smrg stacksize = 2 * npts; 78f220fa62Smrg if( vdata ) delete[] vdata; 79f220fa62Smrg vdata = new GridTrimVertex_p[stacksize]; 80f220fa62Smrg } 81f220fa62Smrg} 82f220fa62Smrg 83f220fa62Smrginline void 84f220fa62SmrgMesher::push( GridTrimVertex *gt ) 85f220fa62Smrg{ 86f220fa62Smrg assert( itop+1 != (int)stacksize ); 87f220fa62Smrg vdata[++itop] = gt; 88f220fa62Smrg} 89f220fa62Smrg 90f220fa62Smrginline void 91f220fa62SmrgMesher::pop( long ) 92f220fa62Smrg{ 93f220fa62Smrg} 94f220fa62Smrg 95f220fa62Smrginline void 96f220fa62SmrgMesher::openMesh() 97f220fa62Smrg{ 98f220fa62Smrg backend.bgntmesh( "addedge" ); 99f220fa62Smrg} 100f220fa62Smrg 101f220fa62Smrginline void 102f220fa62SmrgMesher::closeMesh() 103f220fa62Smrg{ 104f220fa62Smrg backend.endtmesh(); 105f220fa62Smrg} 106f220fa62Smrg 107f220fa62Smrginline void 108f220fa62SmrgMesher::swapMesh() 109f220fa62Smrg{ 110f220fa62Smrg backend.swaptmesh(); 111f220fa62Smrg} 112f220fa62Smrg 113f220fa62Smrginline void 114f220fa62SmrgMesher::clearStack() 115f220fa62Smrg{ 116f220fa62Smrg itop = -1; 117f220fa62Smrg last[0] = 0; 118f220fa62Smrg} 119f220fa62Smrg 120f220fa62Smrgvoid 121f220fa62SmrgMesher::finishLower( GridTrimVertex *gtlower ) 122f220fa62Smrg{ 123f220fa62Smrg for( push(gtlower); 124f220fa62Smrg nextlower( gtlower=new(p) GridTrimVertex ); 125f220fa62Smrg push(gtlower) ) 126f220fa62Smrg addLower(); 127f220fa62Smrg addLast(); 128f220fa62Smrg} 129f220fa62Smrg 130f220fa62Smrgvoid 131f220fa62SmrgMesher::finishUpper( GridTrimVertex *gtupper ) 132f220fa62Smrg{ 133f220fa62Smrg for( push(gtupper); 134f220fa62Smrg nextupper( gtupper=new(p) GridTrimVertex ); 135f220fa62Smrg push(gtupper) ) 136f220fa62Smrg addUpper(); 137f220fa62Smrg addLast(); 138f220fa62Smrg} 139f220fa62Smrg 140f220fa62Smrgvoid 141f220fa62SmrgMesher::mesh( void ) 142f220fa62Smrg{ 143f220fa62Smrg GridTrimVertex *gtlower, *gtupper; 144f220fa62Smrg 145f220fa62Smrg Hull::init( ); 146f220fa62Smrg nextupper( gtupper = new(p) GridTrimVertex ); 147f220fa62Smrg nextlower( gtlower = new(p) GridTrimVertex ); 148f220fa62Smrg 149f220fa62Smrg clearStack(); 150f220fa62Smrg openMesh(); 151f220fa62Smrg push(gtupper); 152f220fa62Smrg 153f220fa62Smrg nextupper( gtupper = new(p) GridTrimVertex ); 154f220fa62Smrg nextlower( gtlower ); 155f220fa62Smrg 156f220fa62Smrg assert( gtupper->t && gtlower->t ); 157f220fa62Smrg 158f220fa62Smrg if( gtupper->t->param[0] < gtlower->t->param[0] ) { 159f220fa62Smrg push(gtupper); 160f220fa62Smrg lastedge = 1; 161f220fa62Smrg if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) { 162f220fa62Smrg finishLower(gtlower); 163f220fa62Smrg return; 164f220fa62Smrg } 165f220fa62Smrg } else if( gtupper->t->param[0] > gtlower->t->param[0] ) { 166f220fa62Smrg push(gtlower); 167f220fa62Smrg lastedge = 0; 168f220fa62Smrg if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) { 169f220fa62Smrg finishUpper(gtupper); 170f220fa62Smrg return; 171f220fa62Smrg } 172f220fa62Smrg } else { 173f220fa62Smrg if( lastedge == 0 ) { 174f220fa62Smrg push(gtupper); 175f220fa62Smrg lastedge = 1; 176f220fa62Smrg if( nextupper(gtupper=new(p) GridTrimVertex) == 0 ) { 177f220fa62Smrg finishLower(gtlower); 178f220fa62Smrg return; 179f220fa62Smrg } 180f220fa62Smrg } else { 181f220fa62Smrg push(gtlower); 182f220fa62Smrg lastedge = 0; 183f220fa62Smrg if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) { 184f220fa62Smrg finishUpper(gtupper); 185f220fa62Smrg return; 186f220fa62Smrg } 187f220fa62Smrg } 188f220fa62Smrg } 189f220fa62Smrg 190f220fa62Smrg while ( 1 ) { 191f220fa62Smrg if( gtupper->t->param[0] < gtlower->t->param[0] ) { 192f220fa62Smrg push(gtupper); 193f220fa62Smrg addUpper(); 194f220fa62Smrg if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) { 195f220fa62Smrg finishLower(gtlower); 196f220fa62Smrg return; 197f220fa62Smrg } 198f220fa62Smrg } else if( gtupper->t->param[0] > gtlower->t->param[0] ) { 199f220fa62Smrg push(gtlower); 200f220fa62Smrg addLower(); 201f220fa62Smrg if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) { 202f220fa62Smrg finishUpper(gtupper); 203f220fa62Smrg return; 204f220fa62Smrg } 205f220fa62Smrg } else { 206f220fa62Smrg if( lastedge == 0 ) { 207f220fa62Smrg push(gtupper); 208f220fa62Smrg addUpper(); 209f220fa62Smrg if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) { 210f220fa62Smrg finishLower(gtlower); 211f220fa62Smrg return; 212f220fa62Smrg } 213f220fa62Smrg } else { 214f220fa62Smrg push(gtlower); 215f220fa62Smrg addLower(); 216f220fa62Smrg if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) { 217f220fa62Smrg finishUpper(gtupper); 218f220fa62Smrg return; 219f220fa62Smrg } 220f220fa62Smrg } 221f220fa62Smrg } 222f220fa62Smrg } 223f220fa62Smrg} 224f220fa62Smrg 225f220fa62Smrginline int 226f220fa62SmrgMesher::isCcw( int ilast ) 227f220fa62Smrg{ 228f220fa62Smrg REAL area = det3( vdata[ilast]->t, vdata[itop-1]->t, vdata[itop-2]->t ); 229f220fa62Smrg return (area < ZERO) ? 0 : 1; 230f220fa62Smrg} 231f220fa62Smrg 232f220fa62Smrginline int 233f220fa62SmrgMesher::isCw( int ilast ) 234f220fa62Smrg{ 235f220fa62Smrg REAL area = det3( vdata[ilast]->t, vdata[itop-1]->t, vdata[itop-2]->t ); 236f220fa62Smrg return (area > -ZERO) ? 0 : 1; 237f220fa62Smrg} 238f220fa62Smrg 239f220fa62Smrginline int 240f220fa62SmrgMesher::equal( int x, int y ) 241f220fa62Smrg{ 242f220fa62Smrg return( last[0] == vdata[x] && last[1] == vdata[y] ); 243f220fa62Smrg} 244f220fa62Smrg 245f220fa62Smrginline void 246f220fa62SmrgMesher::copy( int x, int y ) 247f220fa62Smrg{ 248f220fa62Smrg last[0] = vdata[x]; last[1] = vdata[y]; 249f220fa62Smrg} 250f220fa62Smrg 251f220fa62Smrginline void 252f220fa62SmrgMesher::move( int x, int y ) 253f220fa62Smrg{ 254f220fa62Smrg vdata[x] = vdata[y]; 255f220fa62Smrg} 256f220fa62Smrg 257f220fa62Smrginline void 258f220fa62SmrgMesher::output( int x ) 259f220fa62Smrg{ 260f220fa62Smrg backend.tmeshvert( vdata[x] ); 261f220fa62Smrg} 262f220fa62Smrg 263f220fa62Smrg/*--------------------------------------------------------------------------- 264f220fa62Smrg * addedge - addedge an edge to the triangulation 265f220fa62Smrg * 266f220fa62Smrg * This code has been re-written to generate large triangle meshes 267f220fa62Smrg * from a monotone polygon. Although smaller triangle meshes 268f220fa62Smrg * could be generated faster and with less code, larger meshes 269f220fa62Smrg * actually give better SYSTEM performance. This is because 270f220fa62Smrg * vertices are processed in the backend slower than they are 271f220fa62Smrg * generated by this code and any decrease in the number of vertices 272f220fa62Smrg * results in a decrease in the time spent in the backend. 273f220fa62Smrg *--------------------------------------------------------------------------- 274f220fa62Smrg */ 275f220fa62Smrg 276f220fa62Smrgvoid 277f220fa62SmrgMesher::addLast( ) 278f220fa62Smrg{ 279e7980a23Smrg int ilast = itop; 280f220fa62Smrg 281f220fa62Smrg if( lastedge == 0 ) { 282f220fa62Smrg if( equal( 0, 1 ) ) { 283f220fa62Smrg output( ilast ); 284f220fa62Smrg swapMesh(); 285e7980a23Smrg for( int i = 2; i < ilast; i++ ) { 286f220fa62Smrg swapMesh(); 287f220fa62Smrg output( i ); 288f220fa62Smrg } 289f220fa62Smrg copy( ilast, ilast-1 ); 290f220fa62Smrg } else if( equal( ilast-2, ilast-1) ) { 291f220fa62Smrg swapMesh(); 292f220fa62Smrg output( ilast ); 293e7980a23Smrg for( int i = ilast-3; i >= 0; i-- ) { 294f220fa62Smrg output( i ); 295f220fa62Smrg swapMesh(); 296f220fa62Smrg } 297f220fa62Smrg copy( 0, ilast ); 298f220fa62Smrg } else { 299f220fa62Smrg closeMesh(); openMesh(); 300f220fa62Smrg output( ilast ); 301f220fa62Smrg output( 0 ); 302e7980a23Smrg for( int i = 1; i < ilast; i++ ) { 303f220fa62Smrg swapMesh(); 304f220fa62Smrg output( i ); 305f220fa62Smrg } 306f220fa62Smrg copy( ilast, ilast-1 ); 307f220fa62Smrg } 308f220fa62Smrg } else { 309f220fa62Smrg if( equal( 1, 0) ) { 310f220fa62Smrg swapMesh(); 311f220fa62Smrg output( ilast ); 312e7980a23Smrg for( int i = 2; i < ilast; i++ ) { 313f220fa62Smrg output( i ); 314f220fa62Smrg swapMesh(); 315f220fa62Smrg } 316f220fa62Smrg copy( ilast-1, ilast ); 317f220fa62Smrg } else if( equal( ilast-1, ilast-2) ) { 318f220fa62Smrg output( ilast ); 319f220fa62Smrg swapMesh(); 320e7980a23Smrg for( int i = ilast-3; i >= 0; i-- ) { 321f220fa62Smrg swapMesh(); 322f220fa62Smrg output( i ); 323f220fa62Smrg } 324f220fa62Smrg copy( ilast, 0 ); 325f220fa62Smrg } else { 326f220fa62Smrg closeMesh(); openMesh(); 327f220fa62Smrg output( 0 ); 328f220fa62Smrg output( ilast ); 329e7980a23Smrg for( int i = 1; i < ilast; i++ ) { 330f220fa62Smrg output( i ); 331f220fa62Smrg swapMesh(); 332f220fa62Smrg } 333f220fa62Smrg copy( ilast-1, ilast ); 334f220fa62Smrg } 335f220fa62Smrg } 336f220fa62Smrg closeMesh(); 337e7980a23Smrg //for( long k=0; k<=ilast; k++ ) pop( k ); 338f220fa62Smrg} 339f220fa62Smrg 340f220fa62Smrgvoid 341f220fa62SmrgMesher::addUpper( ) 342f220fa62Smrg{ 343e7980a23Smrg int ilast = itop; 344f220fa62Smrg 345f220fa62Smrg if( lastedge == 0 ) { 346f220fa62Smrg if( equal( 0, 1 ) ) { 347f220fa62Smrg output( ilast ); 348f220fa62Smrg swapMesh(); 349e7980a23Smrg for( int i = 2; i < ilast; i++ ) { 350f220fa62Smrg swapMesh(); 351f220fa62Smrg output( i ); 352f220fa62Smrg } 353f220fa62Smrg copy( ilast, ilast-1 ); 354f220fa62Smrg } else if( equal( ilast-2, ilast-1) ) { 355f220fa62Smrg swapMesh(); 356f220fa62Smrg output( ilast ); 357e7980a23Smrg for( int i = ilast-3; i >= 0; i-- ) { 358f220fa62Smrg output( i ); 359f220fa62Smrg swapMesh(); 360f220fa62Smrg } 361f220fa62Smrg copy( 0, ilast ); 362f220fa62Smrg } else { 363f220fa62Smrg closeMesh(); openMesh(); 364f220fa62Smrg output( ilast ); 365f220fa62Smrg output( 0 ); 366e7980a23Smrg for( int i = 1; i < ilast; i++ ) { 367f220fa62Smrg swapMesh(); 368f220fa62Smrg output( i ); 369f220fa62Smrg } 370f220fa62Smrg copy( ilast, ilast-1 ); 371f220fa62Smrg } 372f220fa62Smrg lastedge = 1; 373e7980a23Smrg //for( long k=0; k<ilast-1; k++ ) pop( k ); 374f220fa62Smrg move( 0, ilast-1 ); 375f220fa62Smrg move( 1, ilast ); 376f220fa62Smrg itop = 1; 377f220fa62Smrg } else { 378f220fa62Smrg if( ! isCcw( ilast ) ) return; 379f220fa62Smrg do { 380f220fa62Smrg itop--; 381f220fa62Smrg } while( (itop > 1) && isCcw( ilast ) ); 382f220fa62Smrg 383f220fa62Smrg if( equal( ilast-1, ilast-2 ) ) { 384f220fa62Smrg output( ilast ); 385f220fa62Smrg swapMesh(); 386e7980a23Smrg for( int i=ilast-3; i>=itop-1; i-- ) { 387f220fa62Smrg swapMesh(); 388f220fa62Smrg output( i ); 389f220fa62Smrg } 390f220fa62Smrg copy( ilast, itop-1 ); 391f220fa62Smrg } else if( equal( itop, itop-1 ) ) { 392f220fa62Smrg swapMesh(); 393f220fa62Smrg output( ilast ); 394e7980a23Smrg for( int i = itop+1; i < ilast; i++ ) { 395f220fa62Smrg output( i ); 396f220fa62Smrg swapMesh(); 397f220fa62Smrg } 398f220fa62Smrg copy( ilast-1, ilast ); 399f220fa62Smrg } else { 400f220fa62Smrg closeMesh(); openMesh(); 401f220fa62Smrg output( ilast ); 402f220fa62Smrg output( ilast-1 ); 403e7980a23Smrg for( int i=ilast-2; i>=itop-1; i-- ) { 404f220fa62Smrg swapMesh(); 405f220fa62Smrg output( i ); 406f220fa62Smrg } 407f220fa62Smrg copy( ilast, itop-1 ); 408f220fa62Smrg } 409e7980a23Smrg //for( int k=itop; k<ilast; k++ ) pop( k ); 410f220fa62Smrg move( itop, ilast ); 411f220fa62Smrg } 412f220fa62Smrg} 413f220fa62Smrg 414f220fa62Smrgvoid 415f220fa62SmrgMesher::addLower() 416f220fa62Smrg{ 417e7980a23Smrg int ilast = itop; 418f220fa62Smrg 419f220fa62Smrg if( lastedge == 1 ) { 420f220fa62Smrg if( equal( 1, 0) ) { 421f220fa62Smrg swapMesh(); 422f220fa62Smrg output( ilast ); 423e7980a23Smrg for( int i = 2; i < ilast; i++ ) { 424f220fa62Smrg output( i ); 425f220fa62Smrg swapMesh(); 426f220fa62Smrg } 427f220fa62Smrg copy( ilast-1, ilast ); 428f220fa62Smrg } else if( equal( ilast-1, ilast-2) ) { 429f220fa62Smrg output( ilast ); 430f220fa62Smrg swapMesh(); 431e7980a23Smrg for( int i = ilast-3; i >= 0; i-- ) { 432f220fa62Smrg swapMesh(); 433f220fa62Smrg output( i ); 434f220fa62Smrg } 435f220fa62Smrg copy( ilast, 0 ); 436f220fa62Smrg } else { 437f220fa62Smrg closeMesh(); openMesh(); 438f220fa62Smrg output( 0 ); 439f220fa62Smrg output( ilast ); 440e7980a23Smrg for( int i = 1; i < ilast; i++ ) { 441f220fa62Smrg output( i ); 442f220fa62Smrg swapMesh(); 443f220fa62Smrg } 444f220fa62Smrg copy( ilast-1, ilast ); 445f220fa62Smrg } 446f220fa62Smrg 447f220fa62Smrg lastedge = 0; 448e7980a23Smrg //for( long k=0; k<ilast-1; k++ ) pop( k ); 449f220fa62Smrg move( 0, ilast-1 ); 450f220fa62Smrg move( 1, ilast ); 451f220fa62Smrg itop = 1; 452f220fa62Smrg } else { 453f220fa62Smrg if( ! isCw( ilast ) ) return; 454f220fa62Smrg do { 455f220fa62Smrg itop--; 456f220fa62Smrg } while( (itop > 1) && isCw( ilast ) ); 457f220fa62Smrg 458f220fa62Smrg if( equal( ilast-2, ilast-1) ) { 459f220fa62Smrg swapMesh(); 460f220fa62Smrg output( ilast ); 461e7980a23Smrg for( int i=ilast-3; i>=itop-1; i--) { 462f220fa62Smrg output( i ); 463f220fa62Smrg swapMesh( ); 464f220fa62Smrg } 465f220fa62Smrg copy( itop-1, ilast ); 466f220fa62Smrg } else if( equal( itop-1, itop) ) { 467f220fa62Smrg output( ilast ); 468f220fa62Smrg swapMesh(); 469e7980a23Smrg for( int i=itop+1; i<ilast; i++ ) { 470f220fa62Smrg swapMesh( ); 471f220fa62Smrg output( i ); 472f220fa62Smrg } 473f220fa62Smrg copy( ilast, ilast-1 ); 474f220fa62Smrg } else { 475f220fa62Smrg closeMesh(); openMesh(); 476f220fa62Smrg output( ilast-1 ); 477f220fa62Smrg output( ilast ); 478e7980a23Smrg for( int i=ilast-2; i>=itop-1; i-- ) { 479f220fa62Smrg output( i ); 480f220fa62Smrg swapMesh( ); 481f220fa62Smrg } 482f220fa62Smrg copy( itop-1, ilast ); 483f220fa62Smrg } 484e7980a23Smrg //for( int k=itop; k<ilast; k++ ) pop( k ); 485f220fa62Smrg move( itop, ilast ); 486f220fa62Smrg } 487f220fa62Smrg} 488f220fa62Smrg 489f220fa62Smrg 490