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

tessmono.c
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 ** Author: Eric Veach, July 1994.
00037 **
00038 ** $Date: 2007-10-19 23:21:45 +0000 (Fri, 19 Oct 2007) $ $Revision: 1.1 $
00039 ** $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/glu32/libtess/tessmono.c,v 1.1 2004/02/02 16:39:15 navaraf Exp $
00040 */
00041 
00042 #include "gluos.h"
00043 #include <stdlib.h>
00044 #include "geom.h"
00045 #include "mesh.h"
00046 #include "tessmono.h"
00047 #include <assert.h>
00048 
00049 #define AddWinding(eDst,eSrc)   (eDst->winding += eSrc->winding, \
00050                  eDst->Sym->winding += eSrc->Sym->winding)
00051 
00052 /* __gl_meshTessellateMonoRegion( face ) tessellates a monotone region
00053  * (what else would it do??)  The region must consist of a single
00054  * loop of half-edges (see mesh.h) oriented CCW.  "Monotone" in this
00055  * case means that any vertical line intersects the interior of the
00056  * region in a single interval.
00057  *
00058  * Tessellation consists of adding interior edges (actually pairs of
00059  * half-edges), to split the region into non-overlapping triangles.
00060  *
00061  * The basic idea is explained in Preparata and Shamos (which I don''t
00062  * have handy right now), although their implementation is more
00063  * complicated than this one.  The are two edge chains, an upper chain
00064  * and a lower chain.  We process all vertices from both chains in order,
00065  * from right to left.
00066  *
00067  * The algorithm ensures that the following invariant holds after each
00068  * vertex is processed: the untessellated region consists of two
00069  * chains, where one chain (say the upper) is a single edge, and
00070  * the other chain is concave.  The left vertex of the single edge
00071  * is always to the left of all vertices in the concave chain.
00072  *
00073  * Each step consists of adding the rightmost unprocessed vertex to one
00074  * of the two chains, and forming a fan of triangles from the rightmost
00075  * of two chain endpoints.  Determining whether we can add each triangle
00076  * to the fan is a simple orientation test.  By making the fan as large
00077  * as possible, we restore the invariant (check it yourself).
00078  */
00079 int __gl_meshTessellateMonoRegion( GLUface *face )
00080 {
00081   GLUhalfEdge *up, *lo;
00082 
00083   /* All edges are oriented CCW around the boundary of the region.
00084    * First, find the half-edge whose origin vertex is rightmost.
00085    * Since the sweep goes from left to right, face->anEdge should
00086    * be close to the edge we want.
00087    */
00088   up = face->anEdge;
00089   assert( up->Lnext != up && up->Lnext->Lnext != up );
00090 
00091   for( ; VertLeq( up->Dst, up->Org ); up = up->Lprev )
00092     ;
00093   for( ; VertLeq( up->Org, up->Dst ); up = up->Lnext )
00094     ;
00095   lo = up->Lprev;
00096 
00097   while( up->Lnext != lo ) {
00098     if( VertLeq( up->Dst, lo->Org )) {
00099       /* up->Dst is on the left.  It is safe to form triangles from lo->Org.
00100        * The EdgeGoesLeft test guarantees progress even when some triangles
00101        * are CW, given that the upper and lower chains are truly monotone.
00102        */
00103       while( lo->Lnext != up && (EdgeGoesLeft( lo->Lnext )
00104          || EdgeSign( lo->Org, lo->Dst, lo->Lnext->Dst ) <= 0 )) {
00105     GLUhalfEdge *tempHalfEdge= __gl_meshConnect( lo->Lnext, lo );
00106     if (tempHalfEdge == NULL) return 0;
00107     lo = tempHalfEdge->Sym;
00108       }
00109       lo = lo->Lprev;
00110     } else {
00111       /* lo->Org is on the left.  We can make CCW triangles from up->Dst. */
00112       while( lo->Lnext != up && (EdgeGoesRight( up->Lprev )
00113          || EdgeSign( up->Dst, up->Org, up->Lprev->Org ) >= 0 )) {
00114     GLUhalfEdge *tempHalfEdge= __gl_meshConnect( up, up->Lprev );
00115     if (tempHalfEdge == NULL) return 0;
00116     up = tempHalfEdge->Sym;
00117       }
00118       up = up->Lnext;
00119     }
00120   }
00121 
00122   /* Now lo->Org == up->Dst == the leftmost vertex.  The remaining region
00123    * can be tessellated in a fan from this leftmost vertex.
00124    */
00125   assert( lo->Lnext != up );
00126   while( lo->Lnext->Lnext != up ) {
00127     GLUhalfEdge *tempHalfEdge= __gl_meshConnect( lo->Lnext, lo );
00128     if (tempHalfEdge == NULL) return 0;
00129     lo = tempHalfEdge->Sym;
00130   }
00131 
00132   return 1;
00133 }
00134 
00135 
00136 /* __gl_meshTessellateInterior( mesh ) tessellates each region of
00137  * the mesh which is marked "inside" the polygon.  Each such region
00138  * must be monotone.
00139  */
00140 int __gl_meshTessellateInterior( GLUmesh *mesh )
00141 {
00142   GLUface *f, *next;
00143 
00144   /*LINTED*/
00145   for( f = mesh->fHead.next; f != &mesh->fHead; f = next ) {
00146     /* Make sure we don''t try to tessellate the new triangles. */
00147     next = f->next;
00148     if( f->inside ) {
00149       if ( !__gl_meshTessellateMonoRegion( f ) ) return 0;
00150     }
00151   }
00152 
00153   return 1;
00154 }
00155 
00156 
00157 /* __gl_meshDiscardExterior( mesh ) zaps (ie. sets to NULL) all faces
00158  * which are not marked "inside" the polygon.  Since further mesh operations
00159  * on NULL faces are not allowed, the main purpose is to clean up the
00160  * mesh so that exterior loops are not represented in the data structure.
00161  */
00162 void __gl_meshDiscardExterior( GLUmesh *mesh )
00163 {
00164   GLUface *f, *next;
00165 
00166   /*LINTED*/
00167   for( f = mesh->fHead.next; f != &mesh->fHead; f = next ) {
00168     /* Since f will be destroyed, save its next pointer. */
00169     next = f->next;
00170     if( ! f->inside ) {
00171       __gl_meshZapFace( f );
00172     }
00173   }
00174 }
00175 
00176 #define MARKED_FOR_DELETION 0x7fffffff
00177 
00178 /* __gl_meshSetWindingNumber( mesh, value, keepOnlyBoundary ) resets the
00179  * winding numbers on all edges so that regions marked "inside" the
00180  * polygon have a winding number of "value", and regions outside
00181  * have a winding number of 0.
00182  *
00183  * If keepOnlyBoundary is TRUE, it also deletes all edges which do not
00184  * separate an interior region from an exterior one.
00185  */
00186 int __gl_meshSetWindingNumber( GLUmesh *mesh, int value,
00187                     GLboolean keepOnlyBoundary )
00188 {
00189   GLUhalfEdge *e, *eNext;
00190 
00191   for( e = mesh->eHead.next; e != &mesh->eHead; e = eNext ) {
00192     eNext = e->next;
00193     if( e->Rface->inside != e->Lface->inside ) {
00194 
00195       /* This is a boundary edge (one side is interior, one is exterior). */
00196       e->winding = (e->Lface->inside) ? value : -value;
00197     } else {
00198 
00199       /* Both regions are interior, or both are exterior. */
00200       if( ! keepOnlyBoundary ) {
00201     e->winding = 0;
00202       } else {
00203     if ( !__gl_meshDelete( e ) ) return 0;
00204       }
00205     }
00206   }
00207   return 1;
00208 }

Generated on Sat May 26 2012 04:22:21 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.