Subversion Repositories gelsvn

Rev

Rev 587 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 587 Rev 591
Line 320... Line 320...
320
\begin{verbatim}
320
\begin{verbatim}
321
VertexID vid;
321
VertexID vid;
322
// ... obtain a vertex ID
322
// ... obtain a vertex ID
323
vec3d p = m.pos(vid);
323
vec3d p = m.pos(vid);
324
\end{verbatim}
324
\end{verbatim}
-
 
325
Note that m.pos(vid) returns a reference to the vertex identified by vid, so we can also assign the vertex position simply using m.pos(vid) = p.
-
 
326
 
325
\texttt{VertexID}, \texttt{FaceID}, and \texttt{HalfEdgeID} are simply indices which we use to refer to entities in the mesh. These types are used to communicate with the \texttt{Manifold} class. For instance to get the position of a vertex, but many other functions -- both inside and outside the \texttt{Manifold} class take one of the ID types as argument. For instance,
327
\texttt{VertexID}, \texttt{FaceID}, and \texttt{HalfEdgeID} are simply indices which we use to refer to entities in the mesh. These types are used to communicate with the \texttt{Manifold} class. For instance to get the position of a vertex, but many other functions -- both inside and outside the \texttt{Manifold} class take one of the ID types as argument. For instance,
326
\begin{verbatim}
328
\begin{verbatim}
327
VertexID Manifold::split_edge(HalfEdgeID h);
329
VertexID Manifold::split_edge(HalfEdgeID h);
328
\end{verbatim}
330
\end{verbatim}
329
splits an edge and returns a \texttt{VertexID} for the introduced vertex. For functions outside the class, we need to also give the \texttt{Manifold} as an argument since an ID does not tell the function which mesh we are referring to. For example
331
splits an edge and returns a \texttt{VertexID} for the introduced vertex. For functions outside the class, we need to also give the \texttt{Manifold} as an argument since an ID does not tell the function which mesh we are referring to. For example
Line 335... Line 337...
335
We might somewhere have stored the \texttt{VertexID}, but frequently we simply iterate through our vertices. In other words, we loop over all vertices. Such a loop requires another type, namely the \texttt{VertexIDIterator}
337
We might somewhere have stored the \texttt{VertexID}, but frequently we simply iterate through our vertices. In other words, we loop over all vertices. Such a loop requires another type, namely the \texttt{VertexIDIterator}
336
\begin{verbatim}
338
\begin{verbatim}
337
for(VertexIDIterator v = m.vertices_begin(); 
339
for(VertexIDIterator v = m.vertices_begin(); 
338
     v != m.vertices_end(); ++v)
340
     v != m.vertices_end(); ++v)
339
{
341
{
340
  Vec3f p = mani.pos(*v);
342
  Vec3d p = mani.pos(*v);
341
  // Do something
343
  // Do something
342
}
344
}
343
\end{verbatim}
345
\end{verbatim}
344
An ID iterator is only useful for iterating over elements in the mesh. However, from the iterator we can obtain the ID by using the dereference operator \texttt{*} as shown above. We also have \texttt{HalfEdgeID}, \texttt{HalfEdgeIDIterator}, \texttt{FaceID}, and \texttt{FaceIDIterator}. Thus, similar code could have been used to iterate over halfedges or faces. Clearly, iterating over elements is just the beginning. The iterators expose how the mesh entities are stored in the \texttt{Manifold} but not how they relate geometrically to one another. 
346
An ID iterator is only useful for iterating over elements in the mesh. However, from the iterator we can obtain the ID by using the dereference operator \texttt{*} as shown above. We also have \texttt{HalfEdgeID}, \texttt{HalfEdgeIDIterator}, \texttt{FaceID}, and \texttt{FaceIDIterator}. Thus, similar code could have been used to iterate over halfedges or faces. Clearly, iterating over elements is just the beginning. The iterators expose how the mesh entities are stored in the \texttt{Manifold} but not how they relate geometrically to one another. 
345
 
347
 
346
\subsection{Walker}
348
\subsection{Walker}
347
To traverse the mesh in a geometric fashion, we use the \texttt{Walker}. A \texttt{Walker} simply encapsulates an ID for a given \texttt{HalfEdge} and a pointer to the data structure which stores the mesh. Thus, to compute the centroid for a given face, we can use a \texttt{Walker}
349
To traverse the mesh in a geometric fashion, we use the \texttt{Walker}. A \texttt{Walker} simply encapsulates an ID for a given \texttt{HalfEdge} and a pointer to the data structure which stores the mesh. Thus, to compute the centroid for a given face, we can use a \texttt{Walker}
348
\begin{verbatim}
350
\begin{verbatim}
349
Vec3f p(0);
351
Vec3d p(0);
350
FaceIDIterator f = m.faces_begin();
352
FaceIDIterator f = m.faces_begin();
351
Walker w = m.walker(*f);
353
Walker w = m.walker(*f);
352
for(; !w.full_circle(); w = w.next()){
354
for(; !w.full_circle(); w = w.next()){
353
  p += m.pos(w.vertex()); 
355
  p += m.pos(w.vertex()); 
354
p /= w.no_steps();
356
p /= w.no_steps();
Line 363... Line 365...
363
\texttt{prev} does the same as \texttt{circulate\_face\_cw} and \texttt{next} does the same as \\\texttt{circulate\_face\_ccw}. The longer names are indicative of the geometric operation while \texttt{prev} and \texttt{next} highlight the connection with the data structure.    It is important to note that all of the functions which operate on \texttt{Walker} instances return a new \texttt{Walker} and do not alter the state of the current walker. Thus to walk around a face, we use \texttt{w = w.next()} as opposed to just \texttt{w.next()} in the for loop above. 
365
\texttt{prev} does the same as \texttt{circulate\_face\_cw} and \texttt{next} does the same as \\\texttt{circulate\_face\_ccw}. The longer names are indicative of the geometric operation while \texttt{prev} and \texttt{next} highlight the connection with the data structure.    It is important to note that all of the functions which operate on \texttt{Walker} instances return a new \texttt{Walker} and do not alter the state of the current walker. Thus to walk around a face, we use \texttt{w = w.next()} as opposed to just \texttt{w.next()} in the for loop above. 
364
That might seem inconvenient but it is more flexible since we can obtain, say, a nearby vertex just by concatenating some traversal functions. For instance \texttt{w.next().opp().next().vertex()} returns an ID to a vertex nearby  -- without changing \texttt{w}. The sequence \texttt{w.next().opp().next()} creates three anonymous walkers. If, on the other hand, the functions used for walking updated the state of  \texttt{w}, we would have needed to first make a named copy of \texttt{w} before updating its state, so that we could get back to the original state.
366
That might seem inconvenient but it is more flexible since we can obtain, say, a nearby vertex just by concatenating some traversal functions. For instance \texttt{w.next().opp().next().vertex()} returns an ID to a vertex nearby  -- without changing \texttt{w}. The sequence \texttt{w.next().opp().next()} creates three anonymous walkers. If, on the other hand, the functions used for walking updated the state of  \texttt{w}, we would have needed to first make a named copy of \texttt{w} before updating its state, so that we could get back to the original state.
365
 
367
 
366
\texttt{Walker} can be used to circulate around both faces and vertices. Below, we use vertex circulation to compute the average of the neighbors of a vertex
368
\texttt{Walker} can be used to circulate around both faces and vertices. Below, we use vertex circulation to compute the average of the neighbors of a vertex
367
\begin{verbatim}
369
\begin{verbatim}
368
Vec3f p(0);
370
Vec3d p(0);
369
VertexIDIterator v = m.vertices_begin();
371
VertexIDIterator v = m.vertices_begin();
370
Walker w = m.walker(*v);
372
Walker w = m.walker(*v);
371
for(; !w.full_circle(); w = w.circulate_vertex_ccw()){
373
for(; !w.full_circle(); w = w.circulate_vertex_ccw()){
372
  p += m.pos(w.vertex()); 
374
  p += m.pos(w.vertex()); 
373
p /= w.no_steps();
375
p /= w.no_steps();
Line 388... Line 390...
388
We could have combined two or all three of these concepts, but would have led to rather bloated datatypes.
390
We could have combined two or all three of these concepts, but would have led to rather bloated datatypes.
389
 
391
 
390
\subsection{Attributes}
392
\subsection{Attributes}
391
Given a \texttt{VertexID},  \texttt{v}, and a \texttt{Manifold}, \texttt{m}, we can obtain the geometric position of the vertex with the method call \texttt{m.pos(v)}. If is fairly important to note that a reference to the position is returned. Thus, we can assign the position of a vertex:
393
Given a \texttt{VertexID},  \texttt{v}, and a \texttt{Manifold}, \texttt{m}, we can obtain the geometric position of the vertex with the method call \texttt{m.pos(v)}. If is fairly important to note that a reference to the position is returned. Thus, we can assign the position of a vertex:
392
\begin{verbatim}
394
\begin{verbatim}
393
Vec3f p;
395
Vec3d p;
394
VertexID v;
396
VertexID v;
395
// ...
397
// ...
396
m.pos(v) = p;
398
m.pos(v) = p;
397
\end{verbatim}
399
\end{verbatim}
398
 
400