
\begin{DoxyItemize}
\item \hyperlink{OpenMeshDoc}{Open\+Mesh Documentation}
\item \hyperlink{OpenVolumeMeshDoc}{Open\+Volume\+Mesh Documentation}
\item \hyperlink{ACGDoc}{A\+CG Documentation} 
\end{DoxyItemize}\hypertarget{OpenMeshDoc}{}\section{Open\+Mesh Documentation}\label{OpenMeshDoc}


Welcome to the Open\+Mesh documentation. Open\+Mesh is a generic and efficient library that offers data structures for representing and manipulating polygonal meshes. It is a powerful tool for handling polygonal meshes. Due to its inherent generative structure it allows the user to create mesh types which are custom tailored to the specific needs of the application. The user can either supply his own data structures for representing vertices, edges and faces or he can conveniently use the predefined structures of Open\+Mesh. Additionally Open\+Mesh offers dynamic properties allowing the user to attach and detach data to the mesh during runtime.

Here you can find information on how to build projects using the Open\+Mesh library as well as further information on mesh handling in Open\+Mesh. The tutorials explain how to use Open\+Mesh by demonstrating real code examples.\hypertarget{a14879_openmesh-python}{}\subsection{Open\+Mesh Python Bindings}\label{a14879_openmesh-python}
We also provide python bindings for Open\+Mesh. You can find them here\+:~\newline
 {\ttfamily \href{https://www.graphics.rwth-aachen.de:9000/OpenMesh/openmesh-python}{\tt https\+://www.\+graphics.\+rwth-\/aachen.\+de\+:9000/\+Open\+Mesh/openmesh-\/python}}\hypertarget{a14879_iov}{}\subsection{Building Open\+Mesh}\label{a14879_iov}
In this section all necessary information on how to build projects using Open\+Mesh is given.

\begin{DoxyItemize}
\item \hyperlink{compiling}{Compiling Open\+Mesh}\end{DoxyItemize}
~\newline
~\newline


\hyperlink{mesh_docu}{Using and understanding Open\+Mesh}

We provide a short overview over the functionality of the Open\+Mesh library and some additional concepts in \hyperlink{tutorial}{Tutorials (code examples)}. Additionally, we explain the most important topics of Open\+Mesh in the following sections\+:

\begin{DoxyItemize}
\item \hyperlink{mesh_features}{Features and Goals of Open\+Mesh} \item \hyperlink{mesh_hds}{The Halfedge Data Structure} \item \hyperlink{mesh_iterators}{Mesh Iterators and Circulators} \item \hyperlink{mesh_navigation}{How to navigate on a mesh} \item \hyperlink{mesh_io}{Read and write meshes from files} \item \hyperlink{mesh_operations}{Some basic operations\+: Flipping and collapsing edges} \item \hyperlink{mesh_hierarchy}{Conceptual Class Hierarchy}\end{DoxyItemize}
The Open\+Mesh\+Tools library that contains some useful tools for i.\+e. mesh processing\+:

\begin{DoxyItemize}
\item \hyperlink{tools_docu}{Open\+Mesh Tools Documentation}\end{DoxyItemize}
~\newline
~\newline
 \hyperlink{tutorial}{Tutorials (code examples)}

This section is supposed to introduce the basic concepts of Open\+Mesh.

\begin{DoxyItemize}
\item \hyperlink{mesh_type}{Specifying your My\+Mesh} \item \hyperlink{tutorial_01}{First Steps -\/ Building a cube} \item \hyperlink{tutorial_build}{How to create your own project using Open\+Mesh} \item \hyperlink{tutorial_02}{Using iterators and circulators} \item \hyperlink{tutorial_03}{Using (custom) properties} \item \hyperlink{tutorial_04}{Using S\+TL algorithms} \item \hyperlink{tutorial_05}{Using standard properties} \item \hyperlink{tutorial_06}{Using mesh attributes and traits} \item \hyperlink{tutorial_07}{Extending the mesh using traits} \item \hyperlink{tutorial_07b}{Deleting geometry elements} \item \hyperlink{tutorial_08}{Using I\+O\+::\+Options} \item \hyperlink{tutorial_09}{Storing custom properties}\end{DoxyItemize}
~\newline
~\newline


\hyperlink{additional_information}{Additional Information on Open\+Mesh}

\begin{DoxyItemize}
\item \hyperlink{mesh_first_to_read}{Notes on template programming} \item \hyperlink{mesh_cpp}{Some words on the C++ implementation} \item \hyperlink{mesh_members}{Where do I find a list of all member functions ?} \item \hyperlink{naming_conventions}{Naming Conventions} \item \hyperlink{mesh_speedup}{Some Notes on how to speedup Open\+Mesh} \item \hyperlink{om_changelog}{Changelog} \end{DoxyItemize}
\hypertarget{compiling}{}\subsection{Compiling Open\+Mesh}\label{compiling}
\hypertarget{a14877_compilers}{}\subsubsection{Tested compilers}\label{a14877_compilers}
Open\+Mesh has been successfully tested for the following operating systems / compilers. This is only a list of tested compilers. More might be supported but are not tested. Make sure that your compiler supports at least C++11

\tabulinesep=1mm
\begin{longtabu} spread 0pt [c]{*{2}{|X[-1]}|}
\hline
Linux &gcc $>$= 6.\+3~\newline
 clang $>$= 3.\+3~\newline
 

\\\cline{1-2}
Windows &Microsoft Visual Studio 2015~\newline
 Microsoft Visual Studio 2017~\newline
 

\\\cline{1-2}
Tested Mac\+OS X Compilers &X\+Code ~\newline
 

\\\cline{1-2}
\end{longtabu}
\hypertarget{a14877_req_libs}{}\subsubsection{Required libraries (\+Only if you want to build the included Apps)}\label{a14877_req_libs}
Install the following external libraries / frameworks if you want to use the included Applications\+:~\newline
~\newline
 \tabulinesep=1mm
\begin{longtabu} spread 0pt [c]{*{2}{|X[-1]}|}
\hline
Qt5&\href{http://qt-project.org/downloads}{\tt https\+://www.\+qt.\+io/download} \\\cline{1-2}
\end{longtabu}
~\newline
\hypertarget{a14877_build_systems}{}\subsubsection{Chosing build system}\label{a14877_build_systems}
Open\+Mesh can be built using the {\bfseries cmake} build system. ~\newline
 ~\newline
\hypertarget{a14877_sec_compiling_unix}{}\subsubsection{Unix}\label{a14877_sec_compiling_unix}
\hypertarget{a14877_linux_using_cmake}{}\paragraph{Compiling Open\+Mesh using C\+Make}\label{a14877_linux_using_cmake}
In order to compile Open\+Mesh, create a directory named e.\+g. \char`\"{}build\char`\"{} in \hyperlink{a06210}{Open\+Mesh}\textquotesingle{}s root directory. {\bfseries Change to the newly created directory} and type ~\newline
~\newline
 {\ttfamily  cmake~..~~~~~~~~~~~~\#\# Generates the appropriate Makefiles~\newline
 make~~~~~~~~~~~~~~~~\#\# Builds the project~\newline
 }~\newline


\begin{DoxyWarning}{Warning}
If your compiler does not support c++11 natively, you might have to enable it by changing the cmake call to\+: ~\newline
 {\ttfamily cmake .. -\/\+D\+C\+M\+A\+K\+E\+\_\+\+C\+X\+X\+\_\+\+F\+L\+A\+GS=-\/std=c++98}
\end{DoxyWarning}
You can choose the build type by using cmake with the flag~\newline
 {\bfseries -\/\+D\+C\+M\+A\+K\+E\+\_\+\+B\+U\+I\+L\+D\+\_\+\+T\+Y\+PE=(Debug$\vert$\+Release)} The default is\+: Release ~\newline


Other flags are\+:~\newline
 {\bfseries -\/\+D\+B\+U\+I\+L\+D\+\_\+\+A\+P\+PS=O\+FF} to disable build of applications and~\newline
 {\bfseries -\/\+D\+C\+M\+A\+K\+E\+\_\+\+I\+N\+S\+T\+A\+L\+L\+\_\+\+P\+R\+E\+F\+IX=$<$path$>$} to specify the install path.~\newline


When calling {\bfseries make install} cmake will install Open\+Mesh into this directory using the subdirectories lib/include/bin.

C\+Make builds both shared and static under Linux.

Everything will then be build in the {\bfseries Build} subdirectory containing the libraries in {\bfseries lib} and the binaries in {\bfseries bin}.

There are some additional targets\+:~\newline
 {\bfseries doc}\+: Builds the Documentation~\newline
 {\bfseries doc-\/install}\+: Builds the Documentation and installs it~\newline
 ~\newline
 \begin{DoxyNote}{Note}
When you link against the static libraries of \hyperlink{a06210}{Open\+Mesh} and get the error \char`\"{}can not be used when making a
shared object; recompile with -\/f\+P\+I\+C\char`\"{} you need to add \char`\"{}-\/f\+P\+I\+C\char`\"{} to the C\+M\+A\+K\+E\+\_\+\+C\+X\+X\+\_\+\+F\+L\+A\+GS. (This is usually added automatically)
\end{DoxyNote}
\hypertarget{a14877_sec_compiling_windows}{}\subsubsection{Windows}\label{a14877_sec_compiling_windows}
\hypertarget{a14877_windows_using_cmake}{}\paragraph{Compiling Open\+Mesh using C\+Make}\label{a14877_windows_using_cmake}
Building \hyperlink{a06210}{Open\+Mesh} on Windows requires cmake to generate the project files for Visual Studio.


\begin{DoxyItemize}
\item Get Visual Studio ( 2015-\/2017 )  
\item Extract Open\+Mesh source code.  
\item Get all required libraries and install them ( including headers! ). 
\item Download and install cmake\+: \href{https://cmake.org/download/}{\tt www.\+cmake.\+org}.~\newline
  
\item Start the cmake gui and open the Open\+Mesh toplevel directory as source directory  
\item Choose a build directory (e.\+g. create a directory called \char`\"{}build\char`\"{} in \hyperlink{a06210}{Open\+Mesh}\textquotesingle{}s root folder)  
\item Click on configure .... If any libraries are left unconfigured, you can adjust the path manually. Rerun configure until everything is configured correctly. ~\newline
 Attention\+: Some build variables are only visible in advanced view mode. Select Visual Studio 9 (2008), Visual Studio 10(2010), Visual Studio 11 (2012), Visual Studio 12 (2013) (Depending on your version) as generator.  
\item Click generate to create the visual studio project files  
\item You can now find a Visual Studio solution file (Open\+Mesh.\+sln) in the {\bfseries build} directory you chose in cmake  
\item Now you can build Open\+Mesh from within Visual Studio using the newly created project file.  
\end{DoxyItemize}

~\newline
 ~\newline
\hypertarget{a14877_sec_compiling_macosx}{}\subsubsection{Mac\+O\+S X}\label{a14877_sec_compiling_macosx}
Download and install required libraries as stated above. You can download Open\+Mesh\textquotesingle{}s sources from {\ttfamily www.\+openmesh.\+org} or check out the latest repository via G\+IT\+:~\newline
 {\ttfamily \href{https://www.graphics.rwth-aachen.de:9000/OpenMesh/OpenMesh}{\tt https\+://www.\+graphics.\+rwth-\/aachen.\+de\+:9000/\+Open\+Mesh/\+Open\+Mesh}}.~\newline
~\newline
\hypertarget{a14877_mac_using_cmake}{}\paragraph{Compiling Open\+Mesh using C\+Make}\label{a14877_mac_using_cmake}
We recommend you to use C\+Make $>$= 3.\+7 as build system. This can also easily be installed via Mac\+Ports as well as the Qt $>$= 5.\+6 library which is used for some example applications in Open\+Mesh.~\newline
 Once installed, change to Open\+Mesh\textquotesingle{}s root directory and create a directory named e.\+g. \char`\"{}build\+Debug\char`\"{} (assuming you want to build with debug symbols).~\newline
 Then type in the following command to initially set up the build environment\+: ~\newline
~\newline
 {\ttfamily  cmake~..~~~~~~~~~~~~\#\# Generates the appropriate Makefiles~\newline
 } ~\newline
 Note\+: If the build directory is not a subdirectory of Open\+Mesh\textquotesingle{}s root folder, replace \char`\"{}..\char`\"{} with Open\+Mesh\textquotesingle{}s absolute (or relative) path. In order to manually set specific build variables, just type\+: ~\newline
~\newline
 {\ttfamily  ccmake~.~~~~~~~~~~~~\#\# Configure build environment~\newline
 } ~\newline
 This opens the C\+Make configure tool. Change the C\+M\+A\+K\+E\+\_\+\+B\+U\+I\+L\+D\+\_\+\+T\+Y\+PE variable to \char`\"{}\+Release\char`\"{} in order to prepare build for release configuration. Now, when everything is set up, just type\+: ~\newline
~\newline
 {\ttfamily  make~~~~~~~~~~~~~~~~\#\# Build Open\+Mesh~\newline
 } ~\newline
 And optionally\+: ~\newline
~\newline
 {\ttfamily  make~doc~~~~~~~~~~~~\#\# Build Open\+Mesh\textquotesingle{}s documentation~\newline
 } ~\newline
 The mac application bundle will be found under \char`\"{}\+Build\char`\"{} in the recently created build folder. It automatically contains all needed shared objects (libs, fonts, textures, etc.).

C\+Make builds both shared and static under Mac\+OS X. \hypertarget{mesh_docu}{}\subsection{Using and understanding Open\+Mesh}\label{mesh_docu}
\begin{DoxyItemize}
\item \hyperlink{mesh_features}{Features and Goals of Open\+Mesh} \item \hyperlink{mesh_hds}{The Halfedge Data Structure} \item \hyperlink{mesh_iterators}{Mesh Iterators and Circulators} \item \hyperlink{mesh_navigation}{How to navigate on a mesh} \item \hyperlink{mesh_io}{Read and write meshes from files} \item \hyperlink{mesh_operations}{Some basic operations\+: Flipping and collapsing edges} \item \hyperlink{mesh_hierarchy}{Conceptual Class Hierarchy} \item \hyperlink{mesh_type}{Specifying your My\+Mesh} \item \hyperlink{mesh_eigen}{Specifying an Open\+Mesh using Eigen3 vectors} \end{DoxyItemize}
\hypertarget{mesh_features}{}\subsubsection{Features and Goals of Open\+Mesh}\label{mesh_features}
The main features of the underlying data structure are\+:

\begin{DoxyItemize}
\item No restriction to triangles meshes, handle general polygonal meshes. \item Explicit representation of vertices, halfedges, edges, and faces. \item Efficient access to the one-\/ring neighborhood of a vertex. \item Ability to handle non-\/manifold vertices (like two faces meeting in only one vertex).\end{DoxyItemize}
The goals/features of the C++ implementation are\+:


\begin{DoxyItemize}
\item Flexibility\+: 
\begin{DoxyItemize}
\item Choose suitable types for scalars and coordinates (e.\+g. float, double, exact arithmetic and two-\/, three-\/, or n-\/dimensional points). 
\item Enhance each item type by your own attributes/properties, like e.\+g. adding a normal vector or a {\ttfamily Face\+Handle} to class {\ttfamily Vertex}. 
\end{DoxyItemize}
\item Efficiency\+: 
\begin{DoxyItemize}
\item Avoid the overhead of virtual inheritance and virtual function calls. 
\item Resolve as many type/attribute dependencies as possible at compile-\/time instead of testing for attributes at run-\/time (e.\+g. normal vectors for faces). 
\end{DoxyItemize}
\item Type-\/safety for handles, {\bfseries no type-\/casting ($\ast$)}\+: Vertices, (Half-\/)Edges, Faces know each other and their corresponding handles.

{\bfseries ($\ast$)} Since version 0.\+10.\+0 the Microsoft Visual\+C++ compiler is supported. Due to the compilers inaptitude to process forwards on template functions correctly, the type-\/safety had to be given up to some extend. Though under the hood void pointers are used, the casting is done within the mesh, and the user transparently uses his handles as before.~\newline
 As soon as the compiler adheres to the C++ standard the type-\/safe version will be restored. 
\end{DoxyItemize}\hypertarget{mesh_hds}{}\subsubsection{The Halfedge Data Structure}\label{mesh_hds}
This section describes the underlying data structure that is used to store the mesh entities (items) vertices, edges, faces, and their connectivity information. There are many popular data structures used to represent polygonal meshes. For a detailed comparison of them refer to the papers at the end of this section.

The data structure used in this project is the so called {\itshape  halfedge data structure }. While {\itshape  face-\/based } structures store their connectivity in faces referencing their vertices and neighbors, {\itshape  edge-\/based } structures put the connectivity information into the edges. Each edge references its two vertices, the faces it belongs to and the two next edges in these faces. If one now splits the edges (i.\+e. an edge connecting vertex {\ttfamily A} and vertex {\ttfamily B} becomes two {\itshape  directed halfeges } from {\ttfamily A} to {\ttfamily B} and vice versa) one gets a {\itshape  halfedge-\/based } data structure. The following figure illustrates the way connectivity is stored in this structure\+:

\tabulinesep=1mm
\begin{longtabu} spread 0pt [c]{*{2}{|X[-1]}|}
\hline
 &
\begin{DoxyItemize}
\item Each {\bfseries vertex} references one outgoing halfedge, i.\+e. a halfedge that starts at this vertex (1). 
\item Each {\bfseries face} references one of the halfedges bounding it (2). 
\item Each {\bfseries halfedge} provides a handle to 
\begin{DoxyItemize}
\item the vertex it points to (3), 
\item the face it belongs to (4) 
\item the next halfedge inside the face (ordered counter-\/clockwise) (5), 
\item the opposite halfedge (6), 
\item (optionally\+: the previous halfedge in the face (7)). 
\end{DoxyItemize}
\end{DoxyItemize}\\\cline{1-2}
\end{longtabu}


Having these links between the items, it is now possible to circulate around a face in order to enumerate all its vertices, halgedges, or neighboring faces. When starting at a vertex\textquotesingle{} halfedge and iterating to the opposite of its previous one, one can easily circulate around this vertex and get all its one-\/ring neighbors, the incoming/outgoing halfedges, or the adjacent faces. All this functionality is encapsulated into the so-\/called {\itshape  circulators }, described in \hyperlink{mesh_iterators}{Mesh Iterators and Circulators}.

\begin{DoxyAttention}{Attention}
In order to efficiently classify a boundary vertex, the outgoing halfedge of these vertices {\bfseries  must be a boundary halfedge } (see Open\+Mesh\+::\+Poly\+Mesh\+T\+::is\+\_\+boundary()). 

Whenever you modify the topology using low-\/level topology changing functions, be sure to guarantee this behaviour (see Open\+Mesh\+::\+Poly\+Mesh\+T\+::adjust\+\_\+outgoing\+\_\+halfedge())
\end{DoxyAttention}
While one does not need to store the previous halfedge (7) explicitly, because it can be derived from the links to the next halfedges, one may do so for the sake of performance. In fact, the previous halfedge is stored by default (\hyperlink{a08800}{Open\+Mesh\+::\+Default\+Traits}). Using traits and attributes the previous halfedge can removed, to gain memory. This kind of mesh customization is explained in \hyperlink{mesh_type}{Specifying your My\+Mesh}.

While the halfedge-\/based structures usually consume more memory than their face-\/based counter-\/parts they have the following important advantages\+:

\begin{DoxyItemize}
\item It is easy to mix faces of arbitrary vertex count in one mesh.\end{DoxyItemize}
\begin{DoxyItemize}
\item We now have an explicit representation of vertices, faces, {\itshape and} edges/halfedges. This becomes extremely useful if one has to store data per edge/halfedge since this can easily be modelled by member variables of these types (see \hyperlink{mesh_type}{Specifying your My\+Mesh}).\end{DoxyItemize}
\begin{DoxyItemize}
\item Circulating around a vertex in order to get its one-\/ring neighbors is an important operation for many kinds of algorithms on polygonal meshes. For face-\/based structures this leads to many {\ttfamily if-\/then} branchings, the halfedge structure provides this funcionality without conditional branching in constant time.\end{DoxyItemize}
{\bfseries References}

S. Campagna, L. Kobbelt, H.-\/P. Seidel, {\itshape  Directed Edges -\/ A Scalable Representation For Triangle Meshes }, A\+CM Journal of Graphics Tools 3 (4), 1998.

Lutz Kettner, {\itshape  Using Generic Programming for Designing a Data Structure for Polyhedral Surfaces}, in Proc. 14th Annual A\+CM Symp. on Computational Geometry, 1998. \hypertarget{mesh_iterators}{}\subsubsection{Mesh Iterators and Circulators}\label{mesh_iterators}

\begin{DoxyItemize}
\item \hyperlink{a14891_it_iters}{Iterators}
\item \hyperlink{a14891_it_iters_h}{How to use iterators in Open\+Mesh}
\item \hyperlink{a14891_it_iters_skipping}{Skipping Iterators}
\item \hyperlink{a14891_it_circs}{Circulators}
\item \hyperlink{a14891_it_circs_h}{How to use circulators in Open\+Mesh}
\end{DoxyItemize}\hypertarget{a14891_it_iters}{}\paragraph{Iterators}\label{a14891_it_iters}
The mesh provides linear iterators (that enumerate vertices, halfedges, edges, and faces). These can be used to easily navigate through a mesh. Each iterator {\ttfamily X\+Y\+Z\+Iter} also exists in a const version {\ttfamily Const\+X\+Y\+Z\+Iter}.

All iterators are defined in the namespace \hyperlink{a06212}{Open\+Mesh\+::\+Iterators}. They are template classes that expect a mesh as template argument to be fully specified. You should use the iterator types provided by the mesh itself, i.\+e. {\ttfamily My\+Mesh\+::\+Vertex\+Iter} instead of {\ttfamily Open\+Mesh\+::\+Iterators\+::\+Vertex\+Iter\+T$<$\+My\+Mesh$>$}.

The iterators are\+:


\begin{DoxyCodeInclude}
\hyperlink{a08764}{MyMesh} mesh;

\textcolor{comment}{// iterate over all vertices}
\textcolor{keywordflow}{for} (MyMesh::VertexIter v\_it=mesh.vertices\_begin(); v\_it!=mesh.vertices\_end(); ++v\_it) 
   ...; \textcolor{comment}{// do something with *v\_it, v\_it->, or *v\_it}

\textcolor{comment}{// iterate over all halfedges}
\textcolor{keywordflow}{for} (MyMesh::HalfedgeIter h\_it=mesh.halfedges\_begin(); h\_it!=mesh.halfedges\_end(); ++h\_it) 
   ...; \textcolor{comment}{// do something with *h\_it, h\_it->, or *h\_it}

\textcolor{comment}{// iterate over all edges}
\textcolor{keywordflow}{for} (MyMesh::EdgeIter e\_it=mesh.edges\_begin(); e\_it!=mesh.edges\_end(); ++e\_it) 
   ...; \textcolor{comment}{// do something with *e\_it, e\_it->, or *e\_it}

\textcolor{comment}{// iterator over all faces}
\textcolor{keywordflow}{for} (MyMesh::FaceIter f\_it=mesh.faces\_begin(); f\_it!=mesh.faces\_end(); ++f\_it) 
   ...; \textcolor{comment}{// do something with *f\_it, f\_it->, or *f\_it}

\end{DoxyCodeInclude}


The corresponding {\ttfamily const} counterparts are

\begin{DoxyItemize}
\item {\ttfamily Const\+Vertex\+Iter}, \item {\ttfamily Const\+Halfedge\+Iter}, \item {\ttfamily Const\+Edge\+Iter}, \item {\ttfamily Const\+Face\+Iter}.\end{DoxyItemize}
The linear iterators are conformant to S\+TL iterators. For a description of their interface see Open\+Mesh\+::\+Concepts\+::\+IteratorT.

When using iterators, use the pre-\/increment operation (++it) for efficiency reasons.

\begin{DoxyRefDesc}{Deprecated}
\item[\hyperlink{a06165__deprecated000001}{Deprecated}]While it is possible to use {\ttfamily handle()} to get the handle of the item referred to by the iterator, this function is deprecated. Simply dereference the iterator instead.\end{DoxyRefDesc}
\hypertarget{a14891_deletedElements}{}\subparagraph{Deleted Elements}\label{a14891_deletedElements}
If no elements of a mesh are marked as deleted, the indices provided by {\ttfamily idx()} are consecutive numbers from 0 to {\itshape number of elements}-\/1 (in the case of vertices this would be from 0 to n\+\_\+vertices()-\/1).

However, note that this is {\bfseries not} the case when elements are marked as deleted and \hyperlink{a08576_aba7fd4df59227f974b44111ac45e835f}{Open\+Mesh\+::\+Array\+Kernel\+::garbage\+\_\+collection()} has not yet been called.

After garbage\+\_\+collection() has been called the elements are reorganized and their handles and iterators are guaranteed to be consecutive numbers again.

\hyperlink{a06210}{Open\+Mesh} uses a lazy deletion scheme to avoid unnecessary updates to the data structure. The halfedge data structure will always be updated directly to ensure that following algorithms will have the correct iterator setups.

So if you delete a face, The face itself will still exist but the halfedges which are now located at the hole will be updated directly, which means that circulators on the adjacent vertices will not come across the face anymore.

If an edge is deleted, the adjacent faces will be removed as well (flagging them deleted and updating the surrounding halfedges). The edge itself will also be flagged as deleted. Again the circulators will not see the deleted primitives anymore.

For a vertex, all adjacent faces and edges are deleted with the schemes above and the vertex flagged as deleted.

The iterators, going across vertices edges and faces will still enumerate all primitives (including deleted ones). Except if you use the skipping iterators, which will skip deleted primitives. The circulators always only enumerate primitives which are not deleted.

\begin{DoxyNote}{Note}

\begin{DoxyItemize}
\item If you delete elements on the mesh, they will still be enumerated by the standard iterators. To skip deleted elements, use the \hyperlink{a14891_it_iters_skipping}{Skipping Iterators} 
\item An iterator to an item usually needs more memory than a handle of an item. To store many references to an item, it is therefore better to use handles. 
\end{DoxyItemize}
\end{DoxyNote}
\hypertarget{a14891_it_iters_h}{}\paragraph{How to use iterators in Open\+Mesh}\label{a14891_it_iters_h}
This example shows how to iterate over all faces of a mesh\+:


\begin{DoxyCode}
\hyperlink{a08764}{MyMesh} mesh;

\textcolor{keywordflow}{for}(MyMesh::FaceIter f\_it = mesh.faces\_begin(); f\_it != mesh.faces\_end(); ++f\_it) \{
    std::cout << \textcolor{stringliteral}{"The face's valence is "} << mesh.valence( *f\_it ) << std::endl;
\}
\end{DoxyCode}
\hypertarget{a14891_it_iters_skipping}{}\paragraph{Skipping Iterators}\label{a14891_it_iters_skipping}
All iterators are also available as skipping iterators. If elements are deleted on a mesh, the standard iterators go over all elements, even deleted ones(which are available until a garbage\+\_\+collection is done). The skipping iterators ignore these elements. You can retrieve a skipping iterator by calling one of the following functions\+:

\begin{DoxyItemize}
\item {\ttfamily vertices\+\_\+sbegin()}, \item {\ttfamily edges\+\_\+sbegin()}, \item {\ttfamily halfedges\+\_\+sbegin()}, \item {\ttfamily faces\+\_\+sbegin()} \end{DoxyItemize}
The ends for these iterators are equal to the standard iterator ends (e.\+g. {\ttfamily vertices\+\_\+end()} ).\hypertarget{a14891_it_circs}{}\paragraph{Circulators}\label{a14891_it_circs}
Open\+Mesh also provides so called Circulators that provide means to enumerate items adjacent to another item of the same or another type. For example, a {\ttfamily Vertex\+Vertex\+Iter} allows to enumerate all vertices immediately adjacent to a (center) vertex (i.\+e. it allows to enumerate the so-\/called 1-\/ring of the center vertex). Analogously, a {\ttfamily Face\+Halfedge\+Iter} enumerates all the halfedges belonging to a face. In general, {\ttfamily Center\+Item\+\_\+\+Auxiliary\+Information\+\_\+\+Target\+Item\+\_\+\+Iter} designates a circulator that enumerates all the target items around a given center item.

The constructor of a circulator is of the form {\ttfamily Circulator(\+Mesh\+Type mesh, Target\+Handle center\+\_\+handle)}, i.\+e. it takes a mesh and the handle of the item to circulate around.

The circulators around a vertex are\+:

\begin{DoxyItemize}
\item {\ttfamily Vertex\+Vertex\+Iter\+:} iterate over all neighboring vertices. \item {\ttfamily Vertex\+I\+Halfedge\+Iter\+:} iterate over all {\itshape incoming} halfedges. \item {\ttfamily Vertex\+O\+Halfedge\+Iter\+:} iterate over all {\itshape outgoing} halfedges. \item {\ttfamily Vertex\+Edge\+Iter\+:} iterate over all incident edges. \item {\ttfamily Vertex\+Face\+Iter\+:} iterate over all adjacent faces.\end{DoxyItemize}
The circulators around a face are\+:

\begin{DoxyItemize}
\item {\ttfamily Face\+Vertex\+Iter\+:} iterate over the face\textquotesingle{}s vertices. \item {\ttfamily Face\+Halfedge\+Iter\+:} iterate over the face\textquotesingle{}s halfedges. \item {\ttfamily Face\+Edge\+Iter\+:} iterate over the face\textquotesingle{}s edges. \item {\ttfamily Face\+Face\+Iter\+:} iterate over all edge-\/neighboring faces.\end{DoxyItemize}
Other circulators\+: \begin{DoxyItemize}
\item {\ttfamily Halfedge\+Loop\+Iter\+:} iterate over a sequence of Halfedges. (all Halfedges over a face or a hole)\end{DoxyItemize}
All circulators provide the operations listed in Circulator\+T$<$\+Mesh$>$, which are basically the same as the iterator funtions.

\begin{DoxyNote}{Note}
Circulators are similar to bidirectional iterators and therefore they have the bidirectional\+\_\+iterator\+\_\+tag. However, the bidirectional requires that the attribute \hyperlink{a06215_ab78a93560926cd2f9958cb028f7ea96dafaaebe1808b5cce96ad4e19df471d58a}{Open\+Mesh\+::\+Attributes\+::\+Prev\+Halfedge} is available. Otherwise it is just a forward iterator.
\end{DoxyNote}
\begin{DoxyRefDesc}{Deprecated}
\item[\hyperlink{a06165__deprecated000002}{Deprecated}]While it is possible to use {\ttfamily operator} {\ttfamily bool()}, which returns true, as long as the circulator hasn\textquotesingle{}t reached the end of the sequence, this function is deprecated. Use the function {\ttfamily is\+\_\+valid()} instead.\end{DoxyRefDesc}


Open\+Mesh provides the following functions (defined in \hyperlink{a08748}{Open\+Mesh\+::\+Poly\+Connectivity}) to get circulators around a specified center item\+:


\begin{DoxyCodeInclude}
\textcolor{comment}{/**************************************************}
\textcolor{comment}{ * Vertex circulators}
\textcolor{comment}{ **************************************************/}

\textcolor{comment}{// Get the vertex-vertex circulator (1-ring) of vertex \_vh}
VertexVertexIter \hyperlink{a08748_a68c1388ce7b5ce1cc9cf8825293ac801}{OpenMesh::PolyConnectivity::vv\_iter} (VertexHandle \_vh);

\textcolor{comment}{// Get the vertex-incoming halfedges circulator of vertex \_vh}
VertexIHalfedgeIter \hyperlink{a08748_ad107901645041fc7f0662ef92c3a079b}{OpenMesh::PolyConnectivity::vih\_iter} (VertexHandle 
      \_vh);

\textcolor{comment}{// Get the vertex-outgoing halfedges circulator of vertex \_vh}
VertexOHalfedgeIter \hyperlink{a08748_ac93ceccd63aed16bcab88930c89ffbbb}{OpenMesh::PolyConnectivity::voh\_iter} (VertexHandle 
      \_vh);

\textcolor{comment}{// Get the vertex-edge circulator of vertex \_vh}
VertexEdgeIter \hyperlink{a08748_af695c0e03e74577d8d97347ca84b1ff2}{OpenMesh::PolyConnectivity::ve\_iter} (VertexHandle \_vh);

\textcolor{comment}{// Get the vertex-face circulator of vertex \_vh}
VertexFaceIter \hyperlink{a08748_a25860bb9999a9b507b3a80e2e37a2e82}{OpenMesh::PolyConnectivity::vf\_iter} (VertexHandle \_vh);

\textcolor{comment}{/**************************************************}
\textcolor{comment}{ * Face circulators}
\textcolor{comment}{ **************************************************/}

\textcolor{comment}{// Get the face-vertex circulator of face \_fh}
FaceVertexIter \hyperlink{a08748_ad063456d88df23b6987a7627ffbd1cdf}{OpenMesh::PolyConnectivity::fv\_iter} (FaceHandle \_fh);

\textcolor{comment}{// Get the face-halfedge circulator of face \_fh}
FaceHalfedgeIter \hyperlink{a08748_a2a0cf023e9159c558bd99f11758dd0d4}{OpenMesh::PolyConnectivity::fh\_iter} (FaceHandle \_fh);

\textcolor{comment}{// Get the face-edge circulator of face \_fh}
FaceEdgeIter \hyperlink{a08748_abf21db5a31b161e47db2539f10ea200c}{OpenMesh::PolyConnectivity::fe\_iter} (FaceHandle \_fh);

\textcolor{comment}{// Get the face-face circulator of face \_fh}
FaceFaceIter \hyperlink{a08748_adb6d2e735b9fdc6750e0c7d47cd2b153}{OpenMesh::PolyConnectivity::ff\_iter} (FaceHandle \_fh);
\end{DoxyCodeInclude}


Additionally to the normal circulators there exists some for each direction (clock-\/wise, counterclock-\/wise). Those circulators might be slower than the normal one, but the direction of circulation is guaranteed. You can get these types of circulators by adding the infix \char`\"{}ccw\char`\"{} or \char`\"{}cw\char`\"{} to the function used to request the circulator of an item after the underscore. Example\+:


\begin{DoxyCode}
VertexVertexIter vvit = mesh.vv\_iter(some\_vertex\_handle);          \textcolor{comment}{// fastest (clock or counterclockwise)}
VertexVertexCWIter vvcwit = mesh.vv\_cwiter(some\_vertex\_handle);    \textcolor{comment}{// clockwise}
VertexVertexCCWIter vvccwit = mesh.vv\_ccwiter(some\_vertex\_handle); \textcolor{comment}{// counter-clockwise}
\end{DoxyCode}


It is also possible to convert a cw circulator to a ccw circulator and vice versa. For this purpose, each circulator provides a constructor taking the other circulator as input. If a cw circulator is converted, the ccw circulator points on the same element as the cw circulator pointed on, but the direction for the increment and decrement changed.~\newline
The conversion is only valid for valid circulators. The resulting circulator from a invalid circulator is still invalid, but might behave in a fashion not expected by normal iterators. Example\+: 
\begin{DoxyCode}
VertexVertexCWIter vvcwit = mesh.vv\_cwend(some\_vertex\_handle);
VertexVertexCCWIter vvccwit = VertexVertexCCWIter(vvcwit); \textcolor{comment}{//conversion of an invalid circulator}
 --vvcwit;  \textcolor{comment}{//is valid now (if the range >= 1)}
 ++vvccwit; \textcolor{comment}{//can still be invalid}
\end{DoxyCode}


CW and C\+CW circulators requires that \hyperlink{a06215_ab78a93560926cd2f9958cb028f7ea96dafaaebe1808b5cce96ad4e19df471d58a}{Open\+Mesh\+::\+Attributes\+::\+Prev\+Halfedge} is available.

\begin{DoxyNote}{Note}
For every circulator there also exists a constant version. To make use of these constant circulators just add the prefix~\newline
 \char`\"{}\+Const\char`\"{} to the type specifier and add the prefix \char`\"{}c\char`\"{} to the function used to request the circulator of an item. Example\+:~\newline

\end{DoxyNote}

\begin{DoxyCode}
ConstVertexVertexIter cvvit = mesh.cvv\_iter(some\_vertex\_handle);
\end{DoxyCode}


\begin{DoxyNote}{Note}
When constructing Circulators from iterators, make sure you don\textquotesingle{}t create a circulator of an deleted element(e.\+g. Face\+Vertexiter of a deleted Face), as this will lead to unpredictable behaviour. Using skipping iterators for iterating over the elements and creating circulators from them is safe as they don\textquotesingle{}t contain deleted elements.
\end{DoxyNote}
\hypertarget{a14891_it_circs_h}{}\paragraph{How to use circulators in Open\+Mesh}\label{a14891_it_circs_h}
The following code example now shows how to enumerate the 1-\/ring of each vertex\+:


\begin{DoxyCodeInclude}
\hyperlink{a08764}{MyMesh} mesh;

\textcolor{comment}{// (linearly) iterate over all vertices}
\textcolor{keywordflow}{for} (MyMesh::VertexIter v\_it=mesh.vertices\_sbegin(); v\_it!=mesh.vertices\_end(); ++v\_it)
\{
  \textcolor{comment}{// circulate around the current vertex}
  \textcolor{keywordflow}{for} (\hyperlink{a08776_adc7d422e2ce13141e8291f7d29f7ecef}{MyMesh::VertexVertexIter} vv\_it=mesh.vv\_iter(*v\_it); vv\_it.is\_valid(); ++
      vv\_it)
  \{
    \textcolor{comment}{// do something with e.g. mesh.point(*vv\_it)}
  \}
\}
\end{DoxyCodeInclude}


Enumerating all halfedges adjacent to a certain face (the inner halfedges) is accomplished as follows\+:


\begin{DoxyCode}
\hyperlink{a08764}{MyMesh} mesh;

...

\textcolor{comment}{// Assuming faceHandle contains the face handle of the target face}

MyMesh::FaceHalfedgeIter fh\_it = mesh.fh\_iter(faceHandle);

\textcolor{keywordflow}{for}(; fh\_it.is\_valid(); ++fh\_it) \{
    std::cout << \textcolor{stringliteral}{"Halfedge has handle "} << *fh\_it << std::endl;
\}
\end{DoxyCode}
 \hypertarget{mesh_navigation}{}\subsubsection{How to navigate on a mesh}\label{mesh_navigation}
\hypertarget{a14892_nav_overview}{}\paragraph{Overview}\label{a14892_nav_overview}
\begin{DoxyItemize}
\item \hyperlink{a14892_nav_intro}{Introduction} \item \hyperlink{a14892_nav_he}{Navigating over halfedges} \item \hyperlink{a14892_nav_bound}{Mesh boundaries} \item \hyperlink{a14892_nav_io}{Using incoming and outgoing halfedges} \item \hyperlink{a14892_nav_opposite}{Using opposite halfedges} \item \hyperlink{a14892_nav_to_from}{Getting the to and from vertices}\end{DoxyItemize}
\hypertarget{a14892_nav_intro}{}\paragraph{Introduction}\label{a14892_nav_intro}
In this tutorial you will learn how to navigate on a mesh using the Open\+Mesh library. In the previous chapter (see \hyperlink{mesh_iterators}{Mesh Iterators and Circulators}) you have learned how to iterate over vertices, edges, halfedges and faces as well as circulate over certain structures such as 1-\/rings and many more. So in this tutorial we will focus on efficiently using the halfedge data structure and some very useful attributes such as the boundary flag. We assume that you already made yourself familiar with the halfedge structure which is used in Open\+Mesh. Further information on this topic can be found in \hyperlink{mesh_hds}{The Halfedge Data Structure}.\hypertarget{a14892_nav_he}{}\paragraph{Navigating over halfedges}\label{a14892_nav_he}
So let\textquotesingle{}s start with navigating over halfedges of a mesh. Assume we have the following mesh topology\+:



We can now select an arbitrary halfedge of this mesh which then offers either one of two possible navigations\+:

\begin{DoxyItemize}
\item If the chosen halfedge lies at a boundary or in other words is not adjacent to a face, we can now navigate along the boundary (or hole) of our mesh by using {\ttfamily next\+\_\+halfedge\+\_\+handle()} or {\ttfamily prev\+\_\+halfedge\+\_\+handle()}\+:\end{DoxyItemize}


\begin{DoxyItemize}
\item If the chosen halfedge is adjacent to a face, we can then navigate along all halfedges that are adjacent to this face. In other words we circulate around the inner halfedges of one face\+:\end{DoxyItemize}


In both cases the code would look something like the following example. Depending on whether the initial halfedge is adjacent to a face or not, we will either navigate on the boundary halfedges of our mesh or along the inner halfedges of a face\+: 
\begin{DoxyCodeInclude}
[...]

TriMesh::HalfedgeHandle heh, heh\_init;

\textcolor{comment}{// Get the halfedge handle assigned to vertex[0]}
heh = heh\_init = mesh.halfedge\_handle(vertex[0].handle());

\textcolor{comment}{// heh now holds the handle to the initial halfedge.}
\textcolor{comment}{// We now get further on the boundary by requesting}
\textcolor{comment}{// the next halfedge adjacent to the vertex heh}
\textcolor{comment}{// points to...}
heh = mesh.next\_halfedge\_handle(heh);

\textcolor{comment}{// We can do this as often as we want:}
\textcolor{keywordflow}{while}(heh != heh\_init) \{
        heh = mesh.next\_halfedge\_handle(heh);
\}

[...]
\end{DoxyCodeInclude}


References\+:~\newline
 \hyperlink{a08324_ad0719d8eacf8a0281327398a231c06a7}{Open\+Mesh\+::\+Concepts\+::\+Kernel\+T$<$ Final\+Mesh\+Items $>$\+::next\+\_\+halfedge\+\_\+handle()}~\newline
 \hyperlink{a08324_a004adf582bbb98f5723c505f4e6363ed}{Open\+Mesh\+::\+Concepts\+::\+Kernel\+T$<$ Final\+Mesh\+Items $>$\+::prev\+\_\+halfedge\+\_\+handle()}\hypertarget{a14892_nav_bound}{}\paragraph{Mesh boundaries}\label{a14892_nav_bound}
As you have seen in the previous section, navigating along boundaries is very simple. In general Open\+Mesh also offers a boundary attribute for edges, vertices and faces. So testing i.\+e. whether a face is a boundary face is quite simple using \hyperlink{a08748_ac86d2e4ea8f50b75876b35b175c4c635}{Open\+Mesh\+::\+Poly\+Connectivity\+::is\+\_\+boundary()}.~\newline


\begin{DoxyNote}{Note}
You can iterate along boundaries by using the next\+\_\+halfedge\+\_\+handle(). If you are on a boundary, the next halfedge is guaranteed to be also a boundary halfedge.
\end{DoxyNote}
So for each type we can make use of one of the following functions\+:


\begin{DoxyCodeInclude}
\textcolor{comment}{// Test if a halfedge lies at a boundary (is not adjacent to a face)}
\textcolor{keywordtype}{bool} is\_boundary (HalfedgeHandle \_heh) \textcolor{keyword}{const}

\textcolor{comment}{// Test if an edge lies at a boundary}
\textcolor{keywordtype}{bool} is\_boundary (EdgeHandle \_eh) \textcolor{keyword}{const}

\textcolor{comment}{// Test if a vertex is adjacent to a boundary edge}
\textcolor{keywordtype}{bool} is\_boundary (VertexHandle \_vh) \textcolor{keyword}{const}

\textcolor{comment}{// Test if a face has at least one adjacent boundary edge.}
\textcolor{comment}{// If \_check\_vertex=true, this function also tests if at least one}
\textcolor{comment}{// of the adjacent vertices is a boundary vertex}
\textcolor{keywordtype}{bool} is\_boundary (FaceHandle \_fh, \textcolor{keywordtype}{bool} \_check\_vertex=\textcolor{keyword}{false}) const
\end{DoxyCodeInclude}
\hypertarget{a14892_nav_io}{}\paragraph{Using incoming and outgoing halfedges}\label{a14892_nav_io}
Open\+Mesh offers quite a lot of iterators and circulators to easily iterate over the structures of a mesh. A very helpful iterator is the \hyperlink{a08748_a5b228884a6385b324b256263eb8254b1}{Open\+Mesh\+::\+Poly\+Connectivity\+::\+Vertex\+I\+Halfedge\+Iter} or the \hyperlink{a08748_a162054e1fc345ce1df9cdfda7433ffc0}{Open\+Mesh\+::\+Poly\+Connectivity\+::\+Vertex\+O\+Halfedge\+Iter} which are used to iterate over all incoming/outgoing halfedges of a vertex. So, sticking to the illustration below, a Open\+Mesh\+::\+Poly\+Connectivity\+:V\+:ertex\+I\+Halfedge\+Iter for the lower most vertex would iterate over all incoming halfedges (blue), whereas the Open\+Mesh\+::\+Poly\+Connectivity\+::\+Open\+Mesh\+::\+Poly\+Connectivity\+::\+Vertex\+O\+Halfedge\+Iter would iterate over all outgoing halfedges (red)\+:



A schematic code example of how to use the halfedge iterators as described above\+: 
\begin{DoxyCodeInclude}
[...]

\textcolor{comment}{// Get some vertex handle}
PolyMesh::VertexHandle v = ...;

\textcolor{keywordflow}{for}(PolyMesh::VertexIHalfedgeIter vih\_it = mesh.vih\_iter(v); vih\_it; ++vih\_it) \{
        \textcolor{comment}{// Iterate over all incoming halfedges...}
\}

\textcolor{keywordflow}{for}(PolyMesh::VertexOHalfedgeIter voh\_it = mesh.voh\_iter(v); voh\_it; ++voh\_it) \{
        \textcolor{comment}{// Iterate over all outgoing halfedges...}
\}

[...]
\end{DoxyCodeInclude}
\hypertarget{a14892_nav_opposite}{}\paragraph{Using opposite halfedges}\label{a14892_nav_opposite}
The halfedge structure splits every edge into two directional parts by creating two directed edges out of one undirected edge. So for every halfedge there exists its counterpart pointing in the opposite direction. Open\+Mesh allows to easily navigate through opposing halfedges via the function \hyperlink{a08324_ae2cc826b6f7a567307c2c24c4f3aee6c}{Open\+Mesh\+::\+Concepts\+::\+Kernel\+T$<$ Final\+Mesh\+Items $>$\+::opposite\+\_\+halfedge\+\_\+handle()}. So in the illustration below {\ttfamily opposite\+\_\+halfedge\+\_\+handle()} for the blue halfedge would return the red halfedge\+:



Use this function as described in the example below\+:


\begin{DoxyCodeInclude}
\textcolor{comment}{// Get the halfedge handle of i.e. the halfedge}
\textcolor{comment}{// that is associated to the first vertex}
\textcolor{comment}{// of our set of vertices}
PolyMesh::HalfedgeHandle heh = mesh.halfedge\_handle(*(mesh.vertices\_begin()));

\textcolor{comment}{// Now get the handle of its opposing halfedge}
PolyMesh::HalfedgeHandle opposite\_heh = mesh.opposite\_halfedge\_handle(heh);
\end{DoxyCodeInclude}


There are also a few more functions that offer easy access to opposing structures\+:


\begin{DoxyCodeInclude}
\textcolor{comment}{// Get the face adjacent to the opposite halfedge}
\hyperlink{a08748_ab553dda9f61dc814111e13e3339cca13}{OpenMesh::PolyConnectivity::opposite\_face\_handle}();

\textcolor{comment}{// Get the handle to the opposite halfedge}
\hyperlink{a08324_ae2cc826b6f7a567307c2c24c4f3aee6c}{OpenMesh::Concepts::KernelT::opposite\_halfedge\_handle}(
      );

\textcolor{comment}{// Get the opposite vertex to the opposite halfedge}
\hyperlink{a08808_a7049e38da17c99169388b764ad0822f7}{OpenMesh::TriConnectivity::opposite\_he\_opposite\_vh}();

\textcolor{comment}{// Get the vertex assigned to the opposite halfedge}
\hyperlink{a08808_a1aa3528bf17160f676e0fc5cca3b8af9}{OpenMesh::TriConnectivity::opposite\_vh}();
\end{DoxyCodeInclude}
\hypertarget{a14892_nav_to_from}{}\paragraph{Getting the to and from vertices}\label{a14892_nav_to_from}


If you have an halfedge, you can get the to and the from handles of the adjacent vertices. \begin{DoxyNote}{Note}
The halfedges have a direction. Therefore the to vertex is the from vertex of the opposite halfedge and vice versa.
\end{DoxyNote}

\begin{DoxyCodeInclude}
\textcolor{comment}{// Get the handle of the to vertex}
\hyperlink{a08324_a919ede88446b9c61b0d709c2fd789c6d}{OpenMesh::Concepts::KernelT::to\_vertex\_handle}();

\textcolor{comment}{// Get the handle of the from vertex}
\hyperlink{a08324_af4747f28572cf5f53fe5491ce9b0ab20}{OpenMesh::Concepts::KernelT::from\_vertex\_handle}();
\end{DoxyCodeInclude}
 \hypertarget{mesh_io}{}\subsubsection{Read and write meshes from files}\label{mesh_io}
This section explains the methods used to read a mesh from a file or write it to a file. The corresponding functions are defined in the namespace Open\+Mesh\+::\+Mesh\+IO. This section is divided into three steps. Step one will give a short example on how to use the Open\+Mesh I\+O\+Manager, step two will give some background information on how I\+O\+Manager works and finally step three will show you how to add your own modules to I\+O\+Manager.

A tutorial with more information regarding file IO can be found here\+: \hyperlink{tutorial_08}{Using I\+O\+::\+Options}\hypertarget{a14890_mesh_io_quick}{}\paragraph{Step 1 -\/ I\+O\+Manager quick start}\label{a14890_mesh_io_quick}
For a quick start you can copy the following code directly to your project.

\begin{DoxyNote}{Note}

\begin{DoxyItemize}
\item If you link statically against \hyperlink{a06210}{Open\+Mesh}, you have to add the define O\+M\+\_\+\+S\+T\+A\+T\+I\+C\+\_\+\+B\+U\+I\+LD to your application. This will ensure that readers and writers get initialized correctly. 
\item I\+O\+Manager uses the filename extension to determine which reader/writer to use. I.\+e. if passing \char`\"{}inputmesh.\+obj\char`\"{} as filename parameter, the O\+B\+J-\/\+File reader/writer will be used to parse/write the file. 
\end{DoxyItemize}
\end{DoxyNote}

\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#include <OpenMesh/Core/IO/MeshIO.hh>}

\hyperlink{a08764}{MyMesh} mesh;

\textcolor{keywordflow}{if} (!\hyperlink{a06213_ac417960ec28ffdd7e7003a2b1ebb2d1c}{OpenMesh::IO::read\_mesh}(mesh, \textcolor{stringliteral}{"some input file"})) 
\{
  std::cerr << \textcolor{stringliteral}{"read error\(\backslash\)n"};
  exit(1);
\}

\textcolor{comment}{// do something with your mesh ...}

\textcolor{keywordflow}{if} (!\hyperlink{a06213_a18286a792ebf896872f5e26182fc5c7b}{OpenMesh::IO::write\_mesh}(mesh, \textcolor{stringliteral}{"some output file"})) 
\{
  std::cerr << \textcolor{stringliteral}{"write error\(\backslash\)n"};
  exit(1);
\}
\end{DoxyCodeInclude}


~\newline
~\newline
\hypertarget{a14890_mesh_io_theory}{}\paragraph{Step 2 -\/ The theory behind I\+O\+Manager}\label{a14890_mesh_io_theory}
Usually mesh reader and writer routines are written directly against the data structure and the respective file format they support. This approach has the main disadvantage that targeting a different data structure or adding another file format leads to duplication of code.

I\+O\+Manager acts as an interface between persistent data on one side and an arbitrary data structure on the other side by means of reader/writer and importer/exporter modules. This is illustrated by the following diagramm \+:



~\newline


Persistent data of arbitrary format is first interpreted by a reader module. The data is then passed -\/ by means of a specified interface -\/ to an importer module for the target data structure. The process for writing data is analogous. The I\+O\+Manager controls the entire process. Reader/\+Writer modules are invisible to the user. Importer/\+Exporter however have to be specified explicitely as they are specific to a data structure.

The complete separation of data structure and persistent data makes it especially easy to maintain existing code and to extend funtionality at both ends as will be shown in step three.

\begin{DoxySeeAlso}{See also}
\hyperlink{a06213}{Open\+Mesh\+::\+IO}\+:\+:{\itshape I\+O\+Manager}
\end{DoxySeeAlso}
~\newline
~\newline
\hypertarget{a14890_mesh_io_extend}{}\paragraph{Step 3 -\/ How to extend I\+O\+Manager}\label{a14890_mesh_io_extend}
\hypertarget{a14890_mesh_io_extend_fileformat}{}\subparagraph{Adding support for a new file format}\label{a14890_mesh_io_extend_fileformat}
Adding support for a new file format involves adding a reader and writer module. Reader modules are classes derived from \hyperlink{a08484}{Open\+Mesh\+::\+I\+O\+::\+Base\+Reader}. The part of the interface that you usually have to define is shown below.


\begin{DoxyCodeInclude}
\textcolor{keyword}{class }\hyperlink{a08336}{BaseReader}
\{
\textcolor{keyword}{public}:

  \textcolor{keyword}{virtual} std::string get\_description() \textcolor{keyword}{const} = 0;
  \textcolor{keyword}{virtual} std::string get\_extensions() \textcolor{keyword}{const} = 0;
  \textcolor{keyword}{virtual} std::string get\_magic()\textcolor{keyword}{ const }\{ \textcolor{keywordflow}{return} std::string(\textcolor{stringliteral}{""}); \}

  \textcolor{keyword}{virtual} \textcolor{keywordtype}{bool} read(std::istream& \_is, \hyperlink{a08332}{BaseImporter}& \_bi) \textcolor{keyword}{const} = 0;
  \textcolor{keyword}{virtual} \textcolor{keywordtype}{bool} read(\textcolor{keyword}{const} std::string& \_filename, \hyperlink{a08332}{BaseImporter}& \_bi) \textcolor{keyword}{const} = 0;

  ...
\};
\end{DoxyCodeInclude}


Based on the file extension or the header information the I\+O\+Manager decides which reader module to use. The reader then parses the format and the information will be passed to the target data structure be means of a class derived from \hyperlink{a08468}{Open\+Mesh\+::\+I\+O\+::\+Base\+Importer}.

Writer modules are derived from \hyperlink{a08544}{Open\+Mesh\+::\+I\+O\+::\+Base\+Writer} and work the same way as reader modules.

~\newline
\hypertarget{a14890_mesh_io_extend_datastruct}{}\subparagraph{Adding support for a new data structure}\label{a14890_mesh_io_extend_datastruct}
As we have already seen, Importers receive information from the reader modules. Reader modules pass information through a specified interface \+:


\begin{DoxyCodeInclude}
\textcolor{keyword}{class }\hyperlink{a08332}{BaseImporter}
\{
\textcolor{keyword}{public}:

  \textcolor{keyword}{virtual} \textcolor{keywordtype}{void} add\_vertex  (\textcolor{keyword}{const} \hyperlink{a08448}{OpenMesh::Vec3f}&) \{\};
  \textcolor{keyword}{virtual} \textcolor{keywordtype}{void} add\_normal  (\textcolor{keyword}{const} \hyperlink{a08448}{OpenMesh::Vec3f}&) \{\};
  \textcolor{keyword}{virtual} \textcolor{keywordtype}{void} add\_texture (\textcolor{keyword}{const} \hyperlink{a08448}{OpenMesh::Vec2f}&) \{\};
  \textcolor{keyword}{virtual} \textcolor{keywordtype}{void} add\_face    (\textcolor{keyword}{const} FaceType&)        \{\};
\};
\end{DoxyCodeInclude}


The Importer is then responsible for filling the target data structure. Exporting information from a data structure is a little bit more involved than importing data to it. The writer modules must be able to iterate over all vectors/texcoords/faces. Therefore an exporter has to provide these iterators \+:


\begin{DoxyCodeInclude}
\textcolor{keyword}{class }\hyperlink{a08328}{BaseExporter}
\{
\textcolor{keyword}{public}:

  \textcolor{keyword}{virtual} \textcolor{keywordtype}{void} update() = 0;
  
  \textcolor{keyword}{virtual} PVertexIter const\_vertices\_begin()   = 0;
  \textcolor{keyword}{virtual} PVertexIter const\_vertices\_end()     = 0;
  
  \textcolor{keyword}{virtual} PTexCoordIter const\_texcoords\_begin() = 0;
  \textcolor{keyword}{virtual} PTexCoordIter const\_texcoords\_end()   = 0;

  \textcolor{keyword}{virtual} PIdxFaceIter const\_idx\_faces\_begin() = 0;
  \textcolor{keyword}{virtual} PIdxFaceIter const\_idx\_faces\_end()   = 0;

  \textcolor{keyword}{virtual} PFaceIter const\_set\_faces\_begin() = 0;
  \textcolor{keyword}{virtual} PFaceIter const\_set\_faces\_end()   = 0;

  \textcolor{keyword}{virtual} \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} n\_faces()     = 0;
  \textcolor{keyword}{virtual} \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} n\_vertices()  = 0;
  \textcolor{keyword}{virtual} \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} n\_texcoords() = 0;
\};
\end{DoxyCodeInclude}


There might be the need for the exporter to cache data from the structure it refers to. The update() function should be called at the beginning of each Base\+Writer\+::save() method and it should make sure that cached information is up to date.

For further information you are encouraged to take a look at the modules provided by Open\+Mesh which can be found in the IO subdirectory. \hypertarget{mesh_operations}{}\subsubsection{Some basic operations\+: Flipping and collapsing edges}\label{mesh_operations}
In this section you will learn about some basic operations on a mesh that Open\+Mesh already provides. Comprising the flipping of edges in a triangle mesh as well as collapsing edges by joining the two adjacent vertices.

\begin{DoxyItemize}
\item \hyperlink{a14893_op_flip}{Flipping edges in triangle meshes} \item \hyperlink{a14893_op_collapse}{Collapsing edges}\end{DoxyItemize}
\hypertarget{a14893_op_flip}{}\paragraph{Flipping edges in triangle meshes}\label{a14893_op_flip}
Considering two adjacent faces of a triangle mesh, there exist exactly two different configurations of the inner edge. Calling the function \hyperlink{a08808_a03b3c3be3c52a194789bd541d24f4c09}{Open\+Mesh\+::\+Tri\+Connectivity\+::flip(\+Edge\+Handle \+\_\+eh)} will flip the specified edge to its opposite orientation as shown in the illustration below.

 So, the following snippet of code shows how to use this in your applications\+:


\begin{DoxyCode}
TriMesh mesh;

\textcolor{comment}{// Add some vertices}
\hyperlink{a08776_a0fc18e13d70825938274e3faf7b55e01}{TriMesh::VertexHandle} vhandle[4];

vhandle[0] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(0, 0, 0));
vhandle[1] = mesh.add\_vertex(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(0, 1, 0));
vhandle[2] = mesh.add\_vertex(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(1, 1, 0));
vhandle[3] = mesh.add\_vertex(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(1, 0, 0));

\textcolor{comment}{// Add two faces}
std::vector<TriMesh::VertexHandle> face\_vhandles;

face\_vhandles.push\_back(vhandle[2]);
face\_vhandles.push\_back(vhandle[1]);
face\_vhandles.push\_back(vhandle[0]);
mesh.add\_face(face\_vhandles);

face\_vhandles.clear();

face\_vhandles.push\_back(vhandle[2]);
face\_vhandles.push\_back(vhandle[0]);
face\_vhandles.push\_back(vhandle[3]);
mesh.add\_face(face\_vhandles);

\textcolor{comment}{// Now the edge adjacent to the two faces connects}
\textcolor{comment}{// vertex vhandle[0] and vhandle[2].}

\textcolor{comment}{// Find this edge and then flip it}
\textcolor{keywordflow}{for}(TriMesh::EdgeIter it = mesh.edges\_begin(); it != mesh.edges\_end(); ++it) \{

        \textcolor{keywordflow}{if}(!mesh.is\_boundary(*it)) \{
                \textcolor{comment}{// Flip edge}
                mesh.flip(*it);
        \}
\}

\textcolor{comment}{// The edge now connects vertex vhandle[1] and vhandle[3].}
\end{DoxyCode}
\hypertarget{a14893_op_collapse}{}\paragraph{Collapsing edges}\label{a14893_op_collapse}
In this section you will learn how to collapse edges such that the two adjacent vertices join. Open\+Mesh provides the function \hyperlink{a08748_a5afce0f6be1f425f5e0d42441fee35df}{Open\+Mesh\+::\+Poly\+Connectivity\+::collapse(\+Halfedge\+Handle \+\_\+heh)} to perform this operation. This will collapse the from-\/vertex (remeber that halfedges are directed) to the to-\/vertex of the halfedge as illustrated below. Note that collapsing edges might cause topological inconsistencies to your mesh. You should verify consistency after collapsing edges by calling \hyperlink{a08748_af1463136f43f48a7e6576701375d018c}{Open\+Mesh\+::\+Poly\+Connectivity\+::is\+\_\+collapse\+\_\+ok()}.

\begin{DoxyNote}{Note}
You have to request status attributes in order to use the collapse and delete functions!
\end{DoxyNote}
 A simple code example related to the illustration might look like this\+:


\begin{DoxyCode}
PolyMesh mesh;

\textcolor{comment}{// Request required status flags}
mesh.request\_vertex\_status();
mesh.request\_edge\_status();
mesh.request\_face\_status();

\textcolor{comment}{// Add some vertices as in the illustration above}
PolyMesh::VertexHandle vhandle[7];
vhandle[0] = mesh.add\_vertex(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(-1, 1, 0));
vhandle[1] = mesh.add\_vertex(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(-1, 3, 0));
vhandle[2] = mesh.add\_vertex(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(0, 0, 0));
vhandle[3] = mesh.add\_vertex(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(0, 2, 0));
vhandle[4] = mesh.add\_vertex(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(0, 4, 0));
vhandle[5] = mesh.add\_vertex(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(1, 1, 0));
vhandle[6] = mesh.add\_vertex(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(1, 3, 0));

\textcolor{comment}{// Add three quad faces}
std::vector<PolyMesh::VertexHandle> face\_vhandles;
face\_vhandles.push\_back(vhandle[1]);
face\_vhandles.push\_back(vhandle[0]);
face\_vhandles.push\_back(vhandle[2]);
face\_vhandles.push\_back(vhandle[3]);
mesh.add\_face(face\_vhandles);

face\_vhandles.clear();
face\_vhandles.push\_back(vhandle[1]);
face\_vhandles.push\_back(vhandle[3]);
face\_vhandles.push\_back(vhandle[5]);
face\_vhandles.push\_back(vhandle[4]);
mesh.add\_face(face\_vhandles);

face\_vhandles.clear();
face\_vhandles.push\_back(vhandle[3]);
face\_vhandles.push\_back(vhandle[2]);
face\_vhandles.push\_back(vhandle[6]);
face\_vhandles.push\_back(vhandle[5]);
mesh.add\_face(face\_vhandles);

\textcolor{comment}{// Now find the edge between vertex vhandle[2]}
\textcolor{comment}{// and vhandle[3]}
\textcolor{keywordflow}{for}(PolyMesh::HalfedgeIter it = mesh.halfedges\_begin(); it != mesh.halfedges\_end(); ++it) \{
  \textcolor{keywordflow}{if}( mesh.to\_vertex\_handle(*it) == vhandle[3] &&
      mesh.from\_vertex\_handle(*it) == vhandle[2])
  \{
    \textcolor{comment}{// Collapse edge}
    mesh.collapse(*it);
    \textcolor{keywordflow}{break};
  \}
\}

\textcolor{comment}{// Our mesh now looks like in the illustration above after the collapsing.}
\end{DoxyCode}
 \hypertarget{mesh_hierarchy}{}\subsubsection{Conceptual Class Hierarchy}\label{mesh_hierarchy}
Since there is no such thing as a Open\+Mesh class and the library makes heavy use of C++ template, we show the inheritance graph of \hyperlink{a08764}{Open\+Mesh\+::\+Tri\+Mesh\+\_\+\+Array\+KernelT} as proxy for all possible mesh types.

Please note! Most of the inheritence relationships are realized by template parameterization! Therefore some of the inheritance links are not documented in a inheritance graph in the reference. This picture shows the overall concept.

\hypertarget{a14886_ch_kernel}{}\paragraph{Building the kernel}\label{a14886_ch_kernel}

\begin{DoxyEnumerate}
\item The Base\+Kernel defines the basic operations on properties like add/remove/access.
\item Next the Attrib\+KernelT adds the standard properties all associated methods.
\item Finally the Array\+KernelT provides the methods to add/remove/access the mesh items vertices, (half-\/)edges, and faces. The base class is passed as a template parameter, since depending on the underlying storage type the Attrib\+Kernel might change.
\end{DoxyEnumerate}\hypertarget{a14886_ch_complete}{}\paragraph{Building the mesh}\label{a14886_ch_complete}

\begin{DoxyEnumerate}
\item The Poly\+MeshT inherits from the kernel and provide all necessary methods to work with polygonal meshes.
\item Finally we derive Tri\+MeshT from Poly\+MeshT to have an specialization for triangle meshes.
\end{DoxyEnumerate}

Looks simple, but it isn\textquotesingle{}t -\/ it\textquotesingle{}s a bit more complicated\+:


\begin{DoxyCodeInclude}
\textcolor{keyword}{template} <\textcolor{keyword}{class} Traits>
\textcolor{keyword}{struct }\hyperlink{a08340}{TriMesh\_ArrayKernel\_GeneratorT}
\{
  \textcolor{keyword}{typedef} FinalMeshItemsT<ArrayItems, Traits, true>  MeshItems;
  \textcolor{keyword}{typedef} AttribKernelT<MeshItems>                   AttribKernel;
  \textcolor{keyword}{typedef} ArrayKernelT<AttribKernel, MeshItems>      MeshKernel;
  \textcolor{keyword}{typedef} TriMeshT<MeshKernel>                       \hyperlink{a08764}{Mesh};
\};
\end{DoxyCodeInclude}


To generate the actual mesh type the helper template class {\ttfamily \hyperlink{a08340}{Tri\+Mesh\+\_\+\+Array\+Kernel\+\_\+\+GeneratorT}} is used. It takes the traits in a template argument and passes it to {\ttfamily Final\+Mesh\+ItemsT} to get the final type of the mesh items (Mesh\+Items). The {\ttfamily Mesh\+Items} defines the types for Point, Normal, Color, Tex\+Coord, Vertex, and for all mesh items. With the help of {\ttfamily Mesh\+Items} create the type of the {\ttfamily Attrib\+Kernel}, which defines the apropriate standard properties for the items. Finally use {\ttfamily Attrib\+Kernel} and {\ttfamily Mesh\+Items} to create the mesh kernel type {\ttfamily Mesh\+Kernel}. It\textquotesingle{}s quite a way to get a kernel . As long as the created kernel follows the kernel concept (\hyperlink{a06169}{Mesh Kernels}), we can easily create now the mesh. Here we use now {\ttfamily Tri\+MeshT} to create the final mesh type {\ttfamily Mesh}. \hypertarget{mesh_type}{}\subsubsection{Specifying your My\+Mesh}\label{mesh_type}
This section will show how to build your own custom tailored type {\ttfamily My\+Mesh}. As we have seen in the section on goals and features there are some parameters to be specified for a mesh. This is done in the following four steps\+:


\begin{DoxyEnumerate}
\item Choose between triangle mesh and general polygonal mesh.


\item Select the mesh kernel


\item Parameterize the mesh by a so-\/called {\itshape Traits} class. You can add arbitrary classes to the mesh items, specify the types {\ttfamily Scalar}, {\ttfamily Point}, {\ttfamily Normal} and {\ttfamily Color}, and use predefined attributes like {\ttfamily Attributes\+::\+Normal} and {\ttfamily Attributes\+::\+Color}.


\item Dynamically bind data to the mesh or the mesh entities (vertex, (half-\/)edge, face) using {\itshape custom} {\itshape properties}.


\end{DoxyEnumerate}

We will explain these four parameterization steps and give a code example at the end of this page.

~\newline
~\newline
\hypertarget{a14887_sec_select_face_type}{}\paragraph{Polygonal or Triangle Mesh?}\label{a14887_sec_select_face_type}
This decision is quite simple\+: Whenever possible choose the triangle mesh. The restriction to triangular faces usually leads to more efficient algorithms (e.\+g. rendering triangles is much faster than rendering arbitrary polygons). Additionally some algorithms are only implemented for triangle meshes while triangle meshes inherit the full functionality of polygonal meshes. For a list of them refer to the following links.

\begin{DoxySeeAlso}{See also}
\hyperlink{a08776}{Open\+Mesh\+::\+Poly\+MeshT} 

\hyperlink{a08816}{Open\+Mesh\+::\+Tri\+MeshT}
\end{DoxySeeAlso}
~\newline
~\newline
\hypertarget{a14887_sec_select_kernel}{}\paragraph{Choosing the right kernel}\label{a14887_sec_select_kernel}
The mesh kernel specifies how the mesh entities (vertices, (half-\/)edges, faces) are internally stored. In fact the entities are kept in so-\/called properties. A property itself provides an array like interface. The kernel defines the corresponding handle types, i.\+e. the way items reference each other. Since the properties have an array like interface the handles are represented internally as indices.

The default kernel is {\ttfamily Array\+KernelT}. Which is good for most situations. But depending on the application a different kernel would be better. E.\+g. the Open\+SG integration has been realized be replacing the kernel by a custom kernel, since Open\+SG provides already array like properties, which could be reused for the intergration. In case of a an Open\+SG environment one might be better off using {\ttfamily O\+S\+G\+\_\+\+Kernel\+::\+Array\+KernelT}.

\begin{DoxySeeAlso}{See also}
\hyperlink{a06169}{Mesh Kernels}
\end{DoxySeeAlso}
~\newline
~\newline
\hypertarget{a14887_sec_select_traits}{}\paragraph{Mesh Traits}\label{a14887_sec_select_traits}
While the last two sections only have chosen from a list of predefined meshes or kernels, respectively, we now come to the user-\/defined customization.

The resulting mesh {\ttfamily My\+Mesh} will provide the following types\+:


\begin{DoxyItemize}
\item The {\itshape point} and {\itshape scalar} type\+: {\ttfamily My\+Mesh\+::\+Point} and {\ttfamily My\+Mesh\+::\+Scalar}. 
\item The {\itshape mesh items}\+: {\ttfamily My\+Mesh\+::\+Vertex}, {\ttfamily My\+Mesh\+::\+Halfedge}, {\ttfamily My\+Mesh\+::\+Edge}, {\ttfamily My\+Mesh\+::\+Face}. 
\item The {\itshape handle} types\+: {\ttfamily My\+Mesh\+::\+Vertex\+Handle}, {\ttfamily My\+Mesh\+::\+Halfedge\+Handle}, {\ttfamily My\+Mesh\+::\+Edge\+Handle}, {\ttfamily My\+Mesh\+::\+Face\+Handle}. 
\end{DoxyItemize}

While the handle types are fixed, the other types can be customized. Each mesh type (see \hyperlink{a06170}{Predefined Mesh Types}) can be parameterized by a so-\/called {\itshape traits} class. Using this mechanism one can


\begin{DoxyEnumerate}
\item change the coordinate type {\ttfamily My\+Mesh\+::\+Point} and the resulting scalar type {\ttfamily My\+Mesh\+::\+Scalar} == {\ttfamily My\+Mesh\+::\+Point\+::value\+\_\+type}, 
\item change the normal type {\ttfamily My\+Mesh\+::\+Normal} 
\item change the color type {\ttfamily My\+Mesh\+::\+Color} 
\item use predefined attributes like normal vector, color, texture coordinates, ... for the mesh items. 
\item add arbitrary classes to the mesh items. 
\end{DoxyEnumerate}

All these customizations are encapsulated in one class {\ttfamily \hyperlink{a08344}{My\+Traits}}, that is used as template argument to the mesh, e.\+g. 
\begin{DoxyCode}
\textcolor{keyword}{struct }\hyperlink{a08344}{MyTraits} \{
  \textcolor{comment}{// your customization}
\};
\textcolor{keyword}{typedef} PolyMesh\_ArrayKernelT<MyTraits>  \hyperlink{a08764}{MyMesh};
\end{DoxyCode}


The rest of this section explains the construction of this traits class, its application to the mesh will be the topic of the next section.

For each mesh entity one can control the predefined attributes to be attached by a traits class using some convenience macros, e.\+g. {\ttfamily Open\+Mesh\+::\+Vertex\+Attributes} and {\ttfamily Open\+Mesh\+::\+Vertex\+Traits} for vertices. The default traits class looks like this\+:


\begin{DoxyCodeInclude}
\textcolor{keyword}{struct }\hyperlink{a08348}{DefaultTraits}
\{
  \textcolor{keyword}{typedef} \hyperlink{a08448}{Vec3f}  Point;
  \textcolor{keyword}{typedef} \hyperlink{a08448}{Vec3f}  Normal;
  \textcolor{keyword}{typedef} \hyperlink{a08448}{Vec2f}  TexCoord;
  \textcolor{keyword}{typedef} \hyperlink{a08448}{Vec3uc} Color;

  VertexTraits    \{\};
  HalfedgeTraits  \{\};
  EdgeTraits      \{\};
  FaceTraits      \{\};
  
  VertexAttributes(0);
  HalfedgeAttributes(\hyperlink{a06215_ab78a93560926cd2f9958cb028f7ea96dafaaebe1808b5cce96ad4e19df471d58a}{Attributes::PrevHalfedge});
  EdgeAttributes(0);
  FaceAttributes(0);
\};
\end{DoxyCodeInclude}


Please note that for example {\ttfamily Vertex\+Traits} is a define concealing a template declaration. The actual template class name is {\ttfamily VertexT}, which is further simplified to a specific type {\ttfamily Vertex} at a later stage during the construction of the mesh kernel.

Because the traits classes always have to provide the template classes {\ttfamily VertexT}, {\ttfamily HalfedgeT}, {\ttfamily EdgeT}, {\ttfamily FaceT}, and the types {\ttfamily Point}, {\ttfamily Normal}, {\ttfamily Color}, and {\ttfamily Tex\+Coord} one should derive this class from the default implementation {\ttfamily \hyperlink{a08348}{Default\+Traits}}. In this case you will only have to define the classes or types you want to override or substitute.

~\newline
 \hypertarget{a14887_sec_change_point}{}\subparagraph{Changing the Point type}\label{a14887_sec_change_point}
Changing the type that is used to store the point coordinates as well as the normal vectors can simply be done by defining this type in the traits class. The following code changes the coordinate type in order to use {\ttfamily double} instead of {\ttfamily float}.


\begin{DoxyCodeInclude}
\textcolor{keyword}{struct }\hyperlink{a08344}{MyTraits} : \textcolor{keyword}{public} \hyperlink{a08800}{OpenMesh::DefaultTraits}
\{
  \textcolor{keyword}{typedef} \hyperlink{a08448}{OpenMesh::Vec3d} Point; \textcolor{comment}{// use double-values points}
\};
\end{DoxyCodeInclude}


Using the \hyperlink{a08448}{Open\+Mesh\+::\+VectorT} class you can easily plug in any scalar type for the use in point coordinates, e.\+g. some exact arithmetic. You can also exchange the whole class representing points as long as it provides the same interface as the \hyperlink{a08448}{Open\+Mesh\+::\+VectorT} class.

~\newline
 \hypertarget{a14887_sec_add_attributes}{}\subparagraph{Adding Predefined Attributes}\label{a14887_sec_add_attributes}
There are some pre-\/defined attributes that can be appended to the mesh items. These global attributes are defined in the namespace \hyperlink{a06215}{Open\+Mesh\+::\+Attributes}. The advantage of these attributes is that they are registered at the items they are added to. Therefore algorithms can check for these attributes at run-\/time as well as at compile-\/time. This is important if you want to implement algorithms acting on different meshes, that may or may not have e.\+g. normal vectors per vertex/face.

Adding these predefined attributes is quite simple. You provide an {\ttfamily unsigned int} in the traits class, whose bits control whether or not a certain attribute should be attached or not.

If you want to add a normal vector to your vertices and faces, and also want to have color information for vertices, the code would look like this\+:


\begin{DoxyCodeInclude}
\textcolor{keyword}{struct }\hyperlink{a08344}{MyTraits} : \textcolor{keyword}{public} \hyperlink{a08800}{OpenMesh::DefaultTraits} 
\{
  VertexAttributes( \hyperlink{a06215_ab78a93560926cd2f9958cb028f7ea96da213616dd2e4d9744d863587001a77988}{OpenMesh::Attributes::Normal} |
                    \hyperlink{a06215_ab78a93560926cd2f9958cb028f7ea96dad51534b15e5d0f65569251f4cb3c0d0c}{OpenMesh::Attributes::Color} );

  FaceAttributes( \hyperlink{a06215_ab78a93560926cd2f9958cb028f7ea96da213616dd2e4d9744d863587001a77988}{OpenMesh::Attributes::Normal} );
\};
\end{DoxyCodeInclude}


Internally each mesh item contains an {\ttfamily enum} defining the integer {\ttfamily Attributes} (containing the bits of used attributes OR\textquotesingle{}ed together). From its set/unset bits you can see whether a certain attribute is used. \hyperlink{a06210}{Open\+Mesh} provides the macro O\+M\+\_\+\+Check\+\_\+\+Attrib for doing this\+:


\begin{DoxyCode}
\textcolor{keywordflow}{if} (OM\_Check\_Attrib(\hyperlink{a08776_a03e6fd1a2fc91d4144374fd28dfbecee}{MyMesh::Vertex}, Normal)
  do\_something\_with\_normals();
\end{DoxyCode}


These run-\/time checks may not be sufficient in some cases. You can also check for attributes at compile-\/time and instantiate the correct functions by using function overloading. The class {\ttfamily Gen\+Prog\+::\+Bool2\+Type} maps true/false information to two different types, {\ttfamily Bool2\+Type$<$true$>$} and {\ttfamily Bool2\+Type$<$false$>$}. An example that draws Open\+GL normals if they are available would look like this\+:


\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#include <OpenMesh/Core/Utils/GenProg.hh>}

\textcolor{comment}{// draw a face normal if we have one}
\textcolor{keywordtype}{void} drawFaceNormal(\textcolor{keyword}{const} \hyperlink{a08776_a71e1e8eaabeb24eca04237931b4bea26}{MyMesh::Face}& \_f) \{ 
  drawFaceNormal(\_f, GenProg::Bool2Type<OM\_Check\_Attrib(\hyperlink{a08776_a71e1e8eaabeb24eca04237931b4bea26}{MyMesh::Face}, Normal)>()); 
\}

\textcolor{comment}{// normal exists -> use it}
\textcolor{keywordtype}{void} drawFaceNormal(\textcolor{keyword}{const} \hyperlink{a08776_a71e1e8eaabeb24eca04237931b4bea26}{MyMesh::Face}& \_f, GenProg::Bool2Type<true>) \{ 
  glNormal3fv(\_f.normal());
\}

\textcolor{comment}{// empty dummy (no normals)}
\textcolor{keywordtype}{void} drawFaceNormal(\textcolor{keyword}{const} \hyperlink{a08776_a71e1e8eaabeb24eca04237931b4bea26}{MyMesh::Face}& \_f, GenProg::Bool2Type<false>)\{\}
\end{DoxyCodeInclude}


Especially the compile-\/time checking for attributes is extremely useful because it does not generate any unnecessary code and does not perform expensive tests at run-\/time.

\begin{DoxySeeAlso}{See also}
\hyperlink{a08800}{Open\+Mesh\+::\+Default\+Traits} 

\hyperlink{a06215}{Open\+Mesh\+::\+Attributes} 

\hyperlink{a06214}{Open\+Mesh\+::\+Gen\+Prog}
\end{DoxySeeAlso}
~\newline
 \hypertarget{a14887_sec_add_traits}{}\subparagraph{Adding User-\/\+Defined Elements}\label{a14887_sec_add_traits}
You can also add arbitrary types/elements/methods to the mesh items by providing a corresponding traits class for these items. Adding some index to the {\ttfamily Vertex} class is easily done by


\begin{DoxyCodeInclude}
\textcolor{keyword}{struct }\hyperlink{a08344}{MyTraits} : \textcolor{keyword}{public} \hyperlink{a08800}{OpenMesh::DefaultTraits}
\{
  VertexTraits
  \{
    \textcolor{keywordtype}{int} some\_additional\_index;
  \};
\};
\end{DoxyCodeInclude}


The macro {\ttfamily Vertex\+Traits} hides some ugly template stuff. In fact, it is defined as


\begin{DoxyCode}
\textcolor{preprocessor}{#define VertexTraits template <class Base, class Refs> struct VertexT : public Base}
\end{DoxyCode}


hence the traits class actually looks like this\+:


\begin{DoxyCodeInclude}
\textcolor{keyword}{struct }\hyperlink{a08344}{MyTraits} : \textcolor{keyword}{public} \hyperlink{a08800}{OpenMesh::DefaultTraits}
\{
  \textcolor{keyword}{template} <\textcolor{keyword}{class} Base, \textcolor{keyword}{class} Refs> \textcolor{keyword}{struct }VertexT : \textcolor{keyword}{public} Base
  \{
    \textcolor{keywordtype}{int} some\_additional\_index;
  \};
\};
\end{DoxyCodeInclude}


You have to keep this in mind when you want to define constructors for your vertex type or when you want to derive the vertex type from other classes.

The template argument {\ttfamily Base} provides access to the mesh handles and to the {\ttfamily Point} and {\ttfamily Scalar} type by its member class {\ttfamily Refs}. Adding a {\ttfamily My\+Mesh\+::\+Face\+Handle} to the vertex class can therefore be implemented like this\+:


\begin{DoxyCodeInclude}
\textcolor{keyword}{struct }\hyperlink{a08344}{MyTraits} : \textcolor{keyword}{public} \hyperlink{a08800}{OpenMesh::DefaultTraits} 
\{
  VertexTraits
  \{
    \textcolor{keywordtype}{int} some\_additional\_index;
    \textcolor{keyword}{typename} Base::Refs::FaceHandle my\_face\_handle;
  \};
\};
\end{DoxyCodeInclude}


Adding elements to other mesh items works in the same manner.

~\newline
 \hypertarget{a14887_sec_algo_traits}{}\subparagraph{Using traits defined by algorithms}\label{a14887_sec_algo_traits}
From version 0.\+10.\+3 on algorithms can define traits/attributes they require and the user can merge these traits into his own traits. A more elegant way is to use dynamic properites, which can be added/removed during runtime by the algorithm. This is the preferred way to attach custom data to the mesh.

An example for an algorithm as well as the application using traits is given in \hyperlink{tutorial_06}{Using mesh attributes and traits}.

~\newline
~\newline
\hypertarget{a14887_sec_properties}{}\paragraph{Dynamic Properties}\label{a14887_sec_properties}
From version 1.\+0 on Open\+Mesh provides dynamic properties. Instead of using traits to bind data at compile time algorithms or the application can use dynamic properties. Similar to entities the properties are accessed and manipulated via handles.

An example for an algorithm as well as the application using properties is given in \hyperlink{tutorial_03}{Using (custom) properties} and \hyperlink{tutorial_04}{Using S\+TL algorithms}.

~\newline
~\newline
\hypertarget{a14887_sec_traits_example}{}\paragraph{Final Implementation Example}\label{a14887_sec_traits_example}
Consider an application where we just want to render triangle meshes. This means we will select the triangle mesh and the {\ttfamily Array\+KernelT}. Faces that are not triangles will automatically be tesselated into triangles. Because we only display meshes and do not dynamically add or remove items, we can just use the {\ttfamily Array\+KernelT}.

All mesh-\/kernel combinations are predefined in the directory {\ttfamily Open\+Mesh/\+Mesh/\+Types}. Refer to \hyperlink{a06170}{Predefined Mesh Types} for a complete list of them. For our example we use the {\ttfamily Tri\+Mesh\+\_\+\+Array\+KernelT} and parameterize it by our {\ttfamily \hyperlink{a08344}{My\+Traits}} class.

We will need face and vertex normals and e.\+g. for color coding vertex curvature, i.\+e. vertex color.


\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#include <OpenMesh/Core/Mesh/TriMesh\_ArrayKernelT.hh>}


\textcolor{comment}{// define traits}
\textcolor{keyword}{struct }\hyperlink{a08344}{MyTraits} : \textcolor{keyword}{public} \hyperlink{a08800}{OpenMesh::DefaultTraits}
\{
  \textcolor{comment}{// use double valued coordinates}
  \textcolor{keyword}{typedef} \hyperlink{a08448}{OpenMesh::Vec3d} Point;

  \textcolor{comment}{// use vertex normals and vertex colors}
  VertexAttributes( OpenMesh::DefaultAttributer::Normal |
                    \hyperlink{a06215_ab78a93560926cd2f9958cb028f7ea96dad51534b15e5d0f65569251f4cb3c0d0c}{OpenMesh::DefaultAttributer::Color} );

  \textcolor{comment}{// store the previous halfedge}
  HalfedgeAttributes( \hyperlink{a06215_ab78a93560926cd2f9958cb028f7ea96dafaaebe1808b5cce96ad4e19df471d58a}{OpenMesh::DefaultAttributer::PrevHalfedge} );

  \textcolor{comment}{// use face normals}
  FaceAttributes( OpenMesh::DefaultAttributer::Normal );

  \textcolor{comment}{// store a face handle for each vertex}
  VertexTraits
  \{
    \textcolor{keyword}{typename} Base::Refs::FaceHandle my\_face\_handle;
  \};

\};


\textcolor{comment}{// Select mesh type (TriMesh) and kernel (ArrayKernel)}
\textcolor{comment}{// and define my personal mesh type (MyMesh)}
\textcolor{keyword}{typedef} \hyperlink{a08764}{OpenMesh::TriMesh\_ArrayKernelT<MyTraits>}  MyMesh;

\textcolor{keywordtype}{int} main(\textcolor{keywordtype}{int} argc, \textcolor{keywordtype}{char} **argv)
\{
  MyMesh mesh;

  \textcolor{comment}{// -------------------- Add dynamic data}

  \textcolor{comment}{// for each vertex an extra double value}
  \hyperlink{a08876}{OpenMesh::VPropHandleT< double >} vprop\_double;
  mesh.add\_property( vprop\_double );

  \textcolor{comment}{// for the mesh an extra string}
  \hyperlink{a08892}{OpenMesh::MPropHandleT< string >} mprop\_string;
  mesh.add\_property( mprop\_string );

  \textcolor{comment}{// -------------------- do something}

  ...;

\}
\end{DoxyCodeInclude}


That\textquotesingle{}s it. 



/$\ast$$\ast$ \hypertarget{mesh_eigen}{}\subsubsection{Specifying an Open\+Mesh using Eigen3 vectors}\label{mesh_eigen}
This section will show how to build your own custom mesh type using Eigen3 vectors for points, normals or other entities.

First of all you need to include the Eigen header shipped with \hyperlink{a06210}{Open\+Mesh}\+: 
\begin{DoxyCode}
\textcolor{preprocessor}{#include <OpenMesh/Core/Geometry/EigenVectorT.hh>}
\end{DoxyCode}


This header contains the external functions and vector traits used by \hyperlink{a06210}{Open\+Mesh}.

Afterwards you can specify your mesh\+:


\begin{DoxyCode}
\textcolor{keyword}{struct }EigenTraits : \hyperlink{a08800}{OpenMesh::DefaultTraits} \{
    \textcolor{keyword}{using} Point = Eigen::Vector3d;
    \textcolor{keyword}{using} Normal = Eigen::Vector3d;

    \textcolor{keyword}{using} \hyperlink{a06215_ab78a93560926cd2f9958cb028f7ea96da358ce33062ef8be1f9928f9197c29ad1}{TexCoord2D} = Eigen::Vector2d;
\};

\textcolor{keyword}{using} EigenTriMesh = \hyperlink{a08764}{OpenMesh::TriMesh\_ArrayKernelT<EigenTraits>}
      ;

EigenTriMesh mesh;
\end{DoxyCode}


Now you can use mesh as any other \hyperlink{a06210}{Open\+Mesh} while using Eigen vectors as the underlying data type.

\begin{DoxyNote}{Note}
\hyperlink{a06210}{Open\+Mesh} uses stl vectors for storing its data. This might lead to errors regarding memory alignment with sse instructions\+: \href{http://eigen.tuxfamily.org/dox/group__TopicStlContainers.html}{\tt http\+://eigen.\+tuxfamily.\+org/dox/group\+\_\+\+\_\+\+Topic\+Stl\+Containers.\+html} You might need to define -\/\+D\+E\+I\+G\+E\+N\+\_\+\+D\+O\+N\+T\+\_\+\+V\+E\+C\+T\+O\+R\+I\+ZE 
\end{DoxyNote}
\hypertarget{tools_docu}{}\subsection{Open\+Mesh Tools Documentation}\label{tools_docu}
\begin{DoxyItemize}
\item \hyperlink{decimater_docu}{Mesh Decimation Framework} \item \hyperlink{subdivider_docu}{Sudivision Tools} \item \hyperlink{vdpm_docu}{View Dependent Progressive Meshes} \item \hyperlink{smoother_docu}{Smoother Tools} \item \hyperlink{smarttagger_docu}{Smart Tagger} \item Miscellaneous \hyperlink{a09276}{Open\+Mesh\+::\+StripifierT} \end{DoxyItemize}
\hypertarget{decimater_docu}{}\subsubsection{Mesh Decimation Framework}\label{decimater_docu}
The mesh decimation framework has 3 building blocks.


\begin{DoxyEnumerate}
\item \hyperlink{a14878_DecimaterAlg}{The decimation algorithm}
\item \hyperlink{a14878_DecimaterMod}{Decimating Modules}
\item \hyperlink{a14878_DecimaterHnd}{Module Handles}
\end{DoxyEnumerate}\hypertarget{a14878_DecimaterAlg}{}\paragraph{The decimation algorithm}\label{a14878_DecimaterAlg}
The decimater (\hyperlink{a08932}{Open\+Mesh\+::\+Decimater\+::\+DecimaterT}) provides the decimation algorithm, while the decimation modules provide the computational part. The modules compute a priority value due to some error metric, which is used by the decimater to feed a priority queue. The lower the error value, the more a potential collapse moves to the front of the queue. The one with the lowest error will always be the candidate for the next collapse.

This implementation does a halfedge collapse, hence simply collapsing one vertex into another connected by a halfedge.

\begin{DoxyNote}{Note}
The decimater ignores all \textquotesingle{}locked\textquotesingle{} and \textquotesingle{}deleted\textquotesingle{} vertices (see \hyperlink{a06215_af600bbf2c3f55c90a2a64848f0547617}{Open\+Mesh\+::\+Attributes\+::\+Status\+Bits})
\end{DoxyNote}
\begin{DoxyAttention}{Attention}
The decimater sets temporarily the status bit \textquotesingle{}tagged\textquotesingle{} and clears it after usage regardless of a previous state.
\end{DoxyAttention}
\hypertarget{a14878_DecimaterLock}{}\paragraph{Block vertices from beeing touched by the Decimater}\label{a14878_DecimaterLock}
You could mark vertices as locked, which should not be modified by the decimater.


\begin{DoxyCode}
\textcolor{comment}{// That might be already requested}
mesh\_->request\_vertex\_status();

\textcolor{comment}{// Get an iterator over all halfedges}
Mesh::HalfedgeIter he\_it, he\_end=mesh\_->halfedges\_end();

\textcolor{comment}{// If halfedge is boundary, lock the corresponding vertices}
\textcolor{keywordflow}{for} (he\_it = mesh\_->halfedges\_begin(); he\_it != he\_end ; ++he\_it)
  \textcolor{keywordflow}{if} (mesh\_->is\_boundary(*he\_it)) \{
     mesh\_->status(\_mesh->to\_vertex\_handle(*he\_it)).set\_locked(\textcolor{keyword}{true});
     mesh\_->status(\_mesh->from\_vertex\_handle(*he\_it)).set\_locked(\textcolor{keyword}{true});
  \}
\end{DoxyCode}
\hypertarget{a14878_DecimaterMod}{}\paragraph{Decimating Modules}\label{a14878_DecimaterMod}
The vertex to be removed is determined by a decimation module, which has to be derived from \hyperlink{a08956}{Open\+Mesh\+::\+Decimater\+::\+Mod\+BaseT}. The framework supplies already a few decimation modules. But it\textquotesingle{}s very easy to build your own (\hyperlink{a08956}{Open\+Mesh\+::\+Decimater\+::\+Mod\+BaseT}). The most important function of a decimation module is \hyperlink{a08956_acb81c6b9a752741fce2366ca605cd14c}{Open\+Mesh\+::\+Decimater\+::\+Mod\+Base\+T\+::collapse\+\_\+priority()}. It takes an \hyperlink{a08928}{Open\+Mesh\+::\+Decimater\+::\+Collapse\+InfoT} describing a potential halfedge collapse, and returns a value due to some error metric. The error value is used by the decimater to feed a priority queue. Collapses with low error will be executed first, and those with large error later. Of course a module computing the error quadric is provided (\hyperlink{a08988}{Open\+Mesh\+::\+Decimater\+::\+Mod\+QuadricT}).

This framework allows to use more than one decimation module with some restrictions. Since the error value is always normalized and sometimes very difficult to compare to other metrics, the framework allows only one non-\/binary module, i.\+e. a module computing a float value. Every further module must be a binary module, i.\+e. collapse\+\_\+prioerity() returns \hyperlink{a08956_a77c942fb03efb3b079a916e005729d94a2b521064f4abfdfb6eb5464308b6f6e7}{Open\+Mesh\+::\+Decimater\+::\+Mod\+Base\+T\+::\+L\+E\+G\+A\+L\+\_\+\+C\+O\+L\+L\+A\+P\+SE} or \hyperlink{a08956_a77c942fb03efb3b079a916e005729d94afc88837943f46ccbf0ef35d3fcf9c5b1}{Open\+Mesh\+::\+Decimater\+::\+Mod\+Base\+T\+::\+I\+L\+L\+E\+G\+A\+L\+\_\+\+C\+O\+L\+L\+A\+P\+SE}. In the algorithm the binary modules are evaluated first. If the evaluated collapse passes the test, then the non-\/binary module contributes to the decision step.

In some cases the module does not contribute anything to the decision engine of the decimater, but instead, e.\+g. simply collects information, while the decimater does it\textquotesingle{}s work. For instance the module \hyperlink{a08980}{Open\+Mesh\+::\+Decimater\+::\+Mod\+Prog\+MeshT} collects information from all collapses that have been done. This information can be used to generate progressive meshes as described in \char`\"{}\+Progressive meshes\char`\"{}, Hoppe, 1996.

Provided decimation modules(\+Binary\+: B, Continuous\+: C, Special\+: X)\+:


\begin{DoxyItemize}
\item \hyperlink{a08948}{Open\+Mesh\+::\+Decimater\+::\+Mod\+Aspect\+RatioT} (B,C)
\item \hyperlink{a08960}{Open\+Mesh\+::\+Decimater\+::\+Mod\+Edge\+LengthT} (B,C)
\item \hyperlink{a08964}{Open\+Mesh\+::\+Decimater\+::\+Mod\+HausdorffT} (B)
\item \hyperlink{a08968}{Open\+Mesh\+::\+Decimater\+::\+Mod\+Independent\+SetsT} (B)
\item \hyperlink{a08972}{Open\+Mesh\+::\+Decimater\+::\+Mod\+Normal\+DeviationT} (B,C)
\item \hyperlink{a08976}{Open\+Mesh\+::\+Decimater\+::\+Mod\+Normal\+FlippingT} (B)
\item \hyperlink{a08980}{Open\+Mesh\+::\+Decimater\+::\+Mod\+Prog\+MeshT} (X)
\item \hyperlink{a08988}{Open\+Mesh\+::\+Decimater\+::\+Mod\+QuadricT} (B,C)
\item \hyperlink{a08992}{Open\+Mesh\+::\+Decimater\+::\+Mod\+RoundnessT} (B,C)
\end{DoxyItemize}\hypertarget{a14878_DecimaterHnd}{}\paragraph{Module Handles}\label{a14878_DecimaterHnd}
Similar to properties the modules are represented outside the decimater by module handles. Before using the decimater a non-\/binary module must be registrated with the decimater.

See \hyperlink{a14878_DecimaterExa}{Basic Setup}.\hypertarget{a14878_DecimaterExa}{}\paragraph{Basic Setup}\label{a14878_DecimaterExa}
The following small example show the basic steps to setup up a decimater\+:


\begin{DoxyCodeInclude}
\textcolor{keyword}{using namespace }\hyperlink{a06210}{OpenMesh};

\textcolor{keyword}{typedef} \hyperlink{a08764}{TriMesh\_ArrayKernelT<>}               \hyperlink{a08764}{Mesh};
\textcolor{keyword}{typedef} Decimater::DecimaterT<Mesh>          Decimater;
\textcolor{keyword}{typedef} Decimater::ModQuadricT<Mesh>::Handle HModQuadric;

Mesh        mesh;             \textcolor{comment}{// a mesh object}
Decimater   decimater(mesh);  \textcolor{comment}{// a decimater object, connected to a mesh}
HModQuadric hModQuadric;      \textcolor{comment}{// use a quadric module}

decimater.add(hModQuadric); \textcolor{comment}{// register module at the decimater}
std::cout << decimater.module(hModQuadric).name() << std::endl; \textcolor{comment}{// module access}

\textcolor{comment}{/*}
\textcolor{comment}{ * since we need exactly one priority module (non-binary)}
\textcolor{comment}{ * we have to call set\_binary(false) for our priority module}
\textcolor{comment}{ * in the case of HModQuadric, unset\_max\_err() calls set\_binary(false) internally}
\textcolor{comment}{ */}
decimater.module(hModQuadric).unset\_max\_err();

decimater.initialize();
decimater.decimate();

\textcolor{comment}{// after decimation: remove decimated elements from the mesh}
mesh.garbage\_collection();
\end{DoxyCodeInclude}
 \hypertarget{subdivider_docu}{}\subsubsection{Sudivision Tools}\label{subdivider_docu}
\hypertarget{a14896_OM_Subdivider_Overview}{}\paragraph{Overview}\label{a14896_OM_Subdivider_Overview}
The Open\+Mesh library provides a few tools for uniform and adaptive subdivision\+:


\begin{DoxyEnumerate}
\item Uniform subdivision
\begin{DoxyEnumerate}
\item \hyperlink{a09220}{Open\+Mesh\+::\+Subdivider\+::\+Uniform\+::\+LoopT}
\item \hyperlink{a09240}{Open\+Mesh\+::\+Subdivider\+::\+Uniform\+::\+Sqrt3T}
\item \hyperlink{a09232}{Open\+Mesh\+::\+Subdivider\+::\+Uniform\+::\+Modified\+ButterflyT}
\item \hyperlink{a09236}{Open\+Mesh\+::\+Subdivider\+::\+Uniform\+::\+Interpolating\+Sqrt3\+L\+GT}
\item \hyperlink{a09176}{Open\+Mesh\+::\+Subdivider\+::\+Uniform\+::\+CompositeT}
\item \hyperlink{a09172}{Open\+Mesh\+::\+Subdivider\+::\+Uniform\+::\+Catmull\+ClarkT}
\item \hyperlink{a09228}{Open\+Mesh\+::\+Subdivider\+::\+Uniform\+::\+MidpointT}
\end{DoxyEnumerate}
\item Adaptive subdivision
\begin{DoxyEnumerate}
\item \hyperlink{a09080}{Open\+Mesh\+::\+Subdivider\+::\+Adaptive\+::\+CompositeT}
\end{DoxyEnumerate}
\item Simple subdivision
\begin{DoxyEnumerate}
\item \hyperlink{a09216}{Open\+Mesh\+::\+Subdivider\+::\+Uniform\+::\+Longest\+EdgeT}
\end{DoxyEnumerate}
\end{DoxyEnumerate}\hypertarget{a14896_OM_Subdivider_Usage}{}\paragraph{Usage}\label{a14896_OM_Subdivider_Usage}
The subdividers directly work on an \hyperlink{a06210}{Open\+Mesh}. The following example shows how to use them\+:


\begin{DoxyCode}
\textcolor{preprocessor}{#include <\hyperlink{a02315}{OpenMesh/Tools/Subdivider/Uniform/CatmullClarkT.hh}
      >}

\textcolor{comment}{// Initialize subdivider}
\hyperlink{a09172}{OpenMesh::Subdivider::Uniform::CatmullClarkT<PolyMesh>}
       catmull;

\textcolor{comment}{// Execute 3 subdivision steps}
catmull.\hyperlink{a09248_a4faaaf5cdd9273b4c28ef9f2a2e942ba}{attach}(mesh\_);
catmull( 3 );
catmull.\hyperlink{a09248_a5e43f1fde3bd9588b4265fe1d1be6a8d}{detach}();
\end{DoxyCode}
 \hypertarget{vdpm_docu}{}\subsubsection{View Dependent Progressive Meshes}\label{vdpm_docu}
The V\+D\+PM software is based on \href{http://www.postech.ac.kr/~leesy/ftp/gi01.pdf}{\tt \char`\"{}\+Truly Selective
\+Refinement of Progressive Meshes\char`\"{}, J. Kim and S. Lee, In Proc. Graphics Interface 2001}.

The library is located in {\ttfamily Open\+Mesh/\+Tools/\+V\+D\+P\+M/} and in {\ttfamily Open\+Mesh/\+Apps/\+V\+D\+Prog\+Mesh/} are demo applications\+:
\begin{DoxyEnumerate}
\item {\ttfamily mkbalancedpm} creates balanced progressive meshes
\item {\ttfamily vdpmanalyzer} takes a progressive mesh and generates a view dependent progressive mesh.
\item {\ttfamily vdpmsynthezier} is viewer for vdpm meshes.
\end{DoxyEnumerate}

\begin{DoxyRefDesc}{Todo}
\item[\hyperlink{a06164__todo000025}{Todo}]Complete V\+D\+PM documentation. \end{DoxyRefDesc}
\hypertarget{smoother_docu}{}\subsubsection{Smoother Tools}\label{smoother_docu}
\hypertarget{a14894_OM_Smoother_Overview}{}\paragraph{Overview}\label{a14894_OM_Smoother_Overview}
The Open\+Mesh library provides tools for smoothing Triangle-\/ and Polymeshes


\begin{DoxyEnumerate}
\item Smoother\+:
\begin{DoxyEnumerate}
\item \hyperlink{a09068}{Open\+Mesh\+::\+Smoother\+::\+SmootherT}
\item \hyperlink{a09064}{Open\+Mesh\+::\+Smoother\+::\+Laplace\+SmootherT}
\item \hyperlink{a09060}{Open\+Mesh\+::\+Smoother\+::\+Jacobi\+Laplace\+SmootherT}
\end{DoxyEnumerate}
\end{DoxyEnumerate}\hypertarget{a14894_OM_Smoother_Usage}{}\paragraph{Usage}\label{a14894_OM_Smoother_Usage}
The smoothers directly work on an \hyperlink{a06210}{Open\+Mesh}. The following example shows how to use them\+:


\begin{DoxyCode}
\textcolor{preprocessor}{#include <\hyperlink{a02276}{OpenMesh/Tools/Smoother/JacobiLaplaceSmootherT.hh}
      >}

\textcolor{comment}{// Initialize smoother with input mesh}
\hyperlink{a09060}{OpenMesh::Smoother::JacobiLaplaceSmootherT<MyMesh>} 
      smoother(mesh);

smoother.initialize( Tangential\_and\_Normal,   \textcolor{comment}{//Smooth direction}
                     C0)                      \textcolor{comment}{//Continuity}
  
\textcolor{comment}{// Execute 3 smooth steps}
smoother.smooth(3);
\end{DoxyCode}
\hypertarget{a14894_Options}{}\paragraph{Options}\label{a14894_Options}
\hypertarget{a14894_Continuity}{}\subparagraph{Continuity}\label{a14894_Continuity}
\begin{DoxyItemize}
\item C0\+: shape is continuous, but not the tangent \item C1\+: shape and tangent are continuous \item C2\+: preserves curvature\end{DoxyItemize}
\hypertarget{a14894_Component}{}\subparagraph{Component}\label{a14894_Component}
\begin{DoxyItemize}
\item Tangential\+: Smooth in tangential direction \item Normal\+: Smooth in normal direction \item Tangential\+\_\+and\+\_\+\+Normal\+: Smooth in tangential and normal direction\end{DoxyItemize}
\hypertarget{a14894_localError}{}\subparagraph{Local Error}\label{a14894_localError}
By default, this option is disabled. You can set local max. local errors (absolute or relative) via following functions\+: 
\begin{DoxyCode}
\textcolor{keywordtype}{void} \hyperlink{a09068_acd0b96d45f71d37584cd91e067397e7b}{OpenMesh::Smoother::SmootherT<Mesh>::set\_relative\_local\_error}
      (Scalar \_err);
\textcolor{keywordtype}{void} \hyperlink{a09068_aa4afc9ae6b9ce5f3fc1ea7372ce0b42f}{OpenMesh::Smoother::SmootherT<Mesh>::set\_absolute\_local\_error}
      (Scalar \_err);
\textcolor{keywordtype}{void} \hyperlink{a09068_aac72d74a6daf8c8fb24a0437f022dabb}{OpenMesh::Smoother::SmootherT<Mesh>::disable\_local\_error\_check}
      ();
\end{DoxyCode}
 \hypertarget{smarttagger_docu}{}\subsubsection{Smart Tagger}\label{smarttagger_docu}
The smart tagger can be used to tag vertices/halfedges/edges/faces on the mesh. It provides an O(1) reset function to untag all primitives at once.

Usage\+:


\begin{DoxyCode}
SmartTaggerVT< MeshType > tagger(mesh);

\textcolor{comment}{// Reset tagged flag on all vertices}
tagger.untag\_all();

\textcolor{comment}{// Check if something is tagged}
\textcolor{keywordtype}{bool} tag = tagger.is\_tagged(vh);

\textcolor{comment}{// Set tagged:}
tagger.set\_tag(vh);
\end{DoxyCode}


For details see \hyperlink{a09056}{Open\+Mesh\+::\+Smart\+TaggerT} \hypertarget{tutorial}{}\subsection{Tutorials (code examples)}\label{tutorial}
The Open\+Mesh mesh library is a powerful tool for handling polygonal meshes. Due to its inherent generative structure it allows the user to create mesh types which are custom tailored to the specific needs of the application. The user can either supply his own data structures for representing vertices, edges and faces or he can conveniently use the predefined structures of Open\+Mesh. Additionally Open\+Mesh offers dynamic properties allowing the user to attach and detach data to the mesh during runtime.

This document is supposed to introduce the basic concepts of Open\+Mesh.

In this tutorial we will introduce the Open\+Mesh library by means of simple examples. The first one just builds a polygonal mesh representing a cube and writes the result to standard output. The following examples develop a simple mesh smoother\+: Recall that the immediate neighbors of a vertex are called the 1-\/ring of this vertex. It is well known that a polygonal mesh can be smoothed by repeatedly replacing each vertex\textquotesingle{} position by the center of gravity (cog) of its 1-\/ring. The basic smoother will

\begin{DoxyItemize}
\item read a polygonal mesh from standard input, \item compute the cog of the 1-\/ring of each vertex, \item replace each vertex\textquotesingle{} position by its cog and finally, \item write the mesh to standard output.\end{DoxyItemize}

\begin{DoxyEnumerate}
\item \hyperlink{tutorial_build}{How to create your own project using Open\+Mesh} 
\item \hyperlink{tutorial_01}{First Steps -\/ Building a cube} 
\item \hyperlink{tutorial_02}{Using iterators and circulators} 
\item \hyperlink{tutorial_03}{Using (custom) properties} 
\item \hyperlink{tutorial_04}{Using S\+TL algorithms} 
\item \hyperlink{tutorial_05}{Using standard properties} 
\item \hyperlink{tutorial_06}{Using mesh attributes and traits} 
\item \hyperlink{tutorial_07}{Extending the mesh using traits} 
\item \hyperlink{tutorial_07b}{Deleting geometry elements} 
\item \hyperlink{tutorial_08}{Using I\+O\+::\+Options} 
\item \hyperlink{tutorial_09}{Storing custom properties} 
\end{DoxyEnumerate}\hypertarget{tutorial_build}{}\subsubsection{How to create your own project using Open\+Mesh}\label{tutorial_build}
In this tutorial we will explain, how to create a new project using Open\+Mesh and build it with the C\+Make build system. We assume, that you have already downloaded the Open\+Mesh source files as well as installed the C\+Make build tools.

There are quite few steps to follow to successfully add your own application to the build tree\+:

\begin{DoxyItemize}
\item Go to Open\+Mesh\+Root/src/\+Open\+Mesh/\+Apps and create a new directory, say \char`\"{}\+My\+Own\+Project\char`\"{} \item Now create a new file called \char`\"{}\+C\+Make\+Lists.\+txt\char`\"{} containing the following lines\+:\end{DoxyItemize}

\begin{DoxyCodeInclude}
include (plugin)
openflipper\_plugin ()
\end{DoxyCodeInclude}


(Remember to replace \char`\"{}\+My\+Project\+Name\char`\"{} with whatever you have chosen as your project\textquotesingle{}s name. Note\+: If you don\textquotesingle{}t want to use $\ast$.hh and $\ast$.cc as your C++ source file suffices, you\textquotesingle{}ll have to change this, too, because C\+Make won\textquotesingle{}t build your sources otherwise.

\begin{DoxyItemize}
\item Create your source files as for example explained in the previous tutorial (\hyperlink{tutorial_01}{First Steps -\/ Building a cube}) and save them in the same directory.\end{DoxyItemize}
\begin{DoxyItemize}
\item Add
\begin{DoxyCode}
add\_subdirectory (MyOwnProject) 
\end{DoxyCode}
 to Open\+Mesh\+Root/src/\+Open\+Mesh/\+Apps/\+C\+Make\+Lists.\+txt (note\+: You can either add this line right after the other projects or at the end of the file).\end{DoxyItemize}
\begin{DoxyItemize}
\item Create a directory called \char`\"{}build\char`\"{} in \hyperlink{a06210}{Open\+Mesh}\textquotesingle{}s root directory. Change to the newly created directory and call 
\begin{DoxyCode}
\hyperlink{a06182}{cmake} .. 
\end{DoxyCode}
 and
\begin{DoxyCode}
make 
\end{DoxyCode}
\end{DoxyItemize}
That\textquotesingle{}s all. Your project will now be built. \hypertarget{tutorial_01}{}\subsubsection{First Steps -\/ Building a cube}\label{tutorial_01}
This small example shows\+: \begin{DoxyItemize}
\item How to declare your type {\ttfamily My\+Mesh}, \item How to add vertices and faces to a mesh, \item How to write a mesh using the IO functions.\end{DoxyItemize}
For each program the first step is to define your type {\ttfamily My\+Mesh}. Open\+Mesh supports general polygonal meshes (faces are polygons with varying number of vertices) as well as specialized triangle meshes (all faces are triangles). In this example we want to build a cube from six quadrangles, therefore we choose the polygonal mesh.

Open\+Mesh also supports different mesh kernels, specifying how all the vertices, edges, and faces are stored internally (see also \hyperlink{a06169}{Mesh Kernels}). However, the storage must provide an array like interface. For the tutorial we use the supplied Array\+Kernel. The predefined combinations of Tri\+Mesh/\+Poly\+Mesh and the kernel are contained in {\ttfamily Open\+Mesh/src/\+Open\+Mesh/\+Core/\+Mesh}, we use the {\ttfamily Poly\+Mesh\+\_\+\+Array\+KernelT}.

 
\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#include <OpenMesh/Core/Mesh/PolyMesh\_ArrayKernelT.hh>}
\textcolor{keyword}{typedef} \hyperlink{a08772}{OpenMesh::PolyMesh\_ArrayKernelT<>}  MyMesh;

\end{DoxyCodeInclude}


Now since we have declared our type {\ttfamily My\+Mesh}, we only have to add 8 vertices and 6 quadrangles to build a cube. Adding a vertex is done using the {\ttfamily add\+\_\+vertex} method. It gets a coordinate and returns a handle to the inserted vertex. We store all handles in an array, since we need them for specifying the faces.


\begin{DoxyCodeInclude}
  vhandle[0] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(-1, -1,  1));
  vhandle[1] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}( 1, -1,  1));
  vhandle[2] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}( 1,  1,  1));
  vhandle[3] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(-1,  1,  1));

\end{DoxyCodeInclude}


~\newline
In order to add a face to the mesh, we have to build a vector holding the handles to the face\textquotesingle{}s vertices. This vector is passed to the {\ttfamily add\+\_\+face} method. The following block will create a face from the first four vertices\+:


\begin{DoxyCodeInclude}
  std::vector<MyMesh::VertexHandle>  face\_vhandles;

  face\_vhandles.clear();
  face\_vhandles.push\_back(vhandle[0]);
  face\_vhandles.push\_back(vhandle[1]);
  face\_vhandles.push\_back(vhandle[2]);
  face\_vhandles.push\_back(vhandle[3]);
  mesh.add\_face(face\_vhandles);

\end{DoxyCodeInclude}


~\newline
The orientation of the face is defined by the order in which the vertices are given\+: If you look at the frontfacing side of the polygon, then the vertices are in counter-\/clockwise order.

After creating all of the six faces, we want to write the resulting mesh to standard output. Open\+Mesh provides some basic input/output methods in the namespace \hyperlink{a06213}{Open\+Mesh\+::\+IO}\+:


\begin{DoxyCodeInclude}
    \textcolor{keywordflow}{if} ( !\hyperlink{a06213_a18286a792ebf896872f5e26182fc5c7b}{OpenMesh::IO::write\_mesh}(mesh, \textcolor{stringliteral}{"output.off"}) )

\end{DoxyCodeInclude}


~\newline
To use the IO facility of Open\+Mesh make sure that the include \hyperlink{a01877_source}{Mesh\+I\+O.\+hh} is included first.

 
\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#include <OpenMesh/Core/IO/MeshIO.hh>}
\textcolor{preprocessor}{#include <OpenMesh/Core/Mesh/PolyMesh\_ArrayKernelT.hh>}

\end{DoxyCodeInclude}


~\newline
The complete source looks like this\+:


\begin{DoxyCodeInclude}
\textcolor{comment}{/* ========================================================================= *}
\textcolor{comment}{ *                                                                           *}
\textcolor{comment}{ *                               OpenMesh                                    *}
\textcolor{comment}{ *           Copyright (c) 2001-2015, RWTH-Aachen University                 *}
\textcolor{comment}{ *           Department of Computer Graphics and Multimedia                  *}
\textcolor{comment}{ *                          All rights reserved.                             *}
\textcolor{comment}{ *                            www.openmesh.org                               *}
\textcolor{comment}{ *                                                                           *}
\textcolor{comment}{ *---------------------------------------------------------------------------*}
\textcolor{comment}{ * This file is part of OpenMesh.                                            *}
\textcolor{comment}{ *---------------------------------------------------------------------------*}
\textcolor{comment}{ *                                                                           *}
\textcolor{comment}{ * Redistribution and use in source and binary forms, with or without        *}
\textcolor{comment}{ * modification, are permitted provided that the following conditions        *}
\textcolor{comment}{ * are met:                                                                  *}
\textcolor{comment}{ *                                                                           *}
\textcolor{comment}{ * 1. Redistributions of source code must retain the above copyright notice, *}
\textcolor{comment}{ *    this list of conditions and the following disclaimer.                  *}
\textcolor{comment}{ *                                                                           *}
\textcolor{comment}{ * 2. Redistributions in binary form must reproduce the above copyright      *}
\textcolor{comment}{ *    notice, this list of conditions and the following disclaimer in the    *}
\textcolor{comment}{ *    documentation and/or other materials provided with the distribution.   *}
\textcolor{comment}{ *                                                                           *}
\textcolor{comment}{ * 3. Neither the name of the copyright holder nor the names of its          *}
\textcolor{comment}{ *    contributors may be used to endorse or promote products derived from   *}
\textcolor{comment}{ *    this software without specific prior written permission.               *}
\textcolor{comment}{ *                                                                           *}
\textcolor{comment}{ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *}
\textcolor{comment}{ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *}
\textcolor{comment}{ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *}
\textcolor{comment}{ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *}
\textcolor{comment}{ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *}
\textcolor{comment}{ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *}
\textcolor{comment}{ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *}
\textcolor{comment}{ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *}
\textcolor{comment}{ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *}
\textcolor{comment}{ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *}
\textcolor{comment}{ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *}
\textcolor{comment}{ *                                                                           *}
\textcolor{comment}{ * ========================================================================= */}


\textcolor{preprocessor}{#include <iostream>}
\textcolor{comment}{// -------------------- OpenMesh}
\textcolor{preprocessor}{#include <OpenMesh/Core/IO/MeshIO.hh>}
\textcolor{preprocessor}{#include <OpenMesh/Core/Mesh/PolyMesh\_ArrayKernelT.hh>}


\textcolor{comment}{// ----------------------------------------------------------------------------}

\textcolor{keyword}{typedef} \hyperlink{a08772}{OpenMesh::PolyMesh\_ArrayKernelT<>}  MyMesh;


\textcolor{comment}{// ----------------------------------------------------------------------------}
\textcolor{comment}{// Build a simple cube and write it to std::cout}
  
\textcolor{keywordtype}{int} main()
\{
  MyMesh mesh;

  \textcolor{comment}{// generate vertices}

  \hyperlink{a08776_a0fc18e13d70825938274e3faf7b55e01}{MyMesh::VertexHandle} vhandle[8];

  vhandle[0] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(-1, -1,  1));
  vhandle[1] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}( 1, -1,  1));
  vhandle[2] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}( 1,  1,  1));
  vhandle[3] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(-1,  1,  1));
  vhandle[4] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(-1, -1, -1));
  vhandle[5] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}( 1, -1, -1));
  vhandle[6] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}( 1,  1, -1));
  vhandle[7] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(-1,  1, -1));


  \textcolor{comment}{// generate (quadrilateral) faces}

  std::vector<MyMesh::VertexHandle>  face\_vhandles;

  face\_vhandles.clear();
  face\_vhandles.push\_back(vhandle[0]);
  face\_vhandles.push\_back(vhandle[1]);
  face\_vhandles.push\_back(vhandle[2]);
  face\_vhandles.push\_back(vhandle[3]);
  mesh.add\_face(face\_vhandles);
 
  face\_vhandles.clear();
  face\_vhandles.push\_back(vhandle[7]);
  face\_vhandles.push\_back(vhandle[6]);
  face\_vhandles.push\_back(vhandle[5]);
  face\_vhandles.push\_back(vhandle[4]);
  mesh.add\_face(face\_vhandles);

  face\_vhandles.clear();
  face\_vhandles.push\_back(vhandle[1]);
  face\_vhandles.push\_back(vhandle[0]);
  face\_vhandles.push\_back(vhandle[4]);
  face\_vhandles.push\_back(vhandle[5]);
  mesh.add\_face(face\_vhandles);

  face\_vhandles.clear();
  face\_vhandles.push\_back(vhandle[2]);
  face\_vhandles.push\_back(vhandle[1]);
  face\_vhandles.push\_back(vhandle[5]);
  face\_vhandles.push\_back(vhandle[6]);
  mesh.add\_face(face\_vhandles);

  face\_vhandles.clear();
  face\_vhandles.push\_back(vhandle[3]);
  face\_vhandles.push\_back(vhandle[2]);
  face\_vhandles.push\_back(vhandle[6]);
  face\_vhandles.push\_back(vhandle[7]);
  mesh.add\_face(face\_vhandles);

  face\_vhandles.clear();
  face\_vhandles.push\_back(vhandle[0]);
  face\_vhandles.push\_back(vhandle[3]);
  face\_vhandles.push\_back(vhandle[7]);
  face\_vhandles.push\_back(vhandle[4]);
  mesh.add\_face(face\_vhandles);


  \textcolor{comment}{// write mesh to output.obj}
  \textcolor{keywordflow}{try}
  \{
    \textcolor{keywordflow}{if} ( !\hyperlink{a06213_a18286a792ebf896872f5e26182fc5c7b}{OpenMesh::IO::write\_mesh}(mesh, \textcolor{stringliteral}{"output.off"}) )
    \{
      std::cerr << \textcolor{stringliteral}{"Cannot write mesh to file 'output.off'"} << std::endl;
      \textcolor{keywordflow}{return} 1;
    \}
  \}
  \textcolor{keywordflow}{catch}( std::exception& x )
  \{
    std::cerr << x.what() << std::endl;
    \textcolor{keywordflow}{return} 1;
  \}

  \textcolor{keywordflow}{return} 0;
\}
\end{DoxyCodeInclude}
 \hypertarget{tutorial_02}{}\subsubsection{Using iterators and circulators}\label{tutorial_02}
This examples shows\+:


\begin{DoxyItemize}
\item How to use iterators,
\item How to use circulators.
\end{DoxyItemize}

This example is the first version of the simple mesh smoother. Here we will introduce {\itshape iterators} and {\itshape circulators}. These two concepts provide functionality to linearly enumerate e.\+g. all vertices of a mesh, and to circulate around a vertex, i.\+e. to enumerate all its one-\/ring neighbors. For a more detailed description, see \hyperlink{mesh_iterators}{Mesh Iterators and Circulators}.

First we have to define the mesh type we want to use. This time we use a triangle mesh instead of a polygonal mesh\+:

 
\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#include <OpenMesh/Core/Mesh/TriMesh\_ArrayKernelT.hh>}
\textcolor{keyword}{typedef} \hyperlink{a08764}{OpenMesh::TriMesh\_ArrayKernelT<>}  MyMesh;

\end{DoxyCodeInclude}


~\newline
We read the mesh to be smoothed from a file\+:


\begin{DoxyCodeInclude}
  \textcolor{keywordflow}{if} ( ! \hyperlink{a06213_ac417960ec28ffdd7e7003a2b1ebb2d1c}{OpenMesh::IO::read\_mesh}(mesh, argv[2]) )

\end{DoxyCodeInclude}


~\newline
One smoothing iteration is done in two steps\+: 
\begin{DoxyEnumerate}
\item For each vertex\+: calculate the barycenter of its one-\/ring neighbors. 
\item For each vertex\+: move the vertex to the computed barycenter. 
\end{DoxyEnumerate}

This can easily be implemented using vertex iterators. The mesh provides begin and end iterators by {\ttfamily vertices\+\_\+begin()} and {\ttfamily vertices\+\_\+end()}.


\begin{DoxyCodeInclude}
  MyMesh::VertexIter          v\_it, v\_end(mesh.vertices\_end());
    \textcolor{keywordflow}{for} (v\_it=mesh.vertices\_begin(); v\_it!=v\_end; ++v\_it)

\end{DoxyCodeInclude}


~\newline
For calculating the barycenter, we have to iterate through the one-\/ring neighborhood of the current vertex. This functionality is provided by the {\ttfamily Vertex\+Vertex\+Iter}\+:

 
\begin{DoxyCodeInclude}
  \hyperlink{a08776_adc7d422e2ce13141e8291f7d29f7ecef}{MyMesh::VertexVertexIter}    vv\_it;
      \textcolor{keywordflow}{for} (vv\_it=mesh.vv\_iter( *v\_it ); vv\_it.is\_valid(); ++vv\_it)

\end{DoxyCodeInclude}


~\newline
Now we can calculate the barycenters for each vertex and store them in the array {\ttfamily cogs}\+:

 
\begin{DoxyCodeInclude}
  std::vector<MyMesh::Point>  cogs;
    \textcolor{keywordflow}{for} (v\_it=mesh.vertices\_begin(); v\_it!=v\_end; ++v\_it)
    \{
      cog[0] = cog[1] = cog[2] = valence = 0.0;
      
      \textcolor{keywordflow}{for} (vv\_it=mesh.vv\_iter( *v\_it ); vv\_it.is\_valid(); ++vv\_it)
      \{
        cog += mesh.point( *vv\_it );
        ++valence;
      \}

      cogs.push\_back(cog / valence);
    \}

\end{DoxyCodeInclude}


~\newline
After we have calculated the barycenters all that is left to do is to move the vertices to the corresponding barycenters. The complete source code is listed below.


\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#include <iostream>}
\textcolor{preprocessor}{#include <vector>}
\textcolor{comment}{// -------------------- OpenMesh}
\textcolor{preprocessor}{#include <OpenMesh/Core/IO/MeshIO.hh>}
\textcolor{preprocessor}{#include <OpenMesh/Core/Mesh/TriMesh\_ArrayKernelT.hh>}

\textcolor{keyword}{typedef} \hyperlink{a08764}{OpenMesh::TriMesh\_ArrayKernelT<>}  MyMesh;


\textcolor{keywordtype}{int} main(\textcolor{keywordtype}{int} argc, \textcolor{keywordtype}{char} **argv)
\{
  MyMesh  mesh;


  \textcolor{comment}{// check command line options}
  \textcolor{keywordflow}{if} (argc != 4) 
  \{
    std::cerr << \textcolor{stringliteral}{"Usage:  "} << argv[0] << \textcolor{stringliteral}{" #iterations infile outfile\(\backslash\)n"};
    \textcolor{keywordflow}{return} 1;
  \}


  \textcolor{comment}{// read mesh from stdin}
  \textcolor{keywordflow}{if} ( ! \hyperlink{a06213_ac417960ec28ffdd7e7003a2b1ebb2d1c}{OpenMesh::IO::read\_mesh}(mesh, argv[2]) )
  \{
    std::cerr << \textcolor{stringliteral}{"Error: Cannot read mesh from "} << argv[2] << std::endl;
    \textcolor{keywordflow}{return} 1;
  \}


  \textcolor{comment}{// this vector stores the computed centers of gravity}
  std::vector<MyMesh::Point>  cogs;
  std::vector<MyMesh::Point>::iterator cog\_it;
  cogs.reserve(mesh.n\_vertices());


  \textcolor{comment}{// smoothing mesh argv[1] times}
  MyMesh::VertexIter          v\_it, v\_end(mesh.vertices\_end());
  \hyperlink{a08776_adc7d422e2ce13141e8291f7d29f7ecef}{MyMesh::VertexVertexIter}    vv\_it;
  \hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}               cog;
  \hyperlink{a08776_a15372f27edf521d8e9028e2abccae342}{MyMesh::Scalar}              valence;
  \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int}                i, N(atoi(argv[1]));


  \textcolor{keywordflow}{for} (i=0; i < N; ++i)
  \{
    cogs.clear();
    \textcolor{keywordflow}{for} (v\_it=mesh.vertices\_begin(); v\_it!=v\_end; ++v\_it)
    \{
      cog[0] = cog[1] = cog[2] = valence = 0.0;
      
      \textcolor{keywordflow}{for} (vv\_it=mesh.vv\_iter( *v\_it ); vv\_it.is\_valid(); ++vv\_it)
      \{
        cog += mesh.point( *vv\_it );
        ++valence;
      \}

      cogs.push\_back(cog / valence);
    \}
    
    \textcolor{keywordflow}{for} (v\_it=mesh.vertices\_begin(), cog\_it=cogs.begin(); 
         v\_it!=v\_end; ++v\_it, ++cog\_it)
      \textcolor{keywordflow}{if} ( !mesh.is\_boundary( *v\_it ) )
        mesh.set\_point( *v\_it, *cog\_it );
  \}


  \textcolor{comment}{// write mesh to stdout}
  \textcolor{keywordflow}{if} ( ! \hyperlink{a06213_a18286a792ebf896872f5e26182fc5c7b}{OpenMesh::IO::write\_mesh}(mesh, argv[3]) )
  \{
    std::cerr << \textcolor{stringliteral}{"Error: cannot write mesh to "} << argv[3] << std::endl;
    \textcolor{keywordflow}{return} 1;
  \}

  \textcolor{keywordflow}{return} 0;
\}
\end{DoxyCodeInclude}
 \hypertarget{tutorial_03}{}\subsubsection{Using (custom) properties}\label{tutorial_03}
This examples shows\+:
\begin{DoxyItemize}
\item How to add and remove custom properties
\item How to get and set the value of a custom property
\end{DoxyItemize}

In the last example we computed the barycenter of each vertex\textquotesingle{} neighborhood and stored it in an array. It would be more convenient and less error-\/prone if we could store this data in the mesh and let Open\+Mesh manage the data. It would be even more helpful if we could attach such properties dynamically to the mesh.

Custom properties can be conveniently created and attached to meshes with the following functions\+:
\begin{DoxyItemize}
\item \hyperlink{a08900_a879b7250e5270fbaee884ec1e0af0a4f}{make\+Temporary\+Property()} creates a property that is temporary to the current scope.
\item \hyperlink{a08900_a6532b67cfcf20a1a0754651f26b7179f}{get\+Or\+Make\+Property()} is used for creating and accessing permanent named properties on a mesh.
\item \hyperlink{a08900_a28070d2a453498769b94d57953420785}{get\+Property()} is used for accessing an existing permanent named property on a mesh.
\end{DoxyItemize}

All three functions take two template arguments\+:
\begin{DoxyItemize}
\item First, the type of the mesh element that the property is attached to (i.\+e. \hyperlink{a08696}{Open\+Mesh\+::\+Vertex\+Handle}, \hyperlink{a08700}{Open\+Mesh\+::\+Halfedge\+Handle}, \hyperlink{a08704}{Open\+Mesh\+::\+Edge\+Handle}, or \hyperlink{a08708}{Open\+Mesh\+::\+Face\+Handle}).
\item Second, the type of the property value that is attached to each element (e.\+g., {\ttfamily int}, {\ttfamily double}, etc.).
\end{DoxyItemize}

All three functions return a handle object (of type \hyperlink{a08900}{Open\+Mesh\+::\+Property\+Manager}) that manages the lifetime of the property and provides read / write access to its values.

In this example, we will store the {\ttfamily cog} value (see previous example) in a vertex property instead of keeping it in a separate array. To do so, we first add a (temporary) property of the desired element type (\hyperlink{a08696}{Open\+Mesh\+::\+Vertex\+Handle}) and value type ({\ttfamily My\+Mesh\+::\+Point}) to the mesh\+:

 
\begin{DoxyCodeInclude}
      \textcolor{keyword}{auto} cog = OpenMesh::makeTemporaryProperty<OpenMesh::VertexHandle, MyMesh::Point>(mesh);

\end{DoxyCodeInclude}


Enough memory is allocated to hold as many values of {\ttfamily My\+Mesh\+::\+Point} as there are vertices. All insert and delete operations on the mesh are synchronized with the attached properties.

Once the property is created, we can use it to compute the centers of the neighborhood of each vertex\+:


\begin{DoxyCodeInclude}
          \textcolor{keywordflow}{for} (\textcolor{keyword}{const} \textcolor{keyword}{auto}& vh : mesh.vertices()) \{
              cog[vh] = \{0,0,0\};
              \textcolor{keywordtype}{int} valence = 0;
              \textcolor{comment}{// Iterate over all 1-ring vertices around vh}
              \textcolor{keywordflow}{for} (\textcolor{keyword}{const} \textcolor{keyword}{auto}& vvh : mesh.vv\_range(vh)) \{
                  cog[vh] += mesh.point(vvh);
                  ++valence;
              \}
              cog[vh] /= valence;
          \}

\end{DoxyCodeInclude}


Finally, we set the new position for each vertex\+:


\begin{DoxyCodeInclude}
          \textcolor{keywordflow}{for} (\textcolor{keyword}{const} \textcolor{keyword}{auto}& vh : mesh.vertices()) \{
              mesh.point(vh) = cog[vh];
          \}

\end{DoxyCodeInclude}
 



Since we chose to use \hyperlink{a08900_a879b7250e5270fbaee884ec1e0af0a4f}{make\+Temporary\+Property()}, the created property is automatically removed from the mesh as soon as we leave the scope of the associated handle variable {\ttfamily cog}.

If, instead, a property is desired to survive its local scope, it should be created with using \hyperlink{a08900_a6532b67cfcf20a1a0754651f26b7179f}{get\+Or\+Make\+Property()}. In that case, the property must be given a name that can later be used to retrieve the property. For example\+:


\begin{DoxyCode}
\textcolor{keyword}{auto} face\_area = OpenMesh::makeTemporaryProperty<OpenMesh::FaceHandle, double>(mesh, \textcolor{stringliteral}{'face\_area'});
\end{DoxyCode}


At a later time, we can use the \hyperlink{a08900_a28070d2a453498769b94d57953420785}{get\+Property()} function to obtain a handle to a property that was previously created by refering to its name\+: 
\begin{DoxyCode}
\textcolor{keywordflow}{try} \{
    \textcolor{keyword}{auto} face\_area = OpenMesh::getProperty<OpenMesh::FaceHandle, double>(mesh, \textcolor{stringliteral}{'face\_area'});
    \textcolor{comment}{// Use the face\_area property.}
\}
\textcolor{keywordflow}{catch} (\textcolor{keyword}{const} std::runtime\_error& e) \{
    \textcolor{comment}{// Property not found. Handle the error here.}
\}
\end{DoxyCode}
 



The functions \hyperlink{a08900_a879b7250e5270fbaee884ec1e0af0a4f}{make\+Temporary\+Property()}, \hyperlink{a08900_a6532b67cfcf20a1a0754651f26b7179f}{get\+Or\+Make\+Property()}, and \hyperlink{a08900_a28070d2a453498769b94d57953420785}{get\+Property()} are the convenient high-\/level interface for creating and accessing mesh properties.

Beneath these convenience functions, there is also a low-\/level property interface where handle and property lifetime must be managed manually. This interface is accessed through a mesh\textquotesingle{}s add\+\_\+property(), remove\+\_\+property(), and property() functions and several property handle classes (\hyperlink{a08876}{Open\+Mesh\+::\+V\+Prop\+HandleT}, \hyperlink{a08880}{Open\+Mesh\+::\+H\+Prop\+HandleT}, \hyperlink{a08884}{Open\+Mesh\+::\+E\+Prop\+HandleT}, \hyperlink{a08888}{Open\+Mesh\+::\+F\+Prop\+HandleT}, \hyperlink{a08892}{Open\+Mesh\+::\+M\+Prop\+HandleT}). 



Below is the complete source code\+:


\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#include <OpenMesh/Core/IO/MeshIO.hh>}
\textcolor{preprocessor}{#include <OpenMesh/Core/Mesh/TriMesh\_ArrayKernelT.hh>}
\textcolor{preprocessor}{#include <OpenMesh/Core/Utils/PropertyManager.hh>}

\textcolor{preprocessor}{#include <iostream>}
\textcolor{preprocessor}{#include <vector>}

\textcolor{keyword}{using} MyMesh = \hyperlink{a08764}{OpenMesh::TriMesh\_ArrayKernelT<>};

\textcolor{keywordtype}{int} main(\textcolor{keywordtype}{int} argc, \textcolor{keywordtype}{char}** argv)
\{
    \textcolor{comment}{// Read command line options}
    MyMesh mesh;
    \textcolor{keywordflow}{if} (argc != 4) \{
        std::cerr << \textcolor{stringliteral}{"Usage: "} << argv[0] << \textcolor{stringliteral}{" #iterations infile outfile"} << std::endl;
        \textcolor{keywordflow}{return} 1;
    \}
    \textcolor{keyword}{const} \textcolor{keywordtype}{int} iterations = argv[1];
    \textcolor{keyword}{const} std::string infile = argv[2];
    \textcolor{keyword}{const} std::string outfile = argv[3];
    
    \textcolor{comment}{// Read mesh file}
    \textcolor{keywordflow}{if} (!\hyperlink{a06213_ac417960ec28ffdd7e7003a2b1ebb2d1c}{OpenMesh::IO::read\_mesh}(mesh, infile)) \{
        std::cerr << \textcolor{stringliteral}{"Error: Cannot read mesh from "} << infile << std::endl;
        \textcolor{keywordflow}{return} 1;
    \}

    \{
      \textcolor{comment}{// Add a vertex property storing the computed centers of gravity}
      \textcolor{keyword}{auto} cog = OpenMesh::makeTemporaryProperty<OpenMesh::VertexHandle, MyMesh::Point>(mesh);

      \textcolor{comment}{// Smooth the mesh several times}
      \textcolor{keywordflow}{for} (\textcolor{keywordtype}{int} i = 0; i < iterations; ++i) \{
          \textcolor{comment}{// Iterate over all vertices to compute centers of gravity}
          \textcolor{keywordflow}{for} (\textcolor{keyword}{const} \textcolor{keyword}{auto}& vh : mesh.vertices()) \{
              cog[vh] = \{0,0,0\};
              \textcolor{keywordtype}{int} valence = 0;
              \textcolor{comment}{// Iterate over all 1-ring vertices around vh}
              \textcolor{keywordflow}{for} (\textcolor{keyword}{const} \textcolor{keyword}{auto}& vvh : mesh.vv\_range(vh)) \{
                  cog[vh] += mesh.point(vvh);
                  ++valence;
              \}
              cog[vh] /= valence;
          \}
          \textcolor{comment}{// Move all vertices to the previously computed positions}
          \textcolor{keywordflow}{for} (\textcolor{keyword}{const} \textcolor{keyword}{auto}& vh : mesh.vertices()) \{
              mesh.point(vh) = cog[vh];
          \}
      \}
    \} \textcolor{comment}{// The cog vertex property is removed from the mesh at the end of this scope}
    
    \textcolor{comment}{// Write mesh file}
    \textcolor{keywordflow}{if} (!\hyperlink{a06213_ac417960ec28ffdd7e7003a2b1ebb2d1c}{OpenMesh::IO::read\_mesh}(mesh, outfile)) \{
        std::cerr << \textcolor{stringliteral}{"Error: Cannot write mesh to "} << outfile << std::endl;
        \textcolor{keywordflow}{return} 1;
    \}
\}
\end{DoxyCodeInclude}
 \hypertarget{tutorial_04}{}\subsubsection{Using S\+TL algorithms}\label{tutorial_04}
Since the Open\+Mesh iterators are (almost) conformant to S\+TL iterators, one can apply the S\+TL algorithms on meshes. The following example shows how to use the S\+TL {\ttfamily for\+\_\+each} construct, since it is easier to read and may be more efficient than hand-\/written loops.

We will define a class which provides the smoothing algorithm, hence define a reusable component. The class must be template class because there is no such thing as a class Open\+Mesh, but many different types of Open\+Mesh\+:

 
\begin{DoxyCodeInclude}
\textcolor{keyword}{template} <\textcolor{keyword}{class} Mesh> \textcolor{keyword}{class }SmootherT

\end{DoxyCodeInclude}


The class SmootherT has two functors, one that computes the barycenter for a given vertex, and a second that sets the vertex position to the corresponding barycenter. A functor is simply a class with a function {\ttfamily operator()(...)}. The first functor {\ttfamily Compute\+C\+OG} computes the barycenter and stores it in a custom vertex property {\ttfamily cog\+\_\+\+:} 


\begin{DoxyCodeInclude}
    \textcolor{keywordtype}{void} operator()(\textcolor{keyword}{const} \textcolor{keyword}{typename} \hyperlink{a08776_a0fc18e13d70825938274e3faf7b55e01}{Mesh::VertexHandle}& \_vh)
    \{
      \textcolor{keyword}{typename} \hyperlink{a08776_adc7d422e2ce13141e8291f7d29f7ecef}{Mesh::VertexVertexIter}  vv\_it;
      \textcolor{keyword}{typename} \hyperlink{a08776_a15372f27edf521d8e9028e2abccae342}{Mesh::Scalar}            valence(0.0);
    
      mesh\_.property(cog\_, \_vh) = \textcolor{keyword}{typename} \hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{Mesh::Point}(0.0, 0.0, 0.0);

      \textcolor{keywordflow}{for} (vv\_it=mesh\_.vv\_iter(\_vh); vv\_it.is\_valid(); ++vv\_it)
      \{
        mesh\_.property(cog\_, \_vh) += mesh\_.point( *vv\_it );
        ++valence;
      \}

      mesh\_.property(cog\_, \_vh ) /= valence;
    \}

\end{DoxyCodeInclude}


Note, that {\ttfamily Compute\+C\+OG} needs to have access to the mesh object and the property handle. Here, both are references to member variables of the smoother object.

The second functor {\ttfamily class} {\ttfamily Set\+C\+OG}, which sets the vertex position, is constructed analogical.

Using these functors and {\ttfamily std\+::for\+\_\+each} from the S\+TL the smoothing algorithm can be realized in a member function of {\ttfamily SmootherT\+:} 

 
\begin{DoxyCodeInclude}
  \textcolor{keywordtype}{void} smooth(\textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} \_iterations)
  \{
    \textcolor{keywordflow}{for} (\textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} i=0; i < \_iterations; ++i)
    \{
      std::for\_each(mesh\_.vertices\_begin(), 
                    mesh\_.vertices\_end(), 
                    ComputeCOG(mesh\_, cog\_));

      std::for\_each(mesh\_.vertices\_begin(), 
                    mesh\_.vertices\_end(), 
                    SetCOG(mesh\_, cog\_));
    \}
  \}

\end{DoxyCodeInclude}


~\newline
The complete example looks like this\+:


\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#include <algorithm>}
\textcolor{preprocessor}{#include <OpenMesh/Core/Utils/Property.hh>}

\textcolor{preprocessor}{#ifndef DOXY\_IGNORE\_THIS}

\textcolor{keyword}{template} <\textcolor{keyword}{class} Mesh> \textcolor{keyword}{class }SmootherT
\{
\textcolor{keyword}{public}:

  \textcolor{keyword}{typedef} \textcolor{keyword}{typename} \hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{Mesh::Point}            cog\_t;
  \textcolor{keyword}{typedef} \hyperlink{a08876}{OpenMesh::VPropHandleT< cog\_t >} Property\_cog;

\textcolor{keyword}{public}:

  \textcolor{comment}{// construct with a given mesh}
  \textcolor{keyword}{explicit} SmootherT(Mesh& \_mesh) 
    : mesh\_(\_mesh)
  \{ 
    mesh\_.add\_property( cog\_ );
  \}

  ~SmootherT()
  \{
    mesh\_.remove\_property( cog\_ );
  \}

  \textcolor{comment}{// smooth mesh \_iterations times}
  \textcolor{keywordtype}{void} smooth(\textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} \_iterations)
  \{
    \textcolor{keywordflow}{for} (\textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} i=0; i < \_iterations; ++i)
    \{
      std::for\_each(mesh\_.vertices\_begin(), 
                    mesh\_.vertices\_end(), 
                    ComputeCOG(mesh\_, cog\_));

      std::for\_each(mesh\_.vertices\_begin(), 
                    mesh\_.vertices\_end(), 
                    SetCOG(mesh\_, cog\_));
    \}
  \}


\textcolor{keyword}{private}:


  \textcolor{comment}{//--- private classes ---}

  \textcolor{keyword}{class }ComputeCOG
  \{
  \textcolor{keyword}{public}:
    ComputeCOG(Mesh& \_mesh, Property\_cog& \_cog) 
      : mesh\_(\_mesh), cog\_(\_cog)
    \{\}

    \textcolor{keywordtype}{void} operator()(\textcolor{keyword}{const} \textcolor{keyword}{typename} \hyperlink{a08776_a0fc18e13d70825938274e3faf7b55e01}{Mesh::VertexHandle}& \_vh)
    \{
      \textcolor{keyword}{typename} \hyperlink{a08776_adc7d422e2ce13141e8291f7d29f7ecef}{Mesh::VertexVertexIter}  vv\_it;
      \textcolor{keyword}{typename} \hyperlink{a08776_a15372f27edf521d8e9028e2abccae342}{Mesh::Scalar}            valence(0.0);
    
      mesh\_.property(cog\_, \_vh) = \textcolor{keyword}{typename} \hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{Mesh::Point}(0.0, 0.0, 0.0);

      \textcolor{keywordflow}{for} (vv\_it=mesh\_.vv\_iter(\_vh); vv\_it.is\_valid(); ++vv\_it)
      \{
        mesh\_.property(cog\_, \_vh) += mesh\_.point( *vv\_it );
        ++valence;
      \}

      mesh\_.property(cog\_, \_vh ) /= valence;
    \}

  \textcolor{keyword}{private}:
    Mesh&         mesh\_;
    Property\_cog& cog\_;
  \};


  \textcolor{keyword}{class }SetCOG
  \{
  \textcolor{keyword}{public}:
    SetCOG(Mesh& \_mesh, Property\_cog& \_cog) 
      : mesh\_(\_mesh), cog\_(\_cog)
    \{\}

    \textcolor{keywordtype}{void} operator()(\textcolor{keyword}{const} \textcolor{keyword}{typename} \hyperlink{a08776_a0fc18e13d70825938274e3faf7b55e01}{Mesh::VertexHandle}& \_vh)
    \{

      \textcolor{keywordflow}{if} (!mesh\_.is\_boundary(\_vh))
        mesh\_.set\_point( \_vh, mesh\_.property(cog\_, \_vh) );
    \}

  \textcolor{keyword}{private}:

    Mesh&         mesh\_;
    Property\_cog& cog\_;
  \};


  \textcolor{comment}{//--- private elements ---}

  Mesh&        mesh\_;
  Property\_cog cog\_;
\};

\textcolor{preprocessor}{#endif}
\end{DoxyCodeInclude}


~\newline
and


\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#include <iostream>}
\textcolor{preprocessor}{#include <vector>}
\textcolor{comment}{// -------------------- OpenMesh}
\textcolor{preprocessor}{#include <OpenMesh/Core/IO/MeshIO.hh>}
\textcolor{preprocessor}{#include <OpenMesh/Core/Mesh/TriMesh\_ArrayKernelT.hh>}
\textcolor{comment}{// -------------------- }
\textcolor{preprocessor}{#include "smooth\_algo.hh"}


\textcolor{comment}{// ----------------------------------------------------------------------------}

\textcolor{preprocessor}{#ifndef DOXY\_IGNORE\_THIS}

\textcolor{keyword}{struct }\hyperlink{a08344}{MyTraits} : \textcolor{keyword}{public} \hyperlink{a08800}{OpenMesh::DefaultTraits}
\{
  HalfedgeAttributes(\hyperlink{a06215_ab78a93560926cd2f9958cb028f7ea96dafaaebe1808b5cce96ad4e19df471d58a}{OpenMesh::Attributes::PrevHalfedge});
\};

\textcolor{preprocessor}{#endif}

\textcolor{keyword}{typedef} \hyperlink{a08764}{OpenMesh::TriMesh\_ArrayKernelT<MyTraits>}  MyMesh;


\textcolor{comment}{// ----------------------------------------------------------------------------}

\textcolor{keywordtype}{int} main(\textcolor{keywordtype}{int} argc, \textcolor{keywordtype}{char} **argv)
\{
  MyMesh  mesh;


  \textcolor{comment}{// check command line options}
  \textcolor{keywordflow}{if} (argc != 4) 
  \{
    std::cerr << \textcolor{stringliteral}{"Usage:  "} << argv[0] << \textcolor{stringliteral}{" #iterations  infile  outfile\(\backslash\)n"};
    \textcolor{keywordflow}{return} 1;
  \}


  \textcolor{comment}{// read mesh from stdin}
  \textcolor{keywordflow}{if} ( ! \hyperlink{a06213_ac417960ec28ffdd7e7003a2b1ebb2d1c}{OpenMesh::IO::read\_mesh}(mesh, argv[2]) )
  \{
     std::cerr << \textcolor{stringliteral}{"Error: Cannot read mesh from "} << argv[2] << std::endl;
     \textcolor{keywordflow}{return} 1;
  \}


  \textcolor{comment}{// smoothing mesh argv[1] times}
  SmootherT<MyMesh> smoother(mesh);
  smoother.smooth(atoi(argv[1]));


  \textcolor{comment}{// write mesh to stdout}
  \textcolor{keywordflow}{if} ( ! \hyperlink{a06213_a18286a792ebf896872f5e26182fc5c7b}{OpenMesh::IO::write\_mesh}(mesh, argv[3]) )
  \{
    std::cerr << \textcolor{stringliteral}{"Error: cannot write mesh to "} << argv[3] << std::endl;
    \textcolor{keywordflow}{return} 1;
  \}
  \textcolor{keywordflow}{return} 0;
\}
\end{DoxyCodeInclude}
 \hypertarget{tutorial_05}{}\subsubsection{Using standard properties}\label{tutorial_05}
This example shows\+:


\begin{DoxyItemize}
\item How to add and remove a standard property,
\item How to get and set the value of a standard property.
\end{DoxyItemize}

As we already have seen, we can bind additional data to the mesh entities by means of properties. Open\+Mesh provides a set of so-\/called standard properties. Unlike the custom properties these have some special features and a different interface, which are the matter in this tutorial.

The following table lists all available standard properties and the suitable entity for which it can be used.

\tabulinesep=1mm
\begin{longtabu} spread 0pt [c]{*{5}{|X[-1]}|}
\hline
~ &Vertex &Face &Edge &Halfedge  \\\cline{1-5}
Color &X &X &X &~  \\\cline{1-5}
Normal &X &X &~ &X  \\\cline{1-5}
Position \textsuperscript{ ($\ast$) }  &X &~ &~ &~  \\\cline{1-5}
Status &X &X &X &X  \\\cline{1-5}
Tex\+Coord &X &~ &~ &X  \\\cline{1-5}
\end{longtabu}


To add a standard property to an entity simply use the appropriate request method, e.\+g. {\ttfamily request\+\_\+face\+\_\+normals()}. The only exception is the position \textsuperscript{($\ast$)}. It cannot be added because it is permanently available, hence it cannot be removed as well.

In this example we
\begin{DoxyEnumerate}
\item add vertex normals to a mesh object
\item load a file
\item check if the file provides vertex normals and calculate them if not
\item move every vertex one unit length along its normal direction
\item print the resulting positions to std\+::cout
\end{DoxyEnumerate}

Let\textquotesingle{}s start with adding vertex normals to the mesh\+:

 
\begin{DoxyCodeInclude}
  mesh.request\_vertex\_normals();

\end{DoxyCodeInclude}


In a similar manner we can request the other standard properties. For example the face normals\+:


\begin{DoxyCodeInclude}
    mesh.request\_face\_normals();

\end{DoxyCodeInclude}


We need them to calculate the vertex normals with {\ttfamily update\+\_\+normals()}, if the file didn\textquotesingle{}t provide any.

But we can do more with standard properties. We can verify if the mesh has already the property vertex normals

 
\begin{DoxyCodeInclude}
  \textcolor{keywordflow}{if} (!mesh.has\_vertex\_normals())
  \{
    std::cerr << \textcolor{stringliteral}{"ERROR: Standard vertex property 'Normals' not available!\(\backslash\)n"};
    \textcolor{keywordflow}{return} 1;
  \}

\end{DoxyCodeInclude}


And after usage we remove them again


\begin{DoxyCodeInclude}
  mesh.release\_vertex\_normals();

\end{DoxyCodeInclude}


But, what happens if for example the vertex status property has been requested twice? Then the first release does nothing, but the second one will remove it. The standard properties have a reference counter, which is incremented by one for each request and decremented by one for each release. If the counter reaches 0 the property will be removed from memory.

As we have seen in the table above, we have 9 dynamically requestable properties. The request functions as defined in \hyperlink{a08324}{Open\+Mesh\+::\+Concepts\+::\+KernelT} are\+:


\begin{DoxyItemize}
\item request\+\_\+edge\+\_\+status() 
\item request\+\_\+edge\+\_\+colors() 
\item request\+\_\+face\+\_\+colors() 
\item request\+\_\+face\+\_\+normals() 
\item request\+\_\+face\+\_\+status() 
\item request\+\_\+face\+\_\+texture\+\_\+index() 
\item request\+\_\+halfedge\+\_\+status() 
\item request\+\_\+halfedge\+\_\+normals() 
\item request\+\_\+halfedge\+\_\+texcoords1\+D() 
\item request\+\_\+halfedge\+\_\+texcoords2\+D() 
\item request\+\_\+halfedge\+\_\+texcoords3\+D() 
\item request\+\_\+vertex\+\_\+colors() 
\item request\+\_\+vertex\+\_\+normals() 
\item request\+\_\+vertex\+\_\+status() 
\item request\+\_\+vertex\+\_\+texcoords1\+D() 
\item request\+\_\+vertex\+\_\+texcoords2\+D() 
\item request\+\_\+vertex\+\_\+texcoords3\+D() 
\end{DoxyItemize}

Added properties can be released by the following functions\+:


\begin{DoxyItemize}
\item release\+\_\+edge\+\_\+status() 
\item release\+\_\+edge\+\_\+colors() 
\item release\+\_\+face\+\_\+colors() 
\item release\+\_\+face\+\_\+normals() 
\item release\+\_\+face\+\_\+status() 
\item release\+\_\+face\+\_\+texture\+\_\+index() 
\item release\+\_\+halfedge\+\_\+status() 
\item release\+\_\+halfedge\+\_\+normals() 
\item release\+\_\+halfedge\+\_\+texcoords1\+D() 
\item release\+\_\+halfedge\+\_\+texcoords2\+D() 
\item release\+\_\+halfedge\+\_\+texcoords3\+D() 
\item release\+\_\+vertex\+\_\+colors() 
\item release\+\_\+vertex\+\_\+normals() 
\item release\+\_\+vertex\+\_\+status() 
\item release\+\_\+vertex\+\_\+texcoords1\+D() 
\item release\+\_\+vertex\+\_\+texcoords2\+D() 
\item release\+\_\+vertex\+\_\+texcoords3\+D() 
\end{DoxyItemize}

A property\textquotesingle{}s existance can be tested with


\begin{DoxyItemize}
\item has\+\_\+edge\+\_\+status() 
\item has\+\_\+edge\+\_\+colors() 
\item has\+\_\+face\+\_\+colors() 
\item has\+\_\+face\+\_\+normals() 
\item has\+\_\+face\+\_\+status() 
\item has\+\_\+face\+\_\+texture\+\_\+index() 
\item has\+\_\+halfedge\+\_\+status() 
\item has\+\_\+halfedge\+\_\+normals() 
\item has\+\_\+halfedge\+\_\+texcoords1\+D() 
\item has\+\_\+halfedge\+\_\+texcoords2\+D() 
\item has\+\_\+halfedge\+\_\+texcoords3\+D() 
\item has\+\_\+vertex\+\_\+colors() 
\item has\+\_\+vertex\+\_\+normals() 
\item has\+\_\+vertex\+\_\+status() 
\item has\+\_\+vertex\+\_\+texcoords1\+D() 
\item has\+\_\+vertex\+\_\+texcoords2\+D() 
\item has\+\_\+vertex\+\_\+texcoords3\+D() 
\end{DoxyItemize}

which return true if a property has been requested before and is available.

The status property is used for marking geometry elements i.\+e. as selected or deleted. See \hyperlink{tutorial_07b}{Deleting geometry elements} for further information.

Now we know how to add and remove standard properties, but how do we access them? Again we need the mesh object. Unlike the custom properties, where we accessed one with the mesh member function {\ttfamily property()}, for each standard property the mesh provides a get and a set method. We have used one pair of get/set methods already in the previous three tutorials, where we computed a new location for the vertex position. Here we move all vertices a unit length along their normal direction\+:

 
\begin{DoxyCodeInclude}
  \textcolor{keywordflow}{for} (MyMesh::VertexIter v\_it = mesh.vertices\_begin();
       v\_it != mesh.vertices\_end(); ++v\_it)
  \{
    mesh.set\_point( *v\_it, mesh.point(*v\_it)+mesh.normal(*v\_it) );
  \}

\end{DoxyCodeInclude}


The get-\/methods take an entity handle and return the value of the desired property, and the set-\/methods require an additional parameter to pass the new value to the property. According to the table not every pair of get/set-\/methods apply to every entity. For example a face has normally no texture coordinates, hence a call to {\ttfamily mesh.\+texcoord2\+D( \+\_\+face\+\_\+handle )} will result in an error when compiling the code.

Since we know how to add/remove/access standard properties, one further question remains. What data types do they have? And are there more hidden secrets? The next tutorial (\hyperlink{tutorial_06}{Using mesh attributes and traits}) will give the answer.

The complete source looks like this\+:


\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#include <iostream>}
\textcolor{comment}{// --------------------}
\textcolor{preprocessor}{#include <OpenMesh/Core/IO/MeshIO.hh>}
\textcolor{preprocessor}{#include <OpenMesh/Core/Mesh/TriMesh\_ArrayKernelT.hh>}


\textcolor{keyword}{typedef} \hyperlink{a08764}{OpenMesh::TriMesh\_ArrayKernelT<>}  MyMesh;


\textcolor{keywordtype}{int} main(\textcolor{keywordtype}{int} argc, \textcolor{keywordtype}{char} **argv)
\{
  MyMesh  mesh;

  \textcolor{keywordflow}{if} (argc!=2)
  \{
    std::cerr << \textcolor{stringliteral}{"Usage: "} << argv[0] << \textcolor{stringliteral}{" <input>\(\backslash\)n"};
    \textcolor{keywordflow}{return} 1;
  \}

  \textcolor{comment}{// request vertex normals, so the mesh reader can use normal information}
  \textcolor{comment}{// if available}
  mesh.request\_vertex\_normals();

  \textcolor{comment}{// assure we have vertex normals}
  \textcolor{keywordflow}{if} (!mesh.has\_vertex\_normals())
  \{
    std::cerr << \textcolor{stringliteral}{"ERROR: Standard vertex property 'Normals' not available!\(\backslash\)n"};
    \textcolor{keywordflow}{return} 1;
  \}

  \hyperlink{a08480}{OpenMesh::IO::Options} opt;
  \textcolor{keywordflow}{if} ( ! \hyperlink{a06213_ac417960ec28ffdd7e7003a2b1ebb2d1c}{OpenMesh::IO::read\_mesh}(mesh,argv[1], opt))
  \{
    std::cerr << \textcolor{stringliteral}{"Error loading mesh from file "} << argv[1] << std::endl;
    \textcolor{keywordflow}{return} 1;
  \}

  \textcolor{comment}{// If the file did not provide vertex normals, then calculate them}
  \textcolor{keywordflow}{if} ( !opt.check( \hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21ad989c6d671050e12953b648c4c72dded}{OpenMesh::IO::Options::VertexNormal} ) )
  \{
    \textcolor{comment}{// we need face normals to update the vertex normals}
    mesh.request\_face\_normals();

    \textcolor{comment}{// let the mesh update the normals}
    mesh.\hyperlink{a08776_a601f21014e50bd5a2243b0e4849c9c14}{update\_normals}();

    \textcolor{comment}{// dispose the face normals, as we don't need them anymore}
    mesh.release\_face\_normals();
  \}

  \textcolor{comment}{// move all vertices one unit length along it's normal direction}
  \textcolor{keywordflow}{for} (MyMesh::VertexIter v\_it = mesh.vertices\_begin();
       v\_it != mesh.vertices\_end(); ++v\_it)
  \{
    std::cout << \textcolor{stringliteral}{"Vertex #"} << *v\_it << \textcolor{stringliteral}{": "} << mesh.point( *v\_it );
    mesh.set\_point( *v\_it, mesh.point(*v\_it)+mesh.normal(*v\_it) );
    std::cout << \textcolor{stringliteral}{" moved to "} << mesh.point( *v\_it ) << std::endl;
  \}

  \textcolor{comment}{// don't need the normals anymore? Remove them!}
  mesh.release\_vertex\_normals();

  \textcolor{comment}{// just check if it really works}
  \textcolor{keywordflow}{if} (mesh.has\_vertex\_normals())
  \{
    std::cerr << \textcolor{stringliteral}{"Ouch! ERROR! Shouldn't have any vertex normals anymore!\(\backslash\)n"};
    \textcolor{keywordflow}{return} 1;
  \}

  \textcolor{keywordflow}{return} 0;
\}
\end{DoxyCodeInclude}
 \hypertarget{tutorial_06}{}\subsubsection{Using mesh attributes and traits}\label{tutorial_06}
this example shows how to change the data type for positions, normals, colors, and texture,

In the previous tutorial (\hyperlink{tutorial_05}{Using standard properties}) we learned to use standard properties by calling the appropriate {\ttfamily request} method. Unlike the custom properties, where the user specifies the data type by passing the type to the handle (e.\+g. {\ttfamily My\+Mesh\+::\+F\+Prop\+HandleT$<$} {\bfseries int}$>$), the data types of the standard properties are defined by so-\/called mesh traits. With traits we can customize and extend the mesh data structure. We can do this by changing two important features


\begin{DoxyEnumerate}
\item changing data type for positions, normals, colors, and texture coordinates
\item extend mesh entities Vertex, Face, Edge, and Halfedge (see tutorial \textquotesingle{}\hyperlink{tutorial_07}{Extending the mesh using traits}\textquotesingle{})
\end{DoxyEnumerate}

Let\textquotesingle{}s start. Every custom traits should derive from the default traits

 
\begin{DoxyCodeInclude}
\textcolor{keyword}{struct }\hyperlink{a08344}{MyTraits} : \hyperlink{a08800}{OpenMesh::DefaultTraits}

\end{DoxyCodeInclude}


As mentioned, we can change the basic data types for the basic types {\ttfamily My\+Mesh\+::\+Point}, {\ttfamily My\+Mesh\+::\+Normal}, {\ttfamily My\+Mesh\+::\+Color}, and {\ttfamily My\+Mesh\+::\+Tex\+Coord}. We can use the provided vector class or we use a different one from another library. Here we simply replace the default type {\ttfamily \hyperlink{a06210_aa8903e7c1a37b97fb332a69122a7c6e8}{Open\+Mesh\+::\+Vec3f}} (defined in the {\ttfamily \hyperlink{a08800}{Open\+Mesh\+::\+Default\+Traits}}) for positions and normals with {\ttfamily \hyperlink{a06210_aca56e7eac7bf182bfff4ea1841d2cea2}{Open\+Mesh\+::\+Vec3d}} 


\begin{DoxyCodeInclude}
  \textcolor{keyword}{typedef} \hyperlink{a08448}{OpenMesh::Vec3d} Point;
  \textcolor{keyword}{typedef} \hyperlink{a08448}{OpenMesh::Vec3d} Normal;

\end{DoxyCodeInclude}


(In general it\textquotesingle{}s better to have the same scalar type for the point and normal vector, for instance {\ttfamily double} in this case. Otherwise we have to cast quite a lot depending on the implementation of the vector class.)

Be aware that these settings overwrite the ones of the parent traits class! As we usually derive from the \hyperlink{a08348}{Default\+Traits} let\textquotesingle{}s have a close look.

Actually the struct {\ttfamily \hyperlink{a08800}{Open\+Mesh\+::\+Default\+Traits}} is merely empty. It solely defines the types for {\ttfamily Point}, {\ttfamily Normal}, {\ttfamily Tex\+Coord}, and {\ttfamily Color} and one attribute, that we used implicitly all the time\+:


\begin{DoxyCodeInclude}
  \textcolor{comment}{// HalfedgeAttributes( OpenMesh::Attributes::PrevHalfedge );}

\end{DoxyCodeInclude}


The attribute {\ttfamily Prev\+Halfedge} is different, as it does not control a property. Yet it has a great impact on the resulting mesh type, as it adds additional information to the halfedge structure. The impact is twofold\+:


\begin{DoxyEnumerate}
\item fast access to previous halfedge
\item increase of memory consumption
\end{DoxyEnumerate}

Using this feature depends highly on our needs. One situation where the previous halfedges are quite handy, is the mesh member function add\+\_\+face(). The execution time for the member function drops dramatically, when the information about the previous halfedge is available. Usually we want to have this information. But if not, because we must save memory, we can easily remove it with


\begin{DoxyCodeInclude}
  \textcolor{comment}{// HalfedgeAttributes( OpenMesh::Attributes::None );}

\end{DoxyCodeInclude}


Then we need 8 bytes less per edge, which can be quite a lot as one can derive from the Euler formula {\bfseries ( $V-E+F=2 (1-g)$)}, that for a regular triangle meshes with genus {\bfseries  $g=0$} the number of edges {\bfseries  $E$} is approximately three times the number of vertices {\bfseries  $V$\+: $ E \approx 3 \cdot V$}.

The complete source looks like this\+:


\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#include <iostream>}
\textcolor{preprocessor}{#include <typeinfo>}
\textcolor{comment}{// --------------------}
\textcolor{preprocessor}{#include <OpenMesh/Core/IO/MeshIO.hh>}

\textcolor{preprocessor}{#include <OpenMesh/Core/Mesh/TriMesh\_ArrayKernelT.hh>}
\textcolor{preprocessor}{#include <OpenMesh/Core/Geometry/VectorT.hh>}

\textcolor{preprocessor}{#ifndef DOXY\_IGNORE\_THIS}

\textcolor{comment}{// Define my personal traits}
\textcolor{keyword}{struct }\hyperlink{a08344}{MyTraits} : \hyperlink{a08800}{OpenMesh::DefaultTraits}
\{
  \textcolor{comment}{// Let Point and Normal be a vector of doubles}
  \textcolor{keyword}{typedef} \hyperlink{a08448}{OpenMesh::Vec3d} Point;
  \textcolor{keyword}{typedef} \hyperlink{a08448}{OpenMesh::Vec3d} Normal;

  \textcolor{comment}{// Already defined in OpenMesh::DefaultTraits}
  \textcolor{comment}{// HalfedgeAttributes( OpenMesh::Attributes::PrevHalfedge );}
  
  \textcolor{comment}{// Uncomment next line to disable attribute PrevHalfedge}
  \textcolor{comment}{// HalfedgeAttributes( OpenMesh::Attributes::None );}
  \textcolor{comment}{//}
  \textcolor{comment}{// or}
  \textcolor{comment}{//}
  \textcolor{comment}{// HalfedgeAttributes( 0 );}
\};

\textcolor{preprocessor}{#endif}

\textcolor{comment}{// Define my mesh with the new traits!}
\textcolor{keyword}{typedef} \hyperlink{a08764}{OpenMesh::TriMesh\_ArrayKernelT<MyTraits>}  MyMesh;

\textcolor{comment}{// ------------------------------------------------------------------ main ----}

\textcolor{keywordtype}{int} main(\textcolor{keywordtype}{int} argc, \textcolor{keywordtype}{char} **argv)
\{
  MyMesh mesh;

  \textcolor{keywordflow}{if} (argc!=2)
  \{
    std::cerr << \textcolor{stringliteral}{"Usage: "} << argv[0] << \textcolor{stringliteral}{" <input>\(\backslash\)n"};
    \textcolor{keywordflow}{return} 1;
  \}

  \textcolor{comment}{// Just make sure that point element type is double}
  \textcolor{keywordflow}{if} ( \textcolor{keyword}{typeid}( \hyperlink{a08916_a127a4d7ca521ed3254cd801917ee67d4}{OpenMesh::vector\_traits<MyMesh::Point>::value\_type}
       ) 
       != \textcolor{keyword}{typeid}(\textcolor{keywordtype}{double}) )
  \{
    std::cerr << \textcolor{stringliteral}{"Ouch! ERROR! Data type is wrong!\(\backslash\)n"};
    \textcolor{keywordflow}{return} 1;
  \}

  \textcolor{comment}{// Make sure that normal element type is double}
  \textcolor{keywordflow}{if} ( \textcolor{keyword}{typeid}( \hyperlink{a08916_a127a4d7ca521ed3254cd801917ee67d4}{OpenMesh::vector\_traits<MyMesh::Normal>::value\_type}
       ) 
       != \textcolor{keyword}{typeid}(\textcolor{keywordtype}{double}) )
  \{
    std::cerr << \textcolor{stringliteral}{"Ouch! ERROR! Data type is wrong!\(\backslash\)n"};
    \textcolor{keywordflow}{return} 1;
  \}

  \textcolor{comment}{// Add vertex normals as default property (ref. previous tutorial)}
  mesh.request\_vertex\_normals();

  \textcolor{comment}{// Add face normals as default property}
  mesh.request\_face\_normals();

  \textcolor{comment}{// load a mesh}
  \hyperlink{a08480}{OpenMesh::IO::Options} opt;
  \textcolor{keywordflow}{if} ( ! \hyperlink{a06213_ac417960ec28ffdd7e7003a2b1ebb2d1c}{OpenMesh::IO::read\_mesh}(mesh,argv[1], opt))
  \{
    std::cerr << \textcolor{stringliteral}{"Error loading mesh from file "} << argv[1] << std::endl;
    \textcolor{keywordflow}{return} 1;
  \}

  \textcolor{comment}{// If the file did not provide vertex normals, then calculate them}
  \textcolor{keywordflow}{if} ( !opt.check( \hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21ad989c6d671050e12953b648c4c72dded}{OpenMesh::IO::Options::VertexNormal} ) &&
       mesh.has\_face\_normals() && mesh.has\_vertex\_normals() )
  \{
    \textcolor{comment}{// let the mesh update the normals}
    mesh.\hyperlink{a08776_a601f21014e50bd5a2243b0e4849c9c14}{update\_normals}();
  \}

  \textcolor{comment}{// move all vertices one unit length along it's normal direction}
  \textcolor{keywordflow}{for} (MyMesh::VertexIter v\_it = mesh.vertices\_begin();
       v\_it != mesh.vertices\_end(); ++v\_it)
  \{
    std::cout << \textcolor{stringliteral}{"Vertex #"} << *v\_it << \textcolor{stringliteral}{": "} << mesh.point( *v\_it );
    mesh.set\_point( *v\_it, mesh.point(*v\_it)+mesh.normal(*v\_it) );
    std::cout << \textcolor{stringliteral}{" moved to "} << mesh.point( *v\_it ) << std::endl;
  \}

  \textcolor{keywordflow}{return} 0;
\}
\end{DoxyCodeInclude}
 \hypertarget{tutorial_07}{}\subsubsection{Extending the mesh using traits}\label{tutorial_07}
This examples shows\+:


\begin{DoxyItemize}
\item How to extend the behaviour of entities using traits.
\end{DoxyItemize}

In the previous tutorial we used attributes and changed the type of the data types {\ttfamily Point}, {\ttfamily Normal}, {\ttfamily Tex\+Coord}, and {\ttfamily Color}. But we can do even more with traits. We can change the behaviour of the mesh entities {\ttfamily Vertex}, {\ttfamily Face}, {\ttfamily Edge}, and {\ttfamily Halfedge}.

One goal in the design was a highly customizable data structure. Using the traits technique makes it possible. We pick up the smoother again and show an alternative way to implement it. Now we place the necessary data and the functions in the vertex itself

 
\begin{DoxyCodeInclude}
\textcolor{keyword}{struct }\hyperlink{a08344}{MyTraits} : \textcolor{keyword}{public} \hyperlink{a08800}{OpenMesh::DefaultTraits}
\{
  \textcolor{comment}{// store barycenter of neighbors in this member}
  \hyperlink{a15268_aa5146d858418fcb93715406a6ce8e30f}{VertexTraits}
  \{
  \textcolor{keyword}{private}:
    Point  cog\_;
  \textcolor{keyword}{public}:

    VertexT() : cog\_( Point(0.0f, 0.0f, 0.0f ) ) \{ \}

    \textcolor{keyword}{const} Point& cog()\textcolor{keyword}{ const }\{ \textcolor{keywordflow}{return} cog\_; \}
    \textcolor{keywordtype}{void} set\_cog(\textcolor{keyword}{const} Point& \_p) \{ cog\_ = \_p; \}
  \};

\end{DoxyCodeInclude}


Note the definition of the vertex entity. We use the supplied define {\ttfamily Vertex\+Traits} (which resolves in a rather inconvenient template definition). Similary we can use the defines {\ttfamily Face\+Traits}, {\ttfamily Edge\+Traits}, and {\ttfamily Halfedge\+Traits} to extend these entities. Now we enhanced the vertex, with the additional member variable {\ttfamily cog\+\_\+}, and the get/set-\/method pair to access the new member.

As before we compute in a first loop the barycenters for all vertices and store the information at the vertices


\begin{DoxyCodeInclude}
      mesh.data(*v\_it).set\_cog(cog / valence);

\end{DoxyCodeInclude}


In the second pass we set the new position of each vertex


\begin{DoxyCodeInclude}
        mesh.set\_point( *v\_it, mesh.data(*v\_it).cog());

\end{DoxyCodeInclude}


It looks neat, but on the other hand we can\textquotesingle{}t remove the data anymore as we could do with properties! By using traits one creates a \textquotesingle{}static\textquotesingle{} configuration, which can\textquotesingle{}t be changed during runtime.

The complete source looks like this\+:


\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#include <iostream>}
\textcolor{preprocessor}{#include <vector>}
\textcolor{comment}{// -------------------- OpenMesh}
\textcolor{preprocessor}{#include <OpenMesh/Core/IO/MeshIO.hh>}
\textcolor{preprocessor}{#include <OpenMesh/Core/Mesh/TriMesh\_ArrayKernelT.hh>}
\textcolor{preprocessor}{#include <\hyperlink{a15268}{OpenMesh/Core/Mesh/Traits.hh}>}

\textcolor{keyword}{struct }\hyperlink{a08344}{MyTraits} : \textcolor{keyword}{public} \hyperlink{a08800}{OpenMesh::DefaultTraits}
\{
  \textcolor{comment}{// store barycenter of neighbors in this member}
  VertexTraits
  \{
  \textcolor{keyword}{private}:
    Point  cog\_;
  \textcolor{keyword}{public}:

    VertexT() : cog\_( Point(0.0f, 0.0f, 0.0f ) ) \{ \}

    \textcolor{keyword}{const} Point& cog()\textcolor{keyword}{ const }\{ \textcolor{keywordflow}{return} cog\_; \}
    \textcolor{keywordtype}{void} set\_cog(\textcolor{keyword}{const} Point& \_p) \{ cog\_ = \_p; \}
  \};
\};

\textcolor{keyword}{typedef} \hyperlink{a08764}{OpenMesh::TriMesh\_ArrayKernelT<MyTraits>}  MyMesh;
\textcolor{keyword}{typedef} \hyperlink{a08764}{OpenMesh::TriMesh\_ArrayKernelT<>}          
      \hyperlink{a08764}{MyMesh2};

\textcolor{comment}{// ---------------------------------------------------------------------------}
\textcolor{preprocessor}{#define SIZEOF( entity,b ) \(\backslash\)}
\textcolor{preprocessor}{  std::cout << \_prefix << "size of " << #entity << ": " \(\backslash\)}
\textcolor{preprocessor}{            << sizeof( entity ) << std::endl;          \(\backslash\)}
\textcolor{preprocessor}{  b += sizeof( entity )}

\textcolor{keyword}{template} <\textcolor{keyword}{typename} Mesh> 
\textcolor{keywordtype}{void} print\_size(\textcolor{keyword}{const} std::string& \_prefix = \textcolor{stringliteral}{""})
\{
  \textcolor{keywordtype}{size\_t} total=0;
  SIZEOF(\textcolor{keyword}{typename} \hyperlink{a08776_a03e6fd1a2fc91d4144374fd28dfbecee}{Mesh::Vertex}, total);
  SIZEOF(\textcolor{keyword}{typename} \hyperlink{a08776_a249b0c195a81eeab341f7f73089d157e}{Mesh::Halfedge}, total);
  SIZEOF(\textcolor{keyword}{typename} \hyperlink{a08776_ab2ccdc42b7b25cf35915d3639fc461b2}{Mesh::Edge}, total);
  SIZEOF(\textcolor{keyword}{typename} \hyperlink{a08776_a71e1e8eaabeb24eca04237931b4bea26}{Mesh::Face}, total);
  std::cout << \_prefix << \textcolor{stringliteral}{"total: "} << total << std::endl;
\}

\textcolor{preprocessor}{#undef SIZEOF}
\textcolor{comment}{// ---------------------------------------------------------------------------}


\textcolor{keywordtype}{int} main(\textcolor{keywordtype}{int} argc, \textcolor{keywordtype}{char} **argv)
\{
  MyMesh  mesh;

  \textcolor{comment}{// check command line options}
  \textcolor{keywordflow}{if} (argc < 4 || argc > 5) 
  \{
    std::cerr << \textcolor{stringliteral}{"Usage:  "} << argv[0] << \textcolor{stringliteral}{" [-s] #iterations infile outfile\(\backslash\)n"};
    exit(1);
  \}

  \textcolor{keywordtype}{int} idx=2;

  \textcolor{comment}{// display size of entities of the enhanced and the default mesh type}
  \textcolor{comment}{// when commandline option '-s' has been used.}
  \textcolor{keywordflow}{if} (argc == 5)
  \{
    \textcolor{keywordflow}{if} (std::string(\textcolor{stringliteral}{"-s"})==argv[idx-1])
    \{
      std::cout << \textcolor{stringliteral}{"Enhanced mesh size statistics\(\backslash\)n"};
      print\_size<MyMesh>(\textcolor{stringliteral}{"  "});
      
      std::cout << \textcolor{stringliteral}{"Default mesh size statistics\(\backslash\)n"};
      print\_size<MyMesh2>(\textcolor{stringliteral}{"  "});
    \}
    \textcolor{comment}{// else ignore!}
    ++idx;
  \}


  \textcolor{comment}{// read mesh from stdin}
  std::cout<< \textcolor{stringliteral}{" Input mesh: "} << argv[idx] << std::endl;
  \textcolor{keywordflow}{if} ( ! \hyperlink{a06213_ac417960ec28ffdd7e7003a2b1ebb2d1c}{OpenMesh::IO::read\_mesh}(mesh, argv[idx]) )
  \{
    std::cerr << \textcolor{stringliteral}{"Error: Cannot read mesh from "} << argv[idx] << std::endl;
    \textcolor{keywordflow}{return} 0;
  \}



  \textcolor{comment}{// smoothing mesh argv[1] times}
  MyMesh::VertexIter          v\_it, v\_end(mesh.vertices\_end());
  \hyperlink{a08776_adc7d422e2ce13141e8291f7d29f7ecef}{MyMesh::VertexVertexIter}    vv\_it;
  \hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}               cog;
  \hyperlink{a08776_a15372f27edf521d8e9028e2abccae342}{MyMesh::Scalar}              valence;
  \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int}                i, N(atoi(argv[idx-1]));

  std::cout<< \textcolor{stringliteral}{"Smooth mesh "} << N << \textcolor{stringliteral}{" times\(\backslash\)n"};

  \textcolor{keywordflow}{for} (i=0; i < N; ++i)
  \{
    \textcolor{keywordflow}{for} (v\_it=mesh.vertices\_begin(); v\_it!=v\_end; ++v\_it)
    \{
      cog[0] = cog[1] = cog[2] = valence = 0.0;
      
      \textcolor{keywordflow}{for} (vv\_it=mesh.vv\_iter(*v\_it); vv\_it.is\_valid(); ++vv\_it)
      \{
        cog += mesh.point( *vv\_it );
        ++valence;
      \}

      mesh.data(*v\_it).set\_cog(cog / valence);
    \}
    
    \textcolor{keywordflow}{for} (v\_it=mesh.vertices\_begin(); v\_it!=v\_end; ++v\_it)
      \textcolor{keywordflow}{if} (!mesh.is\_boundary(*v\_it))
        mesh.set\_point( *v\_it, mesh.data(*v\_it).cog());
  \}


  \textcolor{comment}{// write mesh to stdout}
  std::cout<< \textcolor{stringliteral}{"Output mesh: "} << argv[idx+1] << std::endl;

  \textcolor{keywordflow}{if} ( ! \hyperlink{a06213_a18286a792ebf896872f5e26182fc5c7b}{OpenMesh::IO::write\_mesh}(mesh, argv[idx+1]) )
  \{
      std::cerr << \textcolor{stringliteral}{"Error: cannot write mesh to "} << argv[idx+1] << std::endl;
      \textcolor{keywordflow}{return} 0;
  \}
  \textcolor{keywordflow}{return} 1;
\}
\end{DoxyCodeInclude}
 \hypertarget{tutorial_07b}{}\subsubsection{Deleting geometry elements}\label{tutorial_07b}
This small example shows how to remove faces and vertices from a mesh.

We basically use the geometry created in \hyperlink{tutorial_01}{First Steps -\/ Building a cube}.

If we want our mesh class to be able to remove vertices, faces or edges we have to extend the default traits for our mesh class. Vertices, faces and (half-\/)edges need the \hyperlink{a06215_ab78a93560926cd2f9958cb028f7ea96dad3e94e10c76894ebce6048b8bbb77a74}{Open\+Mesh\+::\+Attributes\+::\+Status} attribute which is used to hold the flag \char`\"{}deleted\char`\"{} if an element is deleted.

Instead of defining the required attributes via traits on compile-\/time, it is possible to request attributes dynamically on run-\/time by requesting them. In this example, we want to delete faces, edges and vertices, therefore requesting the status attribute is required. \begin{DoxyNote}{Note}
You have to request attributes before you use them, if you don\textquotesingle{}t enable them via traits.
\end{DoxyNote}
 
\begin{DoxyCodeInclude}
  \textcolor{comment}{// the request has to be called before a vertex/face/edge can be deleted. it grants access to the status
       attribute}
  mesh.request\_face\_status();
  mesh.request\_edge\_status();
  mesh.request\_vertex\_status();

\end{DoxyCodeInclude}


After having created the geometry of the cube one can delete faces and vertices by simply calling delete\+\_\+vertices() (delete\+\_\+faces() or delete\+\_\+edges() respectively).

Note that there is actually no way to directly delete halfedges since they are automatically affected when the parent edge is marked as deleted!

The status whether an element is marked as deleted can be requested by


\begin{DoxyCode}
mesh.status(handle).deleted();  \textcolor{comment}{// true if element handle is marked as deleted}
                                \textcolor{comment}{// false otherwise}
\end{DoxyCode}


where handle is either a vertex-\/, edge-\/ or face-\/handle.

In this example we delete all faces except one and the corresponding vertices. The code looks like this

 
\begin{DoxyCodeInclude}
  \textcolor{comment}{// Delete face 0}
  mesh.delete\_face(fhandle[0], \textcolor{keyword}{false});
  \textcolor{comment}{// ... face 2}
  mesh.delete\_face(fhandle[2], \textcolor{keyword}{false});
  \textcolor{comment}{// ... face 3}
  mesh.delete\_face(fhandle[3], \textcolor{keyword}{false});
  \textcolor{comment}{// ... face 4}
  mesh.delete\_face(fhandle[4], \textcolor{keyword}{false});
  \textcolor{comment}{// ... face 5}
  mesh.delete\_face(fhandle[5], \textcolor{keyword}{false});
  

  \textcolor{comment}{// If isolated vertices result in a face deletion}
  \textcolor{comment}{// they have to be deleted manually. If you want this}
  \textcolor{comment}{// to happen automatically, change the second parameter}
  \textcolor{comment}{// to true.}

  \textcolor{comment}{// Now delete the isolated vertices 0, 1, 2 and 3}
  mesh.delete\_vertex(vhandle[0], \textcolor{keyword}{false});
  mesh.delete\_vertex(vhandle[1], \textcolor{keyword}{false});
  mesh.delete\_vertex(vhandle[2], \textcolor{keyword}{false});
  mesh.delete\_vertex(vhandle[3], \textcolor{keyword}{false});

\end{DoxyCodeInclude}


Now the deleted faces and vertices are marked as \char`\"{}deleted\char`\"{} internally. Call garbage\+\_\+collection() to definitely remove them from memory.

 
\begin{DoxyCodeInclude}
  \textcolor{comment}{// Delete all elements that are marked as deleted}
  \textcolor{comment}{// from memory.}
  mesh.garbage\_collection();

\end{DoxyCodeInclude}


The full source code of the example\+:


\begin{DoxyCodeInclude}
\textcolor{comment}{/* ========================================================================= *}
\textcolor{comment}{ *                                                                           *}
\textcolor{comment}{ *                               OpenMesh                                    *}
\textcolor{comment}{ *           Copyright (c) 2001-2015, RWTH-Aachen University                 *}
\textcolor{comment}{ *           Department of Computer Graphics and Multimedia                  *}
\textcolor{comment}{ *                          All rights reserved.                             *}
\textcolor{comment}{ *                            www.openmesh.org                               *}
\textcolor{comment}{ *                                                                           *}
\textcolor{comment}{ *---------------------------------------------------------------------------*}
\textcolor{comment}{ * This file is part of OpenMesh.                                            *}
\textcolor{comment}{ *---------------------------------------------------------------------------*}
\textcolor{comment}{ *                                                                           *}
\textcolor{comment}{ * Redistribution and use in source and binary forms, with or without        *}
\textcolor{comment}{ * modification, are permitted provided that the following conditions        *}
\textcolor{comment}{ * are met:                                                                  *}
\textcolor{comment}{ *                                                                           *}
\textcolor{comment}{ * 1. Redistributions of source code must retain the above copyright notice, *}
\textcolor{comment}{ *    this list of conditions and the following disclaimer.                  *}
\textcolor{comment}{ *                                                                           *}
\textcolor{comment}{ * 2. Redistributions in binary form must reproduce the above copyright      *}
\textcolor{comment}{ *    notice, this list of conditions and the following disclaimer in the    *}
\textcolor{comment}{ *    documentation and/or other materials provided with the distribution.   *}
\textcolor{comment}{ *                                                                           *}
\textcolor{comment}{ * 3. Neither the name of the copyright holder nor the names of its          *}
\textcolor{comment}{ *    contributors may be used to endorse or promote products derived from   *}
\textcolor{comment}{ *    this software without specific prior written permission.               *}
\textcolor{comment}{ *                                                                           *}
\textcolor{comment}{ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *}
\textcolor{comment}{ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *}
\textcolor{comment}{ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *}
\textcolor{comment}{ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *}
\textcolor{comment}{ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *}
\textcolor{comment}{ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *}
\textcolor{comment}{ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *}
\textcolor{comment}{ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *}
\textcolor{comment}{ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *}
\textcolor{comment}{ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *}
\textcolor{comment}{ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *}
\textcolor{comment}{ *                                                                           *}
\textcolor{comment}{ * ========================================================================= */}

\textcolor{preprocessor}{#include <iostream>}
\textcolor{comment}{// -------------------- OpenMesh}
\textcolor{preprocessor}{#include <OpenMesh/Core/IO/MeshIO.hh>}
\textcolor{preprocessor}{#include <OpenMesh/Core/Mesh/PolyMesh\_ArrayKernelT.hh>}
\textcolor{preprocessor}{#include <\hyperlink{a02096}{OpenMesh/Core/System/config.h}>}
\textcolor{preprocessor}{#include <OpenMesh/Core/Mesh/Status.hh>}

\textcolor{comment}{// ----------------------------------------------------------------------------}

\textcolor{keyword}{struct }\hyperlink{a08344}{MyTraits} : \textcolor{keyword}{public} \hyperlink{a08800}{OpenMesh::DefaultTraits}
\{
\};


\textcolor{keyword}{typedef} \hyperlink{a08772}{OpenMesh::PolyMesh\_ArrayKernelT<MyTraits>}  MyMesh;


\textcolor{comment}{// ----------------------------------------------------------------------------}
\textcolor{comment}{// Build a simple cube and delete it except one face}
  
\textcolor{keywordtype}{int} main()
\{
  MyMesh mesh;

  \textcolor{comment}{// the request has to be called before a vertex/face/edge can be deleted. it grants access to the status
       attribute}
  mesh.request\_face\_status();
  mesh.request\_edge\_status();
  mesh.request\_vertex\_status();

  \textcolor{comment}{// generate vertices}

  \hyperlink{a08776_a0fc18e13d70825938274e3faf7b55e01}{MyMesh::VertexHandle} vhandle[8];
  MyMesh::FaceHandle   fhandle[6];

  vhandle[0] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(-1, -1,  1));
  vhandle[1] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}( 1, -1,  1));
  vhandle[2] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}( 1,  1,  1));
  vhandle[3] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(-1,  1,  1));
  vhandle[4] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(-1, -1, -1));
  vhandle[5] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}( 1, -1, -1));
  vhandle[6] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}( 1,  1, -1));
  vhandle[7] = mesh.\hyperlink{a08776_ac0577d7120881533e6e3af635382ba82}{add\_vertex}(\hyperlink{a08776_aed10fb4dfb536b53a5e20c8f2442eadf}{MyMesh::Point}(-1,  1, -1));


  \textcolor{comment}{// generate (quadrilateral) faces}

  std::vector<MyMesh::VertexHandle>  tmp\_face\_vhandles;

  tmp\_face\_vhandles.clear();
  tmp\_face\_vhandles.push\_back(vhandle[0]);
  tmp\_face\_vhandles.push\_back(vhandle[1]);
  tmp\_face\_vhandles.push\_back(vhandle[2]);
  tmp\_face\_vhandles.push\_back(vhandle[3]);
  fhandle[0] = mesh.add\_face(tmp\_face\_vhandles);
 
  tmp\_face\_vhandles.clear();
  tmp\_face\_vhandles.push\_back(vhandle[7]);
  tmp\_face\_vhandles.push\_back(vhandle[6]);
  tmp\_face\_vhandles.push\_back(vhandle[5]);
  tmp\_face\_vhandles.push\_back(vhandle[4]);
  fhandle[1] = mesh.add\_face(tmp\_face\_vhandles);
 
  tmp\_face\_vhandles.clear();
  tmp\_face\_vhandles.push\_back(vhandle[1]);
  tmp\_face\_vhandles.push\_back(vhandle[0]);
  tmp\_face\_vhandles.push\_back(vhandle[4]);
  tmp\_face\_vhandles.push\_back(vhandle[5]);
  fhandle[2] = mesh.add\_face(tmp\_face\_vhandles);
 

  tmp\_face\_vhandles.clear();
  tmp\_face\_vhandles.push\_back(vhandle[2]);
  tmp\_face\_vhandles.push\_back(vhandle[1]);
  tmp\_face\_vhandles.push\_back(vhandle[5]);
  tmp\_face\_vhandles.push\_back(vhandle[6]);
  fhandle[3] = mesh.add\_face(tmp\_face\_vhandles);


  tmp\_face\_vhandles.clear();
  tmp\_face\_vhandles.push\_back(vhandle[3]);
  tmp\_face\_vhandles.push\_back(vhandle[2]);
  tmp\_face\_vhandles.push\_back(vhandle[6]);
  tmp\_face\_vhandles.push\_back(vhandle[7]);
  fhandle[4] = mesh.add\_face(tmp\_face\_vhandles);
 

  tmp\_face\_vhandles.clear();
  tmp\_face\_vhandles.push\_back(vhandle[0]);
  tmp\_face\_vhandles.push\_back(vhandle[3]);
  tmp\_face\_vhandles.push\_back(vhandle[7]);
  tmp\_face\_vhandles.push\_back(vhandle[4]);
  fhandle[5] = mesh.add\_face(tmp\_face\_vhandles);

  \textcolor{comment}{// And now delete all faces and vertices}
  \textcolor{comment}{// except face (vh[7], vh[6], vh[5], vh[4])}
  \textcolor{comment}{// whose handle resides in fhandle[1]}

   
  \textcolor{comment}{// Delete face 0}
  mesh.delete\_face(fhandle[0], \textcolor{keyword}{false});
  \textcolor{comment}{// ... face 2}
  mesh.delete\_face(fhandle[2], \textcolor{keyword}{false});
  \textcolor{comment}{// ... face 3}
  mesh.delete\_face(fhandle[3], \textcolor{keyword}{false});
  \textcolor{comment}{// ... face 4}
  mesh.delete\_face(fhandle[4], \textcolor{keyword}{false});
  \textcolor{comment}{// ... face 5}
  mesh.delete\_face(fhandle[5], \textcolor{keyword}{false});
  

  \textcolor{comment}{// If isolated vertices result in a face deletion}
  \textcolor{comment}{// they have to be deleted manually. If you want this}
  \textcolor{comment}{// to happen automatically, change the second parameter}
  \textcolor{comment}{// to true.}

  \textcolor{comment}{// Now delete the isolated vertices 0, 1, 2 and 3}
  mesh.delete\_vertex(vhandle[0], \textcolor{keyword}{false});
  mesh.delete\_vertex(vhandle[1], \textcolor{keyword}{false});
  mesh.delete\_vertex(vhandle[2], \textcolor{keyword}{false});
  mesh.delete\_vertex(vhandle[3], \textcolor{keyword}{false});

  \textcolor{comment}{// Delete all elements that are marked as deleted}
  \textcolor{comment}{// from memory.}
  mesh.garbage\_collection();

  \textcolor{comment}{// write mesh to output.obj}
  \textcolor{keywordflow}{try} \{
        \textcolor{keywordflow}{if} ( !\hyperlink{a06213_a18286a792ebf896872f5e26182fc5c7b}{OpenMesh::IO::write\_mesh}(mesh, \textcolor{stringliteral}{"output.off"}) ) \{
          std::cerr << \textcolor{stringliteral}{"Cannot write mesh to file 'output.off'"} << std::endl;
          \textcolor{keywordflow}{return} 1;
        \}
  \}
  \textcolor{keywordflow}{catch}( std::exception& x )
  \{
    std::cerr << x.what() << std::endl;
    \textcolor{keywordflow}{return} 1;
  \}
 
  \textcolor{keywordflow}{return} 0;
\}
\end{DoxyCodeInclude}
 \hypertarget{tutorial_08}{}\subsubsection{Using IO\+:\+:Options}\label{tutorial_08}
This example shows\+:


\begin{DoxyItemize}
\item How to control the behaviour of {\ttfamily Mesh\+::\+I\+O\+::read\+\_\+mesh()},
\item How to control the behaviour of {\ttfamily Mesh\+::\+I\+O\+::write\+\_\+mesh()}.
\end{DoxyItemize}

The class {\ttfamily \hyperlink{a08480}{Open\+Mesh\+::\+I\+O\+::\+Options}} can be used when reading/writing a mesh. It controls the behaviour of the reader/writer modules by means of enabled/disabled bits in a bitset. The class provides an interface for enabling, disabling and verifying the bits in the set. We distinguish between


\begin{DoxyEnumerate}
\item mode bits -\/ control binary reading/writing
\begin{DoxyItemize}
\item Options\+::\+Binary
\item Options\+::\+M\+SB
\item Options\+::\+L\+SB
\item Options\+::\+Swap (M\+S\+B$\vert$\+L\+SB)
\end{DoxyItemize}
\item property bits -\/ controls which standard properties to read/write
\begin{DoxyItemize}
\item Options\+::\+Vertex\+Normal
\item Options\+::\+Vertex\+Tex\+Coord
\item Options\+::\+Vertex\+Color
\item Options\+::\+Face\+Normal
\item Options\+::\+Face\+Color
\item Options\+::\+Face\+Tex\+Coord
\item Options\+::\+Color\+Alpha
\item Options\+::\+Color\+Float
\item Options\+::\+Custom
\end{DoxyItemize}
\end{DoxyEnumerate}

These bits have different effects when reading or writing. The file format itself is selected by the extension of the filename.

Please take into account, each mesh has to {\bfseries request} the standard property {\bfseries before loading} with the corresponding option. For instance, if you enable Options\+::\+Vertex\+Normal, your mesh has to request vertex normals. Otherwise, they will not be written into the mesh.

\begin{DoxyNote}{Note}
Face Tex Coords will not be saved as a property per face, but as a property per halfedge. Therefore, you have to request the \char`\"{}halfedge\+\_\+texcoords2\+D\char`\"{} property
\end{DoxyNote}
The O\+B\+J-\/reader can also read information about the textures in the $\ast$.mtl file, if available. These texture information (includes texturename and index) will be saved in the property of type\+: 
\begin{DoxyCode}
\hyperlink{a08892}{OpenMesh::MPropHandleT< std::map< int, std::string >} > 
\end{DoxyCode}
 with the name\+: 
\begin{DoxyCode}
\textcolor{stringliteral}{"TextureMapping"} 
\end{DoxyCode}
 This property will be automatically created, if textures were found. There is no other option you have to define for reading texture information beside of the request of the property.~\newline
Additionally, the O\+BJ loader writes the texture index per face, if the property \char`\"{}face\+\_\+texture\+\_\+index\char`\"{} is requested. The texture index is the same index as the index written in the texture mapping. So, it is possible to get the name of the texture from a face via its texture index over the texture mapping property to the texture name. But remember, you have to request the face texture index property first before loading the mesh.

Below in the table you can see what options are suported by which reader/writer (it is possible that the data format can support more). A\+S\+C\+II is not a real option and will be selected, if binary was not defined.


\tabulinesep=1mm
\begin{longtabu} spread 0pt [c]{*{16}{|X[-1]}|}
\caption{{\itshape Reader/\+Writer Feature Support List}}\label{_}\\
\hline
\textbf{ Format/\+Option}&A\+S\+C\+II&Binary&M\+SB&L\+SB&Swap&Vertex\+Normal&Vertex\+Color&Vertex\+Tex\+Coord&Edge\+Color&Face\+Normal&Face\+Color&Face\+Tex\+Coord&Color\+Alpha&Color\+Float&Custom \\\cline{1-16}
\textbf{ O\+BJ}&x&&&&&x&x $\ast$)&x&&x&x&x&&&\\\cline{1-16}
\textbf{ O\+FF}&x&x&&x&&x&x&x&&&x&&x&x&\\\cline{1-16}
\textbf{ P\+LY}&x&x&x&x&&x&x&x&&&x&&x&x&x $\ast$$\ast$) \\\cline{1-16}
\textbf{ OM}&&x&x&x&x&x&x&x&&x&x&&&&x (\hyperlink{tutorial_09}{Storing custom properties} ) \\\cline{1-16}
\textbf{ S\+TL}&x&x&&x&&&&&&x&&&&&\\\cline{1-16}
\textbf{ V\+TK $\ast$$\ast$$\ast$)}&x&&&&&&&&&&&&&&\\\cline{1-16}
\end{longtabu}


$\ast$) can {\itshape read} the non-\/standard extension vertex colors (floats only)\+: \begin{DoxyItemize}
\item defined with vc (e.\+g. used by meshlab) \item colors encoded in a vertex line (v followed by 6 values)\end{DoxyItemize}
$\ast$$\ast$) only vertex and face properties with fundamental types. Take into account, that you don\textquotesingle{}t have to request these custom properties before loading.

$\ast$$\ast$$\ast$) no reader exists

The program does not more than providing a command line based interface to select the option bits for reading/writing and to request mesh properties. Hence illegal combinations are possible and will result in a failure of the program. (The input file won\textquotesingle{}t be damaged in this case, but be careful where you put the ouput file!)

\subparagraph*{Reading meshes}

When reading a file the mode bits are used to give the reader an advice or hint. Depending on the format we can help the reader to interpret the data correctly. First of all we can tell it that the file contains binary data.

 
\begin{DoxyCodeInclude}
        ropt += IO::Options::Binary; 

\end{DoxyCodeInclude}


Further on we can ask the reader two swap the byte-\/order.


\begin{DoxyCodeInclude}
        ropt += IO::Options::Swap; 

\end{DoxyCodeInclude}


(Both can be done via the command line with the options -\/b and -\/s, respectively.)

By default the geometry and the topology is restored from the file. The file might contain more, especially it could provide normals or texture coordinates. We can examine the property bits after reading to find out what else is available\+:

 
\begin{DoxyCodeInclude}
                ropt.check(IO::Options::VertexNormal) 

\end{DoxyCodeInclude}


If a property bit is set it does not mean, that it has been restored as well. The property must have been requested prior reading the file. (The demo program offers the command line option {\ttfamily -\/\+Xv}\mbox{[}nct\mbox{]} and {\ttfamily -\/\+Xf}\mbox{[}nc\mbox{]} to request vertex and face properties.)

\subparagraph*{Writing meshes}

When writing the mesh the mode bits apparently control whether to use the binary variant and the desired byte-\/ordering. For example, if we choose binary mode and want to swap the byte order, we set


\begin{DoxyCodeInclude}
        wopt += IO::Options::Binary; 
        wopt += IO::Options::Swap; 

\end{DoxyCodeInclude}


If the format does not specify the byte order the system byte order is used. If the format does not support binary storage, the mode bits are ignored.

If the format supports storing additional information, which are conform with the standard properties, we can use the property bits to tell the writer what we would like to have stored. If we would like to store the vertex normals we simply set


\begin{DoxyCodeInclude}
              wopt += IO::Options::VertexNormal; 

\end{DoxyCodeInclude}


Finally we can write the data to the file

 
\begin{DoxyCodeInclude}
  \textcolor{keywordflow}{if} ( !IO::write\_mesh( mesh, argv[optind+1], wopt ) )

\end{DoxyCodeInclude}


The method returns false on error, which might have three different reasons\+:


\begin{DoxyEnumerate}
\item the option is not supported by the choosen format
\item a selected standard property is not available
\item a \textquotesingle{}system\textquotesingle{} error like
\begin{DoxyItemize}
\item could not open the file due to access rights
\item disk space exhausted during write
\item ...
\end{DoxyItemize}
\end{DoxyEnumerate}

The complete source looks like this\+:


\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#include <iostream>}
\textcolor{preprocessor}{#include <iterator>}
\textcolor{comment}{// -------------------- OpenMesh}
\textcolor{preprocessor}{#include <OpenMesh/Core/IO/MeshIO.hh>}
\textcolor{preprocessor}{#include <OpenMesh/Core/Mesh/TriMesh\_ArrayKernelT.hh>}
\textcolor{preprocessor}{#include <OpenMesh/Tools/Utils/getopt.h>}

\textcolor{comment}{// ----------------------------------------------------------------------------}

\textcolor{keyword}{using namespace }\hyperlink{a06210}{OpenMesh};

\textcolor{comment}{// ----------------------------------------------------------------------------}

\textcolor{keyword}{typedef} \hyperlink{a08764}{TriMesh\_ArrayKernelT<>}  MyMesh;

\textcolor{comment}{// ----------------------------------------------------------------------------}

\textcolor{preprocessor}{#define CHKROPT( Option ) \(\backslash\)}
\textcolor{preprocessor}{  std::cout << "  provides " << #Option \(\backslash\)}
\textcolor{preprocessor}{            << (ropt.check(IO::Options:: Option)?": yes\(\backslash\)n":": no\(\backslash\)n")}

\textcolor{preprocessor}{#define CHKWOPT( Option ) \(\backslash\)}
\textcolor{preprocessor}{  std::cout << "  write " << #Option \(\backslash\)}
\textcolor{preprocessor}{            << (wopt.check(IO::Options:: Option)?": yes\(\backslash\)n":": no\(\backslash\)n")}

\textcolor{preprocessor}{#define MESHOPT( msg, tf ) \(\backslash\)}
\textcolor{preprocessor}{  std::cout << "  " << msg << ": " << ((tf)?"yes\(\backslash\)n":"no\(\backslash\)n")}

\textcolor{comment}{// ----------------------------------------------------------------------------}

\textcolor{keywordtype}{void} parse\_commandline( \textcolor{keywordtype}{int} \_argc, \textcolor{keywordtype}{char} **\_argv, MyMesh& \_mesh,
                        \hyperlink{a08480}{IO::Options} &ropt, \hyperlink{a08480}{IO::Options} &wopt );

\textcolor{keywordtype}{void} usage\_and\_exit(\textcolor{keywordtype}{int} xcode);

\textcolor{comment}{// ----------------------------------------------------------------------------}

\textcolor{keywordtype}{int} main(\textcolor{keywordtype}{int} argc, \textcolor{keywordtype}{char} **argv)
\{
  MyMesh  mesh;
  \hyperlink{a08480}{IO::Options} ropt, wopt;

  \textcolor{comment}{// -------------------- evaluate commandline}

  parse\_commandline( argc, argv, mesh, ropt, wopt );

  \textcolor{comment}{// -------------------- read mesh}

  \textcolor{keywordflow}{if} ( ! \hyperlink{a06213_ac417960ec28ffdd7e7003a2b1ebb2d1c}{IO::read\_mesh}(mesh,argv[optind], ropt))
  \{
    std::cerr << \textcolor{stringliteral}{"Error loading mesh from file "} << argv[optind] << std::endl;
    \textcolor{keywordflow}{return} 1;
  \}

  \textcolor{comment}{// -------------------- show options}

  std::cout << \textcolor{stringliteral}{"File "} << argv[optind] << std::endl;

  std::cout << \textcolor{stringliteral}{"  is binary: "} 
            << (ropt.check(\hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21a5cb7f45e7ba928e0a23e4a676d10fa8a}{IO::Options::Binary}) ? \textcolor{stringliteral}{" yes\(\backslash\)n"} : \textcolor{stringliteral}{" no\(\backslash\)n"});

  std::cout << \textcolor{stringliteral}{"  byte order: "};
  \textcolor{keywordflow}{if} (ropt.check(\hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21a35dfdd7a0af4b3c83fbdec77a6428ba3}{IO::Options::Swap}))
    std::cout << \textcolor{stringliteral}{"swapped\(\backslash\)n"};
  \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (ropt.check(\hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21ac53f41d3b8306a764e7382372d56b7ec}{IO::Options::LSB}))
    std::cout << \textcolor{stringliteral}{"little endian\(\backslash\)n"};
  \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (ropt.check(\hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21a5976f96b11378c06f15f99bef6cc5f19}{IO::Options::MSB}))
    std::cout << \textcolor{stringliteral}{"big endian\(\backslash\)n"};
  \textcolor{keywordflow}{else}
    std::cout << \textcolor{stringliteral}{"don't care\(\backslash\)n"};
  
  std::cout << \textcolor{stringliteral}{"  provides VertexNormal"}
            << ( \textcolor{comment}{// strange layout for doxygen}
                ropt.check(\hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21ad989c6d671050e12953b648c4c72dded}{IO::Options::VertexNormal}) 
                ? \textcolor{stringliteral}{": yes\(\backslash\)n"}:\textcolor{stringliteral}{": no\(\backslash\)n"});
  CHKROPT( VertexColor    );
  CHKROPT( VertexTexCoord );
  CHKROPT( FaceNormal     );
  CHKROPT( FaceColor      );


  \textcolor{comment}{// -------------------- mesh stats}

  std::cout << \textcolor{stringliteral}{"# Vertices: "} << mesh.n\_vertices() << std::endl;
  std::cout << \textcolor{stringliteral}{"# Edges   : "} << mesh.n\_faces() << std::endl;
  std::cout << \textcolor{stringliteral}{"# Faces   : "} << mesh.n\_faces() << std::endl;


  \textcolor{comment}{// -------------------- show write options}

  std::cout << \textcolor{stringliteral}{"Selected write options:\(\backslash\)n"};
  std::cout << \textcolor{stringliteral}{"  use binary: "} 
            << (wopt.check(\hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21a5cb7f45e7ba928e0a23e4a676d10fa8a}{IO::Options::Binary}) ? \textcolor{stringliteral}{" yes\(\backslash\)n"} : \textcolor{stringliteral}{" no\(\backslash\)n"});

  std::cout << \textcolor{stringliteral}{"  byte order: "};
  \textcolor{keywordflow}{if} (wopt.check(\hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21a35dfdd7a0af4b3c83fbdec77a6428ba3}{IO::Options::Swap}))
    std::cout << \textcolor{stringliteral}{"swapped\(\backslash\)n"};
  \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (wopt.check(\hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21ac53f41d3b8306a764e7382372d56b7ec}{IO::Options::LSB}))
    std::cout << \textcolor{stringliteral}{"little endian\(\backslash\)n"};
  \textcolor{keywordflow}{else} \textcolor{keywordflow}{if} (wopt.check(\hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21a5976f96b11378c06f15f99bef6cc5f19}{IO::Options::MSB}))
    std::cout << \textcolor{stringliteral}{"big endian\(\backslash\)n"};
  \textcolor{keywordflow}{else}
    std::cout << \textcolor{stringliteral}{"don't care\(\backslash\)n"};
  
  std::cout << \textcolor{stringliteral}{"  write VertexNormal"}
            << (wopt.check(\hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21ad989c6d671050e12953b648c4c72dded}{IO::Options::VertexNormal}) ? \textcolor{stringliteral}{": yes\(\backslash\)n"}:\textcolor{stringliteral}{": no\(\backslash\)n"});
  CHKWOPT( VertexColor    );
  CHKWOPT( VertexTexCoord );
  CHKWOPT( FaceNormal     );
  CHKWOPT( FaceColor      );

  \textcolor{comment}{// -------------------- show mesh capabilities}

  std::cout << \textcolor{stringliteral}{"Mesh supports\(\backslash\)n"};
  MESHOPT(\textcolor{stringliteral}{"vertex normals"}, mesh.has\_vertex\_normals());
  MESHOPT(\textcolor{stringliteral}{"vertex colors"}, mesh.has\_vertex\_colors());
  MESHOPT(\textcolor{stringliteral}{"texcoords"}, mesh.has\_vertex\_texcoords2D());
  MESHOPT(\textcolor{stringliteral}{"face normals"}, mesh.has\_face\_normals());
  MESHOPT(\textcolor{stringliteral}{"face colors"}, mesh.has\_face\_colors());

  \textcolor{comment}{// -------------------- write mesh}

  std::cout << \textcolor{stringliteral}{"Write mesh to "} << argv[optind+1] << \textcolor{stringliteral}{".."};
  \textcolor{keywordflow}{if} ( !\hyperlink{a06213_a18286a792ebf896872f5e26182fc5c7b}{IO::write\_mesh}( mesh, argv[optind+1], wopt ) )
  \{
    std::cerr << \textcolor{stringliteral}{"Error"} << std::endl;
    std::cerr << \textcolor{stringliteral}{"Possible reasons:\(\backslash\)n"};
    std::cerr << \textcolor{stringliteral}{"1. Chosen format cannot handle an option!\(\backslash\)n"};
    std::cerr << \textcolor{stringliteral}{"2. Mesh does not provide necessary information!\(\backslash\)n"};
    std::cerr << \textcolor{stringliteral}{"3. Or simply cannot open file for writing!\(\backslash\)n"};
    \textcolor{keywordflow}{return} 1;
  \}
  \textcolor{keywordflow}{else}
    std::cout << \textcolor{stringliteral}{"Ok.\(\backslash\)n"};

  \textcolor{keywordflow}{return} 0;
\}

\textcolor{comment}{// ----------------------------------------------------------------------------}

\textcolor{keywordtype}{void} parse\_commandline( \textcolor{keywordtype}{int} \_argc, \textcolor{keywordtype}{char} **\_argv, MyMesh& \_mesh,
                        \hyperlink{a08480}{IO::Options} &ropt, \hyperlink{a08480}{IO::Options} &wopt )
\{
  \textcolor{keywordtype}{int} c;
  \textcolor{keywordflow}{while} ((c=getopt(\_argc, \_argv, \textcolor{stringliteral}{"bhsBF:LMSV:X:"}))!=-1)
  \{
    \textcolor{keywordflow}{switch}(c) 
    \{
      \textcolor{comment}{// -------------------- read options}

      \textcolor{comment}{// force binary input}
      \textcolor{keywordflow}{case} \textcolor{charliteral}{'b'}: 
        ropt += \hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21a5cb7f45e7ba928e0a23e4a676d10fa8a}{IO::Options::Binary}; 
        \textcolor{keywordflow}{break};

      \textcolor{comment}{// force swapping the byte order, when reading a binary file}
      \textcolor{keywordflow}{case} \textcolor{charliteral}{'s'}: 
        ropt += \hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21a35dfdd7a0af4b3c83fbdec77a6428ba3}{IO::Options::Swap}; 
        \textcolor{keywordflow}{break};

      \textcolor{comment}{// -------------------- write options}

      \textcolor{comment}{// Write binary variant of format if possible}
      \textcolor{keywordflow}{case} \textcolor{charliteral}{'B'}: 
        wopt += \hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21a5cb7f45e7ba928e0a23e4a676d10fa8a}{IO::Options::Binary}; 
        \textcolor{keywordflow}{break};

      \textcolor{comment}{// }
      \textcolor{keywordflow}{case} \textcolor{charliteral}{'F'}:
        \textcolor{keywordflow}{for}(\textcolor{keywordtype}{size\_t} i=0; optarg[i]; ++i)
          \textcolor{keywordflow}{switch}(optarg[i]) \{
            \textcolor{keywordflow}{case} \textcolor{charliteral}{'n'} : wopt += \hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21a20ffc1477fa85d5ba3623817f71d1b39}{IO::Options::FaceNormal}; \textcolor{keywordflow}{break};
            \textcolor{keywordflow}{case} \textcolor{charliteral}{'c'} : wopt += \hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21a3e0b1cda32fe42bde7ac3dc96f977a46}{IO::Options::FaceColor}; \textcolor{keywordflow}{break};
          \}
        \textcolor{keywordflow}{break};

      \textcolor{comment}{// Use little endian when writing binary data}
      \textcolor{keywordflow}{case} \textcolor{charliteral}{'L'}: 
        wopt += \hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21ac53f41d3b8306a764e7382372d56b7ec}{IO::Options::LSB}; 
        \textcolor{keywordflow}{break};

      \textcolor{comment}{// Use big endian when writing binary data}
      \textcolor{keywordflow}{case} \textcolor{charliteral}{'M'}: 
        wopt += \hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21a5976f96b11378c06f15f99bef6cc5f19}{IO::Options::MSB}; 
        \textcolor{keywordflow}{break};

      \textcolor{comment}{// Swap byte order when writing binary data}
      \textcolor{keywordflow}{case} \textcolor{charliteral}{'S'}: 
        wopt += \hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21a35dfdd7a0af4b3c83fbdec77a6428ba3}{IO::Options::Swap}; 
        \textcolor{keywordflow}{break};

      \textcolor{comment}{//}
      \textcolor{keywordflow}{case} \textcolor{charliteral}{'V'}:
      \{
        \textcolor{keywordflow}{for}(\textcolor{keywordtype}{size\_t} i=0; optarg[i]; ++i)
          \textcolor{keywordflow}{switch}(optarg[i]) \{
            \textcolor{keywordflow}{case} \textcolor{charliteral}{'n'} : \textcolor{comment}{// dont't change layout!!}
              wopt += \hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21ad989c6d671050e12953b648c4c72dded}{IO::Options::VertexNormal}; 
              \textcolor{keywordflow}{break};
            \textcolor{keywordflow}{case} \textcolor{charliteral}{'t'} : wopt += \hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21ae9e664738c4c48ac057770fb08a723f0}{IO::Options::VertexTexCoord}; \textcolor{keywordflow}{break};
            \textcolor{keywordflow}{case} \textcolor{charliteral}{'c'} : wopt += \hyperlink{a08480_a9f4f797b08c045b611eaa6f8d149da21af7b6bb87f12fdfe5c9a8f8e1ce9325c7}{IO::Options::VertexColor}; \textcolor{keywordflow}{break};
          \}
        \textcolor{keywordflow}{break};
      \}

      \textcolor{comment}{// -------------------- request mesh' standard properties}
      \textcolor{keywordflow}{case} \textcolor{charliteral}{'X'}:
      \{        
        \textcolor{keywordtype}{char} entity=\textcolor{charliteral}{'\(\backslash\)0'};
        \textcolor{keywordflow}{for}(\textcolor{keywordtype}{size\_t} i=0; optarg[i]; ++i)
          \textcolor{keywordflow}{switch}(optarg[i]) \{
            \textcolor{keywordflow}{case} \textcolor{charliteral}{'v'}: 
            \textcolor{keywordflow}{case} \textcolor{charliteral}{'f'}: entity = optarg[i]; \textcolor{keywordflow}{break};
            \textcolor{keywordflow}{case} \textcolor{charliteral}{'n'}:
              \textcolor{keywordflow}{switch}(entity) \{
                \textcolor{keywordflow}{case} \textcolor{charliteral}{'v'}: \_mesh.request\_vertex\_normals(); \textcolor{keywordflow}{break};
                \textcolor{keywordflow}{case} \textcolor{charliteral}{'f'}: \_mesh.request\_face\_normals(); \textcolor{keywordflow}{break};
              \}
              \textcolor{keywordflow}{break};
            \textcolor{keywordflow}{case} \textcolor{charliteral}{'c'}:
              \textcolor{keywordflow}{switch}(entity) \{
                \textcolor{keywordflow}{case} \textcolor{charliteral}{'v'}: \_mesh.request\_vertex\_colors(); \textcolor{keywordflow}{break};
                \textcolor{keywordflow}{case} \textcolor{charliteral}{'f'}: \_mesh.request\_face\_colors(); \textcolor{keywordflow}{break};
              \}
              \textcolor{keywordflow}{break};
            \textcolor{keywordflow}{case} \textcolor{charliteral}{'t'}:
              \textcolor{keywordflow}{switch}(entity) \{
                \textcolor{keywordflow}{case} \textcolor{charliteral}{'v'}: \_mesh.request\_vertex\_texcoords2D(); \textcolor{keywordflow}{break};
              \}
              \textcolor{keywordflow}{break};
          \}
        \textcolor{keywordflow}{break};
      \}
      
      \textcolor{comment}{// -------------------- help}
      \textcolor{keywordflow}{case} \textcolor{charliteral}{'h'}:
        usage\_and\_exit(0);
      \textcolor{keywordflow}{default}:
        usage\_and\_exit(1);
    \}
  \}

  \textcolor{keywordflow}{if} ( \_argc-optind != 2)
    usage\_and\_exit(1);
\}


\textcolor{comment}{// ----------------------------------------------------------------------------}

\textcolor{keywordtype}{void} usage\_and\_exit(\textcolor{keywordtype}{int} xcode)
\{
  std::ostream &os = xcode ? std::cerr : std::cout;

  os << \textcolor{stringliteral}{"Usage: io\_options [Options] <input> <output>\(\backslash\)n"} 
     << std::endl;
  os << \textcolor{stringliteral}{"  Read and write a mesh, using OpenMesh::IO::Options\(\backslash\)n"}
     << std::endl;
  os << \textcolor{stringliteral}{"Options:\(\backslash\)n"}
     << std::endl;
  os << \textcolor{stringliteral}{"a) read options\(\backslash\)n"}
     << std::endl
     << \textcolor{stringliteral}{"  -b\(\backslash\)n"}
     << \textcolor{stringliteral}{"\(\backslash\)tAssume input file is a binary file\(\backslash\)n"}
     << std::endl
     << \textcolor{stringliteral}{"  -s\(\backslash\)n"}
     << \textcolor{stringliteral}{"\(\backslash\)tSwap byte order when reading a binary file!\(\backslash\)n"}
     << std::endl;
  os << \textcolor{stringliteral}{"b) write options\(\backslash\)n"}
     << std::endl
     << \textcolor{stringliteral}{"  -B\(\backslash\)n"}
     << \textcolor{stringliteral}{"\(\backslash\)tWrite binary data\(\backslash\)n"}
     << std::endl
     << \textcolor{stringliteral}{"  -S\(\backslash\)n"}
     << \textcolor{stringliteral}{"\(\backslash\)tSwap byte order, when writing binary data\(\backslash\)n"}
     << std::endl
     << \textcolor{stringliteral}{"  -M/-L\(\backslash\)n"}
     << \textcolor{stringliteral}{"\(\backslash\)tUse MSB/LSB byte ordering, when writing binary data\(\backslash\)n"}
     << std::endl
     << \textcolor{stringliteral}{"  -V\{n|t|c\}\(\backslash\)n"}
     << \textcolor{stringliteral}{"\(\backslash\)tWrite vertex normals, texcoords, and/or colors\(\backslash\)n"}
     << std::endl
     << \textcolor{stringliteral}{"  -F\{n|c\}\(\backslash\)n"}
     << \textcolor{stringliteral}{"\(\backslash\)tWrite face normals, and/or colors\(\backslash\)n"}
     << std::endl;
  os << \textcolor{stringliteral}{"c) Mesh properties\(\backslash\)n"}
     << std::endl
     << \textcolor{stringliteral}{"  -Xv\{n|c|t\}\(\backslash\)n"}
     << \textcolor{stringliteral}{"\(\backslash\)tRequest vertex property normals|colors|texcoords\(\backslash\)n"}
     << std::endl
     << \textcolor{stringliteral}{"  -Xf\{n|c\}\(\backslash\)n"}
     << \textcolor{stringliteral}{"\(\backslash\)tRequest face property normals|colors\(\backslash\)n"}
     << std::endl;
  exit(xcode);
\}

\textcolor{comment}{// end of file}
\textcolor{comment}{// ============================================================================}
\end{DoxyCodeInclude}
 \hypertarget{tutorial_09}{}\subsubsection{Storing custom properties}\label{tutorial_09}
The Open\+Mesh\textquotesingle{} proprietary OM format allows to store and restore custom properties along with the standard properties. For it we have to use named custom properties like the following one

 
\begin{DoxyCodeInclude}
  \hyperlink{a08876}{OpenMesh::VPropHandleT<float>}       vprop\_float;
  mesh.add\_property(vprop\_float,  \textcolor{stringliteral}{"vprop\_float"});

\end{DoxyCodeInclude}


Here we registered a float property for the vertices at the mesh with name \char`\"{}vprop\+\_\+float\char`\"{}. The name of a property, that we want to make persistent, must follow a few rules


\begin{DoxyEnumerate}
\item max. 256 characters long
\item The prefixes {\ttfamily \char`\"{}v\+:\char`\"{}}, {\ttfamily \char`\"{}h\+:\char`\"{}}, {\ttfamily \char`\"{}e\+:\char`\"{}}, {\ttfamily \char`\"{}f\+:\char`\"{}} and {\ttfamily \char`\"{}m\+:\char`\"{}} are reserved.
\end{DoxyEnumerate}

If we stick to this rules we are fine. Furthermore we have to consider, that the names are handled case-\/sensitive.

To actually make a custom property persistent we have to set the persistent flag in the property with


\begin{DoxyCodeInclude}
  mesh.property(vprop\_float).set\_persistent(\textcolor{keyword}{true});

\end{DoxyCodeInclude}


Now we can use {\ttfamily I\+O\+::mesh\+\_\+write()} to write the mesh to a file on disk. The custom properties are added after the standard properties in the file, with the name and it\textquotesingle{}s binary size. These two pieces of information are evaluated when reading the file again. To successfully restore the custom properties, the mesh must have registered named properties with equal names (case-\/sensitive compare). Additionally, when reading the data, the number of bytes read for a property must match the provided number in the file. If the OM reader did not find a suitable named property, it will simply skip it. If the number of bytes do not match, the complete restore will be terminated and {\ttfamily I\+O\+::read\+\_\+mesh()} will return {\ttfamily false}. And if the data cannot be restored, because the appropriate restore method is not available the exception std\+::logic\+\_\+error() will be thrown.

Since we now know the behaviour, we need to know what kind of data can we store? Without any further effort, simply using named properties and setting the persistent flag, we can store following types


\begin{DoxyItemize}
\item bool, stored as a bitset
\item all other fundamental types except long double, (unsigned) long and size\+\_\+t
\item std\+::string, each up to 65536 characters long
\item Open\+Mesh\+::\+Vec\mbox{[}1,2,3,4,6\mbox{]}\mbox{[}c,uc,s,us,i,ui,f,d\mbox{]}
\end{DoxyItemize}

For further reading we call these types basic types. Apparently we cannot store non-\/basic types, which are


\begin{DoxyItemize}
\item pointers
\item structs/classes
\item even more complex data structures, like container of containers.
\end{DoxyItemize}

However there is a way to store custom types ( else we could not store std\+::string). Let\textquotesingle{}s start with an more simple custom data. For instance we have a struct {\ttfamily \hyperlink{a09600}{My\+Data}} like this

 
\begin{DoxyCodeInclude}
\textcolor{keyword}{struct }\hyperlink{a09600}{MyData}
\{
  \textcolor{keywordtype}{int}             ival;
  \textcolor{keywordtype}{double}          dval;
  \textcolor{keywordtype}{bool}            bval;
  \hyperlink{a08448}{OpenMesh::Vec4f} vec4fval;
\};

\end{DoxyCodeInclude}


Here we keep an int, bool, double value and a vector of 4 floats, which are all basic types. Then we need to specialize the template struct Open\+Mesh\+::\+I\+O\+::binary$<$$>$ within the namespace {\ttfamily \hyperlink{a06213}{Open\+Mesh\+::\+IO}} 


\begin{DoxyCodeInclude}
    \textcolor{keyword}{template} <> \textcolor{keyword}{struct }binary<\hyperlink{a09600}{MyData}>

\end{DoxyCodeInclude}


Remember not to use long double, (unsigned) long and size\+\_\+t as basic types because of inconsistencies between 32/64bit architectures.

Herein we have to implement the following set of static member variables and functions\+:


\begin{DoxyCodeInclude}
      \textcolor{keyword}{static} \textcolor{keyword}{const} \textcolor{keywordtype}{bool} \hyperlink{a06213_afadc77f8b3e81138828deba328e65421}{is\_streamable} = \textcolor{keyword}{true};
      \textcolor{keyword}{static} \textcolor{keywordtype}{size\_t} \hyperlink{a06213_a787a7735700a12801c8a505f2c605681}{size\_of}(\textcolor{keywordtype}{void}) 
      \textcolor{keyword}{static} \textcolor{keywordtype}{size\_t} \hyperlink{a06213_a787a7735700a12801c8a505f2c605681}{size\_of}(\textcolor{keyword}{const} value\_type&) 
      \textcolor{keyword}{static} \textcolor{keywordtype}{size\_t} store(std::ostream& \_os, \textcolor{keyword}{const} value\_type& \_v, \textcolor{keywordtype}{bool} \_swap=\textcolor{keyword}{false})
      \textcolor{keyword}{static} \textcolor{keywordtype}{size\_t} restore( std::istream& \_is, value\_type& \_v, \textcolor{keywordtype}{bool} \_swap=\textcolor{keyword}{false})

\end{DoxyCodeInclude}


The flag {\ttfamily is\+\_\+streamable} has to be set to {\ttfamily true}. Else the data cannot be stored at all.

\subparagraph*{{\ttfamily size\+\_\+of} methods }

Since the size of the custom data can be static, which means we know the size at compile time, or the size of it is dynamic, which means me the size is known at runtime, we have to provide the two {\ttfamily size\+\_\+of()} methods.

The first declaration is for the static case, while the second for the dynamic case. Though the static case is more simple, it is not straight forward. We cannot simply use {\ttfamily sizeof()} to determine the data size, because it will return the number ob bytes it needs in memory (possible 32bit alignment). Instead we need the binary size, hence we have to add up the single elements in the struct.

 
\begin{DoxyCodeInclude}
        \textcolor{keywordflow}{return} \textcolor{keyword}{sizeof}(int)+\textcolor{keyword}{sizeof}(\textcolor{keywordtype}{double})+\textcolor{keyword}{sizeof}(bool)+\textcolor{keyword}{sizeof}(\hyperlink{a08448}{OpenMesh::Vec4f}); 

\end{DoxyCodeInclude}


Actually we would need to sum up the single elements of the vector, but in this case we know for sure the result (4 floats make 16 bytes, which is 32bit aligned therefore {\ttfamily sizeof()} returns the wanted size). But keep in mind, that this a potential location for errors, when writing custom binary support.

The second declaration is for the dynamic case, where the custom data contains pointers or references. This static member must properly count the data, by disolving the pointers/references, if this data has to be stored as well. In the dynamic stetting the static variant cannot return the size, therefore it must return {\ttfamily I\+O\+::\+Unknown\+Size}.

In this case the dynamic variant simply returns the size by calling the static variant, as the sizes are identical for both cases.

\subparagraph*{{\ttfamily store} / {\ttfamily restore} }

For the dynamic case as for the static case, we have to make up a scheme how we would store the data. One option is to store the length of the data and then store the data itself. For instance the type {\ttfamily std\+::string} is implemented this way. (We store first the length in a 16bit word (=$>$ max. length 65536), then the characters follow. Hence {\ttfamily size\+\_\+of()} returns 2 bytes for the length plus the actual length of the value {\ttfamily v}.) Since {\ttfamily \hyperlink{a09600}{My\+Data}} contains only basic types we can implement the necessary methods {\ttfamily store} and {\ttfamily restore}, by simply breaking up the data into the basic types using the pre-\/defined store/restore methods for them\+:


\begin{DoxyCodeInclude}
      \textcolor{keyword}{static} \textcolor{keywordtype}{size\_t} store(std::ostream& \_os, \textcolor{keyword}{const} value\_type& \_v, \textcolor{keywordtype}{bool} \_swap=\textcolor{keyword}{false})
      \{ 
        \textcolor{keywordtype}{size\_t} bytes;
        bytes  = IO::store( \_os, \_v.ival, \_swap );
        bytes += IO::store( \_os, \_v.dval, \_swap );
        bytes += IO::store( \_os, \_v.bval, \_swap );
        bytes += IO::store( \_os, \_v.vec4fval, \_swap );
        \textcolor{keywordflow}{return} \_os.good() ? bytes : 0;
      \}
      \textcolor{keyword}{static} \textcolor{keywordtype}{size\_t} restore( std::istream& \_is, value\_type& \_v, \textcolor{keywordtype}{bool} \_swap=\textcolor{keyword}{false})
      \{ 
        \textcolor{keywordtype}{size\_t} bytes;
        bytes  = IO::restore( \_is, \_v.ival, \_swap );
        bytes += IO::restore( \_is, \_v.dval, \_swap );
        bytes += IO::restore( \_is, \_v.bval, \_swap );
        bytes += IO::restore( \_is, \_v.vec4fval, \_swap );
        \textcolor{keywordflow}{return} \_is.good() ? bytes : 0;
      \}

\end{DoxyCodeInclude}


It\textquotesingle{}s very important, that the store/restore methods count the written/read bytes correctly and return the value. On error both functions must return 0.

A more complex situation is given with the following property

 
\begin{DoxyCodeInclude}
\textcolor{keyword}{typedef} std::map< std::string, unsigned int > MyMap;
  \hyperlink{a08892}{OpenMesh::MPropHandleT<MyMap>}       mprop\_map;

\end{DoxyCodeInclude}


In this case the data contains a container, a map from strings to integer numbers. If we want to store this as well, we need to make up a scheme how the map will be stored in a sequential layout. First we store the number of elements in the map. Then, since the map has an iterator, we simply iterate over all elements and store each pair (key/value). This procedure is equal for the {\ttfamily size\+\_\+of()}, {\ttfamily store()}, and {\ttfamily restore()} methods. For example the {\ttfamily size\+\_\+of()} methods look like this

 
\begin{DoxyCodeInclude}
      \textcolor{keyword}{static} \textcolor{keywordtype}{size\_t} \hyperlink{a06213_a787a7735700a12801c8a505f2c605681}{size\_of}(\textcolor{keywordtype}{void}) \{ \textcolor{keywordflow}{return} UnknownSize; \}
      \textcolor{keyword}{static} \textcolor{keywordtype}{size\_t} \hyperlink{a06213_a787a7735700a12801c8a505f2c605681}{size\_of}(\textcolor{keyword}{const} value\_type& \_v) 
      \{ 
        \textcolor{keywordflow}{if} (\_v.empty())
          \textcolor{keywordflow}{return} \textcolor{keyword}{sizeof}(\textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int});
        
        value\_type::const\_iterator it = \_v.begin();
        \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int}   N     = \_v.size();
        \textcolor{keywordtype}{size\_t}         bytes = IO::size\_of(N);

        \textcolor{keywordflow}{for}(;it!=\_v.end(); ++it)
        \{
          bytes += IO::size\_of( it->first );
          bytes += IO::size\_of( it->second );
        \}
        \textcolor{keywordflow}{return} bytes;
      \}

\end{DoxyCodeInclude}


The implementation of {\ttfamily store()} and {\ttfamily restore()} follow a similar pattern.

The given example program does the following steps


\begin{DoxyEnumerate}
\item Create a mesh and generate a cube
\item Add a few custom properties
\item Fill them with test data
\item Make the properties persistent
\item Store mesh in a file named \textquotesingle{}persistent-\/check.\+om\textquotesingle{}
\item Clear the mesh
\item Restore mesh
\item Check the content on equality with the test data.
\end{DoxyEnumerate}

Since the example is a little bit longer than usual the source is in several files. The main program is in {\ttfamily persistence.\+cc}, the cube generator in {\ttfamily generate\+\_\+cube.\+hh}, {\ttfamily stats.\+hh} provides little tools to display information about the mesh and the properties, the file {\ttfamily fill\+\_\+props.\+hh} providing the test data, and {\ttfamily int2roman.\+hh/}.cc, which is used in fill\+\_\+props.\+hh. All necessary parts are in {\ttfamily persistence.\+cc}, which is displayed in full length below. For the other files please have a look in the directory {\ttfamily Open\+Mesh/\+Doc/\+Tutorial/09-\/persistence/}.


\begin{DoxyCodeInclude}
\textcolor{preprocessor}{#include <iostream>}
\textcolor{preprocessor}{#include <string>}
\textcolor{preprocessor}{#include <map>}
\textcolor{comment}{// -------------------- OpenMesh}
\textcolor{preprocessor}{#include <OpenMesh/Core/IO/MeshIO.hh>}
\textcolor{preprocessor}{#include <OpenMesh/Core/Mesh/TriMesh\_ArrayKernelT.hh>}
\textcolor{preprocessor}{#include <OpenMesh/Core/Mesh/PolyMesh\_ArrayKernelT.hh>}
\textcolor{comment}{// -------------------- little helper}
\textcolor{preprocessor}{#include "generate\_cube.hh"}
\textcolor{preprocessor}{#include "stats.hh"}
\textcolor{preprocessor}{#include "fill\_props.hh"}

\textcolor{comment}{// ----------------------------------------------------------------------------}

\textcolor{comment}{// Set to 1 to use an PolyMesh type.}
\textcolor{preprocessor}{#define UsePolyMesh 1}

\textcolor{comment}{// ----------------------------------------------------------------------------}

\textcolor{keyword}{using namespace }\hyperlink{a06210}{OpenMesh};

\textcolor{comment}{// ----------------------------------------------------------------------------}

\textcolor{keyword}{typedef} \hyperlink{a08764}{TriMesh\_ArrayKernelT<>}  \hyperlink{a05024_a41cbba34c91d41c5325cc019b097ad91}{TriMesh};
\textcolor{keyword}{typedef} \hyperlink{a08772}{PolyMesh\_ArrayKernelT<>} \hyperlink{a05006_a6f3eb4ad4fc6f95326b848d821958f35}{PolyMesh};

\textcolor{preprocessor}{#if UsePolyMesh}
\textcolor{keyword}{typedef} PolyMesh Mesh;
\textcolor{preprocessor}{#else}
\textcolor{keyword}{typedef} TriMesh Mesh;
\textcolor{preprocessor}{#endif}

\textcolor{comment}{// ----------------------------------------------------------------------------}

\textcolor{preprocessor}{#ifndef DOXY\_IGNORE\_THIS}

\textcolor{keyword}{struct }\hyperlink{a09600}{MyData}
\{
  \textcolor{keywordtype}{int}             ival;
  \textcolor{keywordtype}{double}          dval;
  \textcolor{keywordtype}{bool}            bval;
  \hyperlink{a08448}{OpenMesh::Vec4f} vec4fval;

  \hyperlink{a09600}{MyData}()
    : ival(0), dval(0.0), bval(false)
  \{ \}

  \hyperlink{a09600}{MyData}( \textcolor{keyword}{const} \hyperlink{a09600}{MyData}& \_cpy )
    : ival(\_cpy.ival), dval(\_cpy.dval), bval(\_cpy.bval), 
      vec4fval(\_cpy.vec4fval)
  \{ \}


  \textcolor{comment}{// ---------- assignment}

  \hyperlink{a09600}{MyData}& operator = (\textcolor{keyword}{const} \hyperlink{a09600}{MyData}& \_rhs) 
  \{ 
    ival = \_rhs.ival; 
    dval = \_rhs.dval;
    bval = \_rhs.bval;
    vec4fval = \_rhs.vec4fval;
    \textcolor{keywordflow}{return} *\textcolor{keyword}{this};
  \}

  \hyperlink{a09600}{MyData}& operator = (\textcolor{keywordtype}{int}    \_rhs) \{ ival = \_rhs; \textcolor{keywordflow}{return} *\textcolor{keyword}{this}; \}
  \hyperlink{a09600}{MyData}& operator = (\textcolor{keywordtype}{double} \_rhs) \{ dval = \_rhs; \textcolor{keywordflow}{return} *\textcolor{keyword}{this}; \}
  \hyperlink{a09600}{MyData}& operator = (\textcolor{keywordtype}{bool}   \_rhs) \{ bval = \_rhs; \textcolor{keywordflow}{return} *\textcolor{keyword}{this}; \}
  \hyperlink{a09600}{MyData}& operator = (\textcolor{keyword}{const} \hyperlink{a08448}{OpenMesh::Vec4f}& \_rhs) 
  \{ vec4fval = \_rhs; \textcolor{keywordflow}{return} *\textcolor{keyword}{this}; \}


  \textcolor{comment}{// ---------- comparison}

  \textcolor{keywordtype}{bool} operator == (\textcolor{keyword}{const} \hyperlink{a09600}{MyData}& \_rhs)\textcolor{keyword}{ const}
\textcolor{keyword}{  }\{ 
    \textcolor{keywordflow}{return} ival == \_rhs.ival
      &&   dval == \_rhs.dval
      &&   bval == \_rhs.bval
      &&   vec4fval == \_rhs.vec4fval;
  \}

  \textcolor{keywordtype}{bool} operator != (\textcolor{keyword}{const} \hyperlink{a09600}{MyData}& \_rhs)\textcolor{keyword}{ const }\{ \textcolor{keywordflow}{return} !(*\textcolor{keyword}{this} == \_rhs); \}

\};

\textcolor{preprocessor}{#endif}


\textcolor{comment}{// ----------------------------------------------------------------------------}

\textcolor{keyword}{typedef} std::map< std::string, unsigned int > MyMap;


\textcolor{comment}{// ----------------------------------------------------------------------------}

\textcolor{preprocessor}{#ifndef DOXY\_IGNORE\_THIS}

\textcolor{keyword}{namespace }\hyperlink{a06210}{OpenMesh} \{
  \textcolor{keyword}{namespace }IO \{

    \textcolor{comment}{// support persistence for struct MyData}

    \textcolor{keyword}{template} <> \textcolor{keyword}{struct }binary<\hyperlink{a09600}{MyData}>
    \{
      \textcolor{keyword}{typedef} \hyperlink{a09600}{MyData} value\_type;

      \textcolor{keyword}{static} \textcolor{keyword}{const} \textcolor{keywordtype}{bool} is\_streamable = \textcolor{keyword}{true};

      \textcolor{comment}{// return binary size of the value}

      \textcolor{keyword}{static} \textcolor{keywordtype}{size\_t} \hyperlink{a06213_a787a7735700a12801c8a505f2c605681}{size\_of}(\textcolor{keywordtype}{void}) 
      \{ 
        \textcolor{keywordflow}{return} \textcolor{keyword}{sizeof}(int)+\textcolor{keyword}{sizeof}(\textcolor{keywordtype}{double})+\textcolor{keyword}{sizeof}(bool)+\textcolor{keyword}{sizeof}(\hyperlink{a08448}{OpenMesh::Vec4f}); 
      \}

      \textcolor{keyword}{static} \textcolor{keywordtype}{size\_t} \hyperlink{a06213_a787a7735700a12801c8a505f2c605681}{size\_of}(\textcolor{keyword}{const} value\_type&) 
      \{ 
        \textcolor{keywordflow}{return} \hyperlink{a06213_a787a7735700a12801c8a505f2c605681}{size\_of}(); 
      \}

      \textcolor{keyword}{static} \textcolor{keywordtype}{size\_t} store(std::ostream& \_os, \textcolor{keyword}{const} value\_type& \_v, \textcolor{keywordtype}{bool} \_swap=\textcolor{keyword}{false})
      \{ 
        \textcolor{keywordtype}{size\_t} bytes;
        bytes  = IO::store( \_os, \_v.ival, \_swap );
        bytes += IO::store( \_os, \_v.dval, \_swap );
        bytes += IO::store( \_os, \_v.bval, \_swap );
        bytes += IO::store( \_os, \_v.vec4fval, \_swap );
        \textcolor{keywordflow}{return} \_os.good() ? bytes : 0;
      \}

      \textcolor{keyword}{static} \textcolor{keywordtype}{size\_t} restore( std::istream& \_is, value\_type& \_v, \textcolor{keywordtype}{bool} \_swap=\textcolor{keyword}{false})
      \{ 
        \textcolor{keywordtype}{size\_t} bytes;
        bytes  = IO::restore( \_is, \_v.ival, \_swap );
        bytes += IO::restore( \_is, \_v.dval, \_swap );
        bytes += IO::restore( \_is, \_v.bval, \_swap );
        bytes += IO::restore( \_is, \_v.vec4fval, \_swap );
        \textcolor{keywordflow}{return} \_is.good() ? bytes : 0;
      \}
    \};


    \textcolor{keyword}{template} <> \textcolor{keyword}{struct }binary< MyMap >
    \{
      \textcolor{keyword}{typedef} MyMap value\_type;

      \textcolor{keyword}{static} \textcolor{keyword}{const} \textcolor{keywordtype}{bool} is\_streamable = \textcolor{keyword}{true};

      \textcolor{comment}{// return generic binary size of self, if known}
      \textcolor{keyword}{static} \textcolor{keywordtype}{size\_t} \hyperlink{a06213_a787a7735700a12801c8a505f2c605681}{size\_of}(\textcolor{keywordtype}{void}) \{ \textcolor{keywordflow}{return} UnknownSize; \}

      \textcolor{comment}{// return binary size of the value}
      \textcolor{keyword}{static} \textcolor{keywordtype}{size\_t} \hyperlink{a06213_a787a7735700a12801c8a505f2c605681}{size\_of}(\textcolor{keyword}{const} value\_type& \_v) 
      \{ 
        \textcolor{keywordflow}{if} (\_v.empty())
          \textcolor{keywordflow}{return} \textcolor{keyword}{sizeof}(\textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int});
        
        value\_type::const\_iterator it = \_v.begin();
        \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int}   N     = \_v.size();
        \textcolor{keywordtype}{size\_t}         bytes = \hyperlink{a06213_a787a7735700a12801c8a505f2c605681}{IO::size\_of}(N);

        \textcolor{keywordflow}{for}(;it!=\_v.end(); ++it)
        \{
          bytes += \hyperlink{a06213_a787a7735700a12801c8a505f2c605681}{IO::size\_of}( it->first );
          bytes += \hyperlink{a06213_a787a7735700a12801c8a505f2c605681}{IO::size\_of}( it->second );
        \}
        \textcolor{keywordflow}{return} bytes;
      \}

      \textcolor{keyword}{static} 
      \textcolor{keywordtype}{size\_t} store(std::ostream& \_os, \textcolor{keyword}{const} value\_type& \_v, \textcolor{keywordtype}{bool} \_swap=\textcolor{keyword}{false})
      \{ 
        \textcolor{keywordtype}{size\_t}   bytes = 0;
        \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} N = \_v.size();

        value\_type::const\_iterator it = \_v.begin();

        bytes += IO::store( \_os, N, \_swap );

        \textcolor{keywordflow}{for} (; it != \_v.end() && \_os.good(); ++it)
        \{
          bytes += IO::store( \_os, it->first, \_swap );
          bytes += IO::store( \_os, it->second, \_swap );
        \}
        \textcolor{keywordflow}{return} \_os.good() ? bytes : 0;
      \}

      \textcolor{keyword}{static} 
      \textcolor{keywordtype}{size\_t} restore( std::istream& \_is, value\_type& \_v, \textcolor{keywordtype}{bool} \_swap=\textcolor{keyword}{false})
      \{ 
        \textcolor{keywordtype}{size\_t}   bytes = 0;
        \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} N = 0;

        \_v.clear();

        bytes += IO::restore( \_is, N, \_swap );
        value\_type::key\_type key;
        value\_type::mapped\_type  val;

        \textcolor{keywordflow}{for} (\textcolor{keywordtype}{size\_t} i=0; i<N && \_is.good(); ++i)
        \{          
          bytes += IO::restore( \_is, key, \_swap );
          bytes += IO::restore( \_is, val, \_swap );
          \_v[key] = val;
        \}
        \textcolor{keywordflow}{return} \_is.good() ? bytes : 0;
      \}
    \};

  \}
\}

\textcolor{preprocessor}{#endif}


\textcolor{comment}{// ----------------------------------------------------------------------------}

\textcolor{keywordtype}{int} main(\textcolor{keywordtype}{void})
\{
  \textcolor{comment}{//}
  Mesh mesh;

  
  \textcolor{comment}{// generate a geometry}
  generate\_cube<Mesh>(mesh);


  \textcolor{comment}{// should display 8 vertices, 18/12 edges, 12/6 faces (Tri/Poly)}
  mesh\_stats(mesh);


  \textcolor{comment}{// print out information about properties}
  mesh\_property\_stats(mesh);


  std::cout << \textcolor{stringliteral}{"Define some custom properties..\(\backslash\)n"};

  \hyperlink{a08876}{OpenMesh::VPropHandleT<float>}       vprop\_float;
  \hyperlink{a08884}{OpenMesh::EPropHandleT<bool>}        eprop\_bool;
  \hyperlink{a08888}{OpenMesh::FPropHandleT<std::string>} fprop\_string;
  \hyperlink{a08880}{OpenMesh::HPropHandleT<MyData>}      hprop\_mydata;
  \hyperlink{a08892}{OpenMesh::MPropHandleT<MyMap>}       mprop\_map;
    
  std::cout << \textcolor{stringliteral}{".. and registrate them at the mesh object.\(\backslash\)n"};

  mesh.add\_property(vprop\_float,  \textcolor{stringliteral}{"vprop\_float"});
  mesh.add\_property(eprop\_bool,   \textcolor{stringliteral}{"eprop\_bool"});
  mesh.add\_property(fprop\_string, \textcolor{stringliteral}{"fprop\_string"});
  mesh.add\_property(hprop\_mydata, \textcolor{stringliteral}{"hprop\_mydata"});
  mesh.add\_property(mprop\_map,    \textcolor{stringliteral}{"mprop\_map"});


  mesh\_property\_stats(mesh);


  std::cout << \textcolor{stringliteral}{"Now let's fill the props..\(\backslash\)n"};

  fill\_props(mesh, vprop\_float);
  fill\_props(mesh, eprop\_bool);
  fill\_props(mesh, fprop\_string);
  fill\_props(mesh, hprop\_mydata);
  fill\_props(mesh, mprop\_map);


  std::cout << \textcolor{stringliteral}{"Check props..\(\backslash\)n"};
\textcolor{preprocessor}{#define CHK\_PROP( PH ) \(\backslash\)}
\textcolor{preprocessor}{  std::cout << "  " << #PH << " " \(\backslash\)}
\textcolor{preprocessor}{            << (fill\_props(mesh, PH, true)?"ok\(\backslash\)n":"error\(\backslash\)n")}

  CHK\_PROP(vprop\_float);
  CHK\_PROP(eprop\_bool);
  CHK\_PROP(fprop\_string);
  CHK\_PROP(hprop\_mydata);
  CHK\_PROP(mprop\_map);
\textcolor{preprocessor}{#undef CHK\_PROP}


  std::cout << \textcolor{stringliteral}{"Set persistent flag..\(\backslash\)n"};
\textcolor{preprocessor}{#define SET\_PERS( PH ) \(\backslash\)}
\textcolor{preprocessor}{    mesh.property(PH).set\_persistent(true); \(\backslash\)}
\textcolor{preprocessor}{    std::cout << "  " << #PH << " " \(\backslash\)}
\textcolor{preprocessor}{              << (mesh.property(PH).persistent()?"ok\(\backslash\)n":"failed!\(\backslash\)n")}

  mesh.property(vprop\_float).set\_persistent(\textcolor{keyword}{true});
  std::cout << \textcolor{stringliteral}{"  vprop\_float "}
            << (mesh.property(vprop\_float).persistent()?\textcolor{stringliteral}{"ok\(\backslash\)n"}:\textcolor{stringliteral}{"failed!\(\backslash\)n"});
  
  SET\_PERS( eprop\_bool );
  SET\_PERS( fprop\_string );
  SET\_PERS( hprop\_mydata );
  mesh.mproperty(mprop\_map).set\_persistent(\textcolor{keyword}{true});
  std::cout << \textcolor{stringliteral}{"  mprop\_map "}
            << (mesh.mproperty(mprop\_map).persistent()?\textcolor{stringliteral}{"ok\(\backslash\)n"}:\textcolor{stringliteral}{"failed!\(\backslash\)n"});
 

  std::cout << \textcolor{stringliteral}{"Write mesh.."};
  \textcolor{keywordflow}{if} (\hyperlink{a06213_a18286a792ebf896872f5e26182fc5c7b}{IO::write\_mesh}( mesh, \textcolor{stringliteral}{"persistence-check.om"} ))
    std::cout << \textcolor{stringliteral}{"  ok\(\backslash\)n"};
  \textcolor{keywordflow}{else}
  \{
    std::cout << \textcolor{stringliteral}{"  failed\(\backslash\)n"};
    \textcolor{keywordflow}{return} 1;
  \}


  std::cout << \textcolor{stringliteral}{"Clear mesh\(\backslash\)n"};
  mesh.clear();
  mesh\_stats(mesh, \textcolor{stringliteral}{"  "});
  

  std::cout << \textcolor{stringliteral}{"Read back mesh.."};
  \textcolor{keywordflow}{try}
  \{
    \textcolor{keywordflow}{if} (\hyperlink{a06213_ac417960ec28ffdd7e7003a2b1ebb2d1c}{IO::read\_mesh}( mesh, \textcolor{stringliteral}{"persistence-check.om"} ))
      std::cout << \textcolor{stringliteral}{"  ok\(\backslash\)n"};
    \textcolor{keywordflow}{else}
    \{
      std::cout << \textcolor{stringliteral}{"  failed!\(\backslash\)n"};
      \textcolor{keywordflow}{return} 1;
    \}
    mesh\_stats(mesh, \textcolor{stringliteral}{"  "});
  \}
  \textcolor{keywordflow}{catch}( std::exception &x )
  \{
    std::cerr << x.what() << std::endl;
    \textcolor{keywordflow}{return} 1;
  \}


  std::cout << \textcolor{stringliteral}{"Check props..\(\backslash\)n"};
\textcolor{preprocessor}{#define CHK\_PROP( PH ) \(\backslash\)}
\textcolor{preprocessor}{  std::cout << "  " << #PH << " " \(\backslash\)}
\textcolor{preprocessor}{            << (fill\_props(mesh, PH, true)?"ok\(\backslash\)n":"error\(\backslash\)n")}
  CHK\_PROP(vprop\_float);
  CHK\_PROP(eprop\_bool);
  CHK\_PROP(fprop\_string);
  CHK\_PROP(hprop\_mydata);
  CHK\_PROP(mprop\_map);
\textcolor{preprocessor}{#undef CHK\_PROP}

  \textcolor{keywordflow}{return} 0;
\}

\textcolor{comment}{// end of file}
\textcolor{comment}{// ============================================================================}
\end{DoxyCodeInclude}
 \hypertarget{additional_information}{}\subsection{Additional Information on Open\+Mesh}\label{additional_information}
\begin{DoxyItemize}
\item \hyperlink{mesh_first_to_read}{Notes on template programming} \item \hyperlink{mesh_cpp}{Some words on the C++ implementation} \item \hyperlink{mesh_members}{Where do I find a list of all member functions ?} \item \hyperlink{naming_conventions}{Naming Conventions} \item \hyperlink{mesh_speedup}{Some Notes on how to speedup Open\+Mesh} \item \hyperlink{om_changelog}{Changelog} \end{DoxyItemize}
\hypertarget{mesh_first_to_read}{}\subsubsection{Notes on template programming}\label{mesh_first_to_read}
Please note, that Open\+Mesh makes heavily use of C++ templates, generic programming and all that stuff (see \hyperlink{mesh_cpp}{Some words on the C++ implementation}). Therefore read this section carefully (else you get lost in the reference manual)\+:

\subsubsection*{There is no such thing like the Open\+Mesh class}

The library provides a set of classes ( 99\% templates ;-\/) ), where the inheritance relationship is given by template parameterization. You might ask\+: \char`\"{}\+What the heck is that?\char`\"{} It means, a parent class is passed as a template argument to another class\+:


\begin{DoxyCode}
\textcolor{keyword}{class }P1 \{ \}
\textcolor{keyword}{class }P2 \{ \}
\textcolor{keyword}{template} <\textcolor{keyword}{typename} Parent> \textcolor{keyword}{class }B : \textcolor{keyword}{public} Parent \{\}

\textcolor{keyword}{typedef} B<P1> fooB1;
\textcolor{keyword}{typedef} B<P2> fooB2;
\end{DoxyCode}


Voila, we have created two different types of B. Depending on the interface, the public member elements, provided by {\ttfamily P1} or {\ttfamily P2}, {\ttfamily foo\+B1} and {\ttfamily foo\+B2} might have different behaviours or even different interfaces! But if {\ttfamily P1} and {\ttfamily P2} have the some interface or at least a common interface, then from programming point of view there is no difference using {\ttfamily foo\+B1} or {\ttfamily foo\+B2}. And this is all about. Open\+Mesh defines an interface concept for the kernel which is documented in \hyperlink{a08324}{Open\+Mesh\+::\+Concepts\+::\+KernelT}. As long as the kernel provides this the class handling polygonal meshes {\ttfamily \hyperlink{a08776}{Open\+Mesh\+::\+Poly\+MeshT}} can use any kernel.

\subsubsection*{Therefore documentation resides in two spaces}


\begin{DoxyEnumerate}
\item Associated with the class/struct (as usual)
\item In a concept class in cases like the example code above. Hence, if you want to know what a mesh type has to offer refer to \hyperlink{a08324}{Open\+Mesh\+::\+Concepts\+::\+KernelT}, \hyperlink{a08776}{Open\+Mesh\+::\+Poly\+MeshT}, \hyperlink{a08816}{Open\+Mesh\+::\+Tri\+MeshT}. 
\end{DoxyEnumerate}\hypertarget{mesh_cpp}{}\subsubsection{Some words on the C++ implementation}\label{mesh_cpp}
If one takes a look at the goals and features section it soon becomes obvious that these goals cannot be achieved using trivial C++ features only. We make heavy use of templates, (partial) template specialization, generative and generic programming, and the S\+TL. This may be a challenge for you as well as for your compiler, as these are quite late features of the C++ language.

While knowledge of generative programming is only necessary if you want to create your own mesh kernels or extend iterators or similar types, you will {\bfseries N\+OT} need it for simply using these things. Nevertheless working knowledge of C++ and basic knowlege of templates is required. To get into this stuff we recommend the following books\+:

\begin{DoxyItemize}
\item Bjarne Stroustrup, {\itshape  The C++ Programming Language },\end{DoxyItemize}
\begin{DoxyItemize}
\item Matthew H. Austern, {\itshape  Generic Programming and the S\+TL\+: Using and Extending the C++ Standard Template Library },\end{DoxyItemize}
\begin{DoxyItemize}
\item Andrei Alexandrescu, {\itshape  Modern C++ Design\+: Generic Programming and Design Patterns Applied },\end{DoxyItemize}
\begin{DoxyItemize}
\item Krzysztof Czarnecki, Ulrich Eisenecker, {\itshape  Generative Programming\+: Methods, Tools, and Applications }. \end{DoxyItemize}
\hypertarget{mesh_members}{}\subsubsection{Where do I find a list of all member functions ?}\label{mesh_members}
The following picture shows the (simplified) conceptual inheritance diagram for the Open\+Mesh classes.



The basis for all meshes is the corresponding {\ttfamily Mesh\+Kernel}, taking care of the internal storage of the mesh items (vertices, (half-\/)edges, faces). This kernel is inherited by the {\ttfamily Poly\+MeshT}, i.\+e. the general polygonal mesh, adding higher level functionality. For specialization purposes the class {\ttfamily Tri\+MeshT} is derived from {\ttfamily Poly\+MeshT} and overrides some member functions or adds functions only suitable for pure triangle meshes.

In most cases a class (e.\+g. {\ttfamily Poly\+MeshT}) gets the class it should derive from (e.\+g. the mesh kernel) as a template parameter. The documentation class Open\+Mesh\+::\+Concepts\+::\+Mesh\+Kernel\+::\+KernelT lists the minimal interface a mesh kernel must provide. Special kernels may provide some more functionality, in this case refer to this kernel\textquotesingle{}s documentation (see \hyperlink{a06169}{Mesh Kernels}). Therefore your mesh provides the pubic member functions of


\begin{DoxyItemize}
\item The mesh kernel. 
\item The general polygonal mesh. 
\item The specialized triangle mesh (if you use a Tri\+Mesh instead of a Poly\+Mesh). 
\end{DoxyItemize}

\begin{DoxySeeAlso}{See also}
\hyperlink{a06211}{Open\+Mesh\+::\+Concepts} 

\hyperlink{a08324}{Open\+Mesh\+::\+Concepts\+::\+KernelT} 

\hyperlink{a08776}{Open\+Mesh\+::\+Poly\+MeshT} 

\hyperlink{a08816}{Open\+Mesh\+::\+Tri\+MeshT} 
\end{DoxySeeAlso}
\hypertarget{naming_conventions}{}\subsubsection{Naming Conventions}\label{naming_conventions}
Please follow the naming conventions, if you extend the A\+CG-\/code !

{\bfseries Files\+:} \begin{DoxyItemize}
\item {\ttfamily My\+Class.\+cc} for C++-\/\+Implementation of class {\ttfamily My\+Class} \item {\ttfamily My\+Class.\+hh} for C++-\/\+Header of class {\ttfamily My\+Class} \end{DoxyItemize}
{\bfseries Classes\+:} \begin{DoxyItemize}
\item Class names start with a capital letter\+: {\ttfamily My\+Class} \item Class templates end with {\ttfamily T\+:} {\ttfamily My\+Class\+TemplateT} \end{DoxyItemize}
{\bfseries Variables\+:} \begin{DoxyItemize}
\item One leading underscore for parameters in function-\/calls\+: {\ttfamily \+\_\+var} \item One trailing underscore for member-\/variables\+: {\ttfamily var\+\_\+} \item Two trailing underscores for static member-\/variables\+: {\ttfamily var\+\_\+\+\_\+} \end{DoxyItemize}
{\bfseries Functions\+:} \begin{DoxyItemize}
\item Words are separated by capital letter\+: {\ttfamily my\+Function()} \end{DoxyItemize}
{\bfseries Accessing members\+:} \begin{DoxyItemize}
\item To get the member {\ttfamily xxx\+\_\+} use {\ttfamily  const\& xxx() const } \item To set the member {\ttfamily xxx\+\_\+} use {\ttfamily  void set\+\_\+xxx(arg) }\end{DoxyItemize}
The following naming conventions are used for the Open\+Mesh code\+:

{\bfseries Files\+:} \begin{DoxyItemize}
\item {\ttfamily My\+Class.\+cc} for C++-\/\+Implementation of class {\ttfamily My\+Class} \item {\ttfamily My\+Class\+T\+\_\+impl.\+hh} for Header only C++-\/\+Implementation of template class {\ttfamily My\+Class} \item {\ttfamily My\+Class.\+hh} for C++-\/\+Header of class {\ttfamily My\+Class} \end{DoxyItemize}
{\bfseries Classes\+:} \begin{DoxyItemize}
\item Class names start with a capital letter\+: {\ttfamily My\+Class} \item Class templates end with {\ttfamily T\+:} {\ttfamily My\+Class\+TemplateT} \end{DoxyItemize}
{\bfseries Variables\+:} \begin{DoxyItemize}
\item One leading underscore for parameters in function-\/calls\+: {\ttfamily \+\_\+var} \item One trailing underscore for member-\/variables\+: {\ttfamily var\+\_\+} \item Two trailing underscores for static member-\/variables\+: {\ttfamily var\+\_\+\+\_\+} \end{DoxyItemize}
{\bfseries Functions\+:} \begin{DoxyItemize}
\item Words are separated by underscores\+: {\ttfamily my\+\_\+function()} \end{DoxyItemize}
{\bfseries Accessing members\+:} \begin{DoxyItemize}
\item To get the member {\ttfamily xxx\+\_\+} use {\ttfamily  const\& xxx() const } \item To set the member {\ttfamily xxx\+\_\+} use {\ttfamily  void set\+\_\+xxx(arg) } \end{DoxyItemize}
\hypertarget{mesh_speedup}{}\subsubsection{Some Notes on how to speedup Open\+Mesh}\label{mesh_speedup}
On this page we collect some hints which can be used to speedup \hyperlink{a06210}{Open\+Mesh}. This list is not complete, so if you have additional hints, just tell us.


\begin{DoxyItemize}
\item {\bfseries Visual Studio} 
\begin{DoxyItemize}
\item The prebuild binaries we ship are not compiled with full optimization enabled. You can build it yourself with full optimization. (\char`\"{}\+Full Optimization\char`\"{} (Project setting\+: C/\+C++ -\/$>$$>$ Optimization) ). Please remember that you than have to build everything with this flag to avoid incompatibilities. 
\end{DoxyItemize}
\end{DoxyItemize}\hypertarget{om_changelog}{}\subsubsection{Changelog}\label{om_changelog}
 \hypertarget{OpenVolumeMeshDoc}{}\section{Open\+Volume\+Mesh Documentation}\label{OpenVolumeMeshDoc}


Welcome to the Open\+Volume\+Mesh documentation.

Open\+Volume\+Mesh is a generic data structure for the comfortable handling of arbitrary polyhedral meshes. Its concepts are closely related to \hyperlink{a06210}{Open\+Mesh} (\href{http://www.openmesh.org}{\tt http\+://www.\+openmesh.\+org}). In particular, Open\+Volume\+Mesh carries the general idea of storing edges as so-\/called (directed) half-\/edges over to the face definitions. So, faces are split up into so-\/called half-\/faces having opposing orientations. But unlike in the original concept of half-\/edges, local incidence information is not stored on a per half-\/edge basis. Instead, all entities are arranged in arrays, which makes Open\+Volume\+Mesh an index-\/based data structure where the access to entities via handles is accomplished in constant time complexity. By making the data structure index-\/based, we alleviate the major drawback of the half-\/edge data structure of only being capable to represent manifold meshes. In our concept, each entity of dimension $n$ only stores an (ordered) tuple of handles (or indices) pointing to the incident entities of dimension $(n-1)$. These incidence relations are called the top-\/down incidences. They are intrinsic to the implemented concept of volumentric meshes. One can additionally compute bottom-\/up incidences, which means that for each entity of dimension $n$, we also store handles to adjacent entities of dimension $(n+1)$. These incidence relations have to be computed explicitly which can be performed in linear time complexity. Both incidence relations, the top-\/down and the bottom-\/up incidences, are used to provide a set of iterators and circulators that are comfortable in use. As in \hyperlink{a06210}{Open\+Mesh}, Open\+Volume\+Mesh provides an entirely generic underlying property system that allows attaching properties of any kind to the entities.

In this documentation, we first give a concise overview of the implemented concepts in Section \hyperlink{concepts}{Concepts of Open\+Volume\+Mesh}. In Section \hyperlink{iterators_and_circulators}{Iterators and Circulators}, we introduce all necessary iterators provided by Open\+Volume\+Mesh. This library is additionally shipped with a file format that allows for reading and permanent storage of the volumetric meshes from/to files. Its specification can be found in \hyperlink{file_format}{File Format}. For information on the property system, please refer to Section \hyperlink{property_system}{Property System}. Step-\/by-\/step tutorials and code examples can be found in the tutorials section. Open\+Volume\+Mesh comes with a complete C\+Make build system which facilitates building the library platform-\/independently. It is written in pure C++ using the standard template library and does not have any external dependencies except for Google\+Test which is (optionally) needed for building the unit tests. As per default, the unit tests are excluded from the build but can turned on as desired. Find information on how to build Open\+Volume\+Mesh in Section \hyperlink{building_openvolumemesh}{Building Open\+Volume\+Mesh}.

{\bfseries Overview\+:} 

\begin{DoxyItemize}
\item \hyperlink{concepts}{Concepts of Open\+Volume\+Mesh} \item \hyperlink{iterators_and_circulators}{Iterators and Circulators} \item \hyperlink{file_format}{File Format} \item \hyperlink{property_system}{Property System} \item \hyperlink{building_openvolumemesh}{Building Open\+Volume\+Mesh}\end{DoxyItemize}
{\bfseries Tutorials\+:} 

\begin{DoxyItemize}
\item \hyperlink{ovm_tutorial_01}{Tutorial 01\+: Creating a Simple Volume Mesh} \item \hyperlink{ovm_tutorial_02}{Tutorial 02\+: Using Iterators} \item \hyperlink{ovm_tutorial_03}{Tutorial 03\+: Adding Properties} \item \hyperlink{ovm_tutorial_04}{Tutorial 04\+: Using File I/O} \end{DoxyItemize}
\hypertarget{concepts}{}\subsection{Concepts of Open\+Volume\+Mesh}\label{concepts}
\hypertarget{a14928_halfedges}{}\subsubsection{From Half-\/\+Edges to Half-\/\+Faces}\label{a14928_halfedges}
The concepts of Open\+Volume\+Mesh are closely related to those of Open\+Mesh (\href{http://www.openmesh.org}{\tt http\+://www.\+openmesh.\+org}). For further reading on the concepts of Open\+Mesh, refer to \char`\"{}\+Open\+Mesh -\/ A generic and efficient polygon mesh data structure\char`\"{} by Mario Botsch et al. Open\+Mesh is used to handle two-\/manifold geometric meshes. For this purpose, it distinguishes between {\itshape vertices}, {\itshape edges}, and {\itshape faces}. The main idea in Open\+Mesh is to represent the edges as a pair of so-\/called half-\/edges that have opposing orientations. Additional local incidence information is stored for each half-\/edge such that the navigation on the mesh can be completely accomplished by using only these local links to adjacent structures (similar to e.\+g. a linked list). This, of course, assumes the surface mesh to be two-\/manifold.

The main concept of Open\+Volume\+Mesh is slightly different but shares some of its ideas with Open\+Mesh. In order to represent volumetric meshes (three-\/manifolds) that consist of a set of polyhedra, Open\+Volume\+Mesh extends the set of entities by {\itshape cells}. But unlike in the original idea of half-\/edge data structure, in Open\+Volume\+Mesh all entities are stored in arrays (S\+TL vectors) rather than in incidence linked lists. This is why Open\+Volume\+Mesh is index-\/based which has the major advantage that the data structure can handle configurations that are not three-\/manifold (since this is desired in some applications). For example, a set of vertices or just a two-\/manifold surface can be respresented by Open\+Volume\+Mesh as well as an entirely three-\/manifold polyhedral mesh. In order to offer the possibility to locally navigate on the meshes, we carry over the idea of splitting edges into half-\/edges to the faces. This leads to the separation of the faces into pairs of so-\/called half-\/faces. Each of the half-\/faces has opposite orientation to its counter-\/part and can be either incident to a cell or not which makes the half-\/face a boundary half-\/face. The orientation of a half-\/face is uniquely determined by its incident half-\/edges. See Figure 1 for an illustration of this concept.

 \hypertarget{a14928_incidences}{}\subsubsection{Incidence Relations}\label{a14928_incidences}
The entities in Open\+Volume\+Mesh are arranged hierarchically and we distinguish between two incidence relations\+:

\begin{DoxyItemize}
\item The (intrinsic) top-\/down incidences and \item the bottom-\/up incidences.\end{DoxyItemize}
\hypertarget{a14928_top_down}{}\paragraph{The Top-\/\+Down Incidence Relation}\label{a14928_top_down}
Each entity of dimension n is defined as a tuple of entities of dimension n-\/1, except for the vertices. So, edges are defined as a pair of vertices, (half-\/)faces are defined as a j-\/tuple of (half-\/)edges, where j is the valence of the face, and cells are defined as a k-\/tuple of (half-\/)faces, where k is the valence of the cell. This incidence relation is intrinsically given by definition. Open\+Volume\+Mesh can use these incidences in order to provide {\itshape top-\/down} circulators, that is circulators that address all adjacent lower-\/dimensional entities of a given reference entity. Read more on iterators and circulators in Section \hyperlink{iterators_and_circulators}{Iterators and Circulators}. Figure 2 illustrates this hierarchy.

 \hypertarget{a14928_bottom_up}{}\paragraph{The Bottom-\/\+Up Incidence Relation}\label{a14928_bottom_up}
In many cases, the incidence list to higher dimensional entities for a given entity is required. Therefore, Open\+Volume\+Mesh offers the opportunity to explicitly compute the so-\/called {\itshape bottom-\/up} incidences. For this, Open\+Volume\+Mesh stores the following information for the respective entity type in additional caches\+:

\begin{DoxyItemize}
\item {\bfseries Vertex\+:} A list of all outgoing half-\/edges. \item {\bfseries Half-\/\+Edge}\+: An (ordered) list of all incident half-\/faces. \item {\bfseries Half-\/\+Face}\+: The handle to an incident cell or none if it is a boundary half-\/face.\end{DoxyItemize}
These incidence relations are computed automatically for each affected entity when adding/deleting it. In most cases these incidences are needed since many iterators/circulators rely on them. Storing this additional information consumes extra memory that scales linearly with the mesh\textquotesingle{}s complexity. However, in case these incidence relations are not needed (e.\+g. in numerical analysis applications, etc.), they can be disabled by calling Topology\+Kernel\+::enable\+\_\+bottom\+\_\+up\+\_\+incidences() and passing false as parameter. Also it is possible to enable bottom-\/up incidences for single entity types, just call the following functions\+:

\begin{DoxyItemize}
\item Topology\+Kernel\+::enable\+\_\+vertex\+\_\+bottom\+\_\+up\+\_\+incidences() \item Topology\+Kernel\+::enable\+\_\+edge\+\_\+bottom\+\_\+up\+\_\+incidences() \item Topology\+Kernel\+::enable\+\_\+face\+\_\+bottom\+\_\+up\+\_\+incidences()\end{DoxyItemize}
This is useful in cases where only a subset of these incidence relations is required while at the same time keeping the data structure as compact as possible allocating only a minimum of storage overhead.

\begin{DoxyNote}{Note}
Note that most of the iterators and circulators rely on these incidence lists, so, many of them do not work if bottom-\/up incidences are disabled.
\end{DoxyNote}
\hypertarget{a14928_modularity}{}\subsubsection{Modularity -\/ Take only what you need}\label{a14928_modularity}
There exist numerous applications for volumetric mesh data structures including mesh generation, finite element analysis, rendering, etc. Each of them focussing on different design goals such as maximum efficiency, compactness or comfortable navigation. Since our data structure claims to be versatile, it is designed to be as modular as possible such that it suits many of the mentioned application cases. Figure 3 shows the class diagram of the core components of Open\+Volume\+Mesh. With this architecture it is possible to only instanciate what is really needed in a particular use case. For instance, we make a clear distinction between the geometry and topology of a mesh, such that the choice of whether a mesh (graph) requires a geometric embedding or not is up to the user. This may save a lot of unnecessary memory overhead in cases where only topological information of a mesh is needed. The topology kernel implements only a minimal set of (intrinsic) operations on a mesh such as adding/deleting entities, computing incidence relations and instantiate iterator objects. All other additional functions are provided by the so-\/called attribute classes which are presented in the next section.

\hypertarget{a14928_index_based}{}\subsubsection{Using handles to address the entities of a mesh}\label{a14928_index_based}
Open\+Volume\+Mesh is an index-\/based data structure where generally all entities are stored in linear memory arrays (S\+TL vectors). So, each of the entities is uniquely defined through its handle which is a simple class that encapsulates the index of it in the respective array it is stored in. This makes sure the entities can be accessed in $O(1)$. Each of the distinct entity types has its own type-\/safe handle class in order to avoid ambiguity when accessing elements at compile time. The handle classes are each derived from a common base class called \hyperlink{a11604}{Open\+Volume\+Mesh\+::\+Open\+Volume\+Mesh\+Handle}. The iterators as well as the circulators are designed to return a handle to an entity on dereference rather than a reference to the entity itself. A special constant, Open\+Volume\+Mesh\+::\+Topology\+Kernel\+::\+Invalid\+Vertex\+Handle, etc., for each entity is used when trying to access non-\/existing entities.\hypertarget{a14928_genericity}{}\subsubsection{Genericity}\label{a14928_genericity}
\hypertarget{a14928_generic_embedding}{}\paragraph{Generic Embedding}\label{a14928_generic_embedding}
The Open\+Volume\+Mesh library is designed to be as generic as possible. So, at one hand, the developer can choose the vector space into which a mesh is embedded. For example, most instances require their vertices being elements of $\mathrm{R}^3$. But in some cases, one might want e.\+g. two-\/dimensional integer coordinates, so elements in $\mathrm{N}_0^2$. In Open\+Volume\+Mesh, the embedded vector type can be specified as template parameter. The library is shipped with a vector class that also specifies all necessary operations on vectors (such as dot-\/ and cross-\/product, several norms, etc.). The most common vector types are predefined in Vector\+T.\+hh. So, let\textquotesingle{}s say we want to create a polyhedral mesh whose vertices are elements of $\mathrm{N}_0^2$. We use the following code\+:


\begin{DoxyCode}
\textcolor{preprocessor}{#include <OpenVolumeMesh/Geometry/VectorT.hh>}
\textcolor{preprocessor}{#include <OpenVolumeMesh/Mesh/PolyhedralMesh.hh>}

\textcolor{keywordtype}{void} SomeClass::someFunction() \{

  ...

  \textcolor{comment}{// Our two-dimensional integer vector class}
  \textcolor{keyword}{typedef} \hyperlink{a11684}{OpenVolumeMesh::Geometry::Vec2ui} 
      \hyperlink{a06176_ae4755d4e07cff81eb7a26cd0540ce314}{Vec2ui};

  \textcolor{comment}{// Vec2ui stands for "two-dimensional vector of unsigned integers"}

  \textcolor{comment}{// Our mesh using Vec2ui as vector type}
  \hyperlink{a11520}{OpenVolumeMesh::GeometryKernel< Vec2ui >} myMesh;

  ...

\}
\end{DoxyCode}
\hypertarget{a14928_generic_properties}{}\paragraph{Generic Dynamic Properties}\label{a14928_generic_properties}
Similar to the Open\+Mesh data structure, it is possible to attach multiple dynamic properties to any of the entities in Open\+Volume\+Mesh at run-\/time. The underlying property container class makes use of C++ template programming concepts in order to allow the encapsulated property data to be of any data type. However, we have adapted and improved the property concept of \hyperlink{a06210}{Open\+Mesh} such that the allocation of properties is now completely managed by a resource manager implemented in \hyperlink{a11628}{Open\+Volume\+Mesh\+::\+Resource\+Manager}. \hyperlink{a11928}{Properties} are now allocated and returned as a shared pointer that automatically are destroyed and entirely released once they loose scope. This drastically improves the ease-\/of-\/use at one hand and demands less care about memory management at the other hand. Nevertheless, properties may also (in analogy to the property system of \hyperlink{a06210}{Open\+Mesh}) be declared persistent. When declaring a property persistent, the ownership of the property memory is given back to the mesh (from the user context) which makes sure it is not destroyed before the mesh is. Let\textquotesingle{}s assume, we want to attach a label to the vertices and some real valued weight to the edges of a mesh. Consider the following example code\+:


\begin{DoxyCode}
\textcolor{preprocessor}{#include <string>}

\textcolor{preprocessor}{#include <OpenVolumeMesh/Geometry/VectorT.hh>}
\textcolor{preprocessor}{#include <OpenVolumeMesh/PolyhedralMesh/PolyhedralMesh.hh>}

\textcolor{keywordtype}{void} SomeClass::someFunction \{

  ...

  \textcolor{comment}{// Create mesh}
  \textcolor{keyword}{typedef} \hyperlink{a11684}{OpenVolumeMesh::Geometry::Vec3d} \hyperlink{a06176_ae4a56bb6b65d7f966934982a1e370213}{Vec3d};
  \hyperlink{a11520}{OpenVolumeMesh::GeometryKernel< Vec3d >} myMesh;

  \textcolor{comment}{// Fill mesh}
  ...

  \textcolor{comment}{// Attach label property (data type std::string) to the mesh}
  \hyperlink{a11516}{OpenVolumeMesh::VertexPropertyT< std::string >} label =
                myMesh.request\_vertex\_property< std::string >(\textcolor{stringliteral}{"LabelProperty"});

  \textcolor{comment}{// Fill property values}
  \textcolor{keywordflow}{for}(\hyperlink{a11572}{OpenVolumeMesh::VertexIter} v\_it = myMesh.vertices\_begin();
        v\_it != myMesh.vertices\_end(); ++v\_it) \{

    \textcolor{comment}{// Assign same label to each vertex}
    label[*v\_it] = \textcolor{stringliteral}{"My Label"};
  \}
  
  \textcolor{comment}{// Now, attach weight property (data type float) to the mesh}
  \hyperlink{a11516}{OpenVolumeMesh::EdgePropertyT< float >} weight =
                myMesh.request\_edge\_property< \textcolor{keywordtype}{float} >(); \textcolor{comment}{// Also anonymous properties are supported}

  \textcolor{comment}{// Fill property values}
  \textcolor{keywordflow}{for}(\hyperlink{a11576}{OpenVolumeMesh::EdgeIter} e\_it = myMesh.edges\_begin();
        e\_it != myMesh.edges\_end(); ++e\_it) \{

    \textcolor{comment}{// Assign same weight to each edge}
    weight[*e\_it] = 3.14f;
  \}

  \textcolor{comment}{// The properties are automatically released}
  \textcolor{comment}{// when leaving scope}
\}
\end{DoxyCode}
\hypertarget{a14928_attribs}{}\subsubsection{Using attributes to provide extra functionality}\label{a14928_attribs}
Due to the fact that Open\+Volume\+Mesh is designed to be as compact as possible providing the opportunity to only use code that is really needed in a particular case, all extra functionality can be suspended to so-\/called attribute classes. In this context, attributes are not to be understood as those used in the C++ S\+TL concepts. Attribute objects in Open\+Volume\+Mesh are objects instanciated at run-\/time which expect a mesh reference to be injected. Usually they request a certain set of properties from the mesh and provide functions that allow operating on these properties or the mesh itself. The major advantage of the use of these attributes is that they exclusively use additional memory during their life-\/time cycle. As soon as an attribute object looses scope and is thus destroyed, all allocated memory is automatically released again. The following lines of code show how to use attributes (in this case the status attribute providing functions for selecting, tagging and deleting entities)\+:


\begin{DoxyCode}
\textcolor{comment}{// Create mesh object}
GeometricPolyhedralMeshV3d myMesh;

\textcolor{comment}{// Fill mesh with entities}
...

\textcolor{comment}{// Create status attribute object}
StatusAttrib status(myMesh);

\textcolor{comment}{// Select vertex with handle 0}
status[VertexHandle(0)].set\_selected(\textcolor{keyword}{true});
\end{DoxyCode}
 \hypertarget{iterators_and_circulators}{}\subsection{Iterators and Circulators}\label{iterators_and_circulators}
In order to iterate over the entities of a mesh or just a certain neighborhood (circulator) of an entity, Open\+Volume\+Mesh provides a set of iterators and circulators. These iterators are entirely S\+T\+L-\/compatible and can as such be used in all algorithms of the C++ standard template library. We distinguish between two different kinds of iterators\+:

\begin{DoxyItemize}
\item {\bfseries Intrinsic} {\bfseries Iterators\+:} Iterators that do not require bottom-\/up incidences to be computed. \item {\bfseries Bottom-\/\+Up} {\bfseries Incidence} {\bfseries Dependent} {\bfseries Iterators\+:} Iterators that need bottom-\/up incidences to be computed before they can be used.\end{DoxyItemize}
For information on bottom-\/up incidences, refer to Section \hyperlink{concepts}{Concepts of Open\+Volume\+Mesh}. Note since Open\+Volume\+Mesh is an index-\/based data structure, the iterators encapsulate {\itshape handles} to entities. Dereferencing an iterator thus never returns a reference to the entity itself but only a handle to the entity.

The following sections provide a concise overview of the iterators that come along with Open\+Volume\+Mesh.\hypertarget{a14930_intrinsic_iterators}{}\subsubsection{Intrinsic Iterators}\label{a14930_intrinsic_iterators}
\begin{DoxyItemize}
\item \hyperlink{a11572}{Open\+Volume\+Mesh\+::\+Vertex\+Iter}\+: Iterate over all vertices of a mesh. \item \hyperlink{a11576}{Open\+Volume\+Mesh\+::\+Edge\+Iter}\+: Iterate over all edges of a mesh. \item \hyperlink{a11580}{Open\+Volume\+Mesh\+::\+Half\+Edge\+Iter}\+: Iterate over all half-\/edges of a mesh. \item \hyperlink{a11584}{Open\+Volume\+Mesh\+::\+Face\+Iter}\+: Iterate over all faces of a mesh. \item \hyperlink{a11588}{Open\+Volume\+Mesh\+::\+Half\+Face\+Iter}\+: Iterate over all half-\/faces of a mesh. \item \hyperlink{a11592}{Open\+Volume\+Mesh\+::\+Cell\+Iter}\+: Iterate over all cells of a mesh. \item \hyperlink{a11556}{Open\+Volume\+Mesh\+::\+Cell\+Vertex\+Iter}\+: Iterate over all vertices of a given cell.\end{DoxyItemize}
\hypertarget{a14930_incidence_depending_iterators}{}\subsubsection{Bottom-\/\+Up Incidence Dependent Iterators and Circulators}\label{a14930_incidence_depending_iterators}
\hypertarget{a14930_general_iterators}{}\paragraph{Iterators for General Polyhedral Meshes}\label{a14930_general_iterators}
\begin{DoxyItemize}
\item \hyperlink{a11596}{Open\+Volume\+Mesh\+::\+Boundary\+Face\+Iter}\+: Iterate over all boundary faces of a mesh. \item \hyperlink{a11560}{Open\+Volume\+Mesh\+::\+Cell\+Cell\+Iter}\+: Iterate over all adjacent cells of a given reference cell. \item \hyperlink{a11532}{Open\+Volume\+Mesh\+::\+Vertex\+O\+Half\+Edge\+Iter}\+: Iterate over all incident outgoing half-\/edges of a given vertex. \item \hyperlink{a11540}{Open\+Volume\+Mesh\+::\+Half\+Edge\+Half\+Face\+Iter}\+: Iterate over all incident half-\/faces of a given half-\/edge. \item \hyperlink{a11548}{Open\+Volume\+Mesh\+::\+Vertex\+Cell\+Iter}\+: Iterate over all incident cells of a given vertex. \item \hyperlink{a11552}{Open\+Volume\+Mesh\+::\+Half\+Edge\+Cell\+Iter}\+: Iterate over all incident cells of a given half-\/edge.\end{DoxyItemize}
\hypertarget{a14930_hexahedral_mesh_iterators}{}\paragraph{Specializations for Hexahedral Meshes}\label{a14930_hexahedral_mesh_iterators}
\begin{DoxyItemize}
\item \hyperlink{a11696}{Open\+Volume\+Mesh\+::\+Cell\+Sheet\+Cell\+Iter}\+: Iterate over all adjacent hexahedra in the same sheet of a given hexahedron. Also see \hyperlink{ovm_tutorial_02}{Tutorial 02\+: Using Iterators}, last example. \item \hyperlink{a11700}{Open\+Volume\+Mesh\+::\+Half\+Face\+Sheet\+Half\+Face\+Iter}\+: Iterate over all adjacent half-\/faces of a given half-\/face in the same sheet of hexahedra. \item Open\+Volume\+Mesh\+::\+Outside\+Neighbor\+Half\+Face\+Iter\+: Iterate over all adjacent boundary half-\/faces (outside) of a given boundary half-\/face.\end{DoxyItemize}
\begin{DoxyRefDesc}{Todo}
\item[\hyperlink{a06164__todo000050}{Todo}]Make figures for all iterators.\end{DoxyRefDesc}
\hypertarget{file_format}{}\subsection{File Format}\label{file_format}
Open\+Volume\+Mesh comes with a file format specification that is implemented in the \hyperlink{a11668}{Open\+Volume\+Mesh\+::\+I\+O\+::\+File\+Manager} class. As for now, the file format only supports plain text, but a support for binary files is planned. Also the serialization of the persistent properties is not implemented, yet. A full generic support is planned for the future. Open\+Volume\+Mesh files should have the file name extension $\ast$.ovm. Find the file format specification below.\hypertarget{a14929_file_spec}{}\subsubsection{File Format Specification}\label{a14929_file_spec}
\begin{DoxyVerb}OVM ASCII                   # File header indicating whether data is
                            # coded as plain text or binary
Vertices                    # Indicate that all vertices are listed below
n_v                         # The total number of vertices (>= 0)
x_1 y_1 z_1                 # Coordinate of the first vertex
...
x_n y_n z_n                 # Coordinate of the n_v'th vertex
Edges                       # Indicate that edges are specified below
n_e                         # The total number of edges (>= 0)
vs_1 vt_1                   # First edge's source vertex index followed
...                         # by the first edge's target vertex index  
vs_n vt_n                   # Last edge's source and target vertices
Faces                       # Indicate that faces are specified below
n_f                         # The total number of faces (>= 0)
d he1_1 ... hed_1           # The first face's valence followed by its
...                         # incident half-edges' indices
d he1_n ... hed_n           # Last face's definition
Polyhedra                   # Indicates that polyhedra are specified below
n_c                         # The total number of cells (>= 0)
d hf1_1 ... hfd_1           # The first polyhedron's valence followed
...                         # by its incident half-faces' indices
d hf1_n ... hfd_n           # The last polyhedron's definition
# Properties coming soon...
\end{DoxyVerb}
\hypertarget{a14929_file_example}{}\subsubsection{A Simple Example File}\label{a14929_file_example}

\begin{DoxyCodeInclude}
OVM ASCII
Vertices
8
-1.0 -1.0 -1.0
1.0 -1.0 -1.0
1.0 1.0 -1.0
-1.0 1.0 -1.0
-1.0 -1.0 1.0
1.0 -1.0 1.0
1.0 1.0 1.0
-1.0 1.0 1.0
Vertex\_Property "Vertex Weights"
float
1.363
6.334
2.766
8.348
4.214
2.136
7.114
0.651
Edges
12
0 1
1 2
2 3
3 0
4 5
5 6
6 7
7 4
0 4
1 5
2 6
3 7
Edge\_Property "Edge Tag"
bool
1
1
0
1
1
0
0
1
0
0
1
1
Faces
6
4 0 2 4 6
4 8 10 12 14
4 18 10 21 3
4 16 15 23 6
4 20 12 23 5
4 0 18 9 17
Face\_Property "Face Selection"
bool
1
1
0
1
1
0
HalfFace\_Property "HalfFace Constraints"
double
1.22354
0.11698
1.83562
0.19378
0.23567
1.23565
1.23567
0.95874
0.43532
2.22457
0.10957
1.09758
Polyhedra
1
6 1 2 5 6 9 10
\end{DoxyCodeInclude}
 \hypertarget{property_system}{}\subsection{Property System}\label{property_system}
In Open\+Volume\+Mesh it is possible to attach properties of any data type to each of the entity types. This is accomplished by using template programming concepts of C++. All properties are instances of the class \hyperlink{a11504}{Open\+Volume\+Mesh\+::\+Open\+Volume\+Mesh\+PropertyT} that expects a data type as template parameter. See Section \hyperlink{a14928_generic_properties}{Generic Dynamic Properties} for a more detailed overview about how to use properties. Tutorial \hyperlink{ovm_tutorial_03}{Tutorial 03\+: Adding Properties} additionally describes how to use properties in practice using a compilable example. \hypertarget{building_openvolumemesh}{}\subsection{Building Open\+Volume\+Mesh}\label{building_openvolumemesh}
\hypertarget{a14927_building_prerequisites}{}\subsubsection{Prerequisites}\label{a14927_building_prerequisites}
Open\+Volume\+Mesh is equipped with a C\+Make (\href{http://www.cmake.org}{\tt http\+://www.\+cmake.\+org}) build system that should make compiling the library on any platform pretty simple. Make sure you have at least C\+Make version 2.\+6 installed on your machine. Get the latest C\+Make sources or binaries at \href{http://www.cmake.org}{\tt http\+://www.\+cmake.\+org}.

If you are interested in contributing to Open\+Volume\+Mesh by developing on its code base, we highly recommend to install the Google testing framework which can be found here\+: \href{https://github.com/google/googletest}{\tt https\+://github.\+com/google/googletest} This framework is needed in order to build and execute our included unit tests.\hypertarget{a14927_config_and_build}{}\subsubsection{Configuring and building Open\+Volume\+Mesh on Linux and Mac\+O\+SX}\label{a14927_config_and_build}
Open a terminal and extract the Open\+Volume\+Mesh sources or check out the latest subversion revision\+:

\begin{DoxyVerb}git clone https://www.graphics.rwth-aachen.de:9000/OpenVolumeMesh/OpenVolumeMesh.git
\end{DoxyVerb}


It is recommended to build Open\+Volume\+Mesh out-\/of-\/source, so create a folder named e.\+g. \char`\"{}build\char`\"{} {\itshape outside} the Open\+Volume\+Mesh sources root folder. Change to the newly created build directory and just type

\begin{DoxyVerb}cmake /path/to/OpenVolumeMesh/sources
\end{DoxyVerb}


Note that C\+Make configures the build such that it builds with debug symbols per default. If you want to build with release settings (with optimizations turned on), use the tool

\begin{DoxyVerb}ccmake .
\end{DoxyVerb}


inside your build folder. Once everything is configured as desired, just type

\begin{DoxyVerb}make
\end{DoxyVerb}


inside the build folder. The built libraries can be found in the sub-\/folder {\ttfamily Build/lib}. Open\+Volume\+Mesh will be built as a static as well as a dynamic library. If you want to build Open\+Volume\+Mesh\textquotesingle{}s documentation, simply type

\begin{DoxyVerb}make doc
\end{DoxyVerb}
 inside the build folder. The generated doxygen documentation files can then be found in {\ttfamily Build/share/\+Doc/html}.

If you want to install the library as well as its header files, type\+:

\begin{DoxyVerb}sudo make install
\end{DoxyVerb}


This installs the requested files into the {\ttfamily lib} and {\ttfamily include} folders in {\ttfamily /usr/local} (this is the default value that can easily be changed using {\ttfamily ccmake}).

There is also a simple example in the {\ttfamily examples} folder in Open\+Volume\+Mesh\textquotesingle{}s root directory. This example has its own target defined in the C\+Make configuration file found in {\ttfamily examples/\+C\+Make\+Lists.\+txt}. This target is excluded from target {\ttfamily all} and has to be built explicitly. You can easily build it by typing\+:

\begin{DoxyVerb}make simple_mesh
\end{DoxyVerb}


The binary can then be found in {\ttfamily Build/\+Examples}, or whatever you have specified in the C\+Make configuration. \hypertarget{ovm_tutorial_01}{}\subsection{Tutorial 01\+: Creating a Simple Volume Mesh}\label{ovm_tutorial_01}
Creating a volumetric mesh with Open\+Volume\+Mesh is pretty simple. In order to make available the different built-\/in vector types that Open\+Volume\+Mesh provides, just include the following header\+:


\begin{DoxyCode}
\textcolor{preprocessor}{#include <OpenVolumeMesh/Geometry/VectorT.hh>}
\end{DoxyCode}


Depending on whether you want to deal with hexahedral or general polyhedral meshes, either of the following headers has to be included, too\+:


\begin{DoxyCode}
\textcolor{comment}{// Hexahedral meshes}
\textcolor{preprocessor}{#include <OpenVolumeMesh/Mesh/HexahedralMesh.hh>}

\textcolor{comment}{// Polyhedral meshes}
\textcolor{preprocessor}{#include <OpenVolumeMesh/Mesh/PolyhedralMesh.hh>}
\end{DoxyCode}


This provides two different mesh types each\+:

\begin{DoxyItemize}
\item A topological 3D mesh (graph) without geometric embedding which is derived from \hyperlink{a11652}{Open\+Volume\+Mesh\+::\+Topology\+Kernel} \item A topological 3D with a geometric embedding which is derived from \hyperlink{a11520}{Open\+Volume\+Mesh\+::\+Geometry\+Kernel}\end{DoxyItemize}
The first header, for example, predefines a set of commonly used mesh types\+:

\begin{DoxyItemize}
\item {\bfseries Topologic\+Polyhedral\+Mesh\+:} A purely topological polyhedral mesh (no embedding) \item {\bfseries Geometric\+Polyhedral\+Mesh\+V3i\+:} A geometric polyhedral mesh with embedding in $\mathrm{Z}^3$ \item {\bfseries Geometric\+Polyhedral\+Mesh\+V3ui\+:} A geometric polyhedral mesh with embedding in $\mathrm{N}_0^3$ \item {\bfseries Geometric\+Polyhedral\+Mesh\+V3f\+:} A geometric polyhedral mesh with embedding in $\mathrm{R}^3$, single precision \item {\bfseries Geometric\+Polyhedral\+Mesh\+V3d\+:} A geometric polyhedral mesh with embedding in $\mathrm{R}^3$, double precision \item {\bfseries Geometric\+Polyhedral\+Mesh\+V3c\+:} A geometric polyhedral mesh with embedding in $[-128,127]^3$ \item {\bfseries Geometric\+Polyhedral\+Mesh\+V3uc\+:} A geometric polyhedral mesh with embedding in $[0,256]^3$\end{DoxyItemize}
Of course, the second header defines the same mesh types for hexahedral meshes. Just replace Polyhedral by Hexahedral.

\begin{DoxyNote}{Note}
Note that you can also represent hexahedral meshes using the polyhedral mesh kernel, 

but the hexahedral mesh classes are equipped with some specialized functionality 

and iterators for hexahedral meshes.
\end{DoxyNote}
The following code creates a polyhedral mesh instance and fills it with two adjacent tetrahedra. Note that when defining cells in Open\+Volume\+Mesh, the incident half-\/faces that define a cell are supposed to form a two-\/manifold. This particularly implies that they are supposed to have the same orientation (whether their normal points inside the cell or outside the cell does not matter, but convention assumes the half-\/face normals to point inside the cell). Open\+Volume\+Mesh per default performs a check whether the specified half-\/faces form a two-\/manifold when adding a cell. This check can explicitly turned off by passing false as second parameter to \hyperlink{a11652_a0d39e76cff8a318046e640b3887a6845}{Open\+Volume\+Mesh\+::\+Topology\+Kernel\+::add\+\_\+face()}. Note that in these cases, it is not guaranteed that a given mesh is three-\/manifold.


\begin{DoxyCode}
\textcolor{comment}{// Create mesh object}
GeometricPolyhedralMeshV3f myMesh;

\textcolor{comment}{// Add eight vertices}
\hyperlink{a11608}{OpenVolumeMesh::VertexHandle} v0 = myMesh.add\_vertex(
      \hyperlink{a08448}{Vec3f}(-1.0, 0.0, 0.0));
\hyperlink{a11608}{OpenVolumeMesh::VertexHandle} v1 = myMesh.add\_vertex(
      \hyperlink{a08448}{Vec3f}( 0.0, 0.0, 1.0));
\hyperlink{a11608}{OpenVolumeMesh::VertexHandle} v2 = myMesh.add\_vertex(
      \hyperlink{a08448}{Vec3f}( 1.0, 0.0, 0.0));
\hyperlink{a11608}{OpenVolumeMesh::VertexHandle} v3 = myMesh.add\_vertex(
      \hyperlink{a08448}{Vec3f}( 0.0, 0.0,-1.0));
\hyperlink{a11608}{OpenVolumeMesh::VertexHandle} v4 = myMesh.add\_vertex(
      \hyperlink{a08448}{Vec3f}( 0.0, 1.0, 0.0));

std::vector<OpenVolumeMesh::VertexHandle> vertices;

\textcolor{comment}{// Add faces}
vertices.push\_back(v0); vertices.push\_back(v1);vertices.push\_back(v4);
\hyperlink{a11608}{OpenVolumeMesh::FaceHandle} f0 = myMesh.add\_face(vertices);

vertices.clear();
vertices.push\_back(v1); vertices.push\_back(v2);vertices.push\_back(v4);
\hyperlink{a11608}{OpenVolumeMesh::FaceHandle} f1 = myMesh.add\_face(vertices);

vertices.clear();
vertices.push\_back(v0); vertices.push\_back(v1);vertices.push\_back(v2);
\hyperlink{a11608}{OpenVolumeMesh::FaceHandle} f2 = myMesh.add\_face(vertices);

vertices.clear();
vertices.push\_back(v0); vertices.push\_back(v4);vertices.push\_back(v2);
\hyperlink{a11608}{OpenVolumeMesh::FaceHandle} f3 = myMesh.add\_face(vertices);

vertices.clear();
vertices.push\_back(v0); vertices.push\_back(v4);vertices.push\_back(v3);
\hyperlink{a11608}{OpenVolumeMesh::FaceHandle} f4 = myMesh.add\_face(vertices);

vertices.clear();
vertices.push\_back(v2); vertices.push\_back(v3);vertices.push\_back(v4);
\hyperlink{a11608}{OpenVolumeMesh::FaceHandle} f5 = myMesh.add\_face(vertices);

vertices.clear();
vertices.push\_back(v0); vertices.push\_back(v2);vertices.push\_back(v3);
\hyperlink{a11608}{OpenVolumeMesh::FaceHandle} f6 = myMesh.add\_face(vertices);

std::vector<OpenVolumeMesh::HalfFaceHandle> halffaces;

\textcolor{comment}{// Add first tetrahedron}
halffaces.push\_back(myMesh.halfface\_handle(f0, 1));
halffaces.push\_back(myMesh.halfface\_handle(f1, 1));
halffaces.push\_back(myMesh.halfface\_handle(f2, 0)); 
halffaces.push\_back(myMesh.halfface\_handle(f3, 1)); 
myMesh.add\_cell(halffaces);

\textcolor{comment}{// Add second tetrahedron}
halffaces.clear();
halffaces.push\_back(myMesh.halfface\_handle(f4, 1));
halffaces.push\_back(myMesh.halfface\_handle(f5, 1));
halffaces.push\_back(myMesh.halfface\_handle(f3, 0)); 
halffaces.push\_back(myMesh.halfface\_handle(f6, 0)); 
myMesh.add\_cell(halffaces);
\end{DoxyCode}
 \hypertarget{ovm_tutorial_02}{}\subsection{Tutorial 02\+: Using Iterators}\label{ovm_tutorial_02}
Open\+Volume\+Mesh is shipped with a set of useful iterators and circulators to comfortably address the entities (local neighborhood of entities) in a polyhedral mesh. See Section \hyperlink{iterators_and_circulators}{Iterators and Circulators} for a more detailed description of all available iterators and circulators. In this tutorial, we examine how to use the iterators that come along with Open\+Volume\+Mesh.

In the first example, we simply iterate over all half-\/edges of a mesh using the \hyperlink{a11580}{Open\+Volume\+Mesh\+::\+Half\+Edge\+Iter} iterator class\+:


\begin{DoxyCode}
\textcolor{comment}{// Instantiate e.g. a geometric hexahedral mesh}
\hyperlink{a11520}{OpenVolumeMesh::GeometricHexahedralMeshV3d} myMesh;

\textcolor{comment}{// Fill mesh with geometry}
...

\textcolor{comment}{// Iterate over all half-edges}
for(\hyperlink{a11580}{OpenVolumeMesh::HalfEdgeIter} he\_it = myMesh.halfedges\_begin();
        he\_it != myMesh.halfedges\_end(); ++he\_it) \{

    \textcolor{comment}{// Now dereferencing he\_it returns a half-edge handle}
    ...
\}
\end{DoxyCode}


In the next example, we iterate over all incident outgoing half-\/edges of a given vertex. Note that this iterator needs bottom-\/up incidences which are computed automatically per default. Otherwise, the iterator would not be valid. See Section \hyperlink{a14928_bottom_up}{The Bottom-\/\+Up Incidence Relation} for information on the bottom-\/up incidences.


\begin{DoxyCode}
\textcolor{comment}{// Instantiate a polyhedral mesh}
\hyperlink{a11520}{OpenVolumeMesh::GeometricPolyhedralMeshV3f} myMesh;

\textcolor{comment}{// Fill mesh with geometry}
...

typedef \hyperlink{a11608}{OpenVolumeMesh::VertexHandle} VertexHandle;

\textcolor{comment}{// Get first vertex in mesh}
VertexHandle vh = *(myMesh.vertices\_begin());

\textcolor{comment}{// Iterate over all outgoing half-edges of vertex vh}
\textcolor{keywordflow}{for}(\hyperlink{a11532}{OpenVolumeMesh::VertexOHalfEdgeIter} voh\_it = myMesh.voh\_iter(vh);
        voh\_it.valid(); ++voh\_it) \{

    \textcolor{comment}{// Now dereferencing voh\_it returns a half-edge handle}
    ...
\}
\end{DoxyCode}


In the last example, we create a hexahedral mesh and use its specialized \hyperlink{a11696}{Open\+Volume\+Mesh\+::\+Cell\+Sheet\+Cell\+Iter} iterator class. This iterator expects a cell handle as parameter and iterates over all adjacent cells in the same {\itshape sheet}. A sheet is, in the terms of the {\itshape spatial} {\itshape twist} {\itshape continuum}, short S\+TC, a \char`\"{}layer\char`\"{} of hexahedra as illustrated in the following figure. For rurther reading on S\+TC, refer to \char`\"{}\+The spatial twist continuum\+: A connectivity based method for representing all-\/hexahedral finite element meshes\char`\"{} by Peter Murdoch et al. The gray shaded hexahedra form a sheet, all other cells (except the outlines of the boundary cells) are invisible in this illustration.



Starting from a hexahedron, we determine its virtual axis that is {\itshape orthogonal} to the desired sheet (note that there are always two opposing virtual axes that are orthogonal to such a sheet). We create our sheet iterator by passing the reference cell\textquotesingle{}s handle as well as an orthogonal virtual axis with respect to that cell to the iterator\textquotesingle{}s constructor. The iterators then iterates over all directly adjacent cells in the same sheet (those hexahedra that share a common face with the reference hexahedron). Consider the following code\+:


\begin{DoxyCode}
\textcolor{comment}{// Instantiate a hexahedral mesh}
\hyperlink{a11520}{OpenVolumeMesh::GeometricHexahedralMeshV3d} myMesh;

\textcolor{comment}{// Fill mesh with geometry}
...

\textcolor{comment}{// Get handle of first cell}
OpenVolumeMesh::CellHandle ch = *(myMesh.cells\_begin());

\textcolor{comment}{// Iterate over the hexahedra in the same sheet that are adjacent}
\textcolor{comment}{// to the reference hexahedron (cell handle ch)}
\textcolor{keywordflow}{for}(\hyperlink{a11696}{OpenVolumeMesh::CellSheetCellIter} csc\_it = myMesh.csc\_iter(ch);
        csc\_it.valid(); ++csc\_it) \{

    \textcolor{comment}{// Now dereferencing csc\_it returns a cell handle}
    ...
\}
\end{DoxyCode}
 \hypertarget{ovm_tutorial_03}{}\subsection{Tutorial 03\+: Adding Properties}\label{ovm_tutorial_03}
In Open\+Volume\+Mesh it is possible to attach multiple properties to each of the entities. Due to the use of S\+TL template programming, these properties can be of any data type. In this tutorial, we learn how to attach properties to the entities of a polyhedral mesh.

Read Section \hyperlink{a14928_generic_properties}{Generic Dynamic Properties} for a detailed description of the property system.

The following example shows how to attach a floating-\/point property to the vertices of a mesh.


\begin{DoxyCode}
\textcolor{keywordtype}{void} someFunction() \{

    \textcolor{comment}{// Create mesh object}
    \hyperlink{a11520}{OpenVolumeMesh::GeometricPolyhedralMeshV3d} myMesh;
    
    \textcolor{comment}{// Fill mesh with geometry}
    ...
    
    \textcolor{comment}{// Add property}
    \hyperlink{a11516}{OpenVolumeMesh::VertexPropertyT<float>} floatProp =
                myMesh.request\_vertex\_property<\textcolor{keywordtype}{float}>(\textcolor{stringliteral}{"Vertex Weights"});
    
    \textcolor{comment}{// Now, iterate over all vertices and set property value to some number}
    \textcolor{keywordtype}{float} val = 0.0f;
    \textcolor{keywordflow}{for}(\hyperlink{a11572}{OpenVolumeMesh::VertexIter} v\_it = myMesh.vertices\_begin();
            v\_it != myMesh.vertices\_end(); ++v\_it) \{
    
            \textcolor{comment}{// Set property value}
            floatProp[*v\_it] = val;
    
            \textcolor{comment}{// Increase value by 1.5}
            val += 1.5f;
    \}
    
    \textcolor{comment}{// Call some other function}
    someOtherFunction(myMesh);
    
    \textcolor{comment}{// Only at this point the property is destroyed and memory is released}
\}

\textcolor{keywordtype}{void} someOtherFunction(\hyperlink{a11520}{OpenVolumeMesh::GeometricPolyhedralMeshV3d}
      & \_mesh) \{

    \textcolor{comment}{// Try to get property by its name}
    \hyperlink{a11516}{OpenVolumeMesh::VertexPropertyT<float>} floatProp = \_mesh.
      request\_vertex\_property<\textcolor{keywordtype}{float}>(\textcolor{stringliteral}{"Vertex Weights"});

    \textcolor{comment}{// Now floatProp is a valid property that contains}
    \textcolor{comment}{// the values we have inserted before}
    \textcolor{comment}{// Access a property value via floatProp[vertexHandle].}
\}
\end{DoxyCode}


For all other entities, this works the same way. Use class Open\+Volume\+Mesh\+::\+Edge\+PropertyT as edge property, Open\+Volume\+Mesh\+::\+Half\+Face\+PropertyT for half-\/face properties, and so on... \hypertarget{ovm_tutorial_04}{}\subsection{Tutorial 04\+: Using File I/O}\label{ovm_tutorial_04}
The Open\+Volume\+Mesh library is equipped with a file manager class that allows reading polyhedral meshes from file as well as writing mesh objects to files. The format for these files is specified in Section \hyperlink{file_format}{File Format}.

In this tutorial, we will learn how to use the file manager in order to permanently store mesh objects and read them.

Consider the following code for an example on how to write a polyhedral mesh to a file\+:


\begin{DoxyCode}
\textcolor{comment}{// Include the file manager header}
\textcolor{preprocessor}{#include <OpenVolumeMesh/FileManager/FileManager.hh>}

\textcolor{comment}{// Include the polyhedral mesh header}
\textcolor{preprocessor}{#include <OpenVolumeMesh/Mesh/PolyhedralMesh.hh>}
...

void someFunction() \{

    \textcolor{comment}{// Create mesh object}
    \hyperlink{a11520}{OpenVolumeMesh::GeometricPolyhedralMeshV3f} myMesh;

    \textcolor{comment}{// Fill mesh with geometry}
    ...

   \textcolor{comment}{// Create file manager object}
   \hyperlink{a11668}{OpenVolumeMesh::IO::FileManager} fileManager;

   \textcolor{comment}{// Store mesh to file "myMesh.ovm" in the current directory}
   fileManager.\hyperlink{a11668_a377354860dd01186ece6342be795e357}{writeFile}(\textcolor{stringliteral}{"myMesh.ovm"}, myMesh);
\}
\end{DoxyCode}


This works analogously for reading files into mesh objects. See the following code for an example.


\begin{DoxyCode}
\textcolor{comment}{// Include the file manager header}
\textcolor{preprocessor}{#include <OpenVolumeMesh/FileManager/FileManager.hh>}

\textcolor{comment}{// Include the polyhedral mesh header}
\textcolor{preprocessor}{#include <OpenVolumeMesh/Mesh/PolyhedralMesh.hh>}
...

void someFunction() \{

    \textcolor{comment}{// Create an empty mesh object}
    \hyperlink{a11520}{OpenVolumeMesh::GeometricPolyhedralMeshV3f} myMesh;

   \textcolor{comment}{// Create file manager object}
   \hyperlink{a11668}{OpenVolumeMesh::IO::FileManager} fileManager;

   \textcolor{comment}{// Read mesh from file "myMesh.ovm" in the current directory}
   fileManager.\hyperlink{a11668_a16af670f7303a8046c70ba3cd7b58be1}{readFile}(\textcolor{stringliteral}{"myMesh.ovm"}, myMesh);

   \textcolor{comment}{// Now myMesh contains the mesh specified in file "myMesh.ovm"}
\}
\end{DoxyCode}


Function \hyperlink{a11668_a16af670f7303a8046c70ba3cd7b58be1}{Open\+Volume\+Mesh\+::\+I\+O\+::\+File\+Manager\+::read\+File()} expects a total of four parameters, two of which are mandatory (file name and mesh reference). The other two parameters are optional flags that control whether bottom-\/up incidences should be computed automatically and whether a topology check should be performed when adding faces and cells. The two flags are turned on per default. \hypertarget{ACGDoc}{}\section{A\+CG Documentation}\label{ACGDoc}
Subpage

This file contains documentation about the \hyperlink{a06176}{A\+CG} library used inside of Open\+Flipper. The \hyperlink{a06176}{A\+CG} library provides the scenegraph and rendering functions for Open\+Flipper. Also it contains some useful wrappers and math tools to make programming easier. If you build Open\+Flipper, the library will be automatically build and integrated.

\begin{DoxyItemize}
\item \hyperlink{naming_conventions}{Naming Conventions} \item \hyperlink{compiling_ACG}{Compiling A\+CG} \item \hyperlink{pickingDocumentation}{Picking in the A\+CG Scene\+Graph} \item \hyperlink{NonFixedPipelinePage}{The non-\/fixed Open\+GL rendering pipeline} \item \hyperlink{ShaderGenPage}{Dynamic shader assembly overview} \item \hyperlink{TutorialRenderer}{Tutorial\+: Implementation of The Toon Renderer Plugin} \end{DoxyItemize}
\hypertarget{naming_conventions}{}\subsection{Naming Conventions}\label{naming_conventions}
Please follow the naming conventions, if you extend the A\+CG-\/code !

{\bfseries Files\+:} \begin{DoxyItemize}
\item {\ttfamily My\+Class.\+cc} for C++-\/\+Implementation of class {\ttfamily My\+Class} \item {\ttfamily My\+Class.\+hh} for C++-\/\+Header of class {\ttfamily My\+Class} \end{DoxyItemize}
{\bfseries Classes\+:} \begin{DoxyItemize}
\item Class names start with a capital letter\+: {\ttfamily My\+Class} \item Class templates end with {\ttfamily T\+:} {\ttfamily My\+Class\+TemplateT} \end{DoxyItemize}
{\bfseries Variables\+:} \begin{DoxyItemize}
\item One leading underscore for parameters in function-\/calls\+: {\ttfamily \+\_\+var} \item One trailing underscore for member-\/variables\+: {\ttfamily var\+\_\+} \item Two trailing underscores for static member-\/variables\+: {\ttfamily var\+\_\+\+\_\+} \end{DoxyItemize}
{\bfseries Functions\+:} \begin{DoxyItemize}
\item Words are separated by capital letter\+: {\ttfamily my\+Function()} \end{DoxyItemize}
{\bfseries Accessing members\+:} \begin{DoxyItemize}
\item To get the member {\ttfamily xxx\+\_\+} use {\ttfamily  const\& xxx() const } \item To set the member {\ttfamily xxx\+\_\+} use {\ttfamily  void set\+\_\+xxx(arg) }\end{DoxyItemize}
The following naming conventions are used for the Open\+Mesh code\+:

{\bfseries Files\+:} \begin{DoxyItemize}
\item {\ttfamily My\+Class.\+cc} for C++-\/\+Implementation of class {\ttfamily My\+Class} \item {\ttfamily My\+Class\+T\+\_\+impl.\+hh} for Header only C++-\/\+Implementation of template class {\ttfamily My\+Class} \item {\ttfamily My\+Class.\+hh} for C++-\/\+Header of class {\ttfamily My\+Class} \end{DoxyItemize}
{\bfseries Classes\+:} \begin{DoxyItemize}
\item Class names start with a capital letter\+: {\ttfamily My\+Class} \item Class templates end with {\ttfamily T\+:} {\ttfamily My\+Class\+TemplateT} \end{DoxyItemize}
{\bfseries Variables\+:} \begin{DoxyItemize}
\item One leading underscore for parameters in function-\/calls\+: {\ttfamily \+\_\+var} \item One trailing underscore for member-\/variables\+: {\ttfamily var\+\_\+} \item Two trailing underscores for static member-\/variables\+: {\ttfamily var\+\_\+\+\_\+} \end{DoxyItemize}
{\bfseries Functions\+:} \begin{DoxyItemize}
\item Words are separated by underscores\+: {\ttfamily my\+\_\+function()} \end{DoxyItemize}
{\bfseries Accessing members\+:} \begin{DoxyItemize}
\item To get the member {\ttfamily xxx\+\_\+} use {\ttfamily  const\& xxx() const } \item To set the member {\ttfamily xxx\+\_\+} use {\ttfamily  void set\+\_\+xxx(arg) } \end{DoxyItemize}
\hypertarget{compiling_ACG}{}\subsection{Compiling A\+CG}\label{compiling_ACG}
Use the cmake build tool. \hypertarget{pickingDocumentation}{}\subsection{Picking in the A\+CG Scene\+Graph}\label{pickingDocumentation}
\hypertarget{a14874_Overview}{}\subsubsection{Overview}\label{a14874_Overview}
Picking is the operation to find an object in the 3D scene that is visible at a specific position. Usually you click with the mouse into the scene and want to get the node index of the object you clicked on and possibly the specific primitive you hit.

Picking in the \hyperlink{a06176}{A\+CG} Scenegraph is done as color picking. Each node in the scenegraph has functions that are used only when the \hyperlink{a06177}{Scene\+Graph} is traversed in picking mode ( \hyperlink{a06177_af10521b6f81a7a588708218d75936f81}{A\+C\+G\+::\+Scene\+Graph\+::traverse()} with \hyperlink{a07976}{A\+C\+G\+::\+Scene\+Graph\+::\+Pick\+Action} ). These functions render the scene in this special mode, and all objects and their primitives are rendered with a different color.

After rendering, the color at the position, where a mouse click is done, is read. The color is than split into the object and the primitive id used while rendering. Therefore the developer can map the numbers back to what the user clicked on or what is visible at the specific location.\hypertarget{a14874_Rendering}{}\subsubsection{Rendering}\label{a14874_Rendering}
For rendering the color picking, you have to use the \hyperlink{a06177_af10521b6f81a7a588708218d75936f81}{A\+C\+G\+::\+Scene\+Graph\+::traverse()} function with the \hyperlink{a07976}{A\+C\+G\+::\+Scene\+Graph\+::\+Pick\+Action}. The Action will than traverse the \hyperlink{a06177}{Scene\+Graph} and each of the nodes do their rendering.

The \hyperlink{a07976}{Pick\+Action} traverses the \hyperlink{a06177}{Scene\+Graph} in the same hierarchy as the draw function. But for entering, it calls \hyperlink{a07748_aa2409686d081ef760ea381b1766887e3}{A\+C\+G\+::\+Scene\+Graph\+::\+Base\+Node\+::enter\+Pick()} and for leaving \hyperlink{a07748_a0a4a7d32775cfe489e3ebf934b03404d}{A\+C\+G\+::\+Scene\+Graph\+::\+Base\+Node\+::leave\+Pick()}. The actual drawing is done in \hyperlink{a07748_adac324be19fb72e7044dedcc147be86c}{A\+C\+G\+::\+Scene\+Graph\+::\+Base\+Node\+::pick()} between these calls. The node index is set as the picking object name via \hyperlink{a07884_a4f8516aee550bf1ae87bcb16b47f4486}{G\+L\+State\+::pick\+\_\+push\+\_\+name()} and is valid during the \hyperlink{a07748_adac324be19fb72e7044dedcc147be86c}{A\+C\+G\+::\+Scene\+Graph\+::\+Base\+Node\+::pick()} function. Afterwards it is reset via \hyperlink{a07884_aa23cb025cbf8477add015502ad904d4d}{G\+L\+State\+::pick\+\_\+pop\+\_\+name()}. The nodes do not need to handle this explicitly as it is done by the traversal.\hypertarget{a14874_pickingUsage}{}\subsubsection{Usage}\label{a14874_pickingUsage}
\hypertarget{a14874_pickingUsageInNodes}{}\paragraph{Implementation in Nodes}\label{a14874_pickingUsageInNodes}
If you implement your own node and need picking, you have to implement the functions \hyperlink{a07748_adac324be19fb72e7044dedcc147be86c}{A\+C\+G\+::\+Scene\+Graph\+::\+Base\+Node\+::pick()} and if you need to change states \hyperlink{a07748_aa2409686d081ef760ea381b1766887e3}{A\+C\+G\+::\+Scene\+Graph\+::\+Base\+Node\+::enter\+Pick()} and \hyperlink{a07748_a0a4a7d32775cfe489e3ebf934b03404d}{A\+C\+G\+::\+Scene\+Graph\+::\+Base\+Node\+::leave\+Pick()}.

In the pick function, you get the current state and the \hyperlink{a06177_af5fad41dadeca314c2077f897377dbd0}{A\+C\+G\+::\+Scene\+Graph\+::\+Pick\+Target}. The Pick\+Target defines the primitives the user wants to pick. For a mesh, this would be vertices, edges or faces. With \hyperlink{a06177_af5fad41dadeca314c2077f897377dbd0a16466d3b836973188ef3426feda66fcd}{A\+C\+G\+::\+Scene\+Graph\+::\+P\+I\+C\+K\+\_\+\+A\+N\+Y\+T\+H\+I\+NG} you should render all primitives, one after the other with increasing indices.

The main pick function usually splits the picking for each of the primitives in the object. You have to set the maximum number of primitives that should be distinguished by the picking with the \hyperlink{a07884_a591154d91ce1b1afe2766e6f654a4173}{G\+L\+State\+::pick\+\_\+set\+\_\+maximum()} function\+:


\begin{DoxyCode}
\textcolor{comment}{// The picking function}
\textcolor{comment}{// Global object variable object\_ assumed}
\textcolor{keywordtype}{void} ExampleNode::pick(GLState& \_state, \hyperlink{a06177_af5fad41dadeca314c2077f897377dbd0}{PickTarget} \_target)
\{

  \textcolor{comment}{// Switch based on the target}
  \textcolor{keywordflow}{switch} (\_target)
  \{
    \textcolor{keywordflow}{case} \hyperlink{a06177_af5fad41dadeca314c2077f897377dbd0ac350d88f39959a7b143792247f8706dd}{PICK\_VERTEX}:
    \{
      \textcolor{comment}{// Set the maximal number of primitives for this object}
      \textcolor{comment}{// In this case the number of vertices}
      \_state.pick\_set\_maximum (object\_.n\_vertices());
      pick\_vertices( \_state);
      \textcolor{keywordflow}{break};
    \}

    \textcolor{keywordflow}{case} \hyperlink{a06177_af5fad41dadeca314c2077f897377dbd0a06758ad68497c1331f2f6639e17b01fe}{PICK\_EDGE}:
    \{
      \_state.pick\_set\_maximum (object\_.n\_edges());
      pick\_edges(\_state, 0);
      \textcolor{keywordflow}{break};
    \}

    \textcolor{keywordflow}{case} \hyperlink{a06177_af5fad41dadeca314c2077f897377dbd0a16466d3b836973188ef3426feda66fcd}{PICK\_ANYTHING}:
    \{
      \_state.pick\_set\_maximum (object\_.n\_vertices() + object\_.n\_edges());
      pick\_vertices( \_state);
      pick\_edges( \_state, object\_.n\_vertices() );
      \textcolor{keywordflow}{break};
    \}

    \textcolor{keywordflow}{default}:
      \textcolor{keywordflow}{break};
  \}
\}
\end{DoxyCode}


The pick vertices function would than look like the following example. You have to set the name for all of the primitives you want to render. You can render multiple primitives with the same index. This means that if you click on one of these primitives, they will return the same id. This is useful, if one of your components you want to pick consists of multiple parts (e.\+g. an arrow consisting of the cylinder and a cone) and should be handled as one component for the picking.


\begin{DoxyCode}
\textcolor{keywordtype}{void} ExampleNode::pick\_vertices( GLState& \_state )
\{
  \textcolor{keywordflow}{for} (\textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} i=0; i< object\_.n\_vertices(); ++i) \{

    \textcolor{comment}{// Set the picking name of the next primitive.}
    \textcolor{comment}{// This will be the target index returned by the picking.}
    \_state.pick\_set\_name (i);

    \textcolor{comment}{// Render an arbitrary number of primitives which will all get the same picking index.}
    glBegin(GL\_POINTS);
      \textcolor{comment}{// Render the vertex with number i (note that this number matches the picking index returned by the
       picking)}
      glVertex3fv( object\_.vertex(i) );
    glEnd();
  \}

\}
\end{DoxyCode}


For the edges the code would be a bit more complex. If they are picked with \hyperlink{a06177_af5fad41dadeca314c2077f897377dbd0a06758ad68497c1331f2f6639e17b01fe}{A\+C\+G\+::\+Scene\+Graph\+::\+P\+I\+C\+K\+\_\+\+E\+D\+GE} they will be handled as the vertices. If \hyperlink{a06177_af5fad41dadeca314c2077f897377dbd0a16466d3b836973188ef3426feda66fcd}{A\+C\+G\+::\+Scene\+Graph\+::\+P\+I\+C\+K\+\_\+\+A\+N\+Y\+T\+H\+I\+NG} is used, they will be used with the vertices. Therefore the indices given to the edges have to start after the vertices, which is implemented as an offset\+:


\begin{DoxyCode}
\textcolor{keywordtype}{void} ExampleNode::pick\_edges( GLState& \_state, \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} \_offset)
\{
  \textcolor{keywordflow}{for} (\textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} i=0; i<object\_n\_edges(); ++i) \{

    \textcolor{comment}{// Set the name for the current edge}
    \_state.pick\_set\_name (i + \_offset);

    \textcolor{comment}{// Render current edge}
    glBegin(GL\_LINES);
      glVertex3fv( object\_.vertex(  i      % object\_.n\_vertices() ) );
      glVertex3fv( object\_.vertex( (i + 1) % object\_.n\_vertices() ) );
    glEnd();

  \}
\}
\end{DoxyCode}
\hypertarget{a14874_pickingRetrieval}{}\paragraph{Getting the picking information}\label{a14874_pickingRetrieval}
After rendering, you just retrieve the rgba color at the click position. This color can be converted to the node id and the component\+:


\begin{DoxyCode}
\textcolor{comment}{// Color at the picked position}
\hyperlink{a08448}{ACG::Vec4uc} rgba;

\textcolor{comment}{// Read color from framebuffer at desired position into rgba}
std::vector<unsigned int> rv = glState\_.pick\_color\_to\_stack(rgba);

\textcolor{comment}{// something wrong with the color stack}
\textcolor{keywordflow}{if} (rv.size () < 2)
  \textcolor{keywordflow}{return};

\textcolor{comment}{// Index of the picked Node in the SceneGraph ( This can be used to fetch the node from the scenegraph ).}
\_nodeIdx   = rv[1];

\textcolor{comment}{// This is the component of the object at the picked position which has been set with pick\_set\_name()}
\_targetIdx = rv[0];
\end{DoxyCode}


To get the node with the returned index, you can use the \hyperlink{a07956}{A\+C\+G\+::\+Scene\+Graph\+::\+Find\+Node\+Action}.\hypertarget{a14874_pickingNEVER}{}\paragraph{N\+E\+V\+E\+R D\+O T\+H\+IS}\label{a14874_pickingNEVER}
Do not enable lighting, shading, alpha,... basically everything that shades colors! The picking relies on fixed colors. Otherwise the correspondence to the objects/components gets lost and will always fail in weird ways. \hypertarget{NonFixedPipelinePage}{}\subsection{The non-\/fixed Open\+GL rendering pipeline}\label{NonFixedPipelinePage}
The \hyperlink{a06176}{A\+CG} library supports two different approaches to rendering the scenegraph\+: direct fixed-\/function based and data-\/driven. This page focuses on how to make use of the latter. The data-\/driven approach makes it possible to have complete control over the rendering pipeline in a custom render-\/plugin.\hypertarget{a14871_baseNode}{}\subsubsection{The Base\+Node in the Scenegraph}\label{a14871_baseNode}
Every node in the scenegraph is able to provide the renderer with data by creating Render\+Object. A Render\+Object is a collection of data, which is necessary to execute a draw-\/call. This data consists of information about\+: shaders, textures, uniforms, Open\+G\+L-\/states, vertex-\/layout, vertex buffer etc. These Render\+Objects are created in the get\+Render\+Objects() function of a node. Finally, a node is not supposed to execute draw-\/calls on its own in get\+Render\+Objects(), but should only provide render-\/object data.\hypertarget{a14871_iRenderer}{}\subsubsection{The I\+Renderer interface}\label{a14871_iRenderer}
Custom render plugins for the data-\/driven rendering approach have to implement the I\+Renderer interface. This interface provides basic functionality such as collecting render-\/object data from the scenegraph and executing a draw-\/call for a render-\/object.\hypertarget{a14871_renderObject}{}\paragraph{Defining Render\+Objects}\label{a14871_renderObject}
This is the collection of rendering-\/data that is necessary for a draw-\/call. It should be noted that any memory addresses set to a Render\+Object have to remain valid until used in the render-\/plugin. Thus, addresses set in the get\+Render\+Objects() method should point to permanent data in the heap, not to local data in the stack!

Typically, Render\+Objects are initialized somewhat similar to the following manner.


\begin{DoxyCode}
RenderObject ro;
ro.initFromState(&\_state);                 \textcolor{comment}{// copy opengl-states and transforms from GLState}
ro.depthTest = \textcolor{keyword}{true};                       \textcolor{comment}{// force depth-testing}
ro.shaderDesc.shadeMode = SG\_SHADE\_UNLIT;  \textcolor{comment}{// disable lighting}
ro.emissive = \hyperlink{a08448}{Vec3f}(1.0f, 1.0f, 1.0f);     \textcolor{comment}{// base color}

ro.vertexBuffer = myVBO;       \textcolor{comment}{// vertex/index buffer}
ro.indexBuffer = myIBO;
ro.vertexDecl = myVertexDecl;  \textcolor{comment}{// vertex layout}
ro.glDrawElements(GL\_TRIANGLES, indexCount, GL\_UNSIGNED\_INT, 0);  \textcolor{comment}{// same as glDrawElements, but does not
       execute draw-call! stores data only instead}

\_renderer->addRenderObject(&ro);
\end{DoxyCode}
\hypertarget{a14871_vertexDeclaration}{}\subsubsection{Defining the layout of a vertex element}\label{a14871_vertexDeclaration}
The Vertex\+Declaration class is used to specify the layout of a vertex element (Vertex\+Element)\hypertarget{a14871_shaderGenerator}{}\subsubsection{Generating G\+L\+S\+L shaders}\label{a14871_shaderGenerator}
The \hyperlink{ShaderGenerator_page}{Shader Generator} class can be used to generate default \hyperlink{a06188}{G\+L\+SL} shader code. It is possible to have the complete shader generated with typical shading options such as phong or flat shading. Alternatively the main function can be fully customized via template files or Shader\+Modifiers. Template files are specified in Shader\+Gen\+Desc\+::vertex\+Template\+File and Shader\+Gen\+Desc\+::fragment\+Template\+File and they extend the generated code by a user defined main function. Shader vertex I/O attributes and uniforms can also be user defined; however, make sure that there is no name conflict with the generated shader code. Example\+: A vertex offset operation based on normals is accomplished with the following template file\+: 
\begin{DoxyCode}
\textcolor{keywordtype}{void} main()
\{
  \textcolor{comment}{// default vertex transforms are handled by the generator by replacing the SG\_VERTEX\_BEGIN with generated
       code}
  SG\_VERTEX\_BEGIN
  
\textcolor{preprocessor}{#ifdef SG\_NORMALS}
  sg\_vPosPS = g\_mWVP * (inPosition + vec4(inNormal, 0));
\textcolor{preprocessor}{#endif}
  
  SG\_VERTEX\_END
\}
\end{DoxyCode}


But templates are optional and are not needed to generate shaders for mimicking the fixed function pipeline. Alternatively, Shader\+Modifiers are useful for global shading effects which only change few code lines and are also combinable with each other allowing a more dynamic shader customization. The Depth-\/\+Peeling renderer shows how to use these modifiers.\hypertarget{a14871_vertexAttributes}{}\paragraph{Adding custom vertex attributes}\label{a14871_vertexAttributes}
The complete vertex layout is defined by creating a Vertex\+Declaration object. Standard attributes are\+: position, normal, texture coordinate and color. These attributes are marked with their corresponding \hyperlink{a06176_a8e20f3e5c21bdb768c1740315eeb122a}{A\+C\+G\+::\+V\+E\+R\+T\+E\+X\+\_\+\+U\+S\+A\+GE} qualifier and have a predefined variable name in the vertex shader input\+: Their variable names are predefined as \char`\"{}in\+Position\char`\"{}, \char`\"{}in\+Normal\char`\"{}, \char`\"{}in\+Tex\+Coord\char`\"{} and \char`\"{}in\+Color\char`\"{}.

Custom attributes have to be declared with the \hyperlink{a06176_a8e20f3e5c21bdb768c1740315eeb122aafa3293a2b16c5e0fdca7d9282ee8409b}{A\+C\+G\+::\+V\+E\+R\+T\+E\+X\+\_\+\+U\+S\+A\+G\+E\+\_\+\+S\+H\+A\+D\+E\+R\+\_\+\+I\+N\+P\+UT} qualifier as follows\+:


\begin{DoxyCode}
vertexDeclaration.addElement(GL\_FLOAT, 4, VERTEX\_USAGE\_SHADER\_INPUT, byte\_offset, \textcolor{stringliteral}{"inCustomParams"});
\end{DoxyCode}


This vertex declaration is then used with the render object. The vertex shader can now make use of the additional attributes by using the same variable name as in the vertex declaration. In this case the vertex shader would use the attribute like this\+:


\begin{DoxyCode}
in vec4 inCustomParams;

\textcolor{keywordtype}{void} main()
\{
  SG\_VERTEX\_BEGIN;
  
  \textcolor{comment}{// do something with inCustomParams ..}
  
  SG\_VERTEX\_BEGIN;
\}
\end{DoxyCode}


Furthermore, attribute can be passed through to the next shader stage. This has to be done manually and it must be guaranteed that the variable names do not clash with the keywords used by the Shader\+Generator\+:


\begin{DoxyCode}
in vec4 inCustomParams;
out vec4 v2f\_CustomParams; \textcolor{comment}{// make v2f\_CustomParams available in fragment shader for example}

\textcolor{keywordtype}{void} main()
\{
  SG\_VERTEX\_BEGIN;
  
  \textcolor{comment}{// do something with inCustomParams ..}
  
  v2f\_CustomParams = inCustomParams;
  
  SG\_VERTEX\_BEGIN;
\}
\end{DoxyCode}


Note that the vertex shader can be modified to accept the new attributes either with a shader modifier or a shader template file.\hypertarget{a14871_shaderCache}{}\paragraph{The Shader Cache}\label{a14871_shaderCache}
The Shader Cache singleton class should be used to manage the used shaders. You can query a shader from the cache via a shader description. If it is already available, it will be returned from the cache. Otherwise, it is compiled and linked. This ensures more efficient and redundancy free shader management. ( \hyperlink{a07548}{A\+C\+G\+::\+Shader\+Cache} )\hypertarget{a14871_glslShader}{}\paragraph{The G\+L\+S\+L Shader}\label{a14871_glslShader}
The Shader class is a helper class for building and using \hyperlink{a06188}{G\+L\+SL} programs\hypertarget{a14871_Draw}{}\paragraph{Modes}\label{a14871_Draw}
A Draw\+Mode is a set of properties that describe how to present an object (i.\+e. wireframe, textured, flat-\/shaded...). There are two types of Drawmodes\+: bitflags and property-\/based. Bitflags are a combination of predefined Drawmodes such as S\+O\+L\+I\+D\+\_\+\+S\+M\+O\+O\+T\+H\+\_\+\+S\+H\+A\+D\+ED and W\+I\+R\+E\+F\+R\+A\+ME. Afterwards it can be tested with the bitwise \& operator whether it contains such an atomic Draw\+Mode.

Property-\/based draw modes use a different approach by defining a set of properties for an atomic Draw\+Mode. These settings are stored in the Draw\+Mode\+Properties structure. Support for combined drawmodes is possible by adding a new layer for each atomic drawmode. Each layer is represented by one atomic Draw\+Mode\+Properties structure. Initially each property-\/based draw mode consists of exactly one layer which is equivalent to an atomic draw mode. If we also want to render the wireframe or halfedge representation of an object in combination with a solid mode, we can fill out a Draw\+Mode\+Properties struct for that purpose and call Draw\+Mode\+::add\+Layer() to combine wireframe and solid mode.

A scenegraph node can iterate over each layer of a Drawmode via get\+Num\+Layers() and get\+Layer() and draw its object according to the properties of that layer.

Example\+: Draw with gouraud shading\+:


\begin{DoxyCode}
DrawModeProperties props;
props.lightStage(LIGHTSTAGE\_SMOOTH); \textcolor{comment}{// lighting should be done in vertex shader}
props.normalSource(NORMAL\_PER\_VERTEX); \textcolor{comment}{// use smooth vertex normals}

\hyperlink{a06173_a84526ab3d6ed9957600371ff3f94f5df}{drawMode}.\hyperlink{a07792_adcc9a04caa493d1129922b487d9de014}{setDrawModeProperties}(props); \textcolor{comment}{// assign to layer 0}
\end{DoxyCode}


Draw with phong lighting\+:


\begin{DoxyCode}
DrawModeProperties props;
props.lightStage(LIGHTSTAGE\_PHONG); \textcolor{comment}{// lighting should be done in fragment shader}
props.normalSource(NORMAL\_PER\_VERTEX); \textcolor{comment}{// use smooth vertex normals}

\hyperlink{a06173_a84526ab3d6ed9957600371ff3f94f5df}{drawMode}.\hyperlink{a07792_adcc9a04caa493d1129922b487d9de014}{setDrawModeProperties}(props); \textcolor{comment}{// assign to layer 0}
\end{DoxyCode}


Draw with flat shading and wireframe (2 layers)\+:


\begin{DoxyCode}
\textcolor{comment}{// define flat shading properties}
DrawModeProperties props;
props.lightStage(LIGHTSTAGE\_SMOOTH); \textcolor{comment}{// lighting should be done in vertex shader}
props.normalSource(NORMAL\_PER\_FACE); \textcolor{comment}{// use per face normals}

\hyperlink{a06173_a84526ab3d6ed9957600371ff3f94f5df}{drawMode}.\hyperlink{a07792_adcc9a04caa493d1129922b487d9de014}{setDrawModeProperties}(props); \textcolor{comment}{// assign flat shading to layer 0}

\textcolor{comment}{// define unlit properties for wireframe rendering}
props.primitive(PRIMITIVE\_WIREFRAME); \textcolor{comment}{// use wireframe instead of solid faces}
props.lightStage(LIGHTSTAGE\_UNLIT); \textcolor{comment}{// no lighting }

\hyperlink{a06173_a84526ab3d6ed9957600371ff3f94f5df}{drawMode}.\hyperlink{a07792_a0746c5dd0c371e2454ac74575d5e7f41}{addLayer}(&props); \textcolor{comment}{// assign wireframe to layer 1}
\end{DoxyCode}


The object is then rendered in two passes (one for each layer) with different shader programs. Note that the light stage tells the shader generator whether to do the lighting in vertex or fragment shader or to skip it entirely. Then a combination of lighting functions are added to the shader code based on the light configuration in the Shader\+Gen\+Desc structure.

Example based on a D\+I\+R\+E\+C\+T\+I\+O\+N\+AL, D\+I\+R\+E\+C\+T\+I\+O\+N\+AL, P\+O\+I\+N\+T\+L\+I\+G\+HT configuration\+: 
\begin{DoxyCode}
sg\_cColor.xyz += LitDirLight(sg\_vPosVS.xyz, sg\_vNormalVS, g\_vLightDir\_0,  g\_cLightAmbient\_0,  
      g\_cLightDiffuse\_0,  g\_cLightSpecular\_0);
sg\_cColor.xyz += LitDirLight(sg\_vPosVS.xyz, sg\_vNormalVS, g\_vLightDir\_1,  g\_cLightAmbient\_1,  
      g\_cLightDiffuse\_1,  g\_cLightSpecular\_1);
sg\_cColor.xyz += LitPointLight(sg\_vPosVS.xyz, sg\_vNormalVS,  g\_vLightPos\_2,  g\_cLightAmbient\_2,  
      g\_cLightDiffuse\_2,  g\_cLightSpecular\_2, g\_vLightAtten\_2);
\end{DoxyCode}
\hypertarget{a14871_creating_new_renderer_plugins}{}\subsubsection{Creating new renderer plugins}\label{a14871_creating_new_renderer_plugins}
The rendering pipeline is fully customizable via external plugins. Each shader-\/based renderer is represented by a subclass of \hyperlink{a06972}{Render\+Interface} and \hyperlink{a07468}{A\+C\+G\+::\+I\+Renderer}, where \hyperlink{a06972}{Render\+Interface} enables the renderer to be selected in the viewport of Open\+Flipper (right-\/click on coordinate-\/axis -\/$>$ Renderers -\/$>$ \char`\"{}renderer-\/name\char`\"{}). and \hyperlink{a07468}{A\+C\+G\+::\+I\+Renderer} provides the connection of scenegraph-\/nodes to the renderer. Additionally further helper-\/functions are already implemented in I\+Renderer such as the collection and sorting of Render\+Objects and basic rendering procedures of Render\+Objects, but the scene rendering routine must be implemented in the plugin. Plugin-\/\+Render-\/\+Shader\+Pipeline is a minimal example of a simple rendering-\/plugin.

Rendering code is implemented in the render() function inherited by \hyperlink{a06972}{Render\+Interface} and should always look like this\+:


\begin{DoxyCode}
\textcolor{keywordtype}{void} Renderer::render(\hyperlink{a07452}{ACG::GLState}* \_glState, 
      \hyperlink{a07100}{Viewer::ViewerProperties}& \_properties)
\{
  \textcolor{comment}{// collect renderobjects + prepare OpenGL state}
  \hyperlink{a07468_a924e52c39bf07441a9849b6f81179fae}{prepareRenderingPipeline}(\_glState, \_properties.
      \hyperlink{a07100_a76b427bc1e9adc1067a658204058bee4}{drawMode}(), \hyperlink{a06173_adb9160f9b0e24053d577b42efe1d37d4}{PluginFunctions::getSceneGraphRootNode}());

  \textcolor{comment}{// render every object}
  \textcolor{keywordflow}{for} (\textcolor{keywordtype}{int} i = 0; i < \hyperlink{a07468_a4a9afe57b0bb679278e0d1e663cbc04b}{getNumRenderObjects}(); ++i)
    \hyperlink{a07468_a6938529f494f9f25ca2a8ddb9216e671}{renderObject}( \hyperlink{a07468_a3c7b38bf11681ed2f30fb0cd5848e8aa}{getRenderObject}(i) );

  \textcolor{comment}{// restore common opengl state}
  \textcolor{comment}{// log window remains hidden otherwise}
  \hyperlink{a07468_a9001168507700f0c9be585e473e00e57}{finishRenderingPipeline}();
\}
\end{DoxyCode}


The code begins and ends by calling prepare\+Rendering\+Pipeline() and finish\+Rendering\+Pipeline() which are helper-\/functions of I\+Renderer. Here, prepare\+Rendering\+Pipeline traverses the scenegraph to collect render-\/objects and sorts them by priority in ascending order. The sorted list of renderobjects can be accessed via get\+Render\+Object(). Another helper function\+: render\+Object() prepares Open\+GL states (vertex/index source, boolean gl\+Enable states..), sets shader uniforms according the data in the Render\+Object structure and executes the draw call of a Render\+Object. Furthermore it is possible to force the use of a shader or disallow any changes made via gl\+Enable/gl\+Disable by specifying the 2nd and 3rd parameter of render\+Object(). Note that render\+Object() is only a helper-\/function and may also be ignored and implemented on your own. Finally, finish\+Rendering\+Pipeline() resets the Open\+GL state machine such that it does not interfere with following draw-\/calls made by Qt.

The advantage of this data-\/driven design is that a custom render-\/plugin has complete control over the scene-\/rendering. For instance, it is possible to setup custom shaders, modify provided shaders, perform multiple render-\/passes into custom F\+B\+Os etc. If custom F\+B\+Os are used in a renderer, the input F\+BO can be easily restored by calling restore\+Input\+Fbo(). Also, the input F\+BO should not be cleared by a render-\/plugin, as this is done already by Open\+Flipper!

The depth-\/peeling renderer plugin is a more complex example, but showcases the flexibility of the renderer interface. It makes use of global shader effects which are fully integrated to the shader-\/generation pipeline. Only small changes to an existing shader have to be made in order to implement depth peeling and thus the concept of Shader\+Modifiers is used here. Take a look at the Peel\+Shader\+Modifier for example\+:


\begin{DoxyCode}
\textcolor{keyword}{class }\hyperlink{a11116}{PeelLayerModifier} : \textcolor{keyword}{public} ShaderModifier
\{
\textcolor{keyword}{public}:


  \textcolor{keywordtype}{void} \hyperlink{a11116_a72be1c05b31ef4b3088fa8994aaa2608}{modifyFragmentIO}(ShaderGenerator* \_shader)
  \{
    \_shader->addUniform(\textcolor{stringliteral}{"sampler2D g\_DepthLayer"});
  \}

  \textcolor{keywordtype}{void} \hyperlink{a11116_af45caec64259f9a4ab1c26c52f551d81}{modifyFragmentBeginCode}(QStringList* \_code)
  \{
    \textcolor{comment}{// compare current depth with previous layer}
    \_code->push\_back(\textcolor{stringliteral}{"float dp\_prevDepth = texture(g\_DepthLayer, sg\_vScreenPos).x;"});
    \_code->push\_back(\textcolor{stringliteral}{"if (gl\_FragCoord.z <= dp\_prevDepth) discard;"});
  \}

  \textcolor{keywordtype}{void} \hyperlink{a11116_a8bf411eaeda3051cd02acdd33e888aa9}{modifyFragmentEndCode}(QStringList* \_code)
  \{
    \_code->push\_back(\textcolor{stringliteral}{"outFragment = vec4(sg\_cColor.rgb * sg\_cColor.a, sg\_cColor.a);"});
  \}

  \textcolor{keyword}{static} \hyperlink{a11116}{PeelLayerModifier} instance;
\};
\end{DoxyCode}


Applying this modifier to the shader generator will result in a new uniform in the fragment shader (sampler2D g\+\_\+\+Depth\+Layer) and a slightly modified fragment shader. modify\+Fragment\+Begin\+Code() adds shader-\/code before the fragment lighting stage and modify\+Fragment\+End\+Code() adds shader-\/code at the end of the main() function of the shader. Obviously, these code excerpts have to comply to the naming convention of the shader-\/generator.

We have to register each modifier to the shader generator\+:


\begin{DoxyCode}
ShaderProgGenerator::registerModifier(&PeelLayerModifier::instance);
\end{DoxyCode}


Later in the render() function we can make use of this modifier via get\+Program() of Shader\+Cache\+:


\begin{DoxyCode}
\hyperlink{a08132}{GLSL::Program}* peelProg = ShaderCache::getInstance()->getProgram(&sortedObjects\_[k]->
      shaderDesc, PeelLayerModifier::instance);
peelProg->\hyperlink{a08132_ad6b634a00820f63f072e9d380d4dfb5a}{use}();
peelProg->\hyperlink{a08132_ae78ccf1ed98160af603fdaa72cabbe99}{setUniform}(\textcolor{stringliteral}{"g\_DepthLayer"}, 4);

renderObject(sortedObjects\_[k], peelProg, \textcolor{keyword}{true});
\end{DoxyCode}


Multiple shader modifiers can be applied to one shader, but the order of modifiers is undefined.


\begin{DoxyCode}
ShaderCache::getInstance()->getProgram(&shaderDesc, ModifierA\_ID | ModifierB\_ID);
\end{DoxyCode}
\hypertarget{a14871_shader_template_files}{}\subsubsection{Shader template files}\label{a14871_shader_template_files}
Shader generation can be controlled with shader template files. These template files contain custom shader code and are later extended by the Shader\+Generator. Obviously, only one template at a time can be used by the Shader\+Generator, so render-\/plugins should prefer modifiers to retain combinational flexibility.

Example template\+: The depth-\/peeling effect can also be achieved with templates instead of shader-\/modifiers.


\begin{DoxyCode}
\textcolor{comment}{// declare custom uniforms}
uniform sampler2D g\_DepthLayer;

\textcolor{comment}{// the generator takes care of all essential uniforms}

\textcolor{keywordtype}{void} main()
\{
  \textcolor{comment}{// At first, the generator calculates sg\_vScreenPos and sg\_cColor for us here}
  SG\_FRAGMENT\_BEGIN; \textcolor{comment}{// begin code marker, insert generated code here}

  
  
  \textcolor{comment}{// customized peeling code}
  \textcolor{keywordtype}{float} dp\_prevDepth = texture(g\_DepthLayer, sg\_vScreenPos).x;
  \textcolor{keywordflow}{if} (gl\_FragCoord.z <= dp\_prevDepth) discard;

  
  \textcolor{comment}{// end of fragment shader}
  SG\_FRAGMENT\_END; \textcolor{comment}{// end code marker}

  
  \textcolor{comment}{// overwrite color output of generator for peel-layer blending}
  outFragment = vec4(sg\_cColor.rgb * sg\_cColor.a, sg\_cColor.a);
\}
\end{DoxyCode}


Assume that this template file is stored at Shader\+Dir/\+Depth\+Peeling/peel\+Layer.\+template, then the peel shader is assembled as follows\+:


\begin{DoxyCode}
\textcolor{comment}{// QString to fragment shader template}
QString qstrInitTemplate = OpenFlipper::Options::shaderDirStr() + QDir::separator() + QString(\textcolor{stringliteral}{"
      DepthPeeling/peelLayer.template"});

\textcolor{comment}{// make temp-copy of ShaderGenDesc }
ShaderGenDesc peelDesc = sortedObjects\_[k]->shaderDesc;

\textcolor{comment}{// specify template string}
std::string strTemplateFile = qstrInitTemplate.toStdString();
peelDesc.fragmentTemplateFile = strTemplateFile.c\_str();

\textcolor{comment}{// query shader-program from cache}
\hyperlink{a08132}{GLSL::Program}* peelProg = ShaderCache::getInstance()->getProgram(&peelDesc);
\end{DoxyCode}


Keep in mind that this technique eventually overwrites any template set by scenegraph-\/nodes.\hypertarget{a14871_acg_debugging_tips_and_tricks}{}\subsubsection{Debugging tips and tricks}\label{a14871_acg_debugging_tips_and_tricks}
The most important function for debugging dump\+Render\+Objects() is provided by \hyperlink{a07468}{A\+C\+G\+::\+I\+Renderer}. This can be called after call to prepare\+Rendering\+Pipeline() and it creates a text file containing a full data dump of all render objects with all states and shader codes for each. You can just call the dump\+Render\+Objects\+To\+Texxt() function with a filename and a pointer to the sorted\+Objects\+\_\+.

Often encountered errors\+:
\begin{DoxyItemize}
\item lighting disabled in Shader\+Gen\+Desc and black emission color (use different emission color)
\item wrong depth-\/buffer states
\item color write disabled
\item wrong vertex declaration format
\item temporary vertex declaration (it should be a static or member variable) The address set to the render object has to be valid after the call to get\+Render\+Object().
\end{DoxyItemize}

If the whole scene seems to be rendered wrong, it is possible that one draw-\/call causes problems in the Open\+GL state machine. Try to render only a selection of renderobjects until the problematic one is found. \hypertarget{ShaderGenerator_page}{}\subsubsection{Shader Generator}\label{ShaderGenerator_page}
\hypertarget{a14875_ShaderGenerator_auto_shader_uniforms}{}\paragraph{Automatically generated Shader Uniforms}\label{a14875_ShaderGenerator_auto_shader_uniforms}
\hypertarget{a14875_Matrix}{}\subparagraph{Matrix}\label{a14875_Matrix}

\begin{DoxyCode}
mat4 g\_mWVP  - world-view-projection transform
mat4 g\_mWV   - world-view transform
mat4 g\_mWVIT - inverse transpose of world view matrix
mat4 g\_mP    - projection matrix
\end{DoxyCode}
\hypertarget{a14875_Color}{}\subparagraph{Color}\label{a14875_Color}

\begin{DoxyCode}
vec3 g\_cDiffuse - diffuse color
vec3 g\_cAmbient - ambient color
vec3 g\_cEmissive - emissive color
vec3 g\_cSpecular - specular color
vec4 g\_vMaterial - vec4(shininess, alpha, unused, unused)
\end{DoxyCode}
\hypertarget{a14875_Lighting}{}\subparagraph{Lighting}\label{a14875_Lighting}

\begin{DoxyCode}
\textcolor{comment}{// light parameters denoted by zero-based index i}
vec3 g\_cLightDiffuse\_i   - diffuse color
vec3 g\_cLightAmbient\_i   - ambient color
vec3 g\_cLightSpecular\_i  - specular color
vec3 g\_vLightPos\_i       - position in view space (\textcolor{keywordflow}{for} point and spot lights only)
vec3 g\_vLightAtten\_i     - [constant, linear, quadratic] attenuation factors (\textcolor{keywordflow}{for} point and spot lights 
      only)
vec3 g\_vLightDir\_i       - light direction in view space (\textcolor{keywordflow}{for} spot and directional lights only)
vec2 g\_vLightAngleExp\_i  - [cos(spotCutOffAngle), spot exponent] (\textcolor{keywordflow}{for} spot lights only)
\end{DoxyCode}
\hypertarget{a14875_Texturing}{}\subparagraph{Texturing}\label{a14875_Texturing}

\begin{DoxyCode}
sampler2D g\_Texture0     - texture sampler (\textcolor{keywordflow}{if} textured is enabled in ShaderGenDesc)
\end{DoxyCode}
\hypertarget{a14875_ShaderGenerator_auto_shader_inout}{}\paragraph{Automatically generated shader input/output\+:}\label{a14875_ShaderGenerator_auto_shader_inout}
\hypertarget{a14875_ShaderGenerator_vertex_shader_io}{}\subparagraph{Vertex shader IO}\label{a14875_ShaderGenerator_vertex_shader_io}

\begin{DoxyCode}
in vec4 inPosition - vertex position in model space

in vec3 inNormal   - vertex normal (only \textcolor{keywordflow}{if} ShaderGenDesc.shadeMode != unlit)
in vec4 inColor    - vertex color (only \textcolor{keywordflow}{if} ShaderGenDesc.vertexColors == \textcolor{keyword}{true})
in vec2 inTexCoord - texture coordinate (only if ShaderGenDesc.textured == true)

out vec4 outPosCS  - position in clip space
out vec3 outNormal - normal in view space (only if ShaderGenDesc.shadeMode == phong)
out vec4 outPosVS  - position in view space (only if ShaderGenDesc.shadeMode == phong)
out vec4 outColor  - vertex color after lighting (only if ShaderGenDesc.shadeMode == flat or gouraud)
out vec2 outTexCoord - texture coordinate (only if ShaderGenDesc.textured == true)

\textcolor{comment}{// insert input/outputs added from modifiers here}
\end{DoxyCode}
\hypertarget{a14875_ShaderGenerator_fragment_shader_io}{}\subparagraph{Fragment shader IO}\label{a14875_ShaderGenerator_fragment_shader_io}
See vertex shader outputs for fragment inputs. 
\begin{DoxyCode}
out vec4 outFragment - fragment color

\textcolor{comment}{// insert input/outputs added from modifiers here}
\end{DoxyCode}
\hypertarget{a14875_ShaderGenerator_auto_shader_defines}{}\paragraph{Automatically generated shader defines}\label{a14875_ShaderGenerator_auto_shader_defines}
These come in handy when you need to keep compatibility with custom shaders.

Depending on the shademode of \hyperlink{a07560}{Shader\+Gen\+Desc}, exactly one of the following defines is active.
\begin{DoxyItemize}
\item S\+G\+\_\+\+G\+O\+U\+R\+A\+UD
\item S\+G\+\_\+\+F\+L\+AT
\item S\+G\+\_\+\+U\+N\+L\+IT
\item S\+G\+\_\+\+P\+H\+O\+NG
\end{DoxyItemize}

Additional defines\+: 
\begin{DoxyCode}
SG\_NORMALS      \textcolor{comment}{// defined if vertex normals are available}
SG\_TEXTURE      \textcolor{comment}{// defined if ShaderGenDesc.textured     == true}
SG\_VERTEX\_COLOR \textcolor{comment}{// defined if ShaderGenDesc.vertexColors == true}
\end{DoxyCode}


Lighting\+: 
\begin{DoxyCode}
SG\_NUM\_LIGHTS   \textcolor{comment}{// number of lights}

 \textcolor{comment}{//for each light i:}
 SG\_LIGHT\_TYPE\_i \textcolor{comment}{// Determine the type of light i; set to one of \{SG\_LIGHT\_DIRECTIONAL, SG\_LIGHT\_POINT,
       SG\_LIGHT\_SPOT\}}

 \textcolor{comment}{// Example:}
\textcolor{preprocessor}{ #define SG\_LIGHT\_TYPE\_0 SG\_LIGHT\_DIRECTIONAL}
\textcolor{preprocessor}{ #define SG\_LIGHT\_TYPE\_1 SG\_LIGHT\_DIRECTIONAL}
\textcolor{preprocessor}{ #define SG\_LIGHT\_TYPE\_2 SG\_LIGHT\_POINT}
\end{DoxyCode}
\hypertarget{a14875_ShaderGenerator_general_vertex_shader_structure}{}\paragraph{Vertex shader generation structure}\label{a14875_ShaderGenerator_general_vertex_shader_structure}

\begin{DoxyCode}
\textcolor{keywordtype}{void} main()
\{
  vec4 sg\_vPosPS    = g\_mWVP * inPosition;
  vec4 sg\_vPosVS    = g\_mWV  * inPosition;
  vec3 sg\_vNormalVS = vec3(0.0, 1.0, 0.0);
  vec2 sg\_vTexCoord = vec2(0.0, 0.0);
  vec4 sg\_cColor    = vec4(g\_cEmissive, SG\_ALPHA);

\textcolor{preprocessor}{#if normals available}
  sg\_vNormalVS = g\_mWVIT * inNormal;

\textcolor{preprocessor}{#if textured}
  sg\_vTexCoord = inTexCoord;

\textcolor{preprocessor}{#if vertexcolors}
  sg\_cColor = inColor;


\textcolor{preprocessor}{#if vertex-lighting enabled}
  lighting code, save lit color in sg\_cColor


  \textcolor{comment}{// -------------------------------------------------------------------------}
  \textcolor{comment}{// begin customized code}
  \textcolor{comment}{// - insert registered begin-code modifiers, that ideally operate on generated sg\_* variables}
  \textcolor{comment}{// - loaded code from template file is added here}
  \textcolor{comment}{// make sure to use #ifdef #endif if you make use of conditional inputs such as normals, texcoords..}
  \textcolor{comment}{// end of customized code}
  \textcolor{comment}{// -------------------------------------------------------------------------}

  gl\_Position = sv\_vPosPS;
  outPosCS = sg\_vPosPS;

\textcolor{preprocessor}{#if textured}
  outTexCoord = sg\_vTexCoord;

\textcolor{preprocessor}{#if vertex-lighting}
  outColor = sg\_cColor;

\textcolor{preprocessor}{#if fragment-lighting}
  outNormal = sg\_vNormalVS;
  outPosVS = sg\_vPosVS;

  \textcolor{comment}{// end-code modifiers are added here}
\}
\end{DoxyCode}




\hypertarget{a14875_ShaderGenerator_general_fragment_shader_structure}{}\paragraph{Fragment shader generation structure}\label{a14875_ShaderGenerator_general_fragment_shader_structure}

\begin{DoxyCode}
\textcolor{keywordtype}{void} main()
\{

  \textcolor{comment}{// compute screen-projected coordinates, useful for various post-processing effects}
  vec2 sg\_vScreenPos = outPosCS.xy / outPosCS.w * 0.5 + vec2(0.5, 0.5);

  vec4 sg\_cColor = vec4(g\_cEmisive, SG\_ALPHA);

\textcolor{preprocessor}{#if vertex-lighting}
  sg\_cColor = outColor;

\textcolor{preprocessor}{#if fragment lighting}
  vec4 sg\_vPosVS = outPosVS;
  vec3 sg\_vNormalVS = outNormal;
  lighting code here, save color to sg\_cColor


\textcolor{preprocessor}{#if textured}
  vec4 sg\_cTex = texture(g\_Texture0, outTexCoord);
  sg\_cColor *= sg\_cTex;

  \textcolor{comment}{// -------------------------------------------------------------------------}
  \textcolor{comment}{// begin customized code}
  \textcolor{comment}{// - insert registered begin-code modifiers, that ideally operate on generated sg\_* variables}
  \textcolor{comment}{// - loaded code from template file is added here}
  \textcolor{comment}{// make sure to use #ifdef #endif if you make use of conditional inputs such as normals, texcoords..}
  \textcolor{comment}{// end of customized code}
  \textcolor{comment}{// -------------------------------------------------------------------------}

  outFragment = sg\_cColor;

  \textcolor{comment}{// end-code modifiers are added here}
\}
\end{DoxyCode}
 \hypertarget{ShaderGenPage}{}\subsection{Dynamic shader assembly overview}\label{ShaderGenPage}
\hyperlink{a06176}{A\+CG} supports shader generation at runtime and offers a modular shader assembly method. The main class of interest is Shader\+Prog\+Generator, which generates a complete \hyperlink{a06188}{G\+L\+SL} program composed of vertex, fragment and optionally geometry and tessellation shaders. This page documents the assembly process of generated shaders and how Shader\+Modifers and templates will affect the process. \hyperlink{a06188}{G\+L\+SL} versions 1.\+3 and higher are supported.\hypertarget{a14872_shaderFixed}{}\subsubsection{Fixed shader code}\label{a14872_shaderFixed}
Some parts of shader code are fixed and will be available in any generated shader. These include, but are not limited to\+:


\begin{DoxyItemize}
\item essential input uniforms (model-\/view-\/projection matrix, global lights..)
\item essential input/output between two shader stages (ie. normal, texcoord)
\item vertex transformation
\item default lighting functions
\item default texturing
\end{DoxyItemize}\hypertarget{a14872_namingConvention}{}\subsubsection{Naming convention}\label{a14872_namingConvention}
The following naming conventions for uniforms, stage input/output and local variables are used\+:


\begin{DoxyItemize}
\item Defines\+: prefix \char`\"{}\+S\+G\+\_\+\char`\"{}, all uppercase
\item Uniforms\+: prefix \char`\"{}g\+\_\+\char`\"{}
\item Local variables\+: prefix \char`\"{}sg\+\_\+\char`\"{}
\item vertex shader input\+: prefix \char`\"{}in\char`\"{}
\item vertex shader output\+: prefix \char`\"{}out\+Vertex\char`\"{}
\item tessellation-\/control shader output\+: prefix \char`\"{}out\+Tc\char`\"{}
\item tessellation-\/evaluation shader output\+: prefix \char`\"{}out\+Te\char`\"{}
\item geometry shader output\+: prefix \char`\"{}out\+Geometry\char`\"{}
\item fragment shader output\+: prefix \char`\"{}out\+Fragment\char`\"{}

Modifiers and templates can not actually control any shader code provided by the Shader\+Generator, but they can add additional code lines that may overwrite or extend the results of the generated code.
\end{DoxyItemize}\hypertarget{a14872_shaderDefines}{}\subsubsection{Default defines}\label{a14872_shaderDefines}
The Shader\+Generator writes the current configuration given in Shader\+Gen\+Desc to a shader with the help of defines. These defines in the generated shader reflect the state of the active Shader\+Gen\+Desc.

Shading mode\+: defines in which stage lighting should be performed. One of the following defines is generated based on the state of Shader\+Gen\+Desc\+::shade\+Mode.


\begin{DoxyCode}
\textcolor{preprocessor}{#define SG\_GOURAUD 1   // only added iff shadeMode == SG\_SHADE\_GOURAUD}
\textcolor{preprocessor}{#define SG\_FLAT 1      // only added iff shadeMode == SG\_SHADE\_FLAT}
\textcolor{preprocessor}{#define SG\_UNLIT 1     // only added iff shadeMode == SG\_SHADE\_UNLIT}
\textcolor{preprocessor}{#define SG\_PHONG 1     // only added iff shadeMode == SG\_SHADE\_PHONG}
\end{DoxyCode}


If textures, vertex colors and or lighting is enabled in the descriptor, these defines are specified in the shader. 
\begin{DoxyCode}
\textcolor{preprocessor}{#define SG\_TEXTURED 1      // only added iff textured}
\textcolor{preprocessor}{#define SG\_VERTEX\_COLOR 1  // only added iff vertex colors are used}
\textcolor{preprocessor}{#define SG\_NORMALS 1       // only added iff lighting is enabled  ( shadeMode != SG\_SHADE\_UNLIT )}
\end{DoxyCode}


Additionally the light setup is passed to the shader with the following defines. 
\begin{DoxyCode}
\textcolor{preprocessor}{#define SG\_NUM\_LIGHTS N  // N = numLights}
\textcolor{preprocessor}{#define SG\_LIGHT\_TYPE\_X Y // type of light X where X = 0,...,N-1 and  Y =
       SG\_LIGHT\_DIRECTIONAL,SG\_LIGHT\_POINT,SG\_LIGHT\_SPOT}
\end{DoxyCode}


Furthermore, there are stage-\/independent IO defines for default vertex attribute IO. It is recommended to make use of these, instead of using the direct names. 
\begin{DoxyCode}
SG\_INPUT\_POSOS        \textcolor{comment}{// input object space position }
SG\_INPUT\_POSVS        \textcolor{comment}{// input view space position }
SG\_INPUT\_POSCS        \textcolor{comment}{// input clip space position}
SG\_INPUT\_NORMALOS     \textcolor{comment}{// input object space normal}
SG\_INPUT\_NORMALVS     \textcolor{comment}{// input view space normal}
SG\_INPUT\_TEXCOORD     \textcolor{comment}{// input texcoord}
SG\_INPUT\_VERTEXCOLOR  \textcolor{comment}{// input vertex color}

SG\_OUTPUT\_X           \textcolor{comment}{// output corresponding to SG\_INPUT\_X,  ie. SG\_OUTPUT\_POSOS ..}
\end{DoxyCode}


Request defines provided by shader modifiers or templates. Add these somewhere at the beginning of the shader.


\begin{DoxyCode}
SG\_REQUEST\_POSOS        \textcolor{comment}{// shader requires object space position }
SG\_REQUEST\_POSVS        \textcolor{comment}{// shader requires view space position }
SG\_REQUEST\_NORMALOS     \textcolor{comment}{// shader requires object space normal}
SG\_REQUEST\_NORMALVS     \textcolor{comment}{// shader requires view space normal}
SG\_REQUEST\_TEXCOORD     \textcolor{comment}{// shader requires texcoord}
SG\_REQUEST\_VERTEXCOLOR  \textcolor{comment}{// shader requires vertex color}
\end{DoxyCode}
\hypertarget{a14872_shaderUniforms}{}\subsubsection{Default uniforms}\label{a14872_shaderUniforms}
The following default uniforms are guaranteed to be added to any generated shader\+:


\begin{DoxyCode}
mat4 g\_mWVP;         \textcolor{comment}{// proj * view * world matrix}
mat4 g\_mWV;          \textcolor{comment}{// modelview matrix}
mat3 g\_mWVIT;        \textcolor{comment}{// inverse transpose of modelview, used to transform direction vectors such as normals}
mat4 g\_mP;           \textcolor{comment}{// projection matrix}

vec3 g\_vCamPos;      \textcolor{comment}{// camera position in world space}
vec3 g\_vCamDir;      \textcolor{comment}{// camera view direction in world space}

vec3 g\_cDiffuse;     \textcolor{comment}{// diffuse color of material}
vec3 g\_cAmbient;     \textcolor{comment}{// ambient color of material}
vec3 g\_cEmissive;    \textcolor{comment}{// emissive color of material}
vec3 g\_cSpecular;    \textcolor{comment}{// specular color of material}
vec4 g\_vMaterial;    \textcolor{comment}{// other material parameters: vec4(shininess, alpha, 0, 0) }
\end{DoxyCode}


The light configuration is added to a shader if it is supposed to do lighting. If the shader descriptor defines that lighting has to be done via gouraud or flat shading, these are added to the vertex shader. Othwerise, in phong shading these are included in the fragment shader.


\begin{DoxyCode}
vec3 g\_cLightDiffuse\_X;   \textcolor{comment}{// diffuse color of light X}
vec3 g\_cLightAmbient\_X;   \textcolor{comment}{// ambient color of light X}
vec3 g\_cLightSpecular\_X;  \textcolor{comment}{// specular color of light X}
\end{DoxyCode}


additionally for directional lights\+: 
\begin{DoxyCode}
vec3 g\_vLightDir\_X;       \textcolor{comment}{// light direction in view space}
\end{DoxyCode}


additionally for point lights\+: 
\begin{DoxyCode}
vec3 g\_vLightPos\_X;       \textcolor{comment}{// light position in view space}
vec3 g\_vLightAtten\_X;     \textcolor{comment}{// distance attentuation factors: vec3(linear, quadratic, cubic) }
\end{DoxyCode}


additionally for spot lights\+: 
\begin{DoxyCode}
vec3 g\_vLightPos\_X;       \textcolor{comment}{// light position in view space}
vec3 g\_vLightDir\_X;       \textcolor{comment}{// light direction in view space}
vec3 g\_vLightAtten\_X;     \textcolor{comment}{// distance attentuation factors: vec3(linear, quadratic, cubic) }
vec2 g\_vLightAngleExp\_X;  \textcolor{comment}{// angle attenuation factors: vec2(cutoff angle, exponent)}
\end{DoxyCode}


where X is replaced by the light index in range\mbox{[}0,.., num\+Light-\/1\mbox{]}.

Texture\+Sampler uniforms for a fragment shader are generated based on the number of specified textures in Shader\+Gen\+Desc\+:


\begin{DoxyCode}
samplerY g\_TextureX;  \textcolor{comment}{// X: texture stage id = 0,...,numTextures-1   Y: samplerType ie.  1D, 2D, Cube,
       2DRect..}
\end{DoxyCode}


Shader\+Modifiers can add custom uniforms to a generated shader.\hypertarget{a14872_ShaderAttributeIO}{}\subsubsection{Shader attribute IO}\label{a14872_ShaderAttributeIO}
Custom attributes have to be handled manually and are ignored by the generator. In contrast, default attributes consisting of position, normal, texcoord and vertexcolor can be conveniently accessed via the S\+G\+\_\+\+I\+N\+P\+U\+T\+\_\+X, S\+G\+\_\+\+O\+U\+T\+P\+U\+T\+\_\+X defines. Default attributes can be requested in a template or modifier via the S\+G\+\_\+\+R\+E\+Q\+U\+E\+S\+T\+\_\+X defines. It does not matter in what stage the attribute request is defined; the attribute will be available in all stages. In general, all used default attributes in a program are passed down from the vertex shader through all following stages. The fragment shader has only one default output though\+: vec4 out\+Fragment! Also, they are passed down without modifications from the vertex-\/shader; that is, if not done explicitly by a modifier or template afterwards.

However, this is difficult for geometry and tessellation shaders due to their freedom of having multiple inputs or outputs. There is a convenience attribute mapping function sg\+\_\+\+Map\+I\+O() to help with this problem for each of these stages, which maps all default inputs to their corresponding outputs without any modifications.

The implementation of this function looks as follows for each stage\+:

Geometry shader\+: 
\begin{DoxyCode}
\textcolor{keywordtype}{void} sg\_MapIO(\textcolor{keywordtype}{int} inIdx)
\{
  gl\_Position = gl\_in[inIdx].gl\_Position;
  gl\_PrimitiveID = gl\_PrimitiveIDIn;
  SG\_OUTPUT\_X = gl\_in[inIdx].SG\_INPUT\_X
\}
\end{DoxyCode}


Tess-\/control shader\+: 
\begin{DoxyCode}
\textcolor{keywordtype}{void} sg\_MapIO(\textcolor{keywordtype}{int} inIdx)
\{
  gl\_out[gl\_InvocationID].gl\_Position = gl\_in[inIdx].gl\_Position;
  gl\_out[gl\_InvocationID].SG\_OUTPUT\_X = gl\_in[inIdx].SG\_INPUT\_X
\}
\end{DoxyCode}


Tess-\/evaluation shader\+: This is somewhat tricky, since there is no \char`\"{}default\char`\"{} way to interpolate. Still, there are some helpers for barycentric interpolation for triangle patches and bilinear interpolation for quad patches\+: 
\begin{DoxyCode}
\textcolor{keywordtype}{void} sg\_MapIOBarycentric()
\{
  SG\_OUTPUT\_X = gl\_TessCoord.x * SG\_INPUT\_X[0] + gl\_TessCoord.y * SG\_INPUT\_X[1] + gl\_TessCoord.z * 
      SG\_INPUT\_X[2];
  \textcolor{comment}{// same for gl\_Position}
\}

\textcolor{keywordtype}{void} sg\_MapIOBilinear()
\{
  \textcolor{comment}{// bilerp for SG\_OUTPUT\_X <- SG\_INPUT\_X[0..3] by gl\_TessCoord.xy}
  \textcolor{comment}{// same for gl\_Position}
\}
\end{DoxyCode}


Full flexibility for the interpolation stage is possible with special keywords (\char`\"{}\+S\+G\+\_\+\+I\+N\+P\+U\+T\char`\"{}, \char`\"{}\+S\+G\+\_\+\+O\+U\+T\+P\+U\+T\char`\"{}) recognized by the generator exclusively for the tess-\/eval stage\+: However, this only works if the whole instruction does not exceed more than a single line of code.

For instance, a barycentric interpolation of default attributes in a triangle can also be expressed as\+: 
\begin{DoxyCode}
SG\_OUTPUT = gl\_TessCoord.x * SG\_INPUT[0] + gl\_TessCoord.y * SG\_INPUT[1] + gl\_TessCoord.z * SG\_INPUT[2];
\end{DoxyCode}
 The generator then replaces the S\+G\+\_\+\+O\+U\+T\+P\+UT, S\+G\+\_\+\+I\+N\+P\+UT keywords with each available default attribute.

Example 1\+: Displace vertices along normals in a vertex shader


\begin{DoxyCode}
\textcolor{comment}{// this is a vertex shader template!}
\textcolor{preprocessor}{#define SG\_REQUEST\_NORMALOS}

uniform \textcolor{keywordtype}{float} factor;

\textcolor{keywordtype}{void} main()
\{
  SG\_VERTEX\_BEGIN;
  SG\_VERTEX\_END;
  vec4 newPosOS = SG\_INPUT\_POSOS + vec4(SG\_INPUT\_NORMALOS, 0) * factor;
  vec4 newPosCS = g\_mWVP * newPosOS;
  SG\_OUTPUT\_POSCS = gl\_Position = newPosCS;
\textcolor{preprocessor}{  #ifdef SG\_OUTPUT\_POSVS}
  SG\_OUTPUT\_POSVS = g\_mWV * newPosOS;
\textcolor{preprocessor}{  #endif}
\textcolor{preprocessor}{  #ifdef SG\_OUTPUT\_POSOS}
  SG\_OUTPUT\_POSOS = newPosOS;
\textcolor{preprocessor}{  #endif}
\textcolor{preprocessor}{\}}
\end{DoxyCode}


Example 2\+: Write color-\/encoded normals in a fragment shader

Object-\/space normals have to be requested here! This example is implemented as a modifier for a change\+:


\begin{DoxyCode}
\textcolor{keywordtype}{void} modifyVertexIO(\hyperlink{a07568}{ACG::ShaderGenerator}* \_shader)
\{
  \_shader->\hyperlink{a07568_ad5f478c0f84795ad4066e5b957a4e343}{addDefine}(\textcolor{stringliteral}{"SG\_REQUEST\_NORMALOS"});
\}

\textcolor{keywordtype}{void} modifyFragmentEndCode(QStringList* \_code)
\{
  \_code->push\_back(\textcolor{stringliteral}{"outFragment = vec4(normalize(SG\_INPUT\_NORMALOS) * 0.5 + 0.5, 1);"});
\}
\end{DoxyCode}
\hypertarget{a14872_ShaderTemplates}{}\subsubsection{Shader Templates}\label{a14872_ShaderTemplates}
A shader template is glsl code with additional keywords that are interpreted by the shader generator.

Apart from the previously mentioned default defines, additional keywords are\+:


\begin{DoxyCode}
SG\_VERTEX\_BEGIN
SG\_VERTEX\_END
SG\_FRAGMENT\_BEGIN
SG\_FRAGMENT\_END
\end{DoxyCode}


These keywords are location markers, where generated begin-\/ or endcode of the vertex/fragment shader should be generated. However, it is not necessary to use them if the user wants to perform manual lighting and texturing etc. Templates for the tessellation and geometry stage do not have any exclusive keywords, but they can make use of defines, IO keywords and the mapping functions as described in the \char`\"{}\+Shader Attribute I\+O\char`\"{} section.

The vertex shader template without any user defined behaviour is\+:


\begin{DoxyCode}
\textcolor{keywordtype}{void} main()
\{
  SG\_VERTEX\_BEGIN;
  SG\_VERTEX\_END;
\}
\end{DoxyCode}


Likewise, the fragment shader without special behaviour is\+:


\begin{DoxyCode}
\textcolor{keywordtype}{void} main()
\{
  SG\_FRAGMENT\_BEGIN;
  SG\_FRAGMENT\_END;
\}
\end{DoxyCode}
\hypertarget{a14872_vertShaderGen}{}\subsubsection{Vertex shader code generation}\label{a14872_vertShaderGen}
Some parts of a generated shader contain fixed code snippets, which are assembled according to specification in Shader\+Gen\+Desc.

A vertex shader has the following code layout.


\begin{DoxyCode}
\textcolor{keywordtype}{void} main()\{

\textcolor{comment}{// ============================================================}
\textcolor{comment}{// Generated begin code:}
\textcolor{comment}{// read inputs from vertex buffer and initialize generated local variables}
vec4 sg\_vPosPS = g\_mWVP * inPosition;  \textcolor{comment}{// transform pos to projection space}
vec4 sg\_vPosVS = g\_mWV * inPosition;   \textcolor{comment}{// transform pos to view space}

vec4 sg\_cColor = vec4(g\_cEmissive, ALPHA); \textcolor{comment}{// color  (ALPHA: #define ALPHA g\_vMaterial.y)}

vec3 sg\_vNormalVS = vec3(0,1,0); \textcolor{comment}{// unknown vertex normal at this point}

\textcolor{preprocessor}{#if SG\_NORMALS}
sg\_vNormalVS = \hyperlink{a08448_a067799f2aa7a99c8740b909ca13713c4}{normalize}(g\_mWVIT * inNormal); \textcolor{comment}{// transform normal to view space}
\textcolor{preprocessor}{#endif}

\textcolor{preprocessor}{#if SG\_TEXTURED}
vecX sg\_vTexCoord = inTexCoord;
\textcolor{preprocessor}{#endif}

\textcolor{preprocessor}{#if SG\_VERTEX\_COLOR}
sg\_cColor = inColor;
\textcolor{preprocessor}{#endif}

\textcolor{preprocessor}{#if SG\_GOURAUD or SG\_FLAT}
sg\_cColor += lightingCode();
\textcolor{preprocessor}{#endif}

\textcolor{comment}{// ============================================================}


\textcolor{comment}{// Your ShaderModifier adds vertex shader code here.}
\textcolor{comment}{// The modifier may overwrite any local variables from the shader generator.}
\textcolor{keywordflow}{for each} modifier:
 modifier->modifyVertexBeginCode();

\textcolor{comment}{// ============================================================}
\textcolor{comment}{// Generated end code: pass local variables to next shader stage}
gl\_Position = sg\_vPosPS;
outVertexPosCS = sg\_vPosPS;

\textcolor{preprocessor}{#if SG\_TEXTURED}
outVertexTexCoord = sg\_vTexcoord;
\textcolor{preprocessor}{#endif}

\textcolor{preprocessor}{#if SG\_GOURAUD or SG\_FLAT or SG\_VERTEX\_COLOR}
outVertexColor = sg\_cColor;
\textcolor{preprocessor}{#endif}

\textcolor{preprocessor}{#if SG\_PHONG}
outVertexNormal = sg\_vNormalVS;
outVertexPosVS = sg\_vPosVS;
\textcolor{preprocessor}{#endif}

\textcolor{comment}{// ============================================================}

\textcolor{comment}{// Shader modifiers are called again for the end code snippet.}
\textcolor{comment}{// The modifers may write to gl\_Position, outVertexNormal etc. and/or custom outputs}
\textcolor{keywordflow}{for each} modifier:
 modifier->modifyVertexEndCode();
\}
\end{DoxyCode}


\begin{DoxyNote}{Note}
Note that if directives are not generated at all if they do not change the compiled code.
\end{DoxyNote}
\hypertarget{a14872_geomShaderGen}{}\subsubsection{Tessellation/\+Geometry shader code generation}\label{a14872_geomShaderGen}
Tessellation and geometry shaders have a different layout and due to their complexity, there is no clear begin or end code marker for these shaders. The Shader\+Prog\+Generator does not generate a main() function in these cases. However, it provides a convenient passthrough mapping function sg\+\_\+\+Map\+I\+O() for default attribute IO. The sg\+\_\+\+Map\+IO function can be called in a geometry shader template. The rest of the shader including the main() body has to be provided in form of a template file.\hypertarget{a14872_fragShaderGen}{}\subsubsection{Fragment shader generation}\label{a14872_fragShaderGen}
Fragment shaders are assembled similar to vertex shaders\+:


\begin{DoxyCode}
\textcolor{keywordtype}{void} main()\{

\textcolor{comment}{// ============================================================}
\textcolor{comment}{// Generated begin code:}
\textcolor{comment}{// read inputs from vertex/geometry shader:}
vec4 sg\_vPosCS = outVertexPosCS; \textcolor{comment}{// or outGeometryPosCS}
vec2 sg\_vScreenPos = sg\_vPosCS.xy / sg\_vPosCS.w * 0.5 + vec2(0.5, 0.5); \textcolor{comment}{// projective texture coordinates}

vec4 sg\_cColor = vec4(g\_cEmissive, ALPHA); \textcolor{comment}{// color  (ALPHA: #define ALPHA g\_vMaterial.y)}


\textcolor{preprocessor}{#if SG\_GOURAUD or SG\_FLAT or SG\_VERTEX\_COLOR}
sg\_cColor += outVertexColor;  \textcolor{comment}{// or outGeometryColor}
\textcolor{preprocessor}{#endif}

\textcolor{preprocessor}{#if SG\_PHONG}
vec4 sg\_vPosVS = outVertexPosVS;
vec3 sg\_vNormalVS = outNormal;
sg\_cColor += lightingCode();
\textcolor{preprocessor}{#endif}

\textcolor{preprocessor}{#if SG\_TEXTURED}
vec4 sg\_cTex = 0;
\textcolor{keywordflow}{for each} texture stage X:
  sg\_cTex += texture(g\_TextureX, outVertexTexCoord); \textcolor{comment}{// additive combine texture stages}
  
\textcolor{preprocessor}{#if SG\_UNLIT}
sg\_cColor += sg\_cTex; \textcolor{comment}{// additive blending}
\textcolor{preprocessor}{#else}
sg\_cColor *= sg\_cTex; \textcolor{comment}{// multiplicative blending}
\textcolor{preprocessor}{#endif}
\textcolor{preprocessor}{#endif}

\textcolor{preprocessor}{#if }
sg\_cColor = inColor;
\textcolor{preprocessor}{#endif}


\textcolor{comment}{// ============================================================}


\textcolor{comment}{// Your ShaderModifier adds fragment shader code here.}
\textcolor{comment}{// The modifier may overwrite any local variables from the shader generator.}
\textcolor{keywordflow}{for each} modifier:
 modifier->modifyFragmentBeginCode();

\textcolor{comment}{// ============================================================}
\textcolor{comment}{// Generated end code: pass color to output}

outFragment = sg\_cColor;

\textcolor{comment}{// ============================================================}

\textcolor{comment}{// Shader modifiers are called again for the end code snippet.}
\textcolor{comment}{// The modifers may write to outFragment, and/or custom outputs}
\textcolor{keywordflow}{for each} modifier:
 modifier->modifyFragmentEndCode();


\}
\end{DoxyCode}
\hypertarget{a14872_lightingCode}{}\subsubsection{Lighting code generation}\label{a14872_lightingCode}
The Shader\+Generator implements a forward lighting routine that supports any number of lights (within hardcoded S\+G\+\_\+\+M\+A\+X\+\_\+\+S\+H\+A\+D\+E\+R\+\_\+\+L\+I\+G\+H\+TS limit) and any combination of light types. However, it is possible to extend or even completely replace the default lighting routine with Shader\+Modifiers.

The default lighting routine performs the following steps.


\begin{DoxyCode}
\textcolor{preprocessor}{#for each light X:}

\textcolor{preprocessor}{  #if X is directional:}
    sg\_cColor += LitDirLight(sg\_vPosVS, sg\_vNormalVS, g\_vLightDir\_X, ..);
\textcolor{preprocessor}{  #else if X is point light:}
    sg\_cColor += LitPointLight(sg\_vPosVS, sg\_vNormalVS, g\_vLightPos\_X, ..);
\textcolor{preprocessor}{  #else if X is spot light:}
\textcolor{preprocessor}{    sg\_cColor += LitSpotLight(sg\_vPosVS, sg\_vNormalVS, g\_vLightPos\_X, g\_vLightDir\_X, ..);}
\end{DoxyCode}


A Shader\+Modifier can now choose to keep, extend or completely replace the lighting routine provided by the generator. Keep in mind that since modifiers simply add more shader code to the existing routine, only commutative operations are supported correctly.

The modify\+Lighting\+Code function of a modifier receives a light index \mbox{[}0,...,num\+Lights-\/1\mbox{]} and a light type \mbox{[}directional,point,spot\mbox{]} as arguments and is supposed to compute a lighting color based on the uniforms provided by the generator.

Refer to the toon renderer plugin for an example, that implements custom cel lighting functions with a modifier.

Finally, it is possible to perform default lighting in the fragment shader template via the S\+G\+\_\+\+F\+R\+A\+G\+M\+E\+N\+T\+\_\+\+L\+I\+G\+H\+T\+I\+NG keyword. 
\begin{DoxyCode}
SG\_FRAGMENT\_BEGIN;
sg\_vNormalVS = g\_mWV * (mTangentSpace * vNormalTS); \textcolor{comment}{// dot3}
sg\_cColor = vec4(g\_cEmissive, SG\_ALPHA);
SG\_FRAGMENT\_LIGHTING;
SG\_FRAGMENT\_END;
\end{DoxyCode}
\hypertarget{a14872_shaderFlowDiagrams}{}\subsubsection{Shader Data Flow Diagrams}\label{a14872_shaderFlowDiagrams}
\hypertarget{a14872_shader_building_blocks}{}\paragraph{Shader Building Blocks}\label{a14872_shader_building_blocks}
\hypertarget{a14872_shader_IO}{}\paragraph{Shader IO}\label{a14872_shader_IO}
\hypertarget{a14872_shader_geometry_shader}{}\paragraph{Geometry Shader}\label{a14872_shader_geometry_shader}
\hypertarget{a14872_shader_tesselation_control}{}\paragraph{Tesselation Control Shader}\label{a14872_shader_tesselation_control}
\hypertarget{a14872_shader_tesselation_evaluation}{}\paragraph{Tesselation Evaluation Shader}\label{a14872_shader_tesselation_evaluation}
 \hypertarget{TutorialRenderer}{}\subsection{Tutorial\+: Implementation of The Toon Renderer Plugin}\label{TutorialRenderer}
A renderer plugin class has to implement at least the Open\+Flipper \hyperlink{a06972}{Render\+Interface} class. If the plugin wants to make use of the \hyperlink{a06176}{A\+CG} shader pipeline which allows the renderer to have complete control over every draw call, the renderer also has to implement the \hyperlink{a07468}{A\+C\+G\+::\+I\+Renderer} interface. The I\+Renderer interface already provides basic convenience functions, such as building and sorting the list of draw-\/calls to help getting started. In this tutorial we will focus on the implementation process of the toon renderer plugin, which makes use of the \hyperlink{a07468}{A\+C\+G\+::\+I\+Renderer} interface and its convenience functions.\hypertarget{a14873_celShading}{}\subsubsection{Cel shading with Shader\+Modifiers}\label{a14873_celShading}
The toon renderer requires a set of modified shaders, that replace the default lighting with cel shading. A Shader\+Modifier is used to replace the lighting code provided by the \hyperlink{a07568}{A\+C\+G\+::\+Shader\+Generator} with custom shader code. The new lighting functions are defined in the shader include file \char`\"{}celshading.\+glsl\char`\"{}, which is loaded and inserted at run-\/time.

The file contains cel shading functions for directional, spot and point lights called\+: Lit\+Dir\+Light\+\_\+\+Cel(), Lit\+Point\+Light\+\_\+\+Cel(), Lit\+Spot\+Light\+\_\+\+Cel. We include this file in the generated vertex and fragment shader with the modify\+Vertex\+IO and modify\+Fragment\+IO functions of the Shader\+Modifier. Additionally a new uniform is added to the uniform list of each shader, which is related to the cel shading technique.


\begin{DoxyCode}
\textcolor{keywordtype}{void} modifyVertexIO( \hyperlink{a07568}{ACG::ShaderGenerator}* \_shader )  \{
  \textcolor{comment}{// include cel lighting functions defined in CELSHADING\_INCLUDE\_FILE}
  QString includeCelShading = \hyperlink{a07584_a4ddc1ae85719dc115b52a5e971dc0ccb}{ACG::ShaderProgGenerator::getShaderDir}(
      ) + QDir::separator() + QString(CELSHADING\_INCLUDE\_FILE);
  \_shader->\hyperlink{a07568_a93687261bc88f553004b17a61a0e2f80}{addIncludeFile}(includeCelShading);

  \textcolor{comment}{// add shader constant that defines the number of different intensity levels used in lighting}
  \_shader->\hyperlink{a07568_a87cff132858bda2f529707c3c00561a8}{addUniform}(\textcolor{stringliteral}{"float g\_celPaletteSize"}, \textcolor{stringliteral}{"//number of palettes/intensity levels for cel
       shading"});
\}

\textcolor{keywordtype}{void} modifyFragmentIO( \hyperlink{a07568}{ACG::ShaderGenerator}* \_shader )  \{
  \textcolor{comment}{// include cel lighting functions defined in CELSHADING\_INCLUDE\_FILE}
  QString includeCelShading = \hyperlink{a07584_a4ddc1ae85719dc115b52a5e971dc0ccb}{ACG::ShaderProgGenerator::getShaderDir}(
      ) + QDir::separator() + QString(CELSHADING\_INCLUDE\_FILE);
  \_shader->\hyperlink{a07568_a93687261bc88f553004b17a61a0e2f80}{addIncludeFile}(includeCelShading);

  \textcolor{comment}{// Note: We include the cel lighting functions in both shader stages}
  \textcolor{comment}{// because the ShaderGenerator may call modifyLightingCode() for either a vertex or fragment shader.}
  \textcolor{comment}{// It is not yet known in which stage the lighting is performed.}


  \textcolor{comment}{// Additionally write the depth of each fragment to a secondary render-target.}
  \textcolor{comment}{// This depth texture is used in a post-processing outlining step.}
  \_shader->\hyperlink{a07568_a5737eb147ab691feaedc78032aabbe5b}{addOutput}(\textcolor{stringliteral}{"float outDepth"});
  \_shader->\hyperlink{a07568_a87cff132858bda2f529707c3c00561a8}{addUniform}(\textcolor{stringliteral}{"float g\_celPaletteSize"}, \textcolor{stringliteral}{"//number of palettes/intensity levels for cel
       shading"});
\}
\end{DoxyCode}


Next, we tell the Shader\+Generator that our modifier replaces the default lighting functions by implementing the corresponding function.


\begin{DoxyCode}
\textcolor{comment}{// modifier replaces default lighting with cel lighting}
  \textcolor{keywordtype}{bool} replaceDefaultLightingCode() \{\textcolor{keywordflow}{return} \textcolor{keyword}{true};\}
\end{DoxyCode}


The Shader\+Generator then proceeds to call the modify\+Lighting\+Code() implementation of the modifier, which is supposed to generate the lighting shader code for each active scene light. To do this we check the type of the light, call the appropiate cel shading function and accumulate the lighting colors\+:


\begin{DoxyCode}
\textcolor{keywordtype}{void} modifyLightingCode(QStringList* \_code, \textcolor{keywordtype}{int} \_lightId, ACG::ShaderGenLightType \_lightType)  \{
  \textcolor{comment}{// use cel shading functions instead of default lighting:}

  QString buf;

  \textcolor{keywordflow}{switch} (\_lightType)    \{
  \textcolor{keywordflow}{case} ACG::SG\_LIGHT\_DIRECTIONAL:
    buf.sprintf(\textcolor{stringliteral}{"sg\_cColor.xyz += LitDirLight\_Cel(sg\_vPosVS.xyz, sg\_vNormalVS, g\_vLightDir\_%d, 
       g\_cLightAmbient\_%d,  g\_cLightDiffuse\_%d,  g\_cLightSpecular\_%d, g\_celPaletteSize);"}, \_lightId, \_lightId, \_lightId, 
      \_lightId);
    \textcolor{keywordflow}{break};

  \textcolor{keywordflow}{case} ACG::SG\_LIGHT\_POINT:
    buf.sprintf(\textcolor{stringliteral}{"sg\_cColor.xyz += LitPointLight\_Cel(sg\_vPosVS.xyz, sg\_vNormalVS,  g\_vLightPos\_%d, 
       g\_cLightAmbient\_%d,  g\_cLightDiffuse\_%d,  g\_cLightSpecular\_%d,  g\_vLightAtten\_%d, g\_celPaletteSize);"}, \_lightId, 
      \_lightId, \_lightId, \_lightId, \_lightId);
    \textcolor{keywordflow}{break};

  \textcolor{keywordflow}{case} ACG::SG\_LIGHT\_SPOT:
    buf.sprintf(\textcolor{stringliteral}{"sg\_cColor.xyz += LitSpotLight\_Cel(sg\_vPosVS.xyz,  sg\_vNormalVS,  g\_vLightPos\_%d, 
       g\_vLightDir\_%d,  g\_cLightAmbient\_%d,  g\_cLightDiffuse\_%d,  g\_cLightSpecular\_%d,  g\_vLightAtten\_%d, 
       g\_vLightAngleExp\_%d, g\_celPaletteSize);"}, \_lightId, \_lightId, \_lightId, \_lightId, \_lightId, \_lightId, \_lightId);
    \textcolor{keywordflow}{break};
  \textcolor{keywordflow}{default}: \textcolor{keywordflow}{break};
  \}
  \_code->push\_back(buf);
\}
\end{DoxyCode}


For a list of uniforms and variables generated by the Shader\+Generator refer to the \char`\"{}\+Dynamic shader assembly overview\char`\"{} documentation page.\hypertarget{a14873_sceneDepthBuf}{}\subsubsection{Scene depth texture with Shader\+Modifiers}\label{a14873_sceneDepthBuf}
The toon renderer not only performs cel shading, but also implements a post-\/processing step that outlines the silhouette of objects. A texture containing scene depth information is needed in this step, which can be initialized with a Shader\+Modifier. In fact, a single modifier is sufficient which can do both\+: cel shading and depth output.

The depth output texture is declared in modify\+Fragment\+I\+O()\+:


\begin{DoxyCode}
\textcolor{keywordtype}{void} modifyFragmentIO(\hyperlink{a07568}{ACG::ShaderGenerator}* \_shader)\{
...
\_shader->addOutput(\textcolor{stringliteral}{"float outDepth"}); \textcolor{comment}{// write to a second texture target which contains only one channel
       for depth values.}
...
\end{DoxyCode}


We still have to generate a code snippet that writes to the new fragment output channel. This shall be done at the end of the fragment shader, thus we implement the modify\+Fragment\+End\+Code() function\+:


\begin{DoxyCode}
\textcolor{keywordtype}{void} modifyFragmentEndCode(QStringList* \_code)  \{
  \_code->push\_back(\textcolor{stringliteral}{"outDepth = gl\_FragCoord.z;"}); \textcolor{comment}{// write depth to secondary render texture}
\}
\end{DoxyCode}
\hypertarget{a14873_registerCelModifier}{}\subsubsection{Registering the shader modifier}\label{a14873_registerCelModifier}
A modifier has to be registered to the Shader\+Generator before it can be used. Once the modifier is registered, is has received a unique modifier\+ID which is used to apply a modifier at run-\/time to a shader.

The following steps are necessary to register the modifer\+:


\begin{DoxyCode}
\textcolor{comment}{// class definition of the modifier}
\textcolor{keyword}{class }\hyperlink{a11168}{CelShadingModifier} : \textcolor{keyword}{public} \hyperlink{a07580}{ACG::ShaderModifier}\{
\textcolor{keyword}{public}:
....
  \textcolor{keyword}{static} \hyperlink{a11168}{CelShadingModifier} instance;
\}

..

\textcolor{comment}{// register modifier once to the generator, for example in the constructor of the renderer plugin}
ToonRenderer::ToonRenderer() \{
  \hyperlink{a07584_a96b207003d2c540b0b676c0fa267a2ab}{ACG::ShaderProgGenerator::registerModifier}(&
      CelShadingModifier::instance);
\}
\end{DoxyCode}


The modifier can now be used and applied to any shader generated by Shader\+Generator. A modified shader is generated by setting the usage parameter in either the Shader\+Prog\+Generator or the Shader\+Cache\+:


\begin{DoxyCode}
\textcolor{comment}{// modify a shader with cel-shading and depth-output:}
\hyperlink{a08132}{GLSL::Program}* prog = \hyperlink{a07548_a25db1fcdf5081ab345e27732e0d07d56}{ACG::ShaderCache::getInstance}()->
      \hyperlink{a07548_af7e74e2c97dcea1fb3c482ea5d8560d0}{getProgram}(&shaderDesc, CelShadingModifier::instance);
\end{DoxyCode}
\hypertarget{a14873_viewportManagement}{}\subsubsection{Viewport management}\label{a14873_viewportManagement}
The toon renderer supports multiple viewports by allocating a separate offscreen F\+BO for each viewer. The currently active viewport can be queried with the Viewer\+Properties descriptor, which is passed to the render() function. It is recommended that any render plugin treats viewport specific ressources such as F\+B\+Os in the same manner, if offscreen rendering is performed.\hypertarget{a14873_toonRenderMain}{}\subsubsection{The main render() implementation of the toon plugin}\label{a14873_toonRenderMain}
Gathering Render\+Objects and executing draw calls is done with the help of convenience functions provided by the I\+Renderer interface\+:


\begin{DoxyCode}
\textcolor{comment}{// collect renderobjects + prepare OpenGL state}
prepareRenderingPipeline(\_glState, \_properties.\hyperlink{a07100_a76b427bc1e9adc1067a658204058bee4}{drawMode}(), 
      \hyperlink{a06173_adb9160f9b0e24053d577b42efe1d37d4}{PluginFunctions::getSceneGraphRootNode}());
\end{DoxyCode}


Next, we render the scene into an F\+BO with the cel-\/shading modifier. The F\+BO has two color attachments\+: attachment0 contains an R\+G\+BA texture storing scene color, attachment1 contains an R32f texture storing scene depths. This information has to be passed to the shader program such that the fragment outputs are mapped to the correct attachments\+: If the output targets do not match the F\+BO setup, the shader has to be relinked.


\begin{DoxyCode}
\textcolor{comment}{// render every object}
\textcolor{keywordflow}{for} (\textcolor{keywordtype}{int} i = 0; i < getNumRenderObjects(); ++i) \{

  \textcolor{comment}{// Take original shader and apply the celshading modifier}
  \hyperlink{a08132}{GLSL::Program}* prog = \hyperlink{a07548_a25db1fcdf5081ab345e27732e0d07d56}{ACG::ShaderCache::getInstance}()->
      \hyperlink{a07548_af7e74e2c97dcea1fb3c482ea5d8560d0}{getProgram}(&sortedObjects\_[i]->shaderDesc, CelShadingModifier::instance);

  \textcolor{comment}{// eventually the shader has to be relinked after modifiction.}
  \textcolor{comment}{// The fragment shader outputs have to match the current fbo setup:}
  \textcolor{comment}{//  attachment0 -> RGBA scene colors}
  \textcolor{comment}{//  attachment1 -> R32F scene depth}
  
  \textcolor{comment}{// scene color is stored in attachment 0: outFragment}
  \textcolor{comment}{// scene depth is stored in attachment 1: outDepth}
  \textcolor{keywordtype}{int} bRelink = 0;
  \textcolor{keywordflow}{if} (prog->\hyperlink{a08132_a47b57dd0cf11f31ce6d5575557c8e5e6}{getFragDataLocation}(\textcolor{stringliteral}{"outFragment"}) != 0) \{
    prog->\hyperlink{a08132_af3ee55f4c0913c2ef4eadcb3befdd30a}{bindFragDataLocation}(0, \textcolor{stringliteral}{"outFragment"});
    bRelink++;
  \}
  \textcolor{keywordflow}{if} (prog->\hyperlink{a08132_a47b57dd0cf11f31ce6d5575557c8e5e6}{getFragDataLocation}(\textcolor{stringliteral}{"outDepth"}) != 1) \{
    prog->\hyperlink{a08132_af3ee55f4c0913c2ef4eadcb3befdd30a}{bindFragDataLocation}(1, \textcolor{stringliteral}{"outDepth"});
    bRelink++;
  \}
  \textcolor{keywordflow}{if} (bRelink)
    prog->\hyperlink{a08132_ac36df4d93b0280fa8815f21895c24cf8}{link}();

  prog->\hyperlink{a08132_ad6b634a00820f63f072e9d380d4dfb5a}{use}();
  prog->\hyperlink{a08132_ae78ccf1ed98160af603fdaa72cabbe99}{setUniform}(\textcolor{stringliteral}{"g\_celPaletteSize"}, numShades);

  renderObject(sortedObjects\_[i], prog);
\}
\end{DoxyCode}


Render\+Objects, which represent a draw call with many opengl states, can be accesses via the inherited sorted\+Objects\+\_\+ array. The function get\+Num\+Render\+Objects() returns the total number of render-\/objects in the list. A draw call can be executed with the convenience function render\+Object(), but can also be performed manually with the information contained in the Render\+Object data.

In a second pass, a post processing shader is used to perform silhouettte outlining on the previously computed F\+BO. This pass renders into the input F\+BO, which in most cases is the back buffer. A simple call to the convenience function from I\+Renderer is enough to bind the input F\+BO\+:


\begin{DoxyCode}
restoreInputFbo();
\end{DoxyCode}


After configuring the post processing shader, a screen aligned quad which covers the complete viewport is rendered. Since this is an often used technique in post-\/processing, \hyperlink{a06176}{A\+CG} provides another convenience function for drawing screen quads with post projected coordinates\+:


\begin{DoxyCode}
\textcolor{comment}{// draws a counterclockwise quad with coordinates [-1,-1] .. [1,1] and z = -1}
\textcolor{comment}{// (progOutline\_ is our post processing GLSL::Program)}
\hyperlink{a07544_a2deea2d329efedb39a3972721564bf20}{ACG::ScreenQuad::draw}(progOutline\_);
\end{DoxyCode}


The render() implementation ends with a call to another convenience function\+: finish\+Rendering\+Pipeline(). This restores common Open\+GL states to their default value.


\begin{DoxyCode}
finishRenderingPipeline();
\end{DoxyCode}
 