improving doc
This commit is contained in:
parent
1aecce2033
commit
7d980456ea
|
@ -0,0 +1,45 @@
|
|||
/** \page fileformat
|
||||
File Formats
|
||||
============
|
||||
VCGLib provides importer and exporter for several file formats
|
||||
- import: PLY, STL, OFF, OBJ, 3DS, COLLADA, PTX, V3D, PTS, APTS, XYZ, GTS, TRI, ASC, X3D, X3DV, VRML, ALN
|
||||
- export: PLY, STL, OFF, OBJ, 3DS, COLLADA, VRML, DXF, GTS, U3D, IDTF, X3D
|
||||
|
||||
The following code snippet show how to use the PLY importer and exporter:
|
||||
\code
|
||||
#include <wrap/io_trimesh/import.h>
|
||||
// definition of type MyMesh
|
||||
MyMesh m;
|
||||
|
||||
vcg::tri::io::ImporterPLY<MyMesh>::Open(m,"namefile_to_open.ply");
|
||||
// ....
|
||||
vcg::tri::io::ExporterPLY<MyMesh>::Save(m,"namefile_to_save.ply");
|
||||
\endcode
|
||||
|
||||
The previous one is the minimal required interface for all the importers and exporters. Additionally two other parameters can be specified: *mask* and *callback*. The callback is used for providing a feedback during the usually length importing/exporting process. The mask is used to better specify/understand what is loaded/saved.
|
||||
|
||||
Saving Mask and Reading Mask
|
||||
----------------------------
|
||||
Generally all file formats save at least vertex positions and basic connectivity information, but beyond that you may want to choose which other data are stored with the file. To this aim, VCGLib provides a class `vcg::tri::io::Mask` which is essentially a collection of bit names that are used to specify which components you want to write to the file (e.g. stuff like `vcg::tri::io::Mask::IOM_VERTCOLOR`).
|
||||
|
||||
When __saving__ this mask is used in a READ ONLY mode (they are just constants) to specify what component you want to save. For example, if you have stored in your mesh normals per vertex (for rendering purposes) but you consider saving them in ply format just a waste of space, you should specify an appropriate mask with the `Mask::IOM_VERTNORMAL` bit cleared. Obviously not all the formats are able to save all the possible data. For example STL format cannot save texture coords or per vertex color. So to know what you are able to save in a given XXX format there is the function `ExporterXXX::GetExportMaskCapability()` that gives you a bitmask with all the capability of that file format.
|
||||
|
||||
When __loading__ this mask is used in a WRITE ONLY mode to report to the user what fields have been loaded from the file into the mesh (e.g. the initial value of the mask is ignored). In many cases it could be useful to know what data is present into a file to prepare the mesh (e.g. to enable optional components), for this purpose all the importer have also a `ImporterXXX::LoadMask(filename,mask)` that fill the mask only without effectively loading a mesh. Note that for some mesh formats understanding what is contained into a file means parsing the whole file.
|
||||
|
||||
Error Reporting
|
||||
---------------
|
||||
The mesh I/O functions returns ZERO on success and an error code different from zero in case of failure or critical conditions. Use the `static const char *ErrorMsg(int error)` function to get a human understandable description of the error code and static bool `ErrorCritical(int err)` to know if a given error is a critical one or just a warning. For example in the OBJ format the absence of the accompanying material description file, is considered non critical (you are able to get the correct geometry even if you miss material info).
|
||||
|
||||
VMI dump file
|
||||
-------------
|
||||
VMI is an acronym for Vcglib Mesh Image and it is not a proper file format but a simple dump of the `vcg::TriMesh` on a file. Not being a file format means that:
|
||||
there is no specification
|
||||
it is bound to the current version of the VCGLib with no backward compatibility
|
||||
a VMI can be very useful for debug purpose, because it saves:
|
||||
* all the components
|
||||
* all the temporary components (currently only of Optional Component Fast type)
|
||||
* all the vertex, face or mesh attributes you have in your mesh file
|
||||
So if, for example, your algorithm crashes at the n-th step, you can save intermediate results of your computation with VMI and reload it.
|
||||
Note that in order to load a VMI the mesh passed as template to `vcg::tri::ImporterVMI<MeshType>(..)` must be of the same type as the mesh passed to `vcg::tri::ExporterVMI<MeshType>(..)` otherwise the loader returns FALSE.
|
||||
|
||||
*/
|
|
@ -24,6 +24,8 @@ used all over the code).
|
|||
- \subpage adjacency "Adjacency and Topology"
|
||||
- \subpage allocation "Creating and destroying elements"
|
||||
- \subpage attributes "Adding user defined attributes to mesh elements"
|
||||
- \subpage fileformat "Loading and saving meshes"
|
||||
|
||||
|
||||
|
||||
Point3 as an example of the style
|
||||
|
|
|
@ -1,143 +1,141 @@
|
|||
/** \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:
|
||||
The VCG Lib may encode a mesh in several ways, the most common of which is a set of vertices and set of triangles (i.e. triangles for triangle meshes, tetrahedra for tetrahedral meshes). The following line is an example 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:
|
||||
class MyMesh : public vcg::tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace> > {}
|
||||
\endcode
|
||||
where `vcg::TriMesh` is the base type for a triangle mesh and it is templated on:
|
||||
- the type of STL random access container containing the vertices
|
||||
-- which in turn is templated on your vertex type
|
||||
- the type of STL random access container containing the faces
|
||||
-- which in turn is templated on your face type
|
||||
|
||||
Another valid example is:
|
||||
\code
|
||||
class MyMesh : public vcg::tri::TriMesh< std::vector<MyFace> ,std::vector<MyVertex>,std::vector<MyEdge> > {}
|
||||
\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 :
|
||||
In other words, to define a type of mesh you need only to derive from `vcg::tri::TriMesh` and to provide the type of containers of the elements you want to use to encode the mesh. In this second example we also passed a std::vector of type MyEdge, which, as we will see shortly, is the type of our edge. Note that there is no predefined order to follow for passing the template parameters to `TriMesh`.
|
||||
The face, the edge 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 attribute. 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>
|
||||
#include <vcg/complex/complex.h>
|
||||
|
||||
class MyFace;
|
||||
class MyEdge;
|
||||
class MyVertex;
|
||||
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> {};
|
||||
class MyUsedTypes: public vcg::UsedTypes< vcg::Use<MyVertex>::AsVertexType,
|
||||
vcg::Use<MyEdge >::AsEdgeType,
|
||||
vcg::Use<MyFace >::AsFaceType> {};
|
||||
|
||||
class MyVertex0 : public vcg::Vertex<MyUsedTypes, vcg::vertex::Coord3d, vcg::vertex::Normal3f> {};
|
||||
class MyVertex1 : public vcg::Vertex<MyUsedTypes, vcg::vertex::Coord3d, vcg::vertex::Normal3f,vcg::vertex::Color4b> {};
|
||||
class MyVertex2 : public vcg::Vertex<MyUsedTypes > {};
|
||||
\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.
|
||||
|
||||
`vcg::Vertex` is the VCG base class for a vertex.
|
||||
|
||||
`vcg::UsedTypes` declares which are the types invoved in the definition of the mesh. It is a mapping between the names of your entity types (MyVertex,MyEdge,MyFace... and the role they play in the mesh definition). The mapping is established passing the template parameters with the syntax
|
||||
\code
|
||||
vcg::Use<[name of your type] >::As[Vertex | Edge | Face | HEdge | Wedge]Type>
|
||||
\endcode
|
||||
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 values 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 value, it is just 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 entity) type (order is unimportant).
|
||||
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/complex.h>
|
||||
|
||||
#include <vcg/complex/trimesh/base.h>
|
||||
class MyVertex;
|
||||
class MyFace;
|
||||
|
||||
class MyEdge;
|
||||
class MyFace;
|
||||
class MyUsedTypes: public vcg::UsedTypes< vcg::Use<MyVertex>::AsVertexType>,
|
||||
vcg::Use<MyFace> ::AsFaceType>
|
||||
|
||||
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;
|
||||
}
|
||||
class MyVertex : public vcg::Vertex<MyUsedTypes, vcg::vertex::Coord3d, vcg::vertex::Normal3f> {};
|
||||
class MyFace : public vcg::Face <MyUsedTypes, 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.
|
||||
One more comment: `vcg::face::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
|
||||
|
||||
How to create a mesh
|
||||
====================
|
||||
--------------------
|
||||
Once you declared your mesh type, you may want to instance an object and to fill it with vertices 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.
|
||||
|
||||
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.
|
||||
How to copy a mesh
|
||||
------------------
|
||||
Given the intricate nature of the mesh itself it is severely forbidden any attempt of copying meshes as simple object. To copy a mesh you have to use the `try::Append` utility class:
|
||||
\code
|
||||
#include<vcg/complex/trimesh/append.h>
|
||||
|
||||
MyMesh ml,mr;
|
||||
...
|
||||
tri::Append<MyMesh>::Mesh(ml,mr);
|
||||
\endcode
|
||||
This is equivalent to append the content of `mr` onto `ml`. If you want simple copy just clear ml before calling the above function.
|
||||
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)
|
||||
/** vcg/complex/trimesh/update/normal.h */
|
||||
...
|
||||
template <class ComputeMeshType>
|
||||
class UpdateNormals{
|
||||
...
|
||||
// Calculates the face 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)
|
||||
...
|
||||
};
|
||||
// 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/complex/complex.h>
|
||||
#include <vcg/complex/trimesh/update/normals.h> //class UpdateNormals
|
||||
#include <vcg/complex/trimesh/update/curvature.h> //class UpdateCurvature
|
||||
|
||||
#include <vcg/simplex/vertex/base.h>
|
||||
#include <vcg/simplex/vertex/component.h>
|
||||
#include <vcg/simplex/face/base.h>
|
||||
#include <vcg/simplex/face/component.h>
|
||||
class MyVertex;
|
||||
class MyFace;
|
||||
class MyUsedTypes: public vcg::UsedTypes< vcg::Use<MyVertex>::AsVertexType>,
|
||||
vcg::Use<MyFace>::AsFaceType>
|
||||
|
||||
#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 MyVertex: public vcg::Vertex<MyUsedTypes, vcg::vertex::BitFlags,vcg::vertex::Coord3d, vcg::vertex::Normal3f,vcg::vertex::Curvaturef>{};
|
||||
class MyFace: public vcg::Face< MyUsedTypes, vcg::face::BitFlags, vcg::face::VertexRef>{};
|
||||
class MyMesh: public vcg::tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace> > {};
|
||||
|
||||
class MyEdge;
|
||||
class MyFace;
|
||||
int main()
|
||||
{
|
||||
MyMesh m;
|
||||
// fill the mesh
|
||||
...
|
||||
// compute the normal per-vertex -> update the value of v.N() for all v (vcg::vertex::Normal3f)
|
||||
vcg::tri::UpdateNormals<MyMesh>::PerVertexPerFace(m);
|
||||
|
||||
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> > {};
|
||||
// compute the curvature per-vertex -> update the value of v.H() and v.K() (vcg::vertex::Curvaturef)
|
||||
vcg::tri::UpdateCurvature<MyMesh>::MeanAndGaussian(m);
|
||||
|
||||
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;
|
||||
}
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
|
|
Loading…
Reference in New Issue