First version of the new doxygen based documentation

This commit is contained in:
Paolo Cignoni 2012-10-03 11:56:27 +00:00
parent 14cffd1f6e
commit 09ff045451
14 changed files with 2436 additions and 49 deletions

193
docs/Doxygen/adjacency.dxy Normal file
View File

@ -0,0 +1,193 @@
/** \page adjacency
Adjacency
=========
VCG Lib does not have a hard-coded way to encode the adjacencies among simplices. It all depends on which attributes are stored with the simplices and how they are used. I the previous examples the definition of face has always included the attribute vcg::face::VertexRef , which stores 3 pointers to MyVertex accessible with the member function V() (the well known Indexed Data Structure). The reason is that almost all of the algorithms currently implemented in VCG Lib assume its presence. So, if your type MyFace does not include the attribute vcg::face::VertexRef, the definition will be correct but almost no algorithm will work..
There are other adjacency relations that can be useful to navigate a mesh, for example to collect the one-ring neighborhood of a vertex. VCG Lib uses two mechanisms which are explained in the following, along with the attributes they use.
FF Adjacency
============
The face-to-face adjacency, stored in the attribute for the faces vcg::face::FFAdj ( vcg::face::TTAdj for tetrahedra), encodes the adjacency of faces (tetrahedra) through edges (faces). The image below shows two triangle faces with the convention adopted for indexing vertexes and edges.
The vertexes are numbered from 0 to 2 in CCW sense and the edge i = 0..2 is the edge whose extremes are i and (i+1) mod 3 . Therefore the common edge between faces f1 and f2 is the edge 1 of the face f1 and the edge 0 of the face f0.
vcg::face::FFAdj stores, for each edge e of the face f:
FFp(e): a pointer to a face f' sharing e. If e is a border than points to the face f itself
FFi(e):the index of e in the pointed face
\image html "../img/FF_Adj.png" "Indexing of vertexes and edges"
f1->FFp(1) == f0
f1->FFi(1) == 0
f0->FFp(0) == f1
f0->FFi(0) == 1
Note that we specified that FFp(e) point to a adjacent face, not to the adjacent face. The reason is that there could be more than two faces on the same edge, and this is seamlessly supported by VCG Lib. In the picture below is shown an example with 4 faces incident to the same edge
\image html "../img/FF_nonmanifold.png" "Non manifold edge"
In this case the adjacencies are set to form a circular list (not necessarily sorted with the angle around the edge). This is done by the VCG Lib function that update these values (UpdateTopology<MeshType>::FFTopology(MeshType & m)).
In this way VCG Lib provides a way to check if a mesh is manifold on a specific edge because the FF adjacency relation is mutual, i.e. the face f0 points to the face f1 which points to the face f0, if and only if the mesh is manifold over the corresponding edge.
bool IsManifold(MyFace *f,int e) { return (f0 == f0->FFp(0)->FFp(f0->FFi(0)))}
Referring to the picture:
(f0 == f0->FFp(0)->FFp(f0->FFi(0))} equals
(f0 == f1->FFp(0)} equals
(f0 == f0} Ok! It is manifold
Pos
---
The Pos is the VCG Lib implementation of the Cell-Tuple{ref}. Here we give a as short as possible definition, trading formalisms for space. A Pos in a triangle mesh is a triple made of a vertex: pos = (v,e,f) , such that v is an extreme of e and e belong to the face f . The figure shows few pos in a triangle mesh as small triangles "pointing" to a vertex, "leaning" against an edge and inside a face. For example c0=(v,e0,f).
A very nice property is that given a pos c, there is only another neighbor pos c' that can be obtained from c changing only one of the elements of the triple.
We call the operation of passing from a pos to one of its neighbors Flip and write FlipV, FlipE and FlipF to indicate that the flipped element is the vertex, the edge or the face respectively.
For example consider c1: there is only another pos which is the same as c0 except for the vertex component of the triple, and it is c2. For brevity, we write c2 = FlipV(c1).
In the left of the table some other examples are shown just to make this point clear.
\image html "../img/pos_example.png" "Pos Example"
c2 = FlipV(c1)
c0 = FlipE(c1)
c3 = FlipF(c0)
CCW around v
c4 = FlipE(FlipF(c0))
c5 = FlipE(FlipF(c4))
Bounce
c6 = FlipE(FlipF(c5))
CW around v
c3 = FlipE(FlipF(c6))
c1 = FlipE(FlipF(c3))
Bounce
c0 = FlipE(FlipF(c1))
Note that concatenating two flips: FlipF and FlipE we obtain a transition from a pos to the next in counterclockwise or in clockwise sense, depending if the starting pos is on the CCW edge of the face with respect to the vertex or not. Also note that, thanks to how FF adjacency is defined, when a pos is on the border, it bounces back. This pair of flip are widely used in the VCG Lib to run over the one ring neighborhood of manifold vertices.
The following code snippet shows how to use the pos to iterate around a vertex:
sf/apps/sample/trimesh_pos_demo/trimesh_pos_demo.cpp
#include <vcg/simplex/face/pos.h> // include the definition of pos
...includes to define your mesh type
class MyVertex: ...
class MyFace: public vcg::FaceSimp2<MyVertex,MyEdge,MyFace, vcg::face::VertexRef, vcg::face::FFAdj>{};
void OneRingNeighborhood( MyFace * f)
{
MyVertex * v = f->V(0);
MyFace* start = f;
vcg::face::Pos<MyFace> p(f,0,v);// constructor that takes face, edge and vertex
do
{
p.FlipF();
p.FlipE();
}while(p.f!=start);
}
Two important notes:
We arbitrarily picked f->V(0) as pivot vertex. In general one may want to start knowing the vertex. This is done by including the attribute vcg::vertex::VFAdj which basically associates to each vertex pointer to one of the faces incident on it. See the VF Adjacency for details.
This implementation does not work if the vertex is on the border. Just try with the example: from the pos c4 it would find c5,c6,c3 which is in the same face as c4. Of course this does not happen if you use the pos itself as a guard and not just the face. However, even in this case, you would obtain the sequence of pos: c5,c6,c3,c1,c0,c4 corresponding to the faces f2,f2,f1,f0,f0,f1 which probably is not what you want. VCG Lib provides a variation of pos that solves this problem
Jumping Pos
-----------
The Jumping Pos works exactly like the Pos, only it does not bounce when it encounters the border. Instead, it jump around the vertex as if the to border faces sharing the vertex (faces f0 and f2 in the image) were adjacent.
sf/apps/sample/trimesh_pos_demo/trimesh_pos_demo.cpp
#include <vcg/simplex/face/jumping_pos.h> // include the definition of jumping pos
//...includes to define your mesh type
//class MyVertex: ...
class MyFace: public vcg::FaceSimp2<MyVertex,MyEdge,MyFace, vcg::face::VertexRef,vcg::face::FFAdj>{};
void OneRingNeighborhoodJP( MyFace * f)
{
MyVertex * v = f->V(0);
MyFace* start = f;
vcg::face::JumpingPos<MyFace> p(f,0,v);// constructor that takes face, edge and vertex
do
{
p.NextFE();
}while(p.f!=start);
}
VF Adjacency
------------
VCG Lib implements vertex-to-face adjacency, i.e. given a vertex v we can retrieve all the faces incident to v. Let v_star =(f0,f1,f2,...,fk) be the set faces incident to v arranged in a sequence (with no preferred criteria). VCG Lib allows to retrieve v_star in optimal time ( O(#star_v) by using the following attibutes:
vcg::vertex::VFAdj which is a vertex attribute containing a pointer to f0
vcg::face::VFAdj which is a face attribute containing a pointer to the next face in the list v_star for each of its 3 vertices (4 in the case of tetrahedra)
These two attributes are not only a pointers, they also contain an index referring the index of the vertex in the pointed face in the same style as the vcg::face::FFAdj does. The picture below shows a complete example:
\image html "../img/VertexStar.png" "Example of vertex-face adjacency"
v.VFp() == f2
v.VFi() == 0
f2->VFp(0) == f3
f2->VFi(0) == 1
f3->VFp(1) == f1
f3->VFi(1) == 2
f1->VFp(2) == f0
f1->VFi(2) == 2
f0->VFp(2) == NULL
f0->VFi(2) == -1
VFIterator
----------
VFIterator is a simple iterator to run over the faces in the one-ring neighborhood of a vertex using the VF Adjacency (it is just like Pos for the FF Adjacency) The following code snippet shows how to use the VFIterator:
sf/apps/sample/trimesh_pos_demo/trimesh_vfiter_demo.cpp
#include <vcg/simplex/face/pos.h> // include the definition of VFIterator
//...includes to define your mesh type
class MyVertex: public vcg::VertexSimp2<MyVertex,MyEdge,MyFace, vcg::vertex::VFAdj /*,... other attributes*/ >{};
class MyFace: public vcg::FaceSimp2<MyVertex,MyEdge,MyFace, vcg::face::VertexRef,vcg::face::VFAd>{};
void OneRingNeighborhoodVF( MyVertex * v)
{
vcg::face::VFIterator<MyFace> vfi(v); //initialize the iterator tohe first face
for(;!vfi.End();++vfi)
{
MyFace* f = vfi.F();
// ...do something with face f
}
}
Few facts on FF adjacency and VF adjacency
------------------------------------------
Here we make a series of simple statements just to avoid confusion and try to help up choosing the adjacencies the best fit your needs.
If the mesh is manifold, the one-ring neighborhood of a vertex computed by using Pos ( needs FF adjacency) is the same as the one computed by using VFIterator (needs VF adjacency). The order in which the faces are visited can be CW or CCW if using Pos, unspecified by using VIterator
If the mesh is non-manifold, Pos may not find all the faces of the one-ring neighborhood of he vertex, VFIterator always does
Boundary relations and adjacency
--------------------------------
In many algorithms you need to simply the boundary/border condition of a face, e.g. to know if a given face f has one or more adjacent faces on a specified edge e. Using FF adjacency this can be done simply by using the face::IsBorder(f,e) static function that simply checks if the pointer stored in face f on the edge e points to f itself. If you are navigating the mesh using a Pos, you have a Pos member function IsBorder() that reports the boundary condition of the current pos. Similarly, for testing manifoldness of specific places over a mesh, there is a face::IsManifold(f,e) static function and a IsManifold(e) function member of the pos class.
If you are not using FF adjacency evaluating the boundary conditions could be not very efficient, so vcg library provides a technique to cook the current boundary conditions of the mesh into vertex and face flags. Use the members of the UpdateFlags static class to compute flags that reflects the current mesh status and the access these flags using the IsB(e) member function of the face class. Remember that flags based boundary information can become invalid if you change the mesh topology. On the other hand consider that many non-mesh-modifying algorithms do not require explicit FF adjacency but just boundary information (typical examples: most mesh smoothing and curvature computation algorithms).
Please note that the boundary flags are set true also for non manifold conditions.
*/

View File

@ -0,0 +1,77 @@
/** \page allocation
Creating elements
=================
To create a simple single triangle mesh or to add elements to an existing mesh you should use the AddVertices and AddFaces functions, elements are added at the end of the mesh. These functions returns a pointer to the first allocated element.
Adding element to a vector can cause reallocation, and therefore invalidation of any pointer that points to the mesh elements. These fucntion manage safely re-allocation and updating of pointers for all the pointers stored internally in the mesh (e.g. if you add some vertices and that causes a reallocation of the vertex vector, the pointers from faces to vertices will be automatically updated by the Allocator functions.
\code
#include <vcg/complex/trimesh/allocate.h>
//...define MyMesh
MyMesh m;
m.Clear();
Allocator<MyMesh>::AddVertices(m,3);
Allocator<MyMesh>::AddFaces(m,1);
MyMesh::VertexPointer ivp[3];
VertexIterator vi=m.vert.begin();
ivp[0]=&*vi;(*vi).P()=CoordType ( 1.0, 1.0, 1.0); ++vi;
ivp[1]=&*vi;(*vi).P()=CoordType (-1.0, 1.0,-1.0); ++vi;
ivp[2]=&*vi;(*vi).P()=CoordType (-1.0,-1.0, 1.0); ++vi;
FaceIterator fi=m.face.begin();
(*fi).V(0)=ivp[0]; (*fi).V(1)=ivp[1]; (*fi).V(2)=ivp[2];
\endcode
look to platonic.h for more examples.
If you keep interally some pointers to the mesh elements adding elements can invalidate them. In that case you should pass to the code>Allocator</code> functions a PointerUpdater to be used to update your private pointers.
\code
MyMesh m;
...
...
MyMesh::VertexPointer vp = &m.vert[0]; // a potentially dangerous pointer
PointerUpdater<VertexPointer> pu;
// now the vp pointer could be no more valid due to eventual re-allocation of the m.vert vector.
Allocator<MyMesh>::AddVertices(m,3,pu);
// check if an update of the pointer is needed and do it.
if(pu.NeedUpdate()) pu.Update(vp);
\endcode
Destroying Elements
-------------------
Lazy deletion strategy.
Note that the two basic deletion strategies are very low level functions. They simply mark as deleted the corresponding entries without affecting the rest of the structures. So for example if you delete a vertex with these structures without checking that all the faces incident on it have been removed you create a non consistent situation...
Similarly, but less dangerously, when you delete a face its vertices are left around so at the end you can have unreferenced floating vertices.
\code
Allocator<MyMesh>::DeleteVertex(m,v);
Allocator<MyMesh>::DeleteFace(m,v);
\endcode
If your algorithm performs deletion the size of a container could be different from the number of valid element of your meshes (e.g.:
\code
m.vert.size() != m.vn
m.face.size() != m.fn
\endcode
Therefore when you scan the containers of vertices and faces you could encounter deleted elements so you should take care with a simple !IsD() check:
\code
MyMesh::FaceIterator vi;
for(fi = m.face.begin(); vi!=m.face.end(); ++fi )
if(!(*fi).IsD()) // <---- Check added
{
MyMesh::CoordType b = vcg::Barycenter(*fi);
}
\endcode
In some situations, particularly when you have to loop many many times over the element of the mesh without deleting/creating anything, it can be practical and convenient to get rid of deleted elements by explicitly calling the two garbage collecting functions:
\code
Allocator<MyMesh>::CompactVertexVector(m);
Allocator<MyMesh>::CompactFaceVector(m);
\endcode
After calling these function it is safe to not check the IsD() state of every element and always holds that:
\code
m.vert.size() == m.vn
m.face.size() == m.fn
\endcode
Note that if there are no deleted elements in your mesh, the compactor functions returns immediately.
*/

View File

@ -0,0 +1,91 @@
/** \page attributes
User-defined attributes
=======================
VCG Lib also provides a simple mechanism to associate user-defined 'attributes' to the simplicies and to the mesh.
Note that both 'attributes' and 'components' are basically accessory data that are bound to a simplex.
Conceptually the difference is that with the term component VCGLib indicates those values that are considered to 'define' the simplex (its position, its normal its connectivity information), while the user defined attribute is an accessory data which make sense to some specific algorithm, like "the number of time a vertex has been moved" or "a pointer to a string containing a description of the vertex".
Practically the difference is that every optional component has its non optional counterpart and is accessed through a member function of the simplex, so that when you write your algorithm you use v.N() to access the normal both it is has been declared as optional or not, while the attributes are accessed by a handle which is returned at the creation of the attribute.
The following code snippet shows an example:
\code
/* apps/sample/trimesh_attribute/trimesh_attribute.cpp */
#include<vcg/simplex/vertex/base.h>
#include<vcg/simplex/vertex/component.h>
#include<vcg/simplex/face/base.h>
#include<vcg/simplex/face/component.h>
#include<vcg/complex/trimesh/base.h>
#include<vcg/complex/trimesh/allocate.h>
class MyFace;
class MyVertex;
class MyEdge; // dummy prototype never used
class MyVertex : public vcg::VertexSimp2< MyVertex, MyEdge, MyFace, vcg::vertex::Coord3f,vcg::vertex::Normal3f>{};
class MyFace : public vcg::FaceSimp2< MyVertex, MyEdge, MyFace, vcg::face::VertexRef, vcg::face::Normal3f> {};
class MyMesh : public vcg::tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace> > {};
float Irradiance(MyMesh::VertexType v){
// .....
return 1.0;
}
int main()
{
MyMesh m;
//...here m is filled
// add a per-vertex attribute with type float named "Irradiance"
MyMesh::PerVertexAttributeHandle<float> ih = vcg::tri::Allocator<MyMesh>::AddPerVertexAttribute<float> (m,std::string("Irradiance"));
// add a per-vertex attribute with type float named "Radiosity"
vcg::tri::Allocator<MyMesh>::AddPerVertexAttribute<float> (m,std::string("Radiosity"));
// add a per-vertex attribute with type bool and no name specified
MyMesh::PerVertexAttributeHandle<bool> blocked_h = vcg::tri::Allocator<MyMesh>::AddPerVertexAttribute<bool> (m);
MyMesh::VertexIterator vi; int i = 0;
for(vi = m.vert.begin(); vi != m.vert.end(); ++vi,++i){
ih[vi] = Irradiance(*vi); // [] operator takes a iterator
ih[*vi] = Irradiance(*vi); // or a MyMesh::VertexType object
ih[&*vi]= Irradiance(*vi); // or a pointer to it
ih[i] = Irradiance(*vi); // or an integer index
}
// Once created with AddPerVertexAttribute, an handle to the attribute can be obtained as follows
MyMesh::PerVertexAttributeHandle<float> rh = vcg::tri::Allocator<MyMesh>::GetPerVertexAttribute<float>(m,"Radiosity");
// you can query if an attribute is present or not
bool hasRadiosity = vcg::tri::HasPerVertexAttribute(m,"Radiosity");
// you can delete an attibute by name
vcg::tri::Allocator<MyMesh>::DeletePerVertexAttribute<float>(m,"Radiosity");
// you can delete an attibute by handle
vcg::tri::Allocator<MyMesh>::DeletePerVertexAttribute<bool>(m,blocked_h);
}
\endcode
The same can be done for the faces, just replace the occurences of PerVertex with PerFace. Note that if you call add an attribute without specifying a name and you lose the handle, you will not be able to get your handle back.
Note:
Do not get mix up the scope of the handle with the memory allocation of the attribute. If you do not delete an attribute explicitly, it will be allocated until the mesh itself is destroyed, even if you do not have handles to it.
C++ type of a mesh and reflection
---------------------------------
VCG Lib provides a set of functions to implement reflection, i.e. to investigate the type of a mesh at runtime. These functions follow the format Has[attribute](mesh) and return a boolean stating if that particular attribute is present or not.
\code
template<class ComputeMeshType>
static void UpdateNormals<ComputeMeshType>::PerVertex(ComputeMeshType &m)
{
if( !HasPerVertexNormal(m)) return;
...
}
\endcode
You may wonder why those functions are not statically typed and why they needs the mesh object, i.e. why can't you just write ComputeMeshType::HasPerVertexNormal()? The reason is that VCG Lib reflection takes into account optional components, therefore HasPerVertexNormal(m) will return true if the type of the vertex contains the attribute as permanent (e.g. vcg::vertex::Normal3f) OR if it contains the attribute as optional (e.g. vcg::vertex::Normal3fOcf) AND it is enabled, i.e. the relative Enable function has been called.
*/

File diff suppressed because it is too large Load Diff

BIN
docs/Doxygen/img/FF_Adj.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -0,0 +1,311 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.48.1 r9760"
sodipodi:docname="vcglogo.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.6448421"
inkscape:cx="995.39411"
inkscape:cy="396.26054"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:window-width="1870"
inkscape:window-height="1156"
inkscape:window-x="50"
inkscape:window-y="0"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid2987" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:none;stroke:none;stroke-width:1.99999975999999990;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect3853"
width="460"
height="265"
x="90"
y="587.36218"
inkscape:export-filename="/Users/cignoni/devel/vcglib/docs/Doxygen/img/text3830.png"
inkscape:export-xdpi="200.35001"
inkscape:export-ydpi="200.35001" />
<text
sodipodi:linespacing="125%"
id="text3040"
y="839.36218"
x="100"
style="font-size:61.15526199000001384px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#006080;fill-opacity:1;stroke:#003040;font-family:Century Gothic;-inkscape-font-specification:Century Gothic;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
xml:space="preserve"
inkscape:export-filename="/Users/cignoni/devel/vcglib/docs/Doxygen/img/text3830.png"
inkscape:export-xdpi="200.35001"
inkscape:export-ydpi="200.35001"><tspan
y="839.36218"
x="100"
id="tspan3042"
sodipodi:role="line">L I B R A R Y </tspan></text>
<path
style="fill:#006080;stroke:#003040;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;fill-opacity:1;stroke-opacity:1"
inkscape:transform-center-x="-1.0790028"
inkscape:transform-center-y="-5.3460821"
d="m 210,607.36218 -105,180.00001 210,0 z"
id="path3044"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc"
inkscape:export-filename="/Users/cignoni/devel/vcglib/docs/Doxygen/img/text3830.png"
inkscape:export-xdpi="200.35001"
inkscape:export-ydpi="200.35001" />
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path3046"
d="m 430,607.36218 -105,180 210,0 z"
inkscape:transform-center-y="-5.3460821"
inkscape:transform-center-x="-1.0790028"
style="fill:#006080;stroke:#003040;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;fill-opacity:1;stroke-opacity:1"
inkscape:export-filename="/Users/cignoni/devel/vcglib/docs/Doxygen/img/text3830.png"
inkscape:export-xdpi="200.35001"
inkscape:export-ydpi="200.35001" />
<path
style="fill:#006080;stroke:#003040;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;fill-opacity:1;stroke-opacity:1"
inkscape:transform-center-x="-1.0790028"
inkscape:transform-center-y="5.3460821"
d="m 320,781.36218 -105,-180 210,0 z"
id="path3048"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc"
inkscape:export-filename="/Users/cignoni/devel/vcglib/docs/Doxygen/img/text3830.png"
inkscape:export-xdpi="200.35001"
inkscape:export-ydpi="200.35001" />
<text
xml:space="preserve"
style="font-size:108px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#003040;font-family:Century Gothic;-inkscape-font-specification:Century Gothic;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="172.11035"
y="769.17273"
id="text3050"
sodipodi:linespacing="125%"
inkscape:export-filename="/Users/cignoni/devel/vcglib/docs/Doxygen/img/text3830.png"
inkscape:export-xdpi="200.35001"
inkscape:export-ydpi="200.35001"><tspan
sodipodi:role="line"
id="tspan3052"
x="172.11035"
y="769.17273">V</tspan></text>
<text
sodipodi:linespacing="125%"
id="text3054"
y="769.17273"
x="379.77051"
style="font-size:108px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#003040;font-family:Century Gothic;-inkscape-font-specification:Century Gothic;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
xml:space="preserve"
inkscape:export-filename="/Users/cignoni/devel/vcglib/docs/Doxygen/img/text3830.png"
inkscape:export-xdpi="200.35001"
inkscape:export-ydpi="200.35001"><tspan
y="769.17273"
x="379.77051"
id="tspan3056"
sodipodi:role="line">G </tspan></text>
<text
xml:space="preserve"
style="font-size:108px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#003040;font-family:Century Gothic;-inkscape-font-specification:Century Gothic;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="273.19824"
y="700.36218"
id="text3058"
sodipodi:linespacing="125%"
inkscape:export-filename="/Users/cignoni/devel/vcglib/docs/Doxygen/img/text3830.png"
inkscape:export-xdpi="200.35001"
inkscape:export-ydpi="200.35001"><tspan
sodipodi:role="line"
id="tspan3060"
x="273.19824"
y="700.36218">C </tspan></text>
<text
xml:space="preserve"
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
x="367.91953"
y="778.65179"
id="text3830"
sodipodi:linespacing="125%"
inkscape:export-xdpi="200.35001"
inkscape:export-ydpi="200.35001"><tspan
sodipodi:role="line"
id="tspan3832"
x="367.91953"
y="778.65179"> </tspan></text>
<rect
inkscape:export-ydpi="200.35001"
inkscape:export-xdpi="200.35001"
inkscape:export-filename="/Users/cignoni/devel/vcglib/docs/Doxygen/img/text3830.png"
y="147.72942"
x="121.37207"
height="265"
width="460"
id="rect3858"
style="fill:none;stroke:none" />
<path
inkscape:connector-curvature="0"
id="path3887"
style="font-size:61.15526199px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#006080;fill-opacity:1;stroke:#003040;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;font-family:Century Gothic;-inkscape-font-specification:Century Gothic"
d="m 136.71719,355.80398 4.41942,0 0,39.6852 16.87145,0 0,4.2402 -21.29087,0 0,-43.9254" />
<path
inkscape:connector-curvature="0"
id="path3889"
style="font-size:61.15526199px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#006080;fill-opacity:1;stroke:#003040;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;font-family:Century Gothic;-inkscape-font-specification:Century Gothic"
d="m 198.32036,355.80398 4.38956,0 0,43.9254 -4.38956,0 0,-43.9254" />
<path
inkscape:connector-curvature="0"
id="path3891"
style="font-size:61.15526199px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#006080;fill-opacity:1;stroke:#003040;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;font-family:Century Gothic;-inkscape-font-specification:Century Gothic"
d="m 246.96387,355.80398 8.65968,0 c 3.48376,0 6.1613,0.418 8.0326,1.2541 1.87127,0.8163 3.34441,2.0804 4.41943,3.7924 1.09487,1.712 1.64232,3.6132 1.64235,5.7034 -3e-5,1.9509 -0.4778,3.7327 -1.43333,5.3451 -0.95557,1.5926 -2.35904,2.8866 -4.21039,3.8819 2.28931,0.7764 4.05111,1.6922 5.28539,2.7472 1.23422,1.0352 2.18977,2.2994 2.86665,3.7924 0.69673,1.4731 1.0451,3.0757 1.04513,4.8076 -3e-5,3.5236 -1.294,6.5097 -3.88192,8.9583 -2.56807,2.4287 -6.02198,3.643 -10.36176,3.643 l -12.06383,0 0,-43.9254 m 4.29998,4.2999 0,14.0645 2.50832,0 c 3.04581,10e-5 5.28538,-0.2786 6.71872,-0.8361 1.43331,-0.5772 2.56802,-1.4731 3.40415,-2.6874 0.83608,-1.2343 1.25414,-2.5979 1.25416,-4.091 -2e-5,-2.0106 -0.70673,-3.5833 -2.12013,-4.718 -1.39353,-1.1546 -3.62315,-1.7319 -6.68885,-1.732 l -5.07637,0 m 0,18.484 0,16.8416 5.4347,0 c 3.20506,0 5.55412,-0.3086 7.04719,-0.9257 1.49302,-0.6371 2.68746,-1.6225 3.58331,-2.9563 0.91571,-1.3337 1.37358,-2.777 1.37361,-4.3298 -3e-5,-1.9509 -0.63706,-3.653 -1.91111,-5.1062 -1.27409,-1.4532 -3.02593,-2.4486 -5.25553,-2.9861 -1.49306,-0.3583 -4.09096,-0.5375 -7.79371,-0.5375 l -2.47846,0" />
<path
inkscape:connector-curvature="0"
id="path3893"
style="font-size:61.15526199px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#006080;fill-opacity:1;stroke:#003040;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;font-family:Century Gothic;-inkscape-font-specification:Century Gothic"
d="m 316.12188,355.80398 8.74926,0 c 4.87727,0 8.18188,0.1991 9.91384,0.5972 2.60783,0.5972 4.72796,1.8813 6.36039,3.852 1.63236,1.951 2.44856,4.3598 2.4486,7.2264 -4e-5,2.3889 -0.5674,4.4891 -1.70208,6.3007 -1.11484,1.8115 -2.71738,3.1851 -4.80762,4.1208 -2.09029,0.9157 -4.97684,1.3835 -8.65968,1.4034 l 15.79646,20.4249 -5.4347,0 -15.76659,-20.4249 -2.50832,0 0,20.4249 -4.38956,0 0,-43.9254 m 4.38956,4.2999 0,14.9305 7.55482,0.06 c 2.92636,10e-5 5.0863,-0.2786 6.47983,-0.8361 1.4134,-0.5573 2.5083,-1.4432 3.28471,-2.6576 0.79626,-1.2342 1.19441,-2.6078 1.19444,-4.1208 -3e-5,-1.4731 -0.39818,-2.8069 -1.19444,-4.0014 -0.79632,-1.2143 -1.84145,-2.0803 -3.1354,-2.5979 -1.294,-0.5175 -3.44399,-0.7763 -6.44997,-0.7764 l -7.73399,0" />
<path
inkscape:connector-curvature="0"
id="path3895"
style="font-size:61.15526199px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#006080;fill-opacity:1;stroke:#003040;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;font-family:Century Gothic;-inkscape-font-specification:Century Gothic"
d="m 404.89854,355.80398 20.48462,43.9254 -4.71803,0 -6.89789,-14.4527 -18.93185,0 -6.86802,14.4527 -4.8972,0 20.75337,-43.9254 1.075,0 m -0.5375,9.3166 -7.55483,15.9159 15.02007,0 -7.46524,-15.9159" />
<path
inkscape:connector-curvature="0"
id="path3897"
style="font-size:61.15526199px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#006080;fill-opacity:1;stroke:#003040;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;font-family:Century Gothic;-inkscape-font-specification:Century Gothic"
d="m 466.38225,355.80398 8.74926,0 c 4.87728,0 8.18189,0.1991 9.91385,0.5972 2.60783,0.5972 4.72795,1.8813 6.36038,3.852 1.63237,1.951 2.44857,4.3598 2.4486,7.2264 -3e-5,2.3889 -0.56739,4.4891 -1.70207,6.3007 -1.11484,1.8115 -2.71738,3.1851 -4.80762,4.1208 -2.09029,0.9157 -4.97685,1.3835 -8.65968,1.4034 l 15.79645,20.4249 -5.43469,0 -15.7666,-20.4249 -2.50832,0 0,20.4249 -4.38956,0 0,-43.9254 m 4.38956,4.2999 0,14.9305 7.55483,0.06 c 2.92635,10e-5 5.08629,-0.2786 6.47983,-0.8361 1.41339,-0.5573 2.50829,-1.4432 3.2847,-2.6576 0.79627,-1.2342 1.19441,-2.6078 1.19444,-4.1208 -3e-5,-1.4731 -0.39817,-2.8069 -1.19444,-4.0014 -0.79631,-1.2143 -1.84145,-2.0803 -3.1354,-2.5979 -1.294,-0.5175 -3.44398,-0.7763 -6.44997,-0.7764 l -7.73399,0" />
<path
inkscape:connector-curvature="0"
id="path3899"
style="font-size:61.15526199px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#006080;fill-opacity:1;stroke:#003040;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;font-family:Century Gothic;-inkscape-font-specification:Century Gothic"
d="m 533.74861,355.80398 5.07637,0 11.22772,18.0957 11.04856,-18.0957 5.07636,0 -13.91521,22.9332 0,20.9922 -4.32984,0 0,-20.9922 -14.18396,-22.9332" />
<path
inkscape:export-ydpi="200.35001"
inkscape:export-xdpi="200.35001"
inkscape:export-filename="/Users/cignoni/devel/vcglib/docs/Doxygen/img/text3830.png"
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path3864"
d="m 241.37207,167.72938 -105,180 210,0 z"
inkscape:transform-center-y="-5.3460821"
inkscape:transform-center-x="-1.0790028"
style="fill:#006080;fill-opacity:1;stroke:#003040;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
inkscape:export-ydpi="200.35001"
inkscape:export-xdpi="200.35001"
inkscape:export-filename="/Users/cignoni/devel/vcglib/docs/Doxygen/img/text3830.png"
style="fill:#006080;fill-opacity:1;stroke:#003040;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
inkscape:transform-center-x="-1.0790028"
inkscape:transform-center-y="-5.3460821"
d="m 461.37207,167.72938 -105,180 210,0 z"
id="path3866"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
inkscape:export-ydpi="200.35001"
inkscape:export-xdpi="200.35001"
inkscape:export-filename="/Users/cignoni/devel/vcglib/docs/Doxygen/img/text3830.png"
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path3868"
d="m 351.37207,341.72938 -105,-180 210,0 z"
inkscape:transform-center-y="5.3460821"
inkscape:transform-center-x="-1.0790028"
style="fill:#006080;fill-opacity:1;stroke:#003040;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<g
style="font-size:108px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#003040;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;font-family:Century Gothic;-inkscape-font-specification:Century Gothic"
id="text3870"
transform="translate(-28.85742,-922.82222)">
<path
d="m 235.87305,1174.7899 8.4375,0 25.68164,59.959 26.15625,-59.959 8.4375,0 -33.75,77.5723 -1.6875,0 -33.27539,-77.5723"
id="path3915"
inkscape:connector-curvature="0" />
</g>
<g
style="font-size:108px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#003040;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;font-family:Century Gothic;-inkscape-font-specification:Century Gothic"
id="text3874"
transform="translate(-28.85742,-922.82222)">
<path
d="m 524.26953,1187.8153 -6.01172,5.6953 c -4.32429,-4.2538 -9.07038,-7.4706 -14.23828,-9.6504 -5.13287,-2.2147 -10.14263,-3.3222 -15.0293,-3.3222 -6.08207,0 -11.88285,1.4942 -17.40234,4.4824 -5.4844,2.9883 -9.7383,7.0489 -12.76172,12.1816 -3.02345,5.0977 -4.53517,10.4942 -4.53515,16.1895 -2e-5,5.836 1.56443,11.3906 4.69335,16.664 3.12889,5.2383 7.4531,9.3692 12.97266,12.3926 5.5195,2.9883 11.56636,4.4824 18.14063,4.4824 7.98041,0 14.7304,-2.25 20.25,-6.75 5.51945,-4.4999 8.78898,-10.3359 9.80859,-17.5078 l -24.73242,0 0,-7.4883 33.43359,0 c -0.0704,11.9884 -3.63876,21.5157 -10.70508,28.5821 -7.03132,7.0312 -16.45318,10.5469 -28.26562,10.5469 -14.34379,0 -25.69924,-4.8868 -34.06641,-14.6602 -6.4336,-7.5234 -9.65039,-16.2246 -9.65039,-26.1035 0,-7.3476 1.8457,-14.1855 5.53711,-20.5137 3.69139,-6.328 8.75389,-11.2675 15.1875,-14.8183 6.43356,-3.5859 13.7109,-5.3789 21.83203,-5.379 6.57417,10e-5 12.76166,1.1954 18.5625,3.586 5.80071,2.3555 11.46086,6.1524 16.98047,11.3906"
id="path3909"
inkscape:connector-curvature="0" />
</g>
<g
style="font-size:108px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#003040;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;font-family:Century Gothic;-inkscape-font-specification:Century Gothic"
id="text3878"
transform="translate(-28.85742,-922.82222)">
<path
d="m 415.11328,1120.3759 -6.11719,4.6933 c -3.37507,-4.3945 -7.43561,-7.7167 -12.18164,-9.9668 -4.71099,-2.2851 -9.89653,-3.4276 -15.55664,-3.4277 -6.18754,10e-5 -11.918,1.4942 -17.1914,4.4824 -5.27347,2.9532 -9.36917,6.9434 -12.28711,11.9707 -2.88283,4.9922 -4.32424,10.6172 -4.32422,16.875 -2e-5,9.4571 3.23436,17.3496 9.70312,23.6777 6.50388,6.3282 14.69528,9.4922 24.57422,9.4922 10.86322,0 19.95111,-4.2539 27.26367,-12.7617 l 6.11719,4.6406 c -3.86726,4.9219 -8.70124,8.7364 -14.50195,11.4434 -5.76569,2.6719 -12.21685,4.0078 -19.35352,4.0078 -13.57034,0 -24.27541,-4.5176 -32.11523,-13.5527 -6.57423,-7.6289 -9.86134,-16.8398 -9.86133,-27.6328 -10e-6,-11.3555 3.97265,-20.9004 11.91797,-28.6348 7.98044,-7.7695 17.96481,-11.6542 29.95312,-11.6543 7.24214,10e-5 13.78119,1.4415 19.61719,4.3242 5.83587,2.8477 10.61711,6.8556 14.34375,12.0235"
id="path3912"
inkscape:connector-curvature="0" />
</g>
<text
inkscape:export-ydpi="200.35001"
inkscape:export-xdpi="200.35001"
sodipodi:linespacing="125%"
id="text3882"
y="339.0191"
x="399.2916"
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
xml:space="preserve"><tspan
y="339.0191"
x="399.2916"
id="tspan3884"
sodipodi:role="line"> </tspan></text>
<text
xml:space="preserve"
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
x="780"
y="252.36218"
id="text3917"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3919"
x="780"
y="252.36218">&lt;--This is as path (no font!)</tspan></text>
<text
sodipodi:linespacing="125%"
id="text3921"
y="712.36218"
x="760"
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
xml:space="preserve"><tspan
y="712.36218"
x="760"
id="tspan3923"
sodipodi:role="line">&lt;--This is as text (need the Century Gothic font!)</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -1,4 +1,4 @@
/** \mainpage /** \mainpage The VCG Library
The Visualization and Computer Graphics Library (VCG for short) is The Visualization and Computer Graphics Library (VCG for short) is
a open source portable C++ templated library for manipulation, processing a open source portable C++ templated library for manipulation, processing
and displaying with OpenGL of triangle and tetrahedral meshes. and displaying with OpenGL of triangle and tetrahedral meshes.
@ -6,7 +6,7 @@ and displaying with OpenGL of triangle and tetrahedral meshes.
The library, composed by more than 50k lines of code, The library, composed by more than 50k lines of code,
is released under the GPL license, and it is the base of most of the is released under the GPL license, and it is the base of most of the
software tools of the <b>Visual Computing Lab</b> of the Italian National Research Council Institute ISTI software tools of the <b>Visual Computing Lab</b> of the Italian National Research Council Institute ISTI
(http://vcg.isti.cnr.it), like metro and shadevis. (http://vcg.isti.cnr.it), like metro and MeshLab.
The VCG library was built to manage triangular meshes, so most of the classes The VCG library was built to manage triangular meshes, so most of the classes
@ -18,7 +18,16 @@ stored and how it is used to visit the mesh. This part of the library is self
contained, only standard libraries are included, as STL (which are intensively contained, only standard libraries are included, as STL (which are intensively
used all over the code). used all over the code).
\section Intro Point3 as an example of the style
- \subpage install "Installing the VCG Library"
- \subpage basic_concepts "Basic Concepts"
- \subpage adjacency "Adjacency and Topology"
- \subpage allocation "Creating and destroying elements"
- \subpage attributes "Adding user defined attributes to mesh elements"
Point3 as an example of the style
--------
We won't going through all of the files and classes of the library to show how We won't going through all of the files and classes of the library to show how
it is built. You will find most of the information in the code as comments, and it is built. You will find most of the information in the code as comments, and
when understood the implementation flavor, you won't even need the comments. when understood the implementation flavor, you won't even need the comments.
@ -53,29 +62,4 @@ implementing the operator used in the bodies of Point3 operators). Another
common characteristic is the access method to the data (in this case v[3]), common characteristic is the access method to the data (in this case v[3]),
which are always defined as private member. which are always defined as private member.
\subsection ind Indexing and numbering conventions */
Vertex edges, and wedges are ordered according the following convention: face should be seen their vertexes counterclockwise, edge \c i is the one formed by vertex \c i and \c i+1.
\image html img/triord.png "Naming conventions for vertexes and edges"
For a tetrahedrdon we assume that it is \i well-oriented when the vertex \c 0 sees the other vertexes \c 1 2 3 in a counter-clockwise manner
\subsection fft Face-face Topology
With the face-face topology every face has three pointers to Face and three
integers. Given a face with FF topology the pointer \c f.F(i) points to the face that shares the edge \c i with
\c f , and the integer \c f.Z(i) tells the number of edge \c f.i as seen from face
\c f.F(i) (see Figure ).
If the edge \c f.i is on the mesh border, \c f.F(i)==f. The following
proposition holds: \n
\code
(f.F(i)== &f) || (f.F(i))->F(f.Z(i))== &f
\endcode
some text
\image html img/ff.png "Example of face-face topology"
*/

31
docs/Doxygen/install.dxy Normal file
View File

@ -0,0 +1,31 @@
/** \page install
Installation and folder structure
================
VCG Lib uses a SVN repository. To get the right subset of the svn trunk in the devel folder you should issue the following svn command:
svn co https://vcg.svn.sourceforge.net/svnroot/vcg/trunk/vcglib vcglib
Windows users with tortoisesvn (http://www.tortoisesvn.net) installed should
1. create a folder named vcglib.
2. right-click in the newly created vcglib folder and choose SVN Checkout
3. put in the first parameter: https://vcg.svn.sourceforge.net/svnroot/vcg/trunk/vcglib
4. press ok and wait, it should start to check out the last revision of the whole tree.
Folder Structure
================
VCG Lib is mostly made of header files (and its core part it's only header files).
Just download the tarball from here and uncompress it in a folder, e.g. named vcg, inside you compiler "include" directory.
Afterwards, you have to just include the file you need.
Inside vcg folder you will find 4 sub-folders:
- `vcg`: this is the core of the library, where all the algorithms and data structures are defined. This part is pure, quite heavily templated, C++ code with STL support for common data structures and algorithms. You will not find a single include from here to anything else than standard libraries. Note that core part is made of header files (.h files) only.
- `wrap`: here you will find the wrapping of VCG concepts towards specific needs/contexts/libraries. For example you will find all the code to import/export meshes from the hard disk in many formats, or the routines for rendering triangle meshes with OpenGL, supports for common GUI tools like a trackball, and so on..
- `apps`: this folder contains the command line applications developed with the VCG Lib. Many (much more) examples can be found in MeshLab. The apps/simple directory contains a sub-collection of very basic apps. A good starting point for beginners!
- `docs`: documentation lives here (including this tutorial)
*/

View File

@ -0,0 +1,143 @@
/** \page basic_concepts
Basic Concepts
==============
How to define a mesh type
-------------------------
The VCG Lib encodes a mesh as a set of vertices and triangles (i.e. triangles for triangle meshes, tetrahedra for tetrahedral meshes). The following line will be a part of the definition of a VCG type of mesh:
\code
class MyMesh : public vcg::TriMesh< std::vector<MyVertex>, std::vector<MyFace> > {}
vcg::TriMesh is the base type for a triangle mesh and it is templated on:
\endcode
the type of STL container containing the vertices
which in turn is templated on your vertex type
the type of STL container containing the faces
which in turn is templated on your face type
The face and the vertex type are the crucial bits to understand in order to be able to take the best from VCG Lib. A vertex, an edge, a face and a tetrahedron are just an user defined (possibly empty) collection of attributes. For example you will probably expect MyVertex to contain the (x,y,z) position of the vertex, but what about the surface normal at the vertex?.. and the color? VCG Lib gives you a pretty elegant way to define whichever attributes you want to store in each vertex, face, or edge. For example, the following example shows three valid definitions of MyVertex :
\code
#include <vcg/simplex/vertex/base.h>
#include <vcg/simplex/vertex/component.h>
class MyFace;
class MyEdge;
class MyVertex0 : public vcg::VertexSimp2<MyVertex0, MyEdge, MyFace,
vcg::vertex::Coord3d,
vcg::vertex::Normal3f> {};
class MyVertex1 : public vcg::VertexSimp2<MyVertex1, MyEdge, MyFace,
vcg::vertex::Coord3d,
vcg::vertex::Normal3f,
vcg::vertex::Color4b> {};
class MyVertex2 : public vcg::VertexSimp2<MyVertex2, MyEdge,MyFace> {};
\endcode
`vcg::VertexSimp2` is the VCG base class for a vertex belonging to a 2-simplex. If we were to define a tetraedral mesh, for example, we would have used vcg::VertexSimp3. The first 3 templates of vcg::VertexSimp2 must specify the type of all the simplicies involved in the mesh in ascending order: the vertex type itself, the type of edge and the type of triangle (and the type of tetrahedron for the tetrahedral meshes). It can be annoying when you see it but it is useful that every entity involved knows the type of the others and this is the way VCG Lib does it. As you can see the three definitions of MyVertex differ for the remaining template parameters. These specify which attributes will be stored with the vertex type: MyVertex0 is a type storing coordinates as a triple of doubles and normal as a triple of floats, MyVertex1 also store a color value specified as 4 bytes and MyVertex2 does not store any attribute, is an empty class. vcg::Coord3d, vcg::Normal3f, vcg::Color4b and many others are implemented in VCG, their complete list can be found here. You can place any combination of them as a template parameters of your vertex (your simplex) type.
Now we have all it takes for a working definition of MyMesh type:
\code
#include <vector>
#include <vcg/simplex/vertex/base.h>
#include <vcg/simplex/vertex/component.h>
#include <vcg/simplex/face/base.h>
#include <vcg/simplex/face/component.h>
#include <vcg/complex/trimesh/base.h>
class MyEdge;
class MyFace;
class MyVertex : public vcg::VertexSimp2<MyVertex, MyEdge, MyFace,
vcg::vertex::Coord3d,
vcg::vertex::Normal3f> {};
class MyFace : public vcg::FaceSimp2<MyVertex, MyEdge, MyFace,
vcg::face::VertexRef> {};
class MyMesh : public vcg::tri::TriMesh<
std::vector<MyVertex>, std::vector<MyFace> > {};
int main()
{
MyMesh m;
return 0;
}
\endcode
One more comment: vcg::VertexRef is an attribute that stores 3 pointers to the type of vertex, so implementing the Indexed Data structure. This is an example of why the type MyFace needs to know the type MyVertex
note: Although we left the STL type of container of vertices and faces as a template parameter, at the current state many kernel algorithms of VCG Lib assumes they are STL vector, so if you pass a std::list or a map your use of the library will be wuite limited.
How to create a mesh
====================
Once you declared your mesh type, you may want to instance an object and to fill it with vertexes and triangles. It may cross your mind that you could just make some push_back on the vertexes and faces container (data member vert and face of class vcg::tri::Trimesh). In fact this is the wrong way since there can be side effects by adding element to a container. We describe this issue and the correct way of adding mesh element in the Allocation page.
The flags of the mesh elements
------------------------------
Usually to each element of the mesh we associate a small bit vector containing useful single-bit information about vertices and faces. For example the deletion of vertex simply mark a the Deletion bit in thsi vector (more details on the various deletion/allocation issues in the Allocation page. More details on the various kind of flags that can be associated are in the Flags page.
How to process a mesh
---------------------
The algorithms that do something on a mesh are generally written as static member functions of a class templated on the mesh type. For example the code snipped below is part of the class UpdateNormals, which contains the several algorithms to compute the value of the normal
\code
vcg/complex/trimesh/update/normal.h
...
template <class ComputeMeshType>
class UpdateNormals{
...
// Calculates the vertex normal (if stored in the current face type)
static void PerFace(ComputeMeshType &m)
// Calculates the vertex normal. Without exploiting or touching face normals
// The normal of a vertex v is the weigthed average of the normals of the faces incident on v.
static void PerVertex(ComputeMeshType &m)
// Calculates both vertex and face normals.
// The normal of a vertex v is the weigthed average of the normals of the faces incident on v.
static void PerVertexPerFace(ComputeMeshType &m)
...
};
\endcode
This class is part of a kernel of classes with name UpdateValue that compute the value of the vertex or face attributes and that can be found altogether in the folder vcg/complex/trimesh/update. For example, the following example show how to compute the value of the normal and the mean and gaussian curvature per vertex:
\code
#include <vector>
#include <vcg/simplex/vertex/base.h>
#include <vcg/simplex/vertex/component.h>
#include <vcg/simplex/face/base.h>
#include <vcg/simplex/face/component.h>
#include <vcg/complex/trimesh/base.h>
#include <vcg/complex/trimesh/update/normals.h> //class UpdateNormals
#include <vcg/complex/trimesh/update/curvature.h> //class UpdateCurvature
class MyEdge;
class MyFace;
class MyVertex: public vcg::VertexSimp2<MyVertex,MyEdge,MyFace, vcg::vertex::Coord3d, vcg::vertex::Normal3f,vcg::vertex::Curvaturef>{};
class MyFace: public vcg::FaceSimp2<MyVertex,MyEdge,MyFace, vcg::face::VertexRef>{};
class MyMesh: public vcg::tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace> > {};
int main()
{
MyMesh m;
// fill the mesh
...
// compute the normal per-vertex -> update the value of v.N() forall v (vcg::vertex::Normal3f)
vcg::tri::UpdateNormals<MyMesh>::PerVertexPerFace(m);
// compute the curvature per-vertex -> update the value of v.H() and v.K() (vcg::vertex::Curvaturef)
vcg::tri::UpdateCurvature<MyMesh>::MeanAndGaussian(m);
return 0;
}
\endcode
Other than algorithms that update values of the mesh attributes, VCG Lib provides algorithms to create a mesh from another source, for example from point sets (by means of the Ball Pivoting approach) or as isosurfaces from a volumetric dataset (by means of Marching Cubes algorithm). Those algorithm can be found in vcg/complex/trimesh/create/.
Finally, you can find algorithms for refinement (midpoint, Loop, Butterfly...), for smoothing, for closing holes and other that are not currently classified under any specific heading and that you can find under /vcg/complex/trimesh.
*/

View File

@ -1,5 +1,5 @@
/** /**
\page profva dd \page "VCG Library Coding Guide"
\section style VCG Library Coding Guide \section style VCG Library Coding Guide
\subsection naming Naming Rules \subsection naming Naming Rules
@ -112,4 +112,4 @@ Construct to build an object from different a integral type.</P>
</P> </P>
</BODY> </BODY>
</HTML> </HTML>
*/ */