mirror of https://github.com/CGAL/cgal
Add an example with a Polyhedron_3
This commit is contained in:
parent
159360b1c8
commit
150c9c95de
|
|
@ -6,6 +6,10 @@ namespace CGAL {
|
||||||
\cgalAutoToc
|
\cgalAutoToc
|
||||||
\author Keenan Crane, Christina Vaz, Andreas Fabri
|
\author Keenan Crane, Christina Vaz, Andreas Fabri
|
||||||
|
|
||||||
|
\image html octopus.png
|
||||||
|
|
||||||
|
\section sec_HM_introduction Introduction
|
||||||
|
|
||||||
The <em>Heat Method</em> is an algorithm that solves the multiple-source
|
The <em>Heat Method</em> is an algorithm that solves the multiple-source
|
||||||
shortest path problem by returning the geodesic distance for all vertices
|
shortest path problem by returning the geodesic distance for all vertices
|
||||||
of a triangle mesh to the closest vertex in a given set of source vertices.
|
of a triangle mesh to the closest vertex in a given set of source vertices.
|
||||||
|
|
@ -17,12 +21,12 @@ The method works well on triangle meshes with.... For triangle meshes
|
||||||
that do not fulfill these requirements, applying edge flips to obtain an
|
that do not fulfill these requirements, applying edge flips to obtain an
|
||||||
<em>Intrinsic Delaunay Triangulation</em> also gives good results.
|
<em>Intrinsic Delaunay Triangulation</em> also gives good results.
|
||||||
|
|
||||||
\cgalFigureBegin{landscape_meshes, landscape_meshes.png}
|
\cgalFigureBegin{landscape_meshes, landscape.jpg}
|
||||||
Isolines placed on a mesh with and without iDT remeshing.
|
Isolines placed on a mesh with and without iDT remeshing.
|
||||||
\cgalFigureEnd
|
\cgalFigureEnd
|
||||||
|
|
||||||
In the next section we give examples. Section \ref sec_HM_definitions presents
|
In the next section we give some examples. Section \ref sec_HM_definitions presents
|
||||||
the mathematical background. The last section is about the \ref sec_HM_history.
|
the mathematical theory of the Heat method. The last section is about the \ref sec_HM_history.
|
||||||
|
|
||||||
Note that this package requires the third party \ref thirdpartyEigen library.
|
Note that this package requires the third party \ref thirdpartyEigen library.
|
||||||
This implementation is based on \cgalCite{cgal:cww-ghnac-13} and \cgalCite{cgal:fsbs-acidt-06}
|
This implementation is based on \cgalCite{cgal:cww-ghnac-13} and \cgalCite{cgal:fsbs-acidt-06}
|
||||||
|
|
@ -37,12 +41,20 @@ for the `Heat_method_3::Intrinsic_Delaunay_triangulation_3` class.
|
||||||
|
|
||||||
\subsection HM_example_Free_function Using a Free Function
|
\subsection HM_example_Free_function Using a Free Function
|
||||||
|
|
||||||
The first example calls a free function that computes the distances to a single source vertex.
|
The first example calls the free function `Heat_method_3::geodesic_distances_3()`
|
||||||
|
which computes for all vertices of a triangle mesh the distances to a single source vertex.
|
||||||
|
|
||||||
The distances are written into an internal property map of the surface mesh.
|
The distances are written into an internal property map of the surface mesh.
|
||||||
For a `Polyhedron_3` you can use a `std::map` passed to the function `make_assoc_property_map()`, instead.
|
|
||||||
|
|
||||||
\cgalExample{Heat_method_3/heat_method.cpp}
|
\cgalExample{Heat_method_3/heat_method.cpp}
|
||||||
|
|
||||||
|
For a `Polyhedron_3` you can either add a data field to the vertex type, or, as shown
|
||||||
|
in the following exampole create a `boost::unordered_map` and pass it to the function
|
||||||
|
`boost::make_assoc_property_map()` which generates a vertex distance property map.
|
||||||
|
|
||||||
|
\cgalExample{Heat_method_3/heat_method_polyhedron.cpp}
|
||||||
|
|
||||||
|
|
||||||
\subsection HM_example_Class Using the Heat Method Class
|
\subsection HM_example_Class Using the Heat Method Class
|
||||||
|
|
||||||
The following example shows the heat method class. It can be used
|
The following example shows the heat method class. It can be used
|
||||||
|
|
@ -55,11 +67,11 @@ the distances to these two sources.
|
||||||
\cgalExample{Heat_method_3/heat_method_surface_mesh.cpp}
|
\cgalExample{Heat_method_3/heat_method_surface_mesh.cpp}
|
||||||
|
|
||||||
|
|
||||||
\subsection HM_example_Intrinsic Using the Intrinsic Delaunay Triangulation
|
\subsection HM_example_Intrinsic Using the Intrinsic Delaunay Triangulation Class
|
||||||
|
|
||||||
The following example shows the heat method on a triangle mesh using
|
The following example shows the heat method on a triangle mesh using
|
||||||
the intrinsic Delaunay triangulation algorithm. This should be done when the
|
the intrinsic Delaunay triangulation algorithm. This should be done when the
|
||||||
triangles are very .....................
|
triangles have small angles or .....................
|
||||||
|
|
||||||
\cgalExample{Heat_method_3/heat_method_surface_mesh_intrinsic.cpp}
|
\cgalExample{Heat_method_3/heat_method_surface_mesh_intrinsic.cpp}
|
||||||
|
|
||||||
|
|
@ -67,8 +79,8 @@ triangles are very .....................
|
||||||
|
|
||||||
\section sec_HM_definitions Theoretical Background
|
\section sec_HM_definitions Theoretical Background
|
||||||
|
|
||||||
Section \ref Subsection_HM_Definitions_Intro gives an overview of the theory needed by the heat method.
|
Section \ref Subsection_HM_Definitions_Intro gives an overview of the theory needed by the Heat method.
|
||||||
Section \ref Subsection_HM_IDT_Definitions gives the background needed for the Intrinsic Delaunay Triangulation.
|
Section \ref Subsection_HM_IDT_Definitions gives the background needed for the Intrinsic Delaunay triangulation.
|
||||||
|
|
||||||
\subsection Subsection_HM_Definitions_Intro The Heat Method Algorithm
|
\subsection Subsection_HM_Definitions_Intro The Heat Method Algorithm
|
||||||
|
|
||||||
|
|
@ -177,14 +189,11 @@ The algorithm is as follows:
|
||||||
|
|
||||||
The new \f$(\tilde K, \tilde L)\f$ are then used in the Heat Method distance computation.
|
The new \f$(\tilde K, \tilde L)\f$ are then used in the Heat Method distance computation.
|
||||||
|
|
||||||
|
We already in the beginning gave an example where the intrinsic Delaunay triangulation improves the results.
|
||||||
|
The mesh was obtained by giving elevation to a 2D triangulation, which lead to elongated triangles.
|
||||||
|
|
||||||
|
The situation is similar for any triangle mesh that has faces with very small angles as can be seen in the figures below.
|
||||||
|
|
||||||
The following figures demonstrate the difference between the heat method with and without intrinsic Delaunay remeshing.
|
|
||||||
\cgalFigureBegin{landscape_mesh, landscape2withoutidt.png}
|
|
||||||
Isolines placed on a mesh without iDT remeshing
|
|
||||||
\cgalFigureEnd
|
|
||||||
\cgalFigureBegin{landscape_mesh_idt, landscape2withidt.png}
|
|
||||||
Isolines placed on a mesh with iDT remeshing
|
|
||||||
\cgalFigureEnd
|
|
||||||
\cgalFigureBegin{circle_box, red_circle_box_without_idt_bottom.png}
|
\cgalFigureBegin{circle_box, red_circle_box_without_idt_bottom.png}
|
||||||
Isolines placed on a mesh without iDT remeshing
|
Isolines placed on a mesh without iDT remeshing
|
||||||
\cgalFigureEnd
|
\cgalFigureEnd
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,4 @@ Stream_support
|
||||||
Surface_mesh
|
Surface_mesh
|
||||||
Solver_interface
|
Solver_interface
|
||||||
BGL
|
BGL
|
||||||
Polyhedron_3
|
Polyhedron
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
/*!
|
/*!
|
||||||
\example Heat_method_3/heat_method.cpp
|
\example Heat_method_3/heat_method.cpp
|
||||||
|
\example Heat_method_3/heat_method_polyhedron.cpp
|
||||||
\example Heat_method_3/heat_method_surface_mesh.cpp
|
\example Heat_method_3/heat_method_surface_mesh.cpp
|
||||||
\example Heat_method_3/heat_method_surface_mesh_intrinsic.cpp
|
\example Heat_method_3/heat_method_surface_mesh_intrinsic.cpp
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -54,5 +54,6 @@ include_directories( BEFORE include )
|
||||||
include( CGAL_CreateSingleSourceCGALProgram )
|
include( CGAL_CreateSingleSourceCGALProgram )
|
||||||
|
|
||||||
create_single_source_cgal_program( "heat_method.cpp" )
|
create_single_source_cgal_program( "heat_method.cpp" )
|
||||||
|
create_single_source_cgal_program( "heat_method_polyhedron.cpp" )
|
||||||
create_single_source_cgal_program( "heat_method_surface_mesh.cpp" )
|
create_single_source_cgal_program( "heat_method_surface_mesh.cpp" )
|
||||||
create_single_source_cgal_program( "heat_method_surface_mesh_intrinsic.cpp" )
|
create_single_source_cgal_program( "heat_method_surface_mesh_intrinsic.cpp" )
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
typedef CGAL::Simple_cartesian<double> Kernel;
|
typedef CGAL::Simple_cartesian<double> Kernel;
|
||||||
typedef Kernel::Point_3 Point_3;
|
typedef Kernel::Point_3 Point_3;
|
||||||
typedef CGAL::Surface_mesh<Point_3> Surface_mesh;
|
typedef CGAL::Surface_mesh<Point_3> Surface_mesh;
|
||||||
|
|
@ -28,9 +30,10 @@ int main(int argc, char* argv[])
|
||||||
|
|
||||||
CGAL::Heat_method_3::geodesic_distances_3(sm, heat_intensity,source) ;
|
CGAL::Heat_method_3::geodesic_distances_3(sm, heat_intensity,source) ;
|
||||||
|
|
||||||
|
std::cout << "Source vertex " << source << " at: " << sm.point(source) << std::endl;
|
||||||
BOOST_FOREACH(vertex_descriptor vd , vertices(sm)){
|
BOOST_FOREACH(vertex_descriptor vd , vertices(sm)){
|
||||||
std::cout << vd << " is at distance " << get(heat_intensity, vd) << " from " << source << std::endl;
|
std::cout << vd << " ("<< sm.point(vd) << ")"
|
||||||
|
<< " is at distance " << get(heat_intensity, vd) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
#include <CGAL/Simple_cartesian.h>
|
||||||
|
#include <CGAL/Polyhedron_3.h>
|
||||||
|
#include <CGAL/Heat_method_3/Heat_method_3.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <boost/unordered_map.hpp>
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
|
typedef CGAL::Simple_cartesian<double> Kernel;
|
||||||
|
typedef Kernel::Point_3 Point_3;
|
||||||
|
typedef CGAL::Polyhedron_3<Kernel> Surface_mesh;
|
||||||
|
|
||||||
|
typedef boost::graph_traits<Surface_mesh>::vertex_descriptor vertex_descriptor;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
boost::unordered_map<vertex_descriptor, double> heat_intensity;
|
||||||
|
|
||||||
|
vertex_descriptor source = *(vertices(sm).first);
|
||||||
|
|
||||||
|
CGAL::Heat_method_3::geodesic_distances_3(sm,
|
||||||
|
boost::make_assoc_property_map(heat_intensity),
|
||||||
|
source) ;
|
||||||
|
|
||||||
|
std::cout << "Source vertex at: " << source->point() << std::endl;
|
||||||
|
BOOST_FOREACH(vertex_descriptor vd , vertices(sm)){
|
||||||
|
std::cout << vd->point() << " is at distance " << heat_intensity[vd] << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -4,9 +4,10 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <vector>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
typedef CGAL::Simple_cartesian<double> Kernel;
|
typedef CGAL::Simple_cartesian<double> Kernel;
|
||||||
typedef Kernel::Point_3 Point_3;
|
typedef Kernel::Point_3 Point_3;
|
||||||
typedef CGAL::Surface_mesh<Point_3> Surface_mesh;
|
typedef CGAL::Surface_mesh<Point_3> Surface_mesh;
|
||||||
|
|
@ -48,7 +49,6 @@ int main(int argc, char* argv[])
|
||||||
hm.add_source(far);
|
hm.add_source(far);
|
||||||
hm.update();
|
hm.update();
|
||||||
|
|
||||||
|
|
||||||
BOOST_FOREACH(vertex_descriptor vd , vertices(sm)){
|
BOOST_FOREACH(vertex_descriptor vd , vertices(sm)){
|
||||||
std::cout << vd << " is at distance " << get(heat_intensity, vd) << std::endl;
|
std::cout << vd << " is at distance " << get(heat_intensity, vd) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <vector>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
typedef CGAL::Simple_cartesian<double> Kernel;
|
typedef CGAL::Simple_cartesian<double> Kernel;
|
||||||
typedef Kernel::Point_3 Point_3;
|
typedef Kernel::Point_3 Point_3;
|
||||||
|
|
|
||||||
|
|
@ -288,7 +288,7 @@ private:
|
||||||
{
|
{
|
||||||
//currently just working with a single vertex in source set, add the first one for now
|
//currently just working with a single vertex in source set, add the first one for now
|
||||||
Index i;
|
Index i;
|
||||||
Matrix K(num_vertices(tm), 1);
|
Matrix K(static_cast<int>(num_vertices(tm)), 1);
|
||||||
if(sources.empty()) {
|
if(sources.empty()) {
|
||||||
i = 0;
|
i = 0;
|
||||||
K.set_coef(i,0, 1, true);
|
K.set_coef(i,0, 1, true);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue