405 |
jab |
1 |
\documentclass[a4paper]{article}
|
|
|
2 |
\usepackage{listings}
|
|
|
3 |
\usepackage[isolatin]{inputenc}
|
|
|
4 |
\usepackage{makeidx,times}
|
|
|
5 |
\usepackage{fancyhdr}
|
|
|
6 |
\usepackage{graphicx}
|
|
|
7 |
\usepackage{float}
|
|
|
8 |
\usepackage{alltt}
|
|
|
9 |
%%\usepackage{doxygen}
|
|
|
10 |
\usepackage[pdftex,
|
|
|
11 |
pagebackref=true,
|
|
|
12 |
colorlinks=true,
|
|
|
13 |
linkcolor=blue
|
|
|
14 |
]{hyperref}
|
|
|
15 |
\makeindex
|
|
|
16 |
\lstset{tabsize=1,language=C++,basicstyle=\small}
|
|
|
17 |
\author{J. Andreas B{\ae}rentzen}
|
|
|
18 |
\title{Introduction to GEL}
|
|
|
19 |
\setcounter{tocdepth}{2}
|
|
|
20 |
\begin{document}
|
|
|
21 |
\maketitle
|
|
|
22 |
\tableofcontents
|
|
|
23 |
\section{Introduction}
|
|
|
24 |
|
|
|
25 |
GEL is an abbreviation of GEometry and Linear algebra. GEL is a C++ library with tools for manipulating digital representations of geometry such as polygonal meshes, triangle meshes, point clouds, and voxel grids. Since linear algebra tools are invariably needed for this, GEL also contains tools for linear algebra. Finally, GEL contains tools for drawing geometry using OpenGL and various utilities.
|
|
|
26 |
|
|
|
27 |
\subsection{GEL Homepage}
|
|
|
28 |
The online home of GEL is here:
|
|
|
29 |
\href{http://www.imm.dtu.dk/GEL/}{http://www.imm.dtu.dk/GEL/}
|
|
|
30 |
|
|
|
31 |
\subsection{Purpose of this document}
|
|
|
32 |
GEL is not sufficiently documented, but a fair amount of Doxygen documentation is provided for those parts of GEL which are used a lot. The goal of this document is to provide more detail and to help people getting started. In particular, this document focuses on functionality in the CGLA and HMesh namespaces.
|
|
|
33 |
|
|
|
34 |
However, if you are looking for something particular, we \textbf{implore and entreat }you to look at the Doxygen web (start at the GEL homepage).
|
|
|
35 |
|
|
|
36 |
\subsection{Overview of GEL}
|
|
|
37 |
|
|
|
38 |
GEL contains many tools for geometry processing and a number of data structures. Perhaps the most important is the Manifold class which resides in the HMesh namespace. A Manifold is a halfedge based representation of a polygonal mesh. There is also a simpler triangle mesh data structure, TriMesh, based on an indexed face set. There are several voxel grid data structures, a fairly efficient k-D tree for storing points, bounding box hierarchies etc.
|
|
|
39 |
|
|
|
40 |
A number of algorithms exist for manipulating these representations of geometric data. For instance, Manifold has a function quadratic error measures simplification, several functions for smoothing (including anisotropic), mesh optimization, and mesh clean up.
|
|
|
41 |
Another strong point of GEL is the fact that it contains good support for converting between representations; especially between meshes and voxel grids. There are several tools for polygonizing isosurfaces and also converting meshes to distance fields. The tools pertaining to the Manifold data structure are in the HMesh namespace. The other geometry related tools are in the Geometry namespace.
|
|
|
42 |
|
|
|
43 |
There are two packages for linear algebra: CGLA is strictly for small vectors and matrices (dimensions 2,3, and 4). LinAlg is a Lapack wrapper for slightly larger problems. At this point, it is fairly simple but includes a number of functions for solving linear systems, factoring matrices and finding eigensolutions for symmetric matrices.
|
|
|
44 |
|
|
|
45 |
GLGraphics contains facilities for drawing entities from other parts of GEL via OpenGL. Especially TriMesh and Manifold have good support. For instance, there is a nice wireframe drawing class. There are also two virtual trackballs for interactive programs and some tools for viewing in interactive programs and SOIL a small open source library for image loading by Jonathan Dummer.
|
|
|
46 |
|
|
|
47 |
Finally there are some utilities in Util: Getting command line arguments, hash table classes, a 2D grid class, a resource manager, an XML parser by Jeppe Frisvad and other tools.
|
|
|
48 |
|
|
|
49 |
Apart from the namespaces (sublibraries) we have a number of demo applications. Some of these might be useful in themselves. One example is a tool for converting a mesh to a signed distance field and an OBJ viewer which is also able to load X3D and PLY meshes. We are working on the MeshEdit application which is already a highly useful swiss knife for geometry processing.
|
|
|
50 |
|
|
|
51 |
\section{Compilation and Installation}
|
|
|
52 |
|
|
|
53 |
Life would be easier if one's library did not rely on dependencies. We try hard to have only a minimal set, but the following libraries \textit{are} required in order to build GEL.
|
|
|
54 |
\begin{itemize}
|
|
|
55 |
\item OpenGL
|
|
|
56 |
\item GLUT
|
|
|
57 |
\item GLEW
|
|
|
58 |
\item Lapack (and its depencies)
|
|
|
59 |
\item GLConsole (only for MeshEdit).
|
|
|
60 |
\end{itemize}
|
|
|
61 |
OpenGL is typically installed on any platform. GLUT is typically available for any platform. A replacement such as FreeGLUT should be an option. Lapack is typically also available everywhere. The only problem is GLConsole. As of writing only MeshEdit depends on GLConsole which can be obtained from SourceForge:
|
|
|
62 |
|
|
|
63 |
\href{http://sourceforge.net/projects/glconsole/}{http://sourceforge.net/projects/glconsole/}
|
|
|
64 |
|
|
|
65 |
GLConsole is extremely convenient but a well kept, little documented secret. Please do not try to install it unless you need MeshEdit. We will update this text if we either include it in GEL (assuming the authors allow it) or change to some other library.
|
|
|
66 |
|
|
|
67 |
GEL is compiled using CMake. Currently CMake is the official way of producing Visual Studio Solution files. A separate Mac OSX XCode project file is also maintained but may be removed if CMake makes it redundant. A set of Makefiles for various unices are also found in the package but no longer maintained.
|
|
|
68 |
|
|
|
69 |
To install GEL, put the libraries and header files in the logical place. CMake should instruct your build environment on how to do this. Then you can use GEL simply by including the header files and linking against the GEL libraries. On windows using Visual Studio it is important that you define SECURE\_SCL to be 0. This is because Visual Studio is a bit pedantic about not allowing access to the raw memory of STL containers.
|
|
|
70 |
|
|
|
71 |
\section{CGLA}
|
|
|
72 |
|
|
|
73 |
CGLA is a set of numerical C++ vector and matrix classes and class
|
|
|
74 |
templates designed with computer graphics in mind. CGLA stands for
|
|
|
75 |
``Computer Graphics Linear Algebra''. It is a part of the larger
|
|
|
76 |
package called GEL but deserves its own document since it is an important part.
|
|
|
77 |
|
|
|
78 |
Let us get right down to the obvious question: Why create another
|
|
|
79 |
linear algebra package?
|
|
|
80 |
Well, CGLA evolved from a few matrix and vector classes because I
|
|
|
81 |
didn't have anything better. Also, I created CGLA to experiment with
|
|
|
82 |
some template programming techniques. This led to the most important
|
|
|
83 |
feature of CGLA, namely the fact that all vector types are derived
|
|
|
84 |
from the same template.
|
|
|
85 |
|
|
|
86 |
This makes it easy to ensure identical semantics: Since all vectors
|
|
|
87 |
have inherited, say, the * operator from a common ancestor, it works
|
|
|
88 |
the same for all of them.
|
|
|
89 |
|
|
|
90 |
It is important to note that CGLA was designed for Computer Graphics
|
|
|
91 |
(not numerical computations) and this had a number of
|
|
|
92 |
implications. Since, in computer graphics we mainly need small vectors
|
|
|
93 |
of dimension 2,3, or 4 CGLA was designed for vectors of low
|
|
|
94 |
dimensionality. Moreover, the amount of memory allocated for a vector
|
|
|
95 |
is decided by its type at compile time. CGLA does not use dynamic
|
|
|
96 |
memory. CGLA also does not use virtual functions, and most functions
|
|
|
97 |
are inline. These features all help making CGLA relatively fast.
|
|
|
98 |
|
|
|
99 |
Of course, other libraries of vector templates for computer graphics
|
|
|
100 |
exist, but to my knowledge none where the fundamental templates are
|
|
|
101 |
parametrized w.r.t. dimension as well as type. In other words, we have
|
|
|
102 |
a template (\texttt{ArithVec})that gets both type
|
|
|
103 |
(e.g. \texttt{float}) and dimension
|
|
|
104 |
(e.g. 3) as arguments. the intended use of this template is as
|
|
|
105 |
ancestor of concrete types such as \texttt{Vec3f} - a 3D floating
|
|
|
106 |
point type.
|
|
|
107 |
|
|
|
108 |
The use of just one template as basis is very important, I believe,
|
|
|
109 |
since it makes it extremely simple to add new types of
|
|
|
110 |
vectors. Another very generic template is \texttt{ArithMat} which is a
|
|
|
111 |
template for matrix classes. (and not necessarily NxN matrices).
|
|
|
112 |
|
|
|
113 |
From a users perspective CGLA contains a number of vector and matrix
|
|
|
114 |
classes, a quaternion and some utility classes. In summary, the most
|
|
|
115 |
important features are
|
|
|
116 |
\begin{itemize}
|
|
|
117 |
\item A number of 2, 3 and 4 d vector classes.
|
|
|
118 |
\item A number of Matrix classes.
|
|
|
119 |
\item A Quaternion class.
|
|
|
120 |
\item Some test programs.
|
|
|
121 |
\item Works well with OpenGL.
|
|
|
122 |
\end{itemize}
|
|
|
123 |
|
|
|
124 |
|
|
|
125 |
\subsection{Naming conventions}
|
|
|
126 |
|
|
|
127 |
Vectors in CGLA are named \texttt{VecDT} where \texttt{D} stands for
|
|
|
128 |
dimension at \texttt{T}
|
|
|
129 |
for type. For instance a 3D floating point vector is named
|
|
|
130 |
\texttt{Vec3f}. Other types are d (double), s (short), i (int), uc
|
|
|
131 |
(unsigned char), and usi (unsigned shourt int).
|
|
|
132 |
|
|
|
133 |
Matrices are similiarly named \texttt{MatDxDT}. For instance a 4D
|
|
|
134 |
\texttt{double} matrix is called \texttt{Mat4x4d}.
|
|
|
135 |
|
|
|
136 |
\subsection{How to use CGLA}
|
|
|
137 |
|
|
|
138 |
If you need a given CGLA class you can find the header file that
|
|
|
139 |
contains it in this document. Simply include the header file and use
|
|
|
140 |
the class. Remember also that all CGLA functions and classes live in
|
|
|
141 |
the CGLA namespace! Lastly, look at the example programs that came
|
|
|
142 |
with the code.
|
|
|
143 |
|
|
|
144 |
An important point is that you should never use the Arith... classes
|
|
|
145 |
directly. Classes whose names begin with Arith are templates used for
|
|
|
146 |
deriving concrete types. It is simpler, cleaner, and the intended
|
|
|
147 |
thing to do to only use the derived types.
|
|
|
148 |
|
|
|
149 |
In some cases, you may find that you need a vector or matrix class
|
|
|
150 |
that I haven't defined. If so, it is fortunate that CGLA is easy to
|
|
|
151 |
extend. Just look at, say, \texttt{Vec4f} if you need a \texttt{Vec5d}
|
|
|
152 |
class.
|
|
|
153 |
|
|
|
154 |
For some more specific help look at the next section where some of the
|
|
|
155 |
commonly used operations are shown.
|
|
|
156 |
|
|
|
157 |
|
|
|
158 |
\subsection{CGLA: Examples of Usage}
|
|
|
159 |
|
|
|
160 |
The examples below are by no means complete. Many things are
|
|
|
161 |
possible but not covered below. However, most of the common usage is
|
|
|
162 |
shown, so this should be enough to get you started. Note that in the
|
|
|
163 |
following we assume that you are \texttt{using namespace CGLA} and
|
|
|
164 |
hence don't prefix with \texttt{CGLA::}.
|
|
|
165 |
|
|
|
166 |
In short, to compile the examples below you would need the following
|
|
|
167 |
in the top of your file
|
|
|
168 |
|
|
|
169 |
\begin{verbatim}
|
|
|
170 |
#include <iostream> // For input output
|
|
|
171 |
#include "CGLA/Vec3f.h"
|
|
|
172 |
#include "CGLA/Quaternion.h"
|
|
|
173 |
#include "CGLA/Mat4x4f.h"
|
|
|
174 |
|
|
|
175 |
using namespace std; // For input output
|
|
|
176 |
using namespace CGLA;
|
|
|
177 |
\end{verbatim}
|
|
|
178 |
|
|
|
179 |
To begin with let us create 3 3D vectors. This is done as follows:
|
|
|
180 |
\begin{verbatim}
|
|
|
181 |
Vec3f p0(10,10,10);
|
|
|
182 |
Vec3f p1(20,10,10);
|
|
|
183 |
Vec3f p2(10,20,10);
|
|
|
184 |
\end{verbatim}
|
|
|
185 |
if we had left out the arguments the three vectors would have been
|
|
|
186 |
uninitialized, at least in release mode. If we compile in debug mode
|
|
|
187 |
they would have been initialized to ``Not a Number'' to aid
|
|
|
188 |
debugging. However, the $[10 10 10]^T$ vector could also have been
|
|
|
189 |
created differently, using
|
|
|
190 |
\begin{verbatim}
|
|
|
191 |
Vec3f p0(10);
|
|
|
192 |
\end{verbatim}
|
|
|
193 |
|
|
|
194 |
A very common operation is to compute the normal of a triangle from
|
|
|
195 |
the position of its vertices. Assuming the three vectors represent the
|
|
|
196 |
vertices of a triangle, we can compute the normal by finding the
|
|
|
197 |
vector from the first vertex to the two other vertices, taking the
|
|
|
198 |
cross product and normalizing the result. This is a one-liner:
|
|
|
199 |
|
|
|
200 |
\begin{verbatim}
|
|
|
201 |
Vec3f n = normalize(cross(p1-p0,p2-p0));
|
|
|
202 |
\end{verbatim}
|
|
|
203 |
|
|
|
204 |
Quite a lot goes on in the snippet above. Observe that the - operator
|
|
|
205 |
also works for vectors. In fact almost all the arithmetic operators
|
|
|
206 |
work for vectors. You can also use assignment operators (i.e
|
|
|
207 |
\texttt{+=}) which is often faster. Then there is the function
|
|
|
208 |
\texttt{cross} which simply computes the cross product of its
|
|
|
209 |
arguments. Another frequently used function is \texttt{dot} which
|
|
|
210 |
takes the dot product. Finally the vector is normalized using the
|
|
|
211 |
function normalize.
|
|
|
212 |
|
|
|
213 |
Of course, we can print all or at least most CGLA entities. For
|
|
|
214 |
example
|
|
|
215 |
|
|
|
216 |
\begin{verbatim}
|
|
|
217 |
cout << n << endl;
|
|
|
218 |
\end{verbatim}
|
|
|
219 |
|
|
|
220 |
will print the normal vector just computed. We can also treat a vector
|
|
|
221 |
as an array as shown below
|
|
|
222 |
|
|
|
223 |
\begin{verbatim}
|
|
|
224 |
float x = n[0];
|
|
|
225 |
\end{verbatim}
|
|
|
226 |
|
|
|
227 |
here, of course, we just extracted the first coordinate of the
|
|
|
228 |
vector.
|
|
|
229 |
|
|
|
230 |
CGLA contains a number of features that are not used very frequently,
|
|
|
231 |
but which are used frequently enough to warrent inclusion. A good
|
|
|
232 |
example is assigning to a vector using spherical coordinates:
|
|
|
233 |
|
|
|
234 |
\begin{verbatim}
|
|
|
235 |
Vec3f p;
|
|
|
236 |
p.set_spherical(0.955317, 3.1415926f/4.0f , 1);
|
|
|
237 |
\end{verbatim}
|
|
|
238 |
|
|
|
239 |
CGLA also includes a quaternion class. Here it is used to construct a
|
|
|
240 |
quaternion which will rotate the x axis into the y axis.
|
|
|
241 |
|
|
|
242 |
\begin{verbatim}
|
|
|
243 |
Quaternion q;
|
|
|
244 |
q.make_rot(Vec3f(1,0,0), Vec3f(0,1,0));
|
|
|
245 |
\end{verbatim}
|
|
|
246 |
|
|
|
247 |
Next, we construct a $4\times 4$ matrix \texttt{m} and assign a translation
|
|
|
248 |
matrix to the newly constructed matrix. After that we ask the
|
|
|
249 |
quaternion to return a $4\times 4$ matrix corresponding to its
|
|
|
250 |
rotation. This rotation matrix is then multiplied onto \texttt{m}.
|
|
|
251 |
|
|
|
252 |
\begin{verbatim}
|
|
|
253 |
Mat4x4f m = translation_Mat4x4f(Vec3f(1,2,3));
|
|
|
254 |
m *= q.get_mat4x4f();
|
|
|
255 |
\end{verbatim}
|
|
|
256 |
|
|
|
257 |
Just like for vectors, the subscript operator works on
|
|
|
258 |
matrices. However, in this case there are two indices. Just using one
|
|
|
259 |
index will return the ith row as a vector as shown on the first line
|
|
|
260 |
below. On the second line we see that using two indices will get us an
|
|
|
261 |
element in the matrix.
|
|
|
262 |
|
|
|
263 |
\begin{verbatim}
|
|
|
264 |
Vec4f v4 = m[0];
|
|
|
265 |
float c = m[0][3];
|
|
|
266 |
\end{verbatim}
|
|
|
267 |
|
|
|
268 |
There is a number of constructors for vectors. The default constructor
|
|
|
269 |
will create a null vector as we have already seen. We can also specify
|
|
|
270 |
all the coordinates. Finally, we can pass just a single number
|
|
|
271 |
$a$. This will create the $[a\:a\:a]^T$ vector. For instance, below we
|
|
|
272 |
create the $[1\: 1\: 1]^T$ vector. Subsequently, this vector is
|
|
|
273 |
multiplied onto \texttt{m}.
|
|
|
274 |
|
|
|
275 |
\begin{verbatim}
|
|
|
276 |
Vec3f p(1);
|
|
|
277 |
Vec3f p2 = m.mul_3D_point(p);
|
|
|
278 |
\end{verbatim}
|
|
|
279 |
|
|
|
280 |
Note though that \texttt{m} is a $4\times
|
|
|
281 |
4$ matrix so ... how is that possible? Well, we use the function
|
|
|
282 |
\texttt{mul\_3D\_point} which, effectively, adds a $w=1$ coordinate to p
|
|
|
283 |
making it a 4D vector. This $w$ coordinate is stripped afterwards. In
|
|
|
284 |
practice, this means that the translation part of the matrix is also
|
|
|
285 |
applied. There is a similar function \texttt{mul\_3D\_vector} if we want
|
|
|
286 |
to transform vectors without having the translation. This function,
|
|
|
287 |
effectively, sets $w=0$.
|
|
|
288 |
|
|
|
289 |
Finally, CGLA is often used together with OpenGL although there is no
|
|
|
290 |
explicit tie to the OpenGL library. However, we can call the
|
|
|
291 |
\texttt{get} function of most CGLA entities to get a pointer to the
|
|
|
292 |
contents. E.g. \texttt{p.get()} will return a pointer to the first
|
|
|
293 |
float in the 3D vector \texttt{p}. This can be used with OpenGL's
|
|
|
294 |
``v'' functions as shown below.
|
|
|
295 |
|
|
|
296 |
\begin{verbatim}
|
|
|
297 |
glVertex3fv(p.get());
|
|
|
298 |
\end{verbatim}
|
|
|
299 |
|
|
|
300 |
\section{HMesh}
|
|
|
301 |
|
|
|
302 |
HMesh's \texttt{Manifold} class is a halfedge based mesh data structure. This type of data structure restricts you to manifolds, but allows for general N-gons for arbitrary N and makes manipulation somewhat simpler than other types of data structures for meshes. Note that this particular implementation does not allow more than one loop per face.
|
|
|
303 |
|
|
|
304 |
The central element of the data structure is the halfedge. It is not the goal here to discuss the halfedge data structure, but it is probably helpful that you see the syntax for e.g. going from a halfedge to the next. It may also be useful to understand the basics of the data structure. The goal is to explain the basics and show how to navigate around the mesh.
|
|
|
305 |
|
|
|
306 |
First of all, we only access elements via iterators. An iterator can be thought of as a pointer, but it is in fact an iterator to an STL list. Given a
|
|
|
307 |
\begin{verbatim}
|
|
|
308 |
Manifold m;
|
|
|
309 |
\end{verbatim}
|
|
|
310 |
we can loop over all its faces using
|
|
|
311 |
\begin{verbatim}
|
|
|
312 |
for(FaceIter f = m.faces_begin(); f != m.faces_end(); ++f)
|
|
|
313 |
f->touched = -1;
|
|
|
314 |
\end{verbatim}
|
|
|
315 |
|
|
|
316 |
The loop above visited each face f of m and assigned -1 to a variable called touched. The touched variables are simply integers, and a touched variable is associated with each face.
|
|
|
317 |
|
|
|
318 |
Note that we only refer to faces via their iterators. The same is true of vertices and halfedges. Vertices and halfedges also have touched variables, so the above code could be repeated exactly for vertices and halfedges. Here goes:
|
|
|
319 |
\begin{verbatim}
|
|
|
320 |
for(VertexIter v = m.vertices_begin();
|
|
|
321 |
v != m.vertices_end(); ++v)
|
|
|
322 |
v->touched = -1;
|
|
|
323 |
|
|
|
324 |
for(HalfEdgeIter h = m.halfedges_begin();
|
|
|
325 |
h != m.halfedges_end(); ++h)
|
|
|
326 |
h->touched = -1;
|
|
|
327 |
\end{verbatim}
|
|
|
328 |
|
|
|
329 |
What would be the use of setting the touched values to -1? Well, if we want to keep track of whether we have visited a given halfedge, we can initially set the touched values of all halfedges to -1 and then as we visit a halfedge set its value to something different. The same idea can be applied to faces and vertices.
|
|
|
330 |
|
|
|
331 |
Another common use of the touched values is as indices into an array. In this way, you can store auxiliary data with the mesh. In fact, there is a function\\ \texttt{enumerate\_vertices()} which enumerates all vertices (so each has a unique positive (or zero) integer. Similar functions exist for faces and halfedges.
|
|
|
332 |
|
|
|
333 |
So far, we have only discussed touched, but halfedges, faces, and vertices contain other data members. Most of these are iterators pointing to other edges, faces, or vertices. In the following, we briefly mention each member of the datastructures and show how to get to it. To get the opposite halfedge, use
|
|
|
334 |
\begin{verbatim}
|
|
|
335 |
HalfEdgeIter h2 = h1->opp;
|
|
|
336 |
\end{verbatim}
|
|
|
337 |
|
|
|
338 |
To get the next halfedge (in counterclockwise cycle around the vertex),
|
|
|
339 |
\begin{verbatim}
|
|
|
340 |
HalfEdgeIter h2 = h1->next;
|
|
|
341 |
\end{verbatim}
|
|
|
342 |
the previous halfedge,
|
|
|
343 |
\begin{verbatim}
|
|
|
344 |
HalfEdgeIter h2 = h1->prev;
|
|
|
345 |
\end{verbatim}
|
|
|
346 |
the vertex they point at,
|
|
|
347 |
\begin{verbatim}
|
|
|
348 |
VertexIter v = h->vert
|
|
|
349 |
\end{verbatim}
|
|
|
350 |
and the face whose counter clockwise halfedge loop they are one segment of.
|
|
|
351 |
\begin{verbatim}
|
|
|
352 |
FaceIter f = h->face;
|
|
|
353 |
\end{verbatim}
|
|
|
354 |
A vertex knows its position which is a Vec3f. To get the position, use
|
|
|
355 |
\begin{verbatim}
|
|
|
356 |
Vec3f pos = v->pos;
|
|
|
357 |
\end{verbatim}
|
|
|
358 |
A vertex also knows one outgoing halfedge:
|
|
|
359 |
\begin{verbatim}
|
|
|
360 |
HalfEdgeIter h = v->he;
|
|
|
361 |
\end{verbatim}
|
|
|
362 |
A face knows one halfedge in its counterclockwise cycle
|
|
|
363 |
\begin{verbatim}
|
|
|
364 |
HalfEdgeIter h = face->last;
|
|
|
365 |
\end{verbatim}
|
|
|
366 |
|
|
|
367 |
|
|
|
368 |
To move around a face, we can repeatedly ask for the next halfedge. Likewise, to move around a vertex, we can repeatedly ask for \texttt{h->opp->next} but it is not elegant, and in both cases we need a stop condition. Circulators encapsulate the task of visiting all edges delimiting a face or radiating from a vertex in a nice(r) way.
|
|
|
369 |
|
|
|
370 |
Given
|
|
|
371 |
\begin{verbatim}
|
|
|
372 |
VertexIter v
|
|
|
373 |
\end{verbatim}
|
|
|
374 |
we can go:
|
|
|
375 |
\begin{verbatim}
|
|
|
376 |
VertexCirculator vc(v);
|
|
|
377 |
Vec3f p(0.0);
|
|
|
378 |
for( ; !vc.end(); ++vc)
|
|
|
379 |
p += vc.get_vertex()->pos;
|
|
|
380 |
p/= vc.no_steps();
|
|
|
381 |
\end{verbatim}
|
|
|
382 |
|
|
|
383 |
So what does the code above do? It visits each neighboring vertex to a given vertex and computes the average position which is useful in a number of situations.
|
|
|
384 |
|
|
|
385 |
We can do the same thing with a FaceCirculator
|
|
|
386 |
\begin{verbatim}
|
|
|
387 |
FaceCirculator fc(f);
|
|
|
388 |
Vec3f p(0.0);
|
|
|
389 |
for( ; !fc.end(); ++fc)
|
|
|
390 |
p += fc.get_vertex()->pos;
|
|
|
391 |
p/= fc.no_steps();
|
|
|
392 |
\end{verbatim}
|
|
|
393 |
|
|
|
394 |
Internally, both the vertex and face circulators simply keep track of a single halfedge. So \texttt{get\_vertex()} returns the vertex pointed to by that halfedge. There are similar functions for getting the halfedge itself, the face it points to or its opposite halfedge.
|
|
|
395 |
|
|
|
396 |
Use circulators whenever you need to go around a face or vertex, but not when you need more complex navigation which is not easily expressed as circulation. In that case it is probably easier to just use the next, prev, and opp to move around.
|
|
|
397 |
|
|
|
398 |
\subsection{Authors and License}
|
|
|
399 |
Many other people contribute, but the core of GEL was written (mostly) by Andreas B{\ae}entzen (jab{@}imm.dtu.dk), and any bug fixes, contributions, or questions should be addressed to me, unless you know precisely who could take care of the problem.
|
|
|
400 |
|
|
|
401 |
I was considering putting GEL under the LGPL. But it is a long complex
|
|
|
402 |
text. The longer any kind of document, the more chances for loopholes
|
|
|
403 |
in my opinion. Instead, I list a few simple rules below. The most
|
|
|
404 |
important one is that if you want to use GEL for some purpose, and it
|
|
|
405 |
is not crystal clear whether it is against the rules, contact me. As
|
|
|
406 |
for the rules:
|
|
|
407 |
|
|
|
408 |
You are allowed to use GEL for academic or commercial purposes. In
|
|
|
409 |
particular, you are welcome to give GEL to students as a basis for
|
|
|
410 |
academic work or to use it for your own applications.
|
|
|
411 |
|
|
|
412 |
The biggest limitation that I want to impose is that you cannot repackage
|
|
|
413 |
GEL in any way. You are not allowed to distribute another library which
|
|
|
414 |
contains GEL or parts of GEL unless you make it clear that this other
|
|
|
415 |
library contains GEL. You are also not allowed to redistribute GEL in a
|
|
|
416 |
changed form. If you want changes to be made, contact me.
|
|
|
417 |
|
|
|
418 |
Of course, neither I nor my employer will give you any money or be
|
|
|
419 |
held responsible in any way, under any circumstances what so ever - no
|
|
|
420 |
matter what sort of damage GEL might inflict upon you. Not that I can
|
|
|
421 |
foresee GEL causing you any damage :-)
|
|
|
422 |
|
|
|
423 |
If anything is unclear, please contact me. In fact, if you want to use
|
|
|
424 |
GEL for a bigger project, I'd appreciate an email to jab@imm.dtu.dk
|
|
|
425 |
|
|
|
426 |
In a project such as this, it is almost impossible to completely avoid
|
|
|
427 |
building upon fragments of other peoples source code. GEL includes an
|
|
|
428 |
obj loader based on work by Nate Robins. Some pieces of source code
|
|
|
429 |
from Graphics Gems have also been used. Moreover, I have simply included
|
|
|
430 |
rply by Diego Nehab, Princeton University, and the Simple OpenGL Image Loader by
|
|
|
431 |
Jonathan Dummer. All of this amounts to only a fraction of the GEL source code and it should not be in violation of any license. In particular, SOIL and RPLY are under the MIT license and it is acceptable to include these packages as long as the copyright notice is retained (which it is.)
|
|
|
432 |
|
|
|
433 |
\end{document}
|