user manual and examples for it

This commit is contained in:
Christina Vaz 2018-08-10 17:25:24 -04:00
parent 30bc4aa064
commit 9a1b05643c
4 changed files with 98 additions and 48 deletions

View File

@ -49,7 +49,7 @@ The sum is taken over all of the neighboring vertices \f$j\f$. Further, \f$\alph
From this, the symmetric positive-definite system \f$(M-tL_C)u = \delta_{\gamma}\f$ can be solved to find \f$u\f$ where \f$\delta_{\gamma}\f$ is the Kronecker delta over \f$\gamma\f$.
Next, the gradent in a given triangle can be expressed as:
Next, the gradient in a given triangle can be expressed as:
\f$\nabla \cdot X = \frac{1}{2} \sum_j cot\theta_1 (e_1 \cdot X_j) + cot \theta_2 (e_2 \cdot X_j)\f$
@ -67,46 +67,42 @@ Finally, let \f$b \in R^{|V|}\f$ be the integrated divergences of the normalized
The intrinsic Delaunay triangulation thus relies on edge lengths and angles, as does the heat method. The intrinsic Delaunay triangulation does not actually flip the edge. Instead, the edge flips are intrinsic and so the shape of the original embedded mesh does not change. Instead, the IDT mesh is considered as an abstract surface with a locally Euclidean metric. Instead of actually flipping an edge, the algorithm performs a combinatorial flip on it and updates its length. Thus, there is no change to the intrinsic geometry of the input mesh.
Let \f$ K = (V,E,T) \f$ be a 2-manifold triangle mesh, where \f$V\f$ is the vertex set, \f$ E \f$ is the edge set and \f$ T \f$ is the face set (triangle set). Let \f$ L \f$ be the set of Euclidean distances, where \f$ L(e_{ij}) = l_{ij} = || p_i - p_j || \f$ , where \f$ p_i \f$ and \f$ p_j \f$ are the point positions \f$ \in R^3 \f$ of vertices \f$ i \f$ and \f$ j \f$ respectively. Then, let the pair \f$ (K,L) \f$ be the input to the iDT algorithm which returns the pair \f$(\dot K, \dot L)\f$, which are the intrinsic Delaunay mesh and the intrinsic lengths. The algorithm is as follows:
\f$ \forall e \in E : Mark(e) \f$
Stack \f$ s \leftarrow E \f$
while !Empty(\f$s\f$) do
\f$e_{ij} \leftarrow \f$ Pop(\f$s\f$) and Unmark(\f$e_ij\f$)
if !Delaunay(\f$e_{ij}\f$) then
\f$e_{kl} \leftarrow\f$ Flip(\f$e_ij\f$) and compute the new length \f$l_{kl}\f$
for all \f$e \in {e_{kj}, e_{jl}, e_{li}, e_{ik}}\f$ do
if !Mark(\f$e\f$) then
Mark(\f$e\f$) and Push(\f$s,e\f$)
Let \f$ K = (V,E,T) \f$ be a 2-manifold triangle mesh, where \f$V\f$ is the vertex set, \f$ E \f$ is the edge set and \f$ T \f$ is the face set (triangle set). Let \f$ L \f$ be the set of Euclidean distances, where \f$ L(e_{ij}) = l_{ij} = || p_i - p_j || \f$ , where \f$ p_i \f$ and \f$ p_j \f$ are the point positions \f$ \in R^3 \f$ of vertices \f$ i \f$ and \f$ j \f$ respectively. Then, let the pair \f$ (K,L) \f$ be the input to the iDT algorithm which returns the pair \f$(\tilde K, \tilde L)\f$, which are the intrinsic Delaunay mesh and the intrinsic lengths. The algorithm is as follows:
\code
for all edge e in E : Mark(e)
Stack s <-- E
while !Empty(s) do
edge(ij) = Pop(s) and Unmark(edge(ij))
if !Delaunay(edge(ij)) then
edge(kl) = Flip(edge(ij)) and compute the new length length(kl) using the Cosine Theorem
for all edge e in {edge(kj), edge(jl), edge(li), edge(ik)} do
if !Mark(e) then
Mark(e) and Push(s,e)
end if
end for
end if
end while
return (~K,~L)
\endcode
return \f$(\dot K, \dot L)\f$ \f$\leftarrow (K,L)\f$
The new \f$(\dot K, \dot L)\f$ are used in the Heat Method distance computation.
The new \f$(\tilde K, \tilde L)\f$ are then used in the Heat Method distance computation.
\section sec_HM_examples Examples
\subsection HM_FirstExample First Example
\subsection HM_FirstExample Heat Method
The following example shows the heat method on a triangle mesh. The example adds the first vertex into the source set and then uses the heat_intensity property map to read the distance values.
\cgalExample{Heat_method_3/heat_method_surface_mesh.cpp}
The following example shows ...
\section sec_HM_history Design and Implementation History
\subsection HM_FirstExample Heat Method with Intrinsic Delaunay Triangulation
The following example shows the heat method on a triangle mesh using the intrinsic delaunay remeshing algorithm first. The distance values are then printed using the vertex_distance property map.
\cgalExample{Heat_method_3/heat_method_surface_mesh_intrinsic.cpp}
\section sec_HM_history Implementation History
A first version of this package was started by Christina Vaz, Keenan Crane and Andreas Fabri as part of the 2018 Google Summer of Code.
This package ...
*/
} /* namespace CGAL */

View File

@ -12,7 +12,7 @@ find_package( CGAL QUIET COMPONENTS )
if ( NOT CGAL_FOUND )
message(STATUS "This project requires the CGAL library, and will not be compiled.")
return()
return()
endif()
@ -27,7 +27,7 @@ if ( NOT Boost_FOUND )
message(STATUS "This project requires the Boost library, and will not be compiled.")
return()
return()
endif()
@ -36,7 +36,7 @@ find_package(Eigen3 3.1.0)
if (EIGEN3_FOUND)
include( ${EIGEN3_USE_FILE} )
else()
else()
message(STATUS "This project requires the Boost library, and will not be compiled.")
return()
@ -55,5 +55,4 @@ include( CGAL_CreateSingleSourceCGALProgram )
create_single_source_cgal_program( "heat_method_surface_mesh.cpp" )
create_single_source_cgal_program( "flip.cpp" )
create_single_source_cgal_program( "heat_method_surface_mesh_intrinsic.cpp" )

View File

@ -4,34 +4,40 @@
#include <iostream>
#include <fstream>
#include <boost/foreach.hpp>
#include <vector>
#include <iostream>
#include <string>
typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 Point;
typedef CGAL::Surface_mesh<Point> Mesh;
typedef boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
typedef Mesh::Property_map<vertex_descriptor, double> Vertex_distance_map;
typedef CGAL::Heat_method_3::Heat_method_3<Mesh,Kernel,Vertex_distance_map> Heat_method;
typedef Kernel::Point_2 Point_2;
typedef CGAL::Surface_mesh<Point> Surface_mesh;
typedef boost::graph_traits<Surface_mesh>::vertex_descriptor vertex_descriptor;
typedef Surface_mesh::Property_map<vertex_descriptor,double> Vertex_distance_map;
typedef CGAL::Heat_method_3::Heat_method_3<Surface_mesh,Kernel, Vertex_distance_map> Heat_method;
int main(int argc, char* argv[])
int main(int argc, char* argv[])
{
Mesh sm;
std::ifstream in(argv[1]);
//read in mesh
Surface_mesh sm;
const char* filename = (argc > 1) ? argv[1] : "../data/bunny.off";
std::ifstream in(filename);
in >> sm;
Vertex_distance_map heat_intensity =
sm.add_property_map<vertex_descriptor, double>("v:heat_intensity", 0).first;
//the heat intensity will hold the distance values from the source set
Vertex_distance_map heat_intensity = sm.add_property_map<vertex_descriptor, double>("v:heat_intensity", 0).first;
Heat_method hm(sm, heat_intensity);
//add the first vertex as the source set
vertex_descriptor source = *(vertices(sm).first);
hm.add_source(source);
hm.update();
BOOST_FOREACH(vertex_descriptor vd , vertices(sm)){
std::cout << vd << " is at distance " << hm.distance(vd) << " from " << source << std::endl;
std::cout << vd << " is at distance " << get(heat_intensity, vd) << " from " << source << std::endl;
}
std::cout << "done" << std::endl;
return 0;
}

View File

@ -0,0 +1,49 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Heat_method_3/Heat_method_3.h>
#include <CGAL/Heat_method_3/Intrinsic_Delaunay_Triangulation_3.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <iostream>
#include <string>
typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 Point;
typedef Kernel::Point_2 Point_2;
typedef CGAL::Surface_mesh<Point> Surface_mesh;
typedef boost::graph_traits<Surface_mesh>::vertex_descriptor vertex_descriptor;
typedef Surface_mesh::Property_map<vertex_descriptor,double> Vertex_distance_map;
typedef CGAL::Intrinsic_Delaunay_Triangulation_3::Intrinsic_Delaunay_Triangulation_3<Surface_mesh,Kernel, Vertex_distance_map> Idt;
typedef CGAL::Heat_method_3::Heat_method_3<Idt,Kernel, Idt::Vertex_distance_map> Heat_method_idt;
int main(int argc, char* argv[])
{
//read in mesh
Surface_mesh sm;
const char* filename = (argc > 1) ? argv[1] : "../data/bunny.off";
std::ifstream in(filename);
in >> sm;
//the vertex distance map will hold the distance values from the source set
Vertex_distance_map vdm_idt = sm.add_property_map<vertex_descriptor,double>("v:idt",0).first;
//first call the idt remeshing algorithm
Idt idt(sm, vdm_idt);
//pass in the idt object and its vertex_distance_map
Heat_method_idt hm_idt(idt, idt.vertex_distance_map());
//add the first vertex as the source set
vertex_descriptor source = *(vertices(sm).first);
hm_idt.add_source(source);
hm_idt.update();
BOOST_FOREACH(vertex_descriptor vd , vertices(sm)){
std::cout << vd << " is at distance " << get(vdm_idt, vd) << " from " << source << std::endl;
}
return 0;
}