5
OpenMesh – a generic and efficient polygon mesh data structure M. Botsch S. Steinberg S. Bischoff L. Kobbelt Lehrstuhl f ¨ ur Informatik VIII Computergraphik und Multimedia RWTH Aachen Abstract We describe the implementation of a half-edge data structure for the static representation and dynamic handling of arbitrary polygonal meshes. The particular design of the data structures and classes aims at maximum flexibility and high performance. We achieve this by using generative programming concepts which allow the compiler to resolve most of the special case handling decisions at compile time. We evaluate our data structure based on prototypic implementations of mesh processing applications such as decimation and smoothing. 1 Introduction Polygonal meshes are the most appropriate geometry representation for interactive 3D graphics applications. They are flexible enough to approximate arbitrary shapes to any approximation tolerance and they can be processed efficiently by the current graphics hardware which is available even on today’s low cost PCs. One of the long-term goals of the OpenSGplus initiative is to de- sign and implement a set of software tools to enhance the OpenSG API with high level functionality for handling complex geometric objects. In this context a properly designed geometry kernel plays an important role since most high level algorithms will be based on it. The nature of the planned target applications such as level-of- detail management and subdivision surfaces implies that this unified geometry representation should be based on polygonal meshes. In this short paper we describe the design and implementation of our polygonal mesh data structure. We start by identifying the specific requirements for the data structure in the context of the par- ticular algorithms that are planned within the OpenSGplus project. These requirements allow us to identify three major design goals which are flexibility (with respect to the underlying implementation and to the higher level algorithms), efficiency (in time and memory usage), and ease-of-use (the API has to hide the complexity of the underlying data structures). 2 Requirements The main design goal for our library is flexibility. Since we do not want to overly restrict the set of applications, it should be able to provide randomly access to vertices, edges and faces, where faces can be arbitrary polygons and not just triangles. The user should be able to choose between arrays or lists as underlying container types and arbitrary scalar types. The second goal is time and space efficiency. Especially algo- rithms like decimation or smoothing of meshes need to navigate through the one-ring-neighborhood of a vertex. So we must allow fast access to such information. For space efficiency, memory should be allocated only for elements actually used, e.g., polygons with no attributes do not allocate pointers to their elements. The third goal is ease-of-use. The API should be easy to under- stand and to use for non-experts so that it can be integrated easily into any other library like, e.g., OpenSG. Our goal is a user interface that wraps and hides the complex underlying structure with a simple API. 3 Previous Work A polygonal mesh consists of a set of vertices, edges, faces and topological relations between them. Based on these relations, a data structure defines how each element is stored and what references to its neighborhood it needs. In the following we give a short survey over such data structures. We mainly distinguish between face-based and edge-based data structures. Face-based data structures store for each face pointers to its vertices and its neighboring faces. This makes it possible to nav- igate around each vertex by visiting all surrounding faces, which is frequently done in many algorithms. However, special case handling is needed, when navigation runs over items with variable valence. Suppose a mesh that consists of triangles as well as quadrangles, then navigation would not work without many time consuming case distinctions. Edge-based data structures store for each edge pointers to both vertices and to the neighboring edges. Since an edge has always the same topological structure, it is possible to handle polygons with variable valence in one mesh. There are several edge-based variants that differ only in the topo- logical information they store. The winged-edge data structure [2, 12] stores for each edge references to its vertices, to both poly- gons sharing this edge, and to the four neighboring edges or wings (see Figure 1). Traversing the neighborhood requires one case dis- tinction per step, because an edge does not encode its orientation explicitly. The half-edge data structure solves this problem by splitting each edge into two halves, where each half-edge points to its opposite half-edge, an incident vertex and an incident polygon. For a detailed description see [7]. The Computational Geometry Algorithm Library, CGAL 1 , is closely related to our mesh data structure. It is based on half-edges and consists of three main parts. The first part manages and orga- nizes the geometric primitives (vertices, edges and faces), the second part handles the topological relations between the primitives and the third part provides additional functionality like circulators, iterators and I/O support. CGAL is a very powerful library because of its flexibility and effi- ciency. But in the context of our applications some design decisions have to be reconsidered. The CGAL programming interface does not support the inclusion of specialized mesh kernels such as, e.g., quad-tree or array-based representations for recursively refined subdivision surfaces which, however, are necessary for their efficient implementation. This re- striction will also forbid later enhancements like more sophisticated kernels that are able to deal with non–manifold meshes, see Section 4.1. Moreover, for array–based CGAL meshes the size has to be known a priori to the constructor. Therefore, applications that dy- namically change the mesh complexity have to use the less space ef- ficient list–based CGAL mesh. In the OpenMesh implementation we provide, in contrast, dynamic memory management also for array- based meshes. 1 http://www.cgal.org

OpenMesh – a generic and efficient polygon mesh … – a generic and efficient polygon mesh data ... The Computational Geometry Algorithm Library, ... an expensive search within

Embed Size (px)

Citation preview

OpenMesh – a generic and efficient pol ygon mesh data structure

M. Botsch S.Steinberg S.Bischoff L. KobbeltLehrstuhlfur InformatikVIII

ComputergraphikundMultimediaRWTH Aachen

Abstract

Wedescribetheimplementationof ahalf-edgedatastructurefor thestatic representationand dynamichandlingof arbitrary polygonalmeshes.Theparticulardesignof thedatastructuresandclassesaimsat maximumflexibility andhigh performance.We achieve this byusinggenerativeprogrammingconceptswhichallow thecompilertoresolve mostof thespecialcasehandlingdecisionsat compiletime.Weevaluateourdatastructurebasedonprototypicimplementationsof meshprocessingapplicationssuchasdecimationandsmoothing.

1 Intr oduction

Polygonalmeshesarethemostappropriategeometryrepresentationfor interactive 3D graphicsapplications.They areflexible enoughto approximatearbitraryshapesto any approximationtoleranceandthey canbe processedefficiently by the currentgraphicshardwarewhich is availableevenon today’s low costPCs.

Oneof thelong-termgoalsof theOpenSGplusinitiative is to de-signandimplementa setof softwaretools to enhancetheOpenSGAPI with high level functionality for handlingcomplex geometricobjects. In this context a properlydesignedgeometrykernelplaysanimportantrole sincemosthigh level algorithmswill bebasedonit. The natureof the plannedtarget applicationssuchas level-of-detailmanagementandsubdivisionsurfacesimpliesthatthisunifiedgeometryrepresentationshouldbebasedonpolygonalmeshes.

In this short paperwe describethe designand implementationof our polygonalmeshdatastructure. We startby identifying thespecificrequirementsfor thedatastructurein thecontext of thepar-ticular algorithmsthatareplannedwithin the OpenSGplusproject.Theserequirementsallow us to identify threemajor designgoalswhich areflexibility (with respectto theunderlyingimplementationandto thehigherlevel algorithms),efficiency(in time andmemoryusage),andease-of-use(the API hasto hide the complexity of theunderlyingdatastructures).

2 Requirements

Themaindesigngoal for our library is flexibility. Sincewe do notwant to overly restrict the setof applications,it shouldbe able toprovide randomlyaccessto vertices,edgesandfaces,wherefacescanbearbitrarypolygonsandnot just triangles.Theusershouldbeableto choosebetweenarraysor lists asunderlyingcontainertypesandarbitraryscalartypes.

The secondgoal is time and spaceefficiency. Especiallyalgo-rithms like decimationor smoothingof meshesneedto navigatethroughthe one-ring-neighborhoodof a vertex. So we mustallowfastaccessto suchinformation.Forspaceefficiency, memoryshouldbeallocatedonly for elementsactuallyused,e.g.,polygonswith noattributesdonot allocatepointersto their elements.

The third goal is ease-of-use. TheAPI shouldbeeasyto under-standandto usefor non-expertsso that it canbe integratedeasilyinto any otherlibrary like,e.g.,OpenSG.Ourgoalis auserinterfacethatwrapsandhidesthecomplex underlyingstructurewith asimpleAPI.

3 Previous Work

A polygonalmeshconsistsof a set of vertices,edges,facesandtopologicalrelationsbetweenthem.Basedon theserelations,adatastructuredefineshow eachelementis storedandwhatreferencestoits neighborhoodit needs.In the following we give a shortsurveyover suchdatastructures.

We mainly distinguishbetweenface-basedandedge-baseddatastructures.Face-baseddatastructuresstorefor eachfacepointerstoits verticesandits neighboringfaces.This makesit possibleto nav-igatearoundeachvertex by visiting all surroundingfaces,which isfrequentlydonein many algorithms.However, specialcasehandlingis needed,whennavigation runsover itemswith variablevalence.Supposea meshthat consistsof trianglesas well as quadrangles,thennavigationwouldnotwork withoutmany time consumingcasedistinctions.

Edge-baseddatastructuresstorefor eachedgepointersto bothverticesandto theneighboringedges.Sinceanedgehasalwaysthesametopologicalstructure,it is possibleto handlepolygonswithvariablevalencein onemesh.

Thereareseveraledge-basedvariantsthatdiffer only in thetopo-logical information they store. The winged-edge data structure[2, 12] storesfor eachedgereferencesto its vertices,to bothpoly-gonssharingthis edge,andto the four neighboringedgesor wings(seeFigure1). Traversingtheneighborhoodrequiresonecasedis-tinction per step,becausean edgedoesnot encodeits orientationexplicitly.

Thehalf-edge datastructuresolvesthisproblemby splittingeachedgeinto two halves, whereeachhalf-edgepoints to its oppositehalf-edge,anincidentvertex andanincidentpolygon.For adetaileddescriptionsee[7].

The ComputationalGeometryAlgorithm Library, CGAL1, iscloselyrelatedto our meshdatastructure.It is basedon half-edgesandconsistsof threemain parts. The first part managesandorga-nizesthegeometricprimitives(vertices,edgesandfaces),thesecondparthandlesthetopologicalrelationsbetweentheprimitivesandthethird partprovidesadditionalfunctionality like circulators,iteratorsandI/O support.

CGAL is averypowerful library becauseof its flexibility andeffi-ciency. But in thecontext of ourapplicationssomedesigndecisionshave to bereconsidered.

TheCGAL programminginterfacedoesnotsupporttheinclusionof specializedmeshkernelssuchas,e.g.,quad-treeor array-basedrepresentationsfor recursively refinedsubdivision surfaceswhich,however, arenecessaryfor their efficient implementation.This re-strictionwill alsoforbid laterenhancementslike moresophisticatedkernelsthatareableto dealwith non–manifoldmeshes,seeSection4.1.

Moreover, for array–basedCGAL meshesthe size has to beknown a priori to the constructor. Therefore,applicationsthat dy-namicallychangethemeshcomplexity have to usethelessspaceef-ficientlist–basedCGAL mesh.In theOpenMeshimplementationweprovide, in contrast,dynamicmemorymanagementalsofor array-basedmeshes.

1http://www.cgal.org

4 OpenMesh

This sectionwill describethebasicdesigndecisionsleadingto thecurrentOpenMeshimplementation.Theprogramminginterfaceandsomeof the implementationdetailsareexplainedbasedon simpleexamples. A moredetaileddescriptioncanbe found in the docu-mentation[10].

���� 2

57

1

73

5

4 4

6

3

1

1. Vertex �� oneoutgoinghalfedge,

2. Face�� onehalfedge,

3. Halfedge�� targetvertex,

4. Halfedge�� its face,

5. Halfedge�� next halfedge,

6. Halfedge�� oppositehalfedge(implicit),

7. Halfedge�� previoushalfedge(optional).

Figure1: Halfegedatastructure.

4.1 Data Structure

Thefirst designdecisionfor a meshlibrary is to chooseoneof thedatastructuresintroducedin thelastsection.

To beasflexible aspossibleweshouldrepresenteachof themeshitems (vertices,edgesand faces)explicitly, in order to be able toattachadditionalattributesandfunctionalityto them.Sincee.g.pri-mal subdivision algorithmsneedto storenew point positionsperedge(see[13]), it is moreefficient to provide an edgeor halfedgetype in additionto verticesandfacesandto storethis new point intheedgeitself.

Although every generalpolygonalmeshcan be tesselatedto ameshconsistingof triangularfacesonly, wedonot restrictthemeshlibrary to puretrianglemeshes.Insteadwe provide ageneralpolyg-onalmeshontheonehand,andamoreefficient trianglemeshontheotherhand,so that theusercantradeoff betweenspeedandgener-ality.

Whendealingwith arbitrarypolygonalmeshes,halfedge–basedrepresentationsalsoprovide a muchsimpleralgorithmicstructure:Sincehalfedgesstorethemainconnectivity informationandalwayshavethesametopology, vertices,(half–)edgesandfacesaretypesofconstantsize.In contrast,a face–basedrepresentationhasto storeavariableamountof vertex handlesin eachface.

In many real world applicationsone has to deal with non–manifold input data. Thesemeshesmaycontaintwo typesof non–manifolddegeneracies:

� Complex vertices: The neighorhoodof theseverticesis not atopologicaldisc(nora halfdiscat theboundary).

� Complex edges are characterizedby belongingto more thantwo faces.

Our currentOpenMeshimplementationcanhandlecomplex ver-tices, but doesat the momentnot supportcomplex edges. Thisfunctionality could be addedby providing a meshkernel for non–manifoldmeshes(seethenext section).

In orderto enableefficient implementationof standardalgorithmslike e.g. smoothing,subdivision or decimation,the most frequentatomicmeshoperationsperformedby thesealgorithmshave to betakeninto accountwhendesigningthedatastructure.In additiontotheususalconnectivity information,all of thesealgorithmsrequireaccessto the one–ringneighborhoodof a vertex, possiblyin termsof verticesor incidentedgesor faces.

Consideringthesespecial requirementsimplies the use of ahalfedge–baseddatastructure,wherewe have a naturalrepresen-tationof all typesof meshitemsandarbitrarypolygonalfaces.Thehalfedgestructurealso provides fast, constant–timeaccessto theone–ringneighborhoodof vertices.Startingatanoutgoinghalfedgeof a certain vertex, the next halfedgein clockwise order can bereachedby two indirections: go to the next halfedgeof the face,thento its oppositehalfedge.Facebasedstructureshave to performanexpensive searchwithin thecurrentfacein orderto find this nexthalfedge.

Theconnectivity informationstoredin our implementationis il-lustratedin Figure1.

4.2 Interface

Dependingon the applicationone often needsto storeadditionaldatafor certainmeshitems. Thecodein Listings1 and2, e.g.,hasto storeoneadditionalpoint for eachvertex (thecenterof gravity ofits neighbors).While anadditionalarraycouldbeusedto hold thesepoints, this approachwill becomecumbersomeanderror–proneifmore and more externalelementsare to be storedandhave to besynchronizedwith the mesh. The naturalsolution is to pack thisdatadirectly into thecorrespondingmeshitems,like e.g. attachingthe additionalpoint coordinateto the vertex type. This approachwill alsoresultin morecoherencein thememoryfootprint, therebyimproving cacheefficiency aswell.

To provide this flexibility , meshescanbecustom–tailoredfor theneedsof specificalgorithmsby parameterizingthemby a so–calledtraits class. The restof this sectionwill describethe customizingpossibilities,their implementationdetailswill be discussedin sec-tion 4.3. To fully specifyamesh,severalparameterscanbegiven:

FaceType: Specifieswhetherto usea generalpolygonalmeshorthe(moreefficient) trianglemesh.

Kernel: Themeshkernelis responsiblefor storingthemeshitemsinternally. For dynamicmeshes(e.g. for meshdecimation)akernelbasedon doubly linked lists canbe used,sinceinsert-ing/deletingelementsto/from lists is more efficient than forarrays.An array–basedkernelin turn providesfastertraversalandconsumeslessmemoryandshouldthereforeby usedforapplicationsdealingwith staticmeshesonly.

Traits: In additionto theprevioustwo points,themeshis param-eterizedby a traitsclass,thatallows to enhancemeshitemsbyarbitraryfunctionality. Theseuser–definedclassesareaddedtothe correspondingmeshitemsin termsof inheritance.In ad-dition theusercanchoosefrom a setof pre–definedcommonattributeslike e.g. normalvectoror color andattachthemtocertainmeshitems,too. Thetraitsclassalsoselectsthecoordi-natetypeandthescalartypeof themesh,sothat— dependingon theapplication— 2D–,3D–or � –D vectorsandfloat,dou-ble,or evenexactarithmeticcanbeused.

All combinationsof facetypeandmeshkernelsareconvenientlyaccessiblethroughpre–definedclasses,that are further parameter-izedby theusertraits(seeListing 1).

Themeshitemsarereferredtobyhandletypes,thataredefinedbythemeshkernel:anarray–basedkernelusesindicesto addressitems,a list–basedkernelusespointers.ThereforemostAPI functionsarebasedon theseabstracthandletypes.

In order to navigate throughthe mesh,the OpenMeshprovidesiteratorsandcirculators,thatareusedin thesamewayasSTL itera-tors. Iteratorsjust enumerateall meshitemsof onetype: in Listing2 aVertexIter is usedto iteratethroughall thevertices,rangingfrommesh.vertices begin() tomesh.vertices end().

Convenient accessto the one–ringneighborhoodof verticesisprovided by vertex circulators. Given a centervertex, all one–ring information(incoming/outgoinghalfedges,incident facesandneighboringvertices)canbeaccessedusingasimilarsyntaxasfor it-erators.In Listing 2 thecenterof gravity of eachvertex is computed

#include � ACG/Mesh/TriMesh ArrayKernelT.hh�struct MyTraits : public DefaultTraits�

template � classBase� classVertexT : public Base�public :

const Vec3f& cog() const�

return cog ; void setcog(const Vec3f& cog)

�cog = cog;

pri vate:Vec3f cog ;

; ;typedef TriMesh ArrayKernelT� MyTraits� MyMesh;

Listing 1: Definingacustom–tailoredmeshthatstoresanadditionalpointpervertex.

#include � ACG/MeshIO/MeshReader.hh�#include � ACG/MeshIO/MeshWriter.hh�int main(int argc , char � argv)�

unsignedint i (0), N(atoi(argv [1]));MyMesh mesh;MyMesh::VertexIter v it ;MyMesh::VertexIter v end(mesh.verticesend ());MyMesh::ConstVertexVertexIter c i ;

// read meshfrom argv[2]MeshIO::readmesh(mesh,argv[2]);

// smoothN iterationsfor (; i � N; ++i)

�for ( v it =mesh.verticesbegin ();

v it !=v end; ++ v it )�

Vec3f c (0,0,0);float valence(0.0);

for ( c i =MyMesh::ConstVertexVertexIter(mesh, v it .handle());c i ; ++ c i )

�c += mesh.point( c it ); ++valence;

v it � � setcog(c/valence);

for ( v it =mesh.verticesbegin (); v it !=v end; ++ v it )

if (! mesh.isboundary( v i .handle()))mesh.setpoint( v i , v i � � cog());

// write result to argv[3]MeshIO::write mesh(mesh, argv [3]);

Listing 2: This exampleshows how to navigate throughthe meshusingiteratorsandcirculators. It smoothesthe meshby iterativelymoving eachvertex into thebarycenterof its neighbors.

usinga ConstVertexVertexIter, i.e. an iteratorcirculatingarounda centervertex andenumeratingall one–ringvertices.Sincethe one–ringverticeswill not be changed,we usetheConst ver-sionof thecirculator. In thesameway all verticesor (half–) edgesof a givenfacecaneasilybetraversedusingfacecirculators.

4.3 Implementation

The low–level implementationof the halfedgedatastructureof ameshis encapsulatedinto themeshkernel. It is responsiblefor thestorageof meshitems,for accessingthemthroughtheir correspond-ing handlesandfor keepingtheconnectivity informationconsistent.Thechosenmeshkernelactsastemplateparameterfor thepolygonalmesh,that inheritsfrom thekernelandaddshigher–level function-ality, like e.g.topologicaloperatorsusedin meshdecimation.

Themeshcanbefurtherparameterizedbya traitsclass,thatholds

memberclassescorrespondingto thedifferentmeshitems.Thefinalitem typeswill be derived from theseclasses,so that any desiredfunctionality canbe pluggedin by putting it into theseclasses.InListing 1 theclassVertexT is definedto storethepointcoordinatecog .

Theseadditionalattributesare addedto the systempart of thevertex usingsomegenerativeor aspectorientedprogrammingtech-niques(see[1, 5]). This avoidsproblemswith mulitple inheritance(ambiguity, no controlledoverloading)by building a linear inheri-tancechaininstead:

template � classBase�class AddNormal: public Base�public :

const Point& normal() const�

return normal ; void setnormal(const Point& n)

�normal = n;

pri vate:Point normal ;

;typedef AddNormal� SomeVertex � SomeVertexWithNormal;

Listing 3: Adding theattributenormalvectorto vertices.

Sincethehandletypesdependonthecontainersusedby themeshkernel(e.g.aVertexHandlemaybeaVertex* or anint), thekernel itself dependson the meshitems (in order to constructthehandletypes),andtheitemsrequirethehandles(avertex muststorea halfedgehandle),we have to usetemplateforward declarationsto get “safe” handletypes(see[7]). Using this technique,the itemtypesknow eachother and their respective handletypes, therebyavoiding to useandcastvoid pointers.This alsoenablesusto usethe handlestypesin the traits classes,e.g. if the facetype shouldcontaina vertex handle,seeListing 4.

HeretheclassListKernelT getsthefinal meshitemsastem-plate parameterand the classFinalMeshItemsT expects thekernel as templateargument in turn. Thereforethe classFi-nalMeshItemsT doesa forward declarationof the meshkernel,resultingin the classKernel. This classnow provides all typesof items and their correspondinghandles,and hencecan be usedastemplateargumentfor the internalvertex aswell asfor theusertraits. The fully specifiedFinalMeshItems canthenbeusedastheactualtemplateargumentof theListKernelT.

As we have seen,we usea custom–tailoredmeshfor eachappli-cation. All thesemesheswill be differentC++ types. If we wantto designalgorithmsoperatingon all of thesemeshtypes,we eitherhave to derive all meshesfrom a commonvirtual baseclass,or doit the STL way andusegenericprogrammingmethods.Sincevir-tual functions/ classesleadto a certainoverheadin spaceandtime,we have chosenthegenericapproach:every algorithmgetsthetypeMesh in form of a templateparameter.

This leadsto the problemthat certainalgorithmshave to knowaboutsomedetailsof themesh,e.g.whetherthemeshprovidesfacenormalsfor surfacelighting. Usinggenerative programmingmeth-ods(see[1, 5]), thisinformationcanbecheckedfor atcompile–time:if themeshprovidesfacenormals,they will beusedautomatically.

Another example is the optional previous halfedgehandle(cf.Fig. 1): if themeshstorestheprevious halfedgein additionto thenext–halfedgehandle,askingfor prev halfedgejustreturnsthishan-dle. Otherwise,thefacehasto betraversedby iteratively jumpingtothenext halfedgeuntil theoriginaloneis reachedagain.SeeListing5 for theimplementation:theusercallsprev halfedge,this functionin turn calls oneof its helperfunctions,dependingon the resultof(Halfedge::Attributes& HasPrevHalfedge). If we addtheprevioushalfedgeto our vertex class,it will automaticallyregister itself tothe vertex, so that (Halfedge::Attributes& HasPrevHalfedge)willbe true. This decisionis madeat compiletime, so that we addnorun–timeoverhead.

As wehaveseen,theOpenMeshis highly customizable:from theuserspoint of view by pluggingin differenttraitsclasses,andfrom

struct ListItems�// internal vertextemplate � classKernel� class VertexT�public :

// use references provided by Kerneltypedef typenameKernel::HalfedgeHandleHalfedgeHandle;...

; ;

struct ListKernel�template � classFinalMeshItems� classKernelT�public :

// use provided items& define handlestypedef typenameFinalMeshItems::Vertex Vertex ;typedef Vertex VertexHandle;

... // define HalfedgeHandle, EdgeHandle,FaceHandle ;

;

template � classMeshKernel, class SysItems, class Traits �struct FinalMeshItemsT�

// forward declaration of meshkerneltypedef FinalMeshItemsT� MeshKernel, SysItems,Traits� This;typedef typenameMEshKernel::template KernelT� This� Kernel;

// final Vertex typetypedef typenameSysItems:: template VertexT � Kernel� SysVertex;typedef typenameTraits :: template VertexT � SysVertex � Vertex ;

... // define Halfedge, Edge andFace ;

struct MyTraits : public DefaultTraits�template � classBase� struct FaceT : public Base�

typenameBase::Kernel:: VertexHandlemy vertex handle; ;

;

typedef FinalMeshItemsT� ListKernel, ListItems, MyTraits� FinalMeshItems;typedef ListKernel:: KernelT� FinalMeshItems� MyMeshKernel;typedef TriMeshT� MeshKernel� MyMesh;

Listing 4: Templateforwarddeclarationprovidestype–safehandlesfor theinternalmeshitemsaswell asfor theusertraits.

enum�

HasPrevHalfedge= (1 ��� something) ;template � bool b � classBool2Type

�enum

�my bool = b ; ;

HalfedgeHandleprev halfedgehandle(HalfedgeHandleheh)�

returnprev helper( heh,

Bool2Type� (Halfedge::Attributes& HasPrevHalfedge) � ());HalfedgeHandleprev helper(HalfedgeHandleheh, Bool2Type� true � )

�// halfedge handle is storedreturn halfedge( heh). prev halfedgehandle();

HalfedgeHandleprev helper(HalfedgeHandleheh, Bool2Type� false� )�

// cycle through the face to find the previous halfedge

Listing 5: Checkingfor certainfeaturesat compiletime

the developerspoint of view by implementingnew meshkernels.Sincemostof theseoptionscanbecheckedfor atcompile–time,wedo not loseefficiency by providing this generality.

5 Examples and Applications

In thefollowing sectionwe presentsomeexampleapplicationsthatwe have implementedusing the OpenMeshlibrary. Theseappli-cationstake strongadvantageof the OpenMeshlibrary’s genericconception,e.g. thepossibility to associatearbitraryattributeswiththemeshprimitivesat compile-time.This enablesflexible, custom-tailoredmeshtypeswithouttherun-timeoverheadknown from otherprogrammingtechniqueslike virtual inheritance.Although the in-ternalstructureof theOpenMeshlibrary is quiteinvolved,theactualusageof thelibrary is not: Well known designpatternslikeadaptors,iteratorsandtraitsfacilitatetheaccessto themesh,henceapplicationprogrammingeffort is keptata minimum.

As attributesareonly allocatedwhenactuallyneeded,nomemoryis wastedfor unusedattributes.For themereconnectivity informa-tion theOpenMeshlibrary needsto allocate4 bytes(= onepointer)per vertex, 12 bytes(= threepointers)per halfedgeand4 bytes(=onepointer)perface.Any user-specifiedattributeswill increasethememoryrequirementsaccordingly.

Becauseall attributesof a meshare statically definedat com-pile time, it is not possibleto addfurther attributesto the meshatrun-time. This functionality, however, is desireablefor someappli-cations,in particularwhenthe attribute in questionis neededonlytemporarilyin theapplication’s life-time. Hencewe assignauniqueidentifier to eachprimitive which canthenbeusedasanindex intoan array of attributesthat is kept outsideof the actualmeshdatastructure.

5.1 Mesh Smoothing

Becauseof the limitations that areinherentto a physicalsamplingprocess,meshesthatareacquiredby a3D scannerusuallyarenoisy.To remove this noise,so-calledsmoothingalgorithmshave beende-veloped(seee.g.[11]). A notedlysimpleoneis derived from min-imizing the membraneenergy of the meshand is implementedbyrepeatedlymoving verticesto the centerof gravity of their neigh-bors. Listing 2 shows how this algorithmcanbe implementedin afew linesof codeusingonly thestandardfunctionsthatareprovidedby the OpenMeshlibrary. Note that only the necessaryattributesare attachedto eachvertex (in this casethe vertex’ position) andthat no further memoryis allocatedfor unusedattributes(like thevertex’ normal). BecausetheOpenMeshlibrary supportsconstant-time (w.r.t. the total numberof vertices)iterationarounda vertex,the smoothingalgorithmis very fast. Figure2 shows the resultofapplyingthesmoothingalgorithmto a noisymesh.

Figure2: Left: Curvatureplot of a noisy meshacquiredby a 3Dscanner(400000triangles).Right: Curvatureplot of themeshafterapplying 50 iterationsof the smoothingalgorithm. The completesmoothingtookabout10secondson a standardPC.

5.2 Mesh Decimation

Meshesthat are generatedby scanningphysicalmodelstypicallyconsistof millions of triangles(see[9]). Becausemany downstreamalgorithmscannothandlethis muchdataefficiently, meshdecima-tion techniqueshave beendevelopedto reducethenumberof facesof a polygonalmesh(see[8]). This is doneby repeatedlyremov-ing verticesfrom a mesh,e.g. by collapsingedgesor by removingthe trianglesadjacentto a vertex and retriangulatingthe resultinghole.BecausetheOpenMeshlibrary alwayskeepstrackof thelocalconnectivity information,these(Euler-)operationscanefficiently beperformedandare, in fact, alreadyprovided by the library. UsingtheOpenMesh’s traitsconceptit is furthermoreeasyto consistentlyassociateandupdatean a global approximationerror, like e.g. thedistanceto theoriginalmeshor theso-callederror-quadric(see[6]),to eachvertex. Light-weight vertex handlescan thenbe storedina priority-queueto schedulethe decimationorder. Our implemen-tation basedon the OpenMeshlibrary useserror-quadricsaserrormeasureandachievesa decimationrateof 20000trianglespersec-ond(Figure3).

Figure3: Left: Bunny consistingof 70000triangles(modelcour-tesyof StanfordUniversityComputerGraphicsLaboratory).Right:Bunny aftermeshdecimationusingtheerror-quadrictechnique(700triangles). The completedecimationprocesstook lessthan4 sec-onds.

5.3 Geometr y Transmission

We have developeda schemefor robustly transmitting3D geome-try over a network (see[3]). This schemeis robust in thesensethata certainpercentageof vertex lossdueto network jamming is tol-eratedby the client-sidereconstructionalgorithm(Figure4). Theimplementationusesa numberof techniquesto speedup andfacil-itate the reconstructionprocess.For example,a spacepartitioningschemeis usedto efficiently locatetrianglesandedgesin the spa-tial vicinity of a transmittedvertex. Using the handleconceptofthe OpenMeshlibrary, the spacepartitioningcreatesonly minimalmemoryoverhead.Furthermoreattributeslike featureinformationareeasilyattachedto eachvertex or edgeusingtheOpenMeshtraitsconcept.

6 Conc lusions and Future Work

The OpenMeshlibrary is an efficient andversatileimplementationof a halfedgedatastructure.Becauseof its genericapproachit al-lows for advancedoptimizationsat compile-timeandhenceusuallyresultsin very fastexecutables.This flexibility is achieved by us-ing involved templateconceptsof the C++ programminglanguageasdefinedin theISOC++standard.Unfortunately, at thetimebeingsomeC++ compilersarenot ISOC++ compliantandfail to compiletheOpenMeshlibrary. As anext developmentstepwethereforeplanto provideworkaroundsfor thesecompilers.

Besidesthat, the OpenMeshlibrary currentlyprovides only thehalfedgedatastructurepeseanda few supportingcomponents.In

Figure4: Local reconstructionof a horsemodel.Notetheirregularmeshstructurethatrequiresa flexible halfedgedatastructure.

analogyto the STL (StandardTemplateLibrary) we plan to alsoprovide commonalgorithmsworking on thatstructure,like e.g. formeshsmoothingor meshdecimation.Thesealgorithmswill alsobegenericandhencewill provideanoptimalinteractionwith themeshstructure.

References

[1] A. Alexandrescu,ModernC++ Design: GenericProgrammingandDesignPatternsApplied, Addison–Wesley, 2001.

[2] B. G. Baumgart,A Polyhedron Representationfor ComputerVision,NationalComputerConference,Anaheim,CA, 1975,pp589-596.

[3] S. Bischoff, L. Kobbelt,TowardsRobustBroadcastingof 3D Geom-etryData, to appear.

[4] S. Campagna,L. Kobbelt,H.-P. Seidel,DirectedEdges- A ScalableRepresentationFor TriangleMeshes, ACM Journalof GraphicsTools3 (4), 1998.

[5] K. Czarnecki,U. Eisenecker, Generative Programming: Methods,Tools,andApplications, Addison–Wesley, 2000.

[6] M. Garland,P. Heckbert,SurfaceSimplificationUsingQuadricErrorMetrics, SIGGRAPH97Proceedings,1997,pp209–216.

[7] Lutz Kettner, Using Generic Programmingfor Designinga DataStructure for Polyhedral Surfaces, in Proc.14thAnnualACM Symp.onComputationalGeometry, 1998.

[8] L. Kobbelt,S.Campagna,H.-P. Seidel,Ageneral frameworkfor meshdecimation, GraphicsInterface’98 Proceedings,1998,pp43–50.

[9] M. Levoy et al., TheDigital Michelangelo Project: 3D ScanningofLargeStatues, SIGGRAPH00 Proceedings,2000,pp131–144.

[10] M. Botsch, S. Bischoff, Online documentationof the OpenMeshpackage, http://www-i8.informatik.rwth-aachen.de,researchsection.

[11] G. Taubin, A Signal ProcessingApproach to Fair SurfaceDesign,SIGGRAPH95Proceedings,1995,pp351–358.

[12] K. Weiler, Edge-BasedData Structures for Solid Modeling inCurved-SurfaceEnvironments, IEEE ComputerGraphicsandAppli-cation,1985,5(1):21-40

[13] D. Zorin etal.,Subdivisionfor ModelingandAnimation, SIGGRAPH01CourseNotes,2000.