From a315eceb3dd14c83823dc4261d1e7ca42dbb08e3 Mon Sep 17 00:00:00 2001 From: cignoni Date: Thu, 11 Oct 2012 10:36:05 +0000 Subject: [PATCH] updated documentation (converted shot and camera...) --- docs/Doxygen/attributes.dxy | 67 +++--------------- docs/Doxygen/doxyfile | 16 +++-- docs/Doxygen/examples.dxy | 15 ++++- docs/Doxygen/groups.dxy | 57 ++++++++++++---- docs/Doxygen/img/shot-Camera_model.png | Bin 0 -> 37995 bytes docs/Doxygen/img/shot-Distort1.jpg | Bin 0 -> 4133 bytes docs/Doxygen/img/shot-Distort2.jpg | Bin 0 -> 7230 bytes docs/Doxygen/img/shot-Distort3.jpg | Bin 0 -> 3061 bytes docs/Doxygen/img/shot-Focal.jpg | Bin 0 -> 3239 bytes docs/Doxygen/img/shot-Projection.png | Bin 0 -> 2964 bytes docs/Doxygen/index.dxy | 74 ++++++++------------ docs/Doxygen/main_concept.dxy | 90 +++++++++++++++---------- docs/Doxygen/shot.dxy | 78 +++++++++++++++++++++ 13 files changed, 237 insertions(+), 160 deletions(-) create mode 100644 docs/Doxygen/img/shot-Camera_model.png create mode 100644 docs/Doxygen/img/shot-Distort1.jpg create mode 100644 docs/Doxygen/img/shot-Distort2.jpg create mode 100644 docs/Doxygen/img/shot-Distort3.jpg create mode 100644 docs/Doxygen/img/shot-Focal.jpg create mode 100644 docs/Doxygen/img/shot-Projection.png create mode 100644 docs/Doxygen/shot.dxy diff --git a/docs/Doxygen/attributes.dxy b/docs/Doxygen/attributes.dxy index fc3c59ac..dbd3c939 100644 --- a/docs/Doxygen/attributes.dxy +++ b/docs/Doxygen/attributes.dxy @@ -10,69 +10,22 @@ Conceptually the difference is that with the term component VCGLib indicates tho 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 -#include -#include -#include -#include -#include +\dontinclude trimesh_attribute.cpp +\skip include +\until main +\until } -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> {}; +You also have functions to check if a given attribute exists, retrieve an handle for it and eventually deleting it (using the handle or by name). +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. -class MyMesh : public vcg::tri::TriMesh< std::vector, std::vector > {}; - -float Irradiance(MyMesh::VertexType v){ - // ..... - return 1.0; -} +\until } -int main() -{ - MyMesh m; - //...here m is filled - - // add a per-vertex attribute with type float named "Irradiance" - MyMesh::PerVertexAttributeHandle ih = vcg::tri::Allocator::AddPerVertexAttribute (m,std::string("Irradiance")); - - // add a per-vertex attribute with type float named "Radiosity" - vcg::tri::Allocator::AddPerVertexAttribute (m,std::string("Radiosity")); - - // add a per-vertex attribute with type bool and no name specified - MyMesh::PerVertexAttributeHandle blocked_h = vcg::tri::Allocator::AddPerVertexAttribute (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 rh = vcg::tri::Allocator::GetPerVertexAttribute(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::DeletePerVertexAttribute(m,"Radiosity"); - - // you can delete an attibute by handle - vcg::tri::Allocator::DeletePerVertexAttribute(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. +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 --------------------------------- @@ -88,4 +41,4 @@ 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. -*/ \ No newline at end of file +*/ diff --git a/docs/Doxygen/doxyfile b/docs/Doxygen/doxyfile index 7e144633..41c3b8c2 100644 --- a/docs/Doxygen/doxyfile +++ b/docs/Doxygen/doxyfile @@ -32,7 +32,7 @@ PROJECT_NAME = "VCG Library" # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 0.1 +PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer @@ -45,7 +45,7 @@ PROJECT_BRIEF = # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. -PROJECT_LOGO = +PROJECT_LOGO = /Users/cignoni/Documents/devel/vcglib/docs/Doxygen/img/vcglogo.png # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. @@ -386,7 +386,7 @@ EXTRACT_STATIC = NO # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. -EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in @@ -666,7 +666,9 @@ WARN_LOGFILE = # with spaces. INPUT = . \ - ../../vcg/complex/algorithms/update + ../../vcg/complex/algorithms/update \ + ../../apps/sample/trimesh_base \ + ../../apps/sample/trimesh_attribute # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is @@ -731,7 +733,7 @@ EXCLUDE_SYMBOLS = # directories that contain example code fragments that are included (see # the \include command). -EXAMPLE_PATH = +EXAMPLE_PATH = ../../apps/sample/trimesh_base # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp @@ -795,7 +797,7 @@ FILTER_SOURCE_PATTERNS = # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. -SOURCE_BROWSER = NO +SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. @@ -849,7 +851,7 @@ VERBATIM_HEADERS = NO # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. -ALPHABETICAL_INDEX = NO +ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns diff --git a/docs/Doxygen/examples.dxy b/docs/Doxygen/examples.dxy index 4f8eca60..ff5e6e36 100644 --- a/docs/Doxygen/examples.dxy +++ b/docs/Doxygen/examples.dxy @@ -1,2 +1,13 @@ -/** \page Examples -\* +/** +\page examples + +There are a number of very simple and short examples meant to document the various features of the library. + +trimesh_base.cpp + +trimesh_attribute.cpp + +trimesh_normal.cpp + + +*/ diff --git a/docs/Doxygen/groups.dxy b/docs/Doxygen/groups.dxy index 53d5527e..0fb3dd6f 100644 --- a/docs/Doxygen/groups.dxy +++ b/docs/Doxygen/groups.dxy @@ -1,18 +1,49 @@ /** \defgroup space Space -This module contains all the basic types for representing spatial entities like points (vcg::Point3) box3, line planes etc. This module contains the documentation for the types and the functions used for... */ - /** \defgroup math Math This module contains the documentation for the types and the functions used for representing and managing mathematical entities. +This module contains all the basic types for representing spatial entities like points (vcg::Point3) box3, line planes etc. +This module contains the documentation for the types and the functions used for... */ - /** \defgroup simplex Simplexes The moudule containing the various simplicial complexes -*/ //@{ -/** \defgroup vertex Vertexes Vertex of edge, triangular and tetrahedral meshes This module contains the documentation for the types and the functions used for representing and managing vertexes of meshes. -*/ -/** \defgroup face Faces Face of a triangular or a tetrahedral mesh -*/ /** \defgroup tetra Tetrahedra Tetrahedral element of a tetrahedral complex. -*/ //@} /** \defgroup complex Complexes The moudule containing the various simplicial complexes -*/ //@{ /** \defgroup edgemesh Edge Meshes (i.e. PolyLines) This module contains the documentation for the types and the functions used for representing and managing generic polylines, or in other words \b edge\b meshes. + +/** \defgroup math Math +This module contains the documentation for the types and the functions used for representing and managing mathematical entities. */ - /** \defgroup trimesh Triangular Meshes This module contains the documentation for the types and the functions used for representing and managing generic \b triangular \b meshes. -*/ /** \defgroup tetramesh Tetrahedral Meshes This module contains the documentation for the types and the functions used for representing and managing generic tetrahedral of meshes. -*/ //@} \ No newline at end of file + +/** \defgroup simplex Simplexes +The module containing the various simplicial complexes +*/ +//@{ +/** \defgroup vertex Vertexes +Vertex of edge, triangular and tetrahedral meshes +This module contains the documentation for the types and the functions used for representing and managing vertexes of meshes. +*/ +/** \defgroup face Faces +Face of a triangular or a tetrahedral mesh +*/ + +//@} + +/** \defgroup complex Complexes +The module containing the various simplicial complexes +*/ + +//@{ + +/** \defgroup edgemesh Edge Meshes (i.e. PolyLines) +This module contains the documentation for the types and the functions used for representing and managing generic polylines, or in other words \b edge\b meshes. +*/ + +/** \defgroup trimesh Triangular Meshes +This module contains the documentation for the types and the functions used for representing and managing generic \b triangular \b meshes. +*/ + +/** \defgroup tetramesh Tetrahedral Meshes +This module contains the documentation for the types and the functions used for representing and managing generic tetrahedral of meshes. +*/ + +//@} + +/** \defgroup code_sample Code Examples +This module contains a number of small examples to explain the library features +*/ + diff --git a/docs/Doxygen/img/shot-Camera_model.png b/docs/Doxygen/img/shot-Camera_model.png new file mode 100644 index 0000000000000000000000000000000000000000..6c30e909c99b4cc3b284817ef87eb76df874f233 GIT binary patch literal 37995 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 J%bVW({{Z&E(EtDd literal 0 HcmV?d00001 diff --git a/docs/Doxygen/img/shot-Distort1.jpg b/docs/Doxygen/img/shot-Distort1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..97effe9bc1fcfe6ec54093f744d7206f9561b8d1 GIT binary patch literal 4133 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 literal 0 HcmV?d00001 diff --git a/docs/Doxygen/img/shot-Projection.png b/docs/Doxygen/img/shot-Projection.png new file mode 100644 index 0000000000000000000000000000000000000000..f05a22a1886c457e28ecc8312cf7276a852b8d12 GIT binary patch literal 2964 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 Computing Lab of the Italian National Research Council Institute ISTI (http://vcg.isti.cnr.it), like metro and MeshLab. -The VCG library was built to manage triangular meshes, so most of the classes -and algorithms it contains are related to such object. This is especially true -for the things that are in the "mesh" folder of the tree. This document -basically explains how the concept of mesh is implemented, i.e. what the "type" -of a mesh is and how it can be obtained, how the connectivity of the mesh is -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 -used all over the code). +The VCG library is tailored to mostly manage triangular meshes: +The library is fairly large and offers many state of the art functionalities for processing meshes, like: +- high quality simplfication, +- efficient spatial query structures (uniform grids, hashed grids, kdtree, ...) , +- advanced smoothing and fairing algorithms, +- computation of curvature, +- optimization of texture coordinates, +- Hausdorff distance computation, +- Geodesic paths +- mesh repairing capabilities and many many other. +- isosurface extraction and advancing front meshing algorithms +- subdivision surfaces +Documentation +------- +Start from the following pages for basic concepts and needs. - \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" - \subpage fileformat "Loading and saving meshes" +- \subpage shot "Camera and shot abstraction for managing views" +- \subpage examples "Short Examples showing various features of the lib" +Notable Applications +------- +A number of applications have been developed using the vcglib: +- MeshLab: the renowed open source mesh processing is based on this library. +- \subpage metro "Metro, the tool for measuring differences between meshes" - -Point3 as an example of the style --------- -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 -when understood the implementation flavor, you won't even need the comments. - -The definition of class Point3 looks like this: - -\code - - template class Point3 { - public: - Point3() { } - ~Point3() { } - - private: - T _v[3]; -// .... -// .... - public: - T & X(){return v[0];} - T & Y(){return v[1];} - T & Z(){return v[2];} - -// ...... operators - }; -\endcode - - -You will find that most of (if not all of) the classes have some template -parameters. In this case it is used to say which type is used as coordinate -(most of the times it will be float or double, but it can be any type -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]), -which are always defined as private member. +Contacts +------- +For any info about licensing the (portion of the library) please contact us:
+ Paolo Cignoni (p.cignoni@isti.cnr.it)
+ Fabio Ganovelli (f.ganovelli@isti.cnr.it)
+Visual Computing Lab of the Italian National Research Council Institute ISTI */ diff --git a/docs/Doxygen/main_concept.dxy b/docs/Doxygen/main_concept.dxy index 59550ae3..740ab863 100644 --- a/docs/Doxygen/main_concept.dxy +++ b/docs/Doxygen/main_concept.dxy @@ -1,94 +1,104 @@ /** \page basic_concepts - How to define a mesh type -========================= +===== 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::tri::TriMesh< std::vector, std::vector > {} \endcode -where `vcg::TriMesh` is the base type for a triangle mesh and it is templated on: +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 + - 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 + - which in turn is templated on your face type Another valid example is: \code class MyMesh : public vcg::tri::TriMesh< std::vector ,std::vector,std::vector > {} -\endcode + \endcode -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`. +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 +#include +#include class MyVertex; class MyFace; class MyEdge; class MyUsedTypes: public vcg::UsedTypes< vcg::Use::AsVertexType, - vcg::Use::AsEdgeType, - vcg::Use::AsFaceType> {}; + vcg::Use::AsEdgeType, + vcg::Use::AsFaceType> {}; class MyVertex0 : public vcg::Vertex {}; class MyVertex1 : public vcg::Vertex {}; class MyVertex2 : public vcg::Vertex {}; \endcode - -`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 +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). +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 +#include + +#include +#include +#include +#include + +#include class MyVertex; class MyFace; class MyUsedTypes: public vcg::UsedTypes< vcg::Use::AsVertexType>, - vcg::Use ::AsFaceType> + vcg::Use::AsFaceType> class MyVertex : public vcg::Vertex {}; -class MyFace : public vcg::Face {}; -class MyMesh : public vcg::tri::TriMesh< std::vector, std::vector > {}; +class MyFace : public vcg::Face {}; +class MyMesh : public vcg::tri::TriMesh< std::vector, std::vector > {}; int main() { MyMesh m; return 0; } -\endcode -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 +\endcode + +One more comment: vcg::VertexRef is an attribute that stores 3 pointers to the type of vertex, so implementing the Idexed 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. 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: +------------ +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 Append utility class: \code -#include + #include MyMesh ml,mr; ... tri::Append::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. + +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 UpdateNormals{ @@ -99,7 +109,7 @@ 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) @@ -108,18 +118,26 @@ 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 -#include //class UpdateNormals + +#include + +#include +#include +#include +#include + +#include +#include //class UpdateNormals #include //class UpdateCurvature class MyVertex; class MyFace; class MyUsedTypes: public vcg::UsedTypes< vcg::Use::AsVertexType>, - vcg::Use::AsFaceType> + vcg::Use::AsFaceType> class MyVertex: public vcg::Vertex{}; -class MyFace: public vcg::Face< MyUsedTypes, vcg::face::BitFlags, vcg::face::VertexRef>{}; -class MyMesh: public vcg::tri::TriMesh< std::vector, std::vector > {}; +class MyFace: public vcg::Face{}; +class MyMesh: public vcg::tri::TriMesh< std::vector, std::vector > {}; int main() { @@ -135,7 +153,7 @@ int main() 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. -*/ + +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.*/ diff --git a/docs/Doxygen/shot.dxy b/docs/Doxygen/shot.dxy new file mode 100644 index 00000000..8514af79 --- /dev/null +++ b/docs/Doxygen/shot.dxy @@ -0,0 +1,78 @@ +/** +\page shot + +Viewing and manipulation +------------------------ +In this section, all that concerns the definition of a view and the manipulation of a mesh will be explained. + +Shot and camera +-------------- +This section presents the structure of the shot and camera of the library. +After an overview of the camera model used, all the components of the shot class are listed and described. +Then, a set of examples of the most important operations (projection and un-projection) and of the interactions between shots and between a shot and the trackball are presented. Finally, simple examples of a shot are visually shown, in order to help with the implementations of eventual wrapped to and from other shot-camera formats. + +The camera model + +In generale, the camera parameters can be divided in two groups: +- \b Extrinsic (or external) parameters: these are the parameters associated to the position in the space of the camera. + +- \bIntrinsic (or internal) parameters: these values are related to the peculiar characteristics of the camera, like the focal length (the zoom) or the distortion introduced by the lenses. + +If these group of values are put in a proper camera model, it is possible to transform any point in the space in the corresponding point on the image plane of the camera (and viceversa). + +\image html "../img/shot-Camera_model.png" An example scheme of a perspective camera model + + +In fact, given a simple perspective camera model like the one shown in figure, extrinsic parameters can be used to transform a point from its world coordinates {xw,yw,zw} to the camera 3D coordinate system {x,y,z}): +\image html "../img/shot-Projection.png" +In this case the extrinsic parameters are a 3 X 3 rotation matrix R and a translation vector T, which define the orientation and position of the camera. In order to transform the 3D camera coordinate in 2D image plane coordinates (Xu,Yu) it's necessary to know the measure of the distance between the point of view and the image plane (OO1 in figure): this value, indicated with f, is usually known as the focal length. The relation between the camera and image coordinates of the point can be expressed as follows: +\image html "../img/shot-Focal.jpg" + +Another aspect of the structure of a camera that can be characterized is the distortion introduced by the lenses: if we suppose that the distortion is radial (performed along the radial direction respect to the center of distortion) we can calculate the undistorted image coordinates + +\image html "../img/shot-Distort1.jpg" +where +\image html "../img/shot-Distort2.jpg" +and +\image html "../img/shot-Distort3.jpg" + +In conclusion, a quite accurate model of a camera can be described by: +- A 3x3 rotation matrix and a translation vector for extrinsic parameters +- The values of focal, center of distortion and one or more distortion coefficients for intrinsic parameters + +While this set of parameters provides everything to transform any 3D point in its corresponding point in the image plane, this could be not enough in peculiar applications. If an accurate estimation of the real position of the camera respect to the object is needed, some more data about the camera model are needed: in particular, the sensor physical size together with the resolution in pixel of the acquired image. If these a-priori data are known, a unique set of camera parameters is associated to any shot. + +The VCG Shot + +The implementation of a Shot in the VCG library can be found in vcg\math\shot.h + +The shot is composed by two elements: + +- the \b Extrinsics parameters, which are stored in the class Shot (in the type ReferenceFrame) that contains viewpoint and view direction. +The Extrinsics parameters are kept as a rotation matrix "rot" and a translation vector "tra" +NOTE: the translation matrix "tra" corresponds to -viewpoint while the rotation matrix "rot" +corresponds to the axis of the reference frame by row, i.e.
+rot[0][0 1 2] == X axis
+rot[1][0 1 2] == Y axis
+rot[2][0 1 2] == Z axis
+It follows that the matrix made with the upper left 3x3 equal to rot and the 4th column equal to tra and (0,0,0,1) in the bottom row transform a point from world coordinates to the reference frame of the shot. +- the \b Instrinsics parameters, which are stored as a Camera type (check vcg/math/camera) and that +determines how a point in the frame of the camera is projected in the 2D projection plane. This information was kept indendent of the extrinsic parameters because more than one shot can share the same intrinsic parameters set. + +The attributes of a Camera, which is define in vcg\math\shot.h, are: +\code +//------ camera intrinsics +ScalarType FocalMm; /// Focal Distance: the distance between focal center and image plane. Expressed in mm +Point2 ViewportPx; /// Dimension of the Image Plane (in pixels) +Point2< S> PixelSizeMm; /// Dimension in mm of a single pixel +Point2< S> CenterPx; /// Position of the projection of the focal center on the image plane. Expressed in pixels +Point2< S> DistorCenterPx; /// Position of the radial distortion center on the image plane in pixels +S k[4]; /// 1st & 2nd order radial lens distortion coefficient (only the first 2 terms are used) +//------------------------ +\endcode +While the extrinsic parameters usually change between the shots, some (sometimes all) of the intrinsics are strongly related to the camera model used. In particular, some values are usually known before camera calibration: viewportPx and CenterPx. Moreover, if an accurate calibration is needed, it is necessary to fill the PixelSizeMm value. + +This can be inferred from the camera datasheet (it can be calculated by dividing the sensor width and height, in mm, by the resolution of the image) or, in some cases, from the EXIF of the image (in the CANON models, it is the inverse of FocalPlane X-resolution and FocalPlane Y-resolution, scaled from inches to mm if necessary). If a correct PixelSizeMm is not set, the values of the camera parameters can be different from the real ones, even though the image is perfectly aligned to a 3D model. + +Also the focal distance can be inferred from EXIF, but its value is indicative. If a calibrated camera is used, then all the intrinsic parameters should be known in advance. +*/