ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

mesher.cc
Go to the documentation of this file.
00001 /*
00002 ** License Applicability. Except to the extent portions of this file are
00003 ** made subject to an alternative license as permitted in the SGI Free
00004 ** Software License B, Version 1.1 (the "License"), the contents of this
00005 ** file are subject only to the provisions of the License. You may not use
00006 ** this file except in compliance with the License. You may obtain a copy
00007 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
00008 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
00009 **
00010 ** http://oss.sgi.com/projects/FreeB
00011 **
00012 ** Note that, as provided in the License, the Software is distributed on an
00013 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
00014 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
00015 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
00016 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
00017 **
00018 ** Original Code. The Original Code is: OpenGL Sample Implementation,
00019 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
00020 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
00021 ** Copyright in any portions created by third parties is as indicated
00022 ** elsewhere herein. All Rights Reserved.
00023 **
00024 ** Additional Notice Provisions: The application programming interfaces
00025 ** established by SGI in conjunction with the Original Code are The
00026 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
00027 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
00028 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
00029 ** Window System(R) (Version 1.3), released October 19, 1998. This software
00030 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
00031 ** published by SGI, but has not been independently verified as being
00032 ** compliant with the OpenGL(R) version 1.2.1 Specification.
00033 */
00034 
00035 /*
00036  * mesher.c++
00037  *
00038  * $Date: 2006-03-12 00:07:02 +0000 (Sun, 12 Mar 2006) $ $Revision: 1.1 $
00039  * $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/glu32/libnurbs/internals/mesher.cc,v 1.1 2004/02/02 16:39:11 navaraf Exp $
00040  */
00041 
00042 #include "glimports.h"
00043 #include "myassert.h"
00044 #include "mystdio.h"
00045 #include "gridvertex.h"
00046 #include "gridtrimvertex.h"
00047 #include "jarcloc.h"
00048 #include "gridline.h"
00049 #include "trimline.h"
00050 #include "uarray.h"
00051 #include "backend.h"
00052 #include "mesher.h"
00053 
00054 
00055 const float Mesher::ZERO = 0.0;
00056 
00057 Mesher::Mesher( Backend& b ) 
00058     : backend( b ), 
00059     p( sizeof( GridTrimVertex ), 100, "GridTrimVertexPool" )
00060 {
00061     stacksize = 0;
00062     vdata = 0;
00063     lastedge = 0; //needed to prevent purify UMR 
00064 }
00065 
00066 Mesher::~Mesher( void )
00067 {
00068     if( vdata ) delete[] vdata;
00069 }
00070 
00071 void 
00072 Mesher::init( unsigned int npts )
00073 {
00074     p.clear();
00075     if( stacksize < npts ) {
00076     stacksize = 2 * npts;
00077     if( vdata ) delete[] vdata;     
00078     vdata = new GridTrimVertex_p[stacksize];
00079     } 
00080 }
00081 
00082 inline void
00083 Mesher::push( GridTrimVertex *gt )
00084 {
00085     assert( itop+1 != (int)stacksize );
00086     vdata[++itop] = gt;
00087 }
00088 
00089 inline void
00090 Mesher::pop( long )
00091 {
00092 }
00093 
00094 inline void
00095 Mesher::openMesh()
00096 {
00097     backend.bgntmesh( "addedge" );
00098 }
00099 
00100 inline void
00101 Mesher::closeMesh()
00102 {
00103     backend.endtmesh();
00104 }
00105 
00106 inline void
00107 Mesher::swapMesh()
00108 {
00109     backend.swaptmesh();
00110 }
00111 
00112 inline void
00113 Mesher::clearStack()
00114 {
00115     itop = -1;
00116     last[0] = 0;
00117 }
00118 
00119 void
00120 Mesher::finishLower( GridTrimVertex *gtlower )
00121 {
00122     for( push(gtlower); 
00123      nextlower( gtlower=new(p) GridTrimVertex ); 
00124      push(gtlower) ) 
00125         addLower();
00126     addLast();
00127 }
00128 
00129 void
00130 Mesher::finishUpper( GridTrimVertex *gtupper )
00131 {
00132     for( push(gtupper); 
00133      nextupper( gtupper=new(p) GridTrimVertex ); 
00134      push(gtupper) ) 
00135         addUpper();
00136     addLast();
00137 }
00138 
00139 void
00140 Mesher::mesh( void )
00141 {
00142     GridTrimVertex *gtlower, *gtupper;
00143 
00144     Hull::init( );
00145     nextupper( gtupper = new(p) GridTrimVertex );
00146     nextlower( gtlower = new(p) GridTrimVertex );
00147 
00148     clearStack();
00149     openMesh();
00150     push(gtupper);
00151 
00152     nextupper( gtupper = new(p) GridTrimVertex );
00153     nextlower( gtlower );
00154 
00155     assert( gtupper->t && gtlower->t );
00156     
00157     if( gtupper->t->param[0] < gtlower->t->param[0] ) {
00158     push(gtupper);
00159     lastedge = 1;
00160     if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) {
00161         finishLower(gtlower);
00162         return;
00163     }
00164     } else if( gtupper->t->param[0] > gtlower->t->param[0] ) {
00165     push(gtlower);
00166     lastedge = 0;
00167     if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) {
00168         finishUpper(gtupper);
00169         return;
00170     }
00171     } else {
00172     if( lastedge == 0 ) {
00173         push(gtupper);
00174         lastedge = 1;
00175         if( nextupper(gtupper=new(p) GridTrimVertex) == 0 ) {
00176         finishLower(gtlower);
00177         return;
00178         }
00179     } else {
00180         push(gtlower);
00181         lastedge = 0;
00182         if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) {
00183         finishUpper(gtupper);
00184         return;
00185         }
00186     }
00187     }
00188 
00189     while ( 1 ) {
00190     if( gtupper->t->param[0] < gtlower->t->param[0] ) {
00191             push(gtupper);
00192         addUpper();
00193         if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) {
00194         finishLower(gtlower);
00195         return;
00196         }
00197     } else if( gtupper->t->param[0] > gtlower->t->param[0] ) {
00198             push(gtlower);
00199         addLower();
00200         if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) {
00201         finishUpper(gtupper);
00202         return;
00203         }
00204     } else {
00205         if( lastedge == 0 ) {
00206         push(gtupper);
00207         addUpper();
00208         if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) {
00209             finishLower(gtlower);
00210             return;
00211         }
00212         } else {
00213         push(gtlower);
00214         addLower();
00215         if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) {
00216             finishUpper(gtupper);
00217             return;
00218         }
00219         }
00220     }
00221     }
00222 }
00223 
00224 inline int
00225 Mesher::isCcw( int ilast )
00226 {
00227     REAL area = det3( vdata[ilast]->t, vdata[itop-1]->t, vdata[itop-2]->t );
00228     return (area < ZERO) ? 0 : 1;
00229 }
00230 
00231 inline int
00232 Mesher::isCw( int ilast  )
00233 {
00234     REAL area = det3( vdata[ilast]->t, vdata[itop-1]->t, vdata[itop-2]->t );
00235     return (area > -ZERO) ? 0 : 1;
00236 }
00237 
00238 inline int
00239 Mesher::equal( int x, int y )
00240 {
00241     return( last[0] == vdata[x] && last[1] == vdata[y] );
00242 }
00243 
00244 inline void
00245 Mesher::copy( int x, int y )
00246 {
00247     last[0] = vdata[x]; last[1] = vdata[y];
00248 }
00249  
00250 inline void
00251 Mesher::move( int x, int y ) 
00252 {
00253     vdata[x] = vdata[y];
00254 }
00255 
00256 inline void
00257 Mesher::output( int x )
00258 {
00259     backend.tmeshvert( vdata[x] );
00260 }
00261 
00262 /*---------------------------------------------------------------------------
00263  * addedge - addedge an edge to the triangulation
00264  *
00265  *  This code has been re-written to generate large triangle meshes
00266  *  from a monotone polygon.  Although smaller triangle meshes
00267  *  could be generated faster and with less code, larger meshes
00268  *  actually give better SYSTEM performance.  This is because
00269  *  vertices are processed in the backend slower than they are
00270  *  generated by this code and any decrease in the number of vertices
00271  *  results in a decrease in the time spent in the backend.
00272  *---------------------------------------------------------------------------
00273  */
00274 
00275 void
00276 Mesher::addLast( )
00277 {
00278     register int ilast = itop;
00279 
00280     if( lastedge == 0 ) {
00281     if( equal( 0, 1 ) ) {
00282         output( ilast );
00283         swapMesh();
00284         for( register int i = 2; i < ilast; i++ ) {
00285         swapMesh();
00286         output( i );
00287         }
00288         copy( ilast, ilast-1 );
00289     } else if( equal( ilast-2, ilast-1) ) {
00290         swapMesh();
00291         output( ilast );
00292         for( register int i = ilast-3; i >= 0; i-- ) {
00293         output( i );
00294         swapMesh();
00295         }
00296         copy( 0, ilast );
00297     } else {
00298         closeMesh();    openMesh();
00299         output( ilast );
00300         output( 0 );
00301         for( register int i = 1; i < ilast; i++ ) {
00302         swapMesh();
00303         output( i );
00304         }
00305         copy( ilast, ilast-1 );
00306     }
00307     } else {
00308     if( equal( 1, 0) ) {
00309         swapMesh();
00310         output( ilast );
00311         for( register int i = 2; i < ilast; i++ ) {
00312         output( i );
00313         swapMesh();
00314         }
00315         copy( ilast-1, ilast );
00316     } else if( equal( ilast-1, ilast-2) ) {
00317         output( ilast );
00318         swapMesh();
00319         for( register int i = ilast-3; i >= 0; i-- ) {
00320         swapMesh();
00321         output( i );
00322         }
00323         copy( ilast, 0 );
00324     } else {
00325         closeMesh();    openMesh();
00326         output( 0 );
00327         output( ilast );
00328         for( register int i = 1; i < ilast; i++ ) {
00329         output( i );
00330         swapMesh();
00331         }
00332         copy( ilast-1, ilast );
00333     }
00334     }
00335     closeMesh();
00336     //for( register long k=0; k<=ilast; k++ ) pop( k );
00337 }
00338 
00339 void
00340 Mesher::addUpper( )
00341 {
00342     register int ilast = itop;
00343 
00344     if( lastedge == 0 ) {
00345     if( equal( 0, 1 ) ) {
00346         output( ilast );
00347         swapMesh();
00348         for( register int i = 2; i < ilast; i++ ) {
00349         swapMesh();
00350         output( i );
00351         }
00352         copy( ilast, ilast-1 );
00353     } else if( equal( ilast-2, ilast-1) ) {
00354         swapMesh();
00355         output( ilast );
00356         for( register int i = ilast-3; i >= 0; i-- ) {
00357         output( i );
00358         swapMesh();
00359         }
00360         copy( 0, ilast );
00361     } else {
00362         closeMesh();    openMesh();
00363         output( ilast );
00364         output( 0 );
00365         for( register int i = 1; i < ilast; i++ ) {
00366         swapMesh();
00367         output( i );
00368         }
00369         copy( ilast, ilast-1 );
00370     }
00371     lastedge = 1;
00372         //for( register long k=0; k<ilast-1; k++ ) pop( k );
00373     move( 0, ilast-1 );
00374     move( 1, ilast );
00375     itop = 1;
00376     } else {
00377     if( ! isCcw( ilast ) ) return;
00378     do {
00379         itop--;
00380     } while( (itop > 1) && isCcw( ilast ) );
00381 
00382     if( equal( ilast-1, ilast-2 ) ) {
00383         output( ilast );
00384         swapMesh();
00385         for( register int i=ilast-3; i>=itop-1; i-- ) {
00386         swapMesh();
00387         output( i );
00388         }
00389         copy( ilast, itop-1 );
00390     } else if( equal( itop, itop-1 ) ) {
00391         swapMesh();
00392         output( ilast );
00393         for( register int i = itop+1; i < ilast; i++ ) {
00394         output( i );
00395         swapMesh();
00396         }
00397         copy( ilast-1, ilast );
00398     } else {
00399         closeMesh();    openMesh();
00400         output( ilast );
00401         output( ilast-1 );
00402         for( register int i=ilast-2; i>=itop-1; i-- ) {
00403         swapMesh();
00404         output( i );
00405         } 
00406         copy( ilast, itop-1 );
00407     }
00408         //for( register int k=itop; k<ilast; k++ ) pop( k );
00409     move( itop, ilast );
00410     }
00411 }
00412 
00413 void
00414 Mesher::addLower()
00415 {
00416     register int ilast = itop;
00417 
00418     if( lastedge == 1 ) {
00419     if( equal( 1, 0) ) {
00420         swapMesh();
00421         output( ilast );
00422         for( register int i = 2; i < ilast; i++ ) {
00423         output( i );
00424         swapMesh();
00425         }
00426         copy( ilast-1, ilast );
00427     } else if( equal( ilast-1, ilast-2) ) {
00428         output( ilast );
00429         swapMesh();
00430         for( register int i = ilast-3; i >= 0; i-- ) {
00431         swapMesh();
00432         output( i );
00433         }
00434         copy( ilast, 0 );
00435     } else {
00436         closeMesh();    openMesh();
00437         output( 0 );
00438         output( ilast );
00439         for( register int i = 1; i < ilast; i++ ) {
00440         output( i );
00441         swapMesh();
00442         }
00443         copy( ilast-1, ilast );
00444     }
00445 
00446     lastedge = 0;
00447         //for( register long k=0; k<ilast-1; k++ ) pop( k );
00448     move( 0, ilast-1 );
00449     move( 1, ilast );
00450     itop = 1;
00451     } else {
00452     if( ! isCw( ilast ) ) return;
00453     do {
00454         itop--;
00455     } while( (itop > 1) && isCw( ilast ) );
00456 
00457     if( equal( ilast-2, ilast-1) ) {
00458         swapMesh();
00459         output( ilast );
00460         for( register int i=ilast-3; i>=itop-1; i--) {
00461         output( i );
00462         swapMesh( );
00463         }
00464         copy( itop-1, ilast );
00465     } else if( equal( itop-1, itop) ) {
00466         output( ilast );
00467         swapMesh();
00468         for( register int i=itop+1; i<ilast; i++ ) {
00469         swapMesh( );
00470         output( i );
00471         }
00472         copy( ilast, ilast-1 );
00473     } else {
00474         closeMesh();    openMesh();
00475         output( ilast-1 );
00476         output( ilast );
00477         for( register int i=ilast-2; i>=itop-1; i-- ) {
00478         output( i );
00479         swapMesh( );
00480         }
00481         copy( itop-1, ilast );
00482     }
00483         //for( register int k=itop; k<ilast; k++ ) pop( k );
00484     move( itop, ilast );
00485     }
00486 }
00487 
00488 

Generated on Thu May 24 2012 04:24:12 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.