CLean and improve examples

This commit is contained in:
Mael Rouxel-Labbé 2019-10-18 23:20:26 +02:00
parent 09bd731ff9
commit 9314f5a3d7
7 changed files with 104 additions and 208 deletions

View File

@ -1,6 +1,3 @@
#include <iostream>
#include <fstream>
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
@ -12,10 +9,12 @@
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Edge_length_cost.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Midpoint_placement.h>
typedef OpenMesh::PolyMesh_ArrayKernelT</* MyTraits*/> Surface_mesh;
#include <iostream>
#include <fstream>
typedef boost::graph_traits<Surface_mesh>::edge_descriptor edge_descriptor;
typedef boost::graph_traits<Surface_mesh>::edge_iterator edge_iterator;
typedef OpenMesh::PolyMesh_ArrayKernelT</* default traits*/> Surface_mesh;
typedef boost::graph_traits<Surface_mesh>::edge_descriptor edge_descriptor;
class Constrained_edge_map
{
@ -33,10 +32,10 @@ public:
inline friend reference get(const Constrained_edge_map& em, key_type e)
{
bool b = em.sm_.property(em.constraint,em.sm_.edge_handle(e.idx()));
bool b = em.sm_.property(em.constraint,em.sm_.edge_handle(e.idx()));
return b;
}
inline friend void put(const Constrained_edge_map& em, key_type e, value_type b)
{
em.sm_.property(em.constraint,em.sm_.edge_handle(e.idx())) = b;
@ -47,14 +46,13 @@ private:
OpenMesh::EPropHandleT<bool> constraint;
};
namespace SMS = CGAL::Surface_mesh_simplification;
int main(int argc, char** argv)
int main(int argc, char** argv)
{
Surface_mesh surface_mesh;
Constrained_edge_map constraints_map(surface_mesh);
if(argc==2)
OpenMesh::IO::read_mesh(surface_mesh, argv[1]);
else
@ -66,11 +64,10 @@ int main(int argc, char** argv)
}
// For the pupose of the example we mark 10 edges as constrained edges
edge_iterator b,e;
int count=0;
for(boost::tie(b,e) = edges(surface_mesh); b!= e; ++b){
put(constraints_map,*b,(count++ <100));
}
for(edge_descriptor e : edges(surface_mesh))
put(constraints_map, e, (count++ < 100));
// This is a stop predicate (defines when the algorithm terminates).
// In this example, the simplification stops when the number of undirected edges
// left in the surface mesh drops below the specified number (1000)
@ -79,19 +76,16 @@ int main(int argc, char** argv)
// This the actual call to the simplification algorithm.
// The surface mesh and stop conditions are mandatory arguments.
int r = SMS::edge_collapse
(surface_mesh
,stop
,CGAL::parameters::halfedge_index_map (get(CGAL::halfedge_index ,surface_mesh))
.vertex_point_map(get(boost::vertex_point, surface_mesh))
.edge_is_constrained_map(constraints_map)
);
int r = SMS::edge_collapse(surface_mesh, stop,
CGAL::parameters::halfedge_index_map(get(CGAL::halfedge_index,surface_mesh))
.vertex_point_map(get(boost::vertex_point, surface_mesh))
.edge_is_constrained_map(constraints_map));
surface_mesh.garbage_collection();
std::cout << "\nFinished...\n" << r << " edges removed.\n"
std::cout << "\nFinished...\n" << r << " edges removed.\n"
<< num_edges(surface_mesh) << " final edges.\n";
OpenMesh::IO::write_mesh(surface_mesh, "out.off");
OpenMesh::IO::write_mesh(surface_mesh, "out.off");
return EXIT_SUCCESS;
}

View File

@ -9,65 +9,60 @@
#include <CGAL/Surface_mesh_simplification/edge_collapse.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_ratio_stop_predicate.h>
typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 Point;
typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 Point;
// Setup an enriched polyhedron type which stores an id() field in the items
typedef CGAL::Polyhedron_3<Kernel,CGAL::Polyhedron_items_with_id_3> Surface_mesh;
typedef CGAL::Polyhedron_3<Kernel,CGAL::Polyhedron_items_with_id_3> Surface_mesh;
typedef boost::graph_traits<Surface_mesh>::halfedge_descriptor halfedge_descriptor;
typedef boost::graph_traits<Surface_mesh>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Surface_mesh>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Surface_mesh>::halfedge_descriptor halfedge_descriptor;
namespace SMS = CGAL::Surface_mesh_simplification;
int main(int argc, char** argv)
int main(int argc, char** argv)
{
Surface_mesh surface_mesh;
Surface_mesh surface_mesh;
std::ifstream is(argv[1]);
is >> surface_mesh;
if(!CGAL::is_triangle_mesh(surface_mesh)){
if(!CGAL::is_triangle_mesh(surface_mesh))
{
std::cerr << "Input geometry is not triangulated." << std::endl;
return EXIT_FAILURE;
}
// The items in this polyhedron have an "id()" field
// The items in this polyhedron have an "id()" field
// which the default index maps used in the algorithm
// need to get the index of a vertex/edge.
// However, the Polyhedron_3 class doesn't assign any value to
// this id(), so we must do it here:
int index = 0;
for(halfedge_descriptor hd : halfedges(surface_mesh)){
for(halfedge_descriptor hd : halfedges(surface_mesh))
hd->id() = index++;
}
index = 0;
for(vertex_descriptor vd : vertices(surface_mesh)){
for(vertex_descriptor vd : vertices(surface_mesh))
vd->id() = index++;
}
// In this example, the simplification stops when the number of undirected edges
// drops below 10% of the initial count
SMS::Count_ratio_stop_predicate<Surface_mesh> stop(0.1);
// The index maps are not explicitelty passed as in the previous
// example because the surface mesh items have a proper id() field.
// On the other hand, we pass here explicit cost and placement
// function which differ from the default policies, ommited in
// the previous example.
int r = SMS::edge_collapse(surface_mesh, stop);
std::cout << "\nFinished...\n" << r << " edges removed.\n"
std::cout << "\nFinished...\n" << r << " edges removed.\n"
<< (surface_mesh.size_of_halfedges()/2) << " final edges.\n";
std::ofstream os(argc > 2 ? argv[2] : "out.off");
os.precision(17);
os << surface_mesh;
return EXIT_SUCCESS;
}
return EXIT_SUCCESS;
}

View File

@ -3,18 +3,10 @@
#include <CGAL/Surface_mesh_simplification/edge_collapse.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_ratio_stop_predicate.h>
#include <CGAL/IO/STL_reader.h>
#include <CGAL/IO/PLY_reader.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Bounded_normal_change_placement.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/GarlandHeckbert_cost.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/GarlandHeckbert_placement.h>
// @tmp only required for STL reading
#include <CGAL/Polygon_mesh_processing/orient_polygon_soup.h>
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
#include <chrono>
#include <iostream>
#include <fstream>
@ -27,53 +19,20 @@ typedef CGAL::Surface_mesh<Point_3> Surface_mesh;
namespace SMS = CGAL::Surface_mesh_simplification;
template <typename K, typename Mesh>
void read_mesh(const char* filename,
Mesh& sm)
{
typedef typename K::Point_3 Point;
std::ifstream in(filename, std::ios::binary);
if(!in.good())
{
std::cerr << "Error: can't read file: " << filename << std::endl;
std::exit(1);
}
std::string fn(filename);
if(fn.substr(fn.find_last_of(".") + 1) == "stl")
{
std::vector<Point> points;
std::vector<std::array<int, 3> > faces;
CGAL::read_STL(in, points, faces);
if(!CGAL::Polygon_mesh_processing::orient_polygon_soup(points, faces))
std::cerr << "W: File does not describe a polygon mesh" << std::endl;
CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(points, faces, sm);
}
else if(fn.substr(fn.find_last_of(".") + 1) == "off")
{
if(!in || !(in >> sm))
{
std::cerr << "Error: cannot OFF open mesh\n";
return;
}
}
else
{
std::cerr << "Unknown file type" << std::endl;
return;
}
}
int main(int argc, char** argv)
{
Surface_mesh surface_mesh;
const char* filename = argv[1];
read_mesh<Kernel>(filename, surface_mesh);
std::ifstream is(argv[1]);
if(!is)
{
std::cerr << "Filename provided is invalid\n";
return EXIT_FAILURE;
}
is >> surface_mesh;
if(!CGAL::is_triangle_mesh(surface_mesh))
{
std::cerr << "Input geometry is not triangulated." << std::endl;

View File

@ -1,55 +1,56 @@
#include <iostream>
#include <fstream>
#include <CGAL/boost/graph/graph_traits_Linear_cell_complex_for_combinatorial_map.h>
// Simplification function
#include <CGAL/Surface_mesh_simplification/edge_collapse.h>
// Stop-condition policy
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_stop_predicate.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Edge_length_cost.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Midpoint_placement.h>
typedef CGAL::Simple_cartesian<double> Kernel;
typedef CGAL::Linear_cell_complex_traits<3, Kernel> MyTraits;
typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map_helper
<2, 3, MyTraits>::type LCC;
#include <iostream>
#include <fstream>
typedef CGAL::Simple_cartesian<double> Kernel;
typedef CGAL::Linear_cell_complex_traits<3, Kernel> MyTraits;
typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map_helper<2, 3, MyTraits>::type LCC;
namespace SMS = CGAL::Surface_mesh_simplification;
int main(int argc, char** argv)
{
if(argc<2 || argc>3)
if(argc < 2 || argc > 3)
{
std::cout<<"Usage: simplification_Linear_cell_complex inofffile [outofffile]"<<std::endl;
std::cout << "Usage: simplification_Linear_cell_complex inofffile [outofffile]" << std::endl;
return EXIT_FAILURE;
}
LCC lcc;
CGAL::read_off(argv[1], lcc);
lcc.display_characteristics(std::cout)<<", is_valid="<<CGAL::is_valid(lcc)<<std::endl;
lcc.display_characteristics(std::cout) << ", is_valid=" << CGAL::is_valid(lcc) << std::endl;
// This is a stop predicate (defines when the algorithm terminates).
// In this example, the simplification stops when the number of undirected edges
// left in the surface mesh drops below the specified number (1000)
SMS::Count_stop_predicate<LCC> stop(1000);
// This the actual call to the simplification algorithm.
// The surface mesh and stop conditions are mandatory arguments.
// The index maps are needed because the vertices and edges
// of this surface mesh lack an "id()" field.
int r = SMS::edge_collapse
(lcc
,stop
,CGAL::parameters::halfedge_index_map(get(CGAL::halfedge_index, lcc))
.vertex_index_map(get(boost::vertex_index, lcc))
.get_cost(SMS::Edge_length_cost<LCC>())
.get_placement(SMS::Midpoint_placement<LCC>())
);
int r = SMS::edge_collapse(lcc, stop,
CGAL::parameters::halfedge_index_map(get(CGAL::halfedge_index, lcc))
.vertex_index_map(get(boost::vertex_index, lcc))
.get_cost(SMS::Edge_length_cost<LCC>())
.get_placement(SMS::Midpoint_placement<LCC>()));
std::cout << "\nFinished...\n" << r << " edges removed.\n"
<< (lcc.number_of_darts()/2) << " final edges.\n";
lcc.display_characteristics(std::cout)<<", is_valid="<<CGAL::is_valid(lcc)<<std::endl;
lcc.display_characteristics(std::cout) << ", is_valid=" << CGAL::is_valid(lcc) << std::endl;
CGAL::write_off((argc > 2 ? argv[2] : "out.off"), lcc);
return EXIT_SUCCESS;
}
// EOF //

View File

@ -1,6 +1,3 @@
#include <iostream>
#include <fstream>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polyhedron_3.h>
@ -10,19 +7,22 @@
// Stop-condition policy
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_stop_predicate.h>
#include <iostream>
#include <fstream>
typedef CGAL::Simple_cartesian<double> Kernel;
typedef CGAL::Polyhedron_3<Kernel> Surface_mesh;
typedef CGAL::Simple_cartesian<double> Kernel;
typedef CGAL::Polyhedron_3<Kernel> Surface_mesh;
namespace SMS = CGAL::Surface_mesh_simplification;
int main(int argc, char** argv)
int main(int argc, char** argv)
{
Surface_mesh surface_mesh;
std::ifstream is(argv[1]);
is >> surface_mesh;
if(!CGAL::is_triangle_mesh(surface_mesh)){
if(!CGAL::is_triangle_mesh(surface_mesh))
{
std::cerr << "Input geometry is not triangulated." << std::endl;
return EXIT_FAILURE;
}
@ -31,24 +31,21 @@ int main(int argc, char** argv)
// In this example, the simplification stops when the number of undirected edges
// left in the surface mesh drops below the specified number (1000)
SMS::Count_stop_predicate<Surface_mesh> stop(1000);
// This the actual call to the simplification algorithm.
// The surface mesh and stop conditions are mandatory arguments.
// The index maps are needed because the vertices and edges
// of this surface mesh lack an "id()" field.
int r = SMS::edge_collapse
(surface_mesh
,stop
,CGAL::parameters::vertex_index_map(get(CGAL::vertex_external_index, surface_mesh))
.halfedge_index_map (get(CGAL::halfedge_external_index, surface_mesh))
);
std::cout << "\nFinished...\n" << r << " edges removed.\n"
int r = SMS::edge_collapse(surface_mesh, stop,
CGAL::parameters::vertex_index_map(get(CGAL::vertex_external_index, surface_mesh))
.halfedge_index_map(get(CGAL::halfedge_external_index, surface_mesh)));
std::cout << "\nFinished...\n" << r << " edges removed.\n"
<< (surface_mesh.size_of_halfedges()/2) << " final edges.\n";
std::ofstream os(argc > 2 ? argv[2] : "out.off");
os.precision(17);
os << surface_mesh;
return EXIT_SUCCESS;
return EXIT_SUCCESS;
}

View File

@ -1,20 +1,16 @@
#include <iostream>
#include <fstream>
#include <chrono>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Surface_mesh_simplification/edge_collapse.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_ratio_stop_predicate.h>
#include <CGAL/IO/STL_reader.h>
#include <CGAL/IO/PLY_reader.h>
#include <CGAL/Polygon_mesh_processing/orient_polygon_soup.h>
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
#include <chrono>
#include <fstream>
#include <iostream>
typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 Point_3;
typedef CGAL::Surface_mesh<Point_3> Surface_mesh;
typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 Point_3;
typedef CGAL::Surface_mesh<Point_3> Surface_mesh;
namespace SMS = CGAL::Surface_mesh_simplification;
@ -31,47 +27,9 @@ void read_mesh(const char* filename,
std::exit(1);
}
std::string fn(filename);
if(fn.substr(fn.find_last_of(".") + 1) == "stl")
if(!in || !(in >> sm))
{
std::vector<Point> points;
std::vector<std::array<int, 3> > faces;
CGAL::read_STL(in, points, faces);
if(!CGAL::Polygon_mesh_processing::orient_polygon_soup(points, faces))
std::cerr << "W: File does not describe a polygon mesh" << std::endl;
CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(points, faces, sm);
}
else if(fn.substr(fn.find_last_of(".") + 1) == "off")
{
if(!in || !(in >> sm))
{
std::cerr << "Error: cannot OFF open mesh\n";
return;
}
}
else if(fn.substr(fn.find_last_of(".") + 1) == "ply")
{
std::vector<Point> points;
std::vector<std::vector<std::size_t> > polygons;
std::vector<CGAL::Color> fcolors;
std::vector<CGAL::Color> vcolors;
if(!(CGAL::read_PLY(in, points, polygons, fcolors, vcolors)))
{
std::cerr << "Error: cannot open PLY mesh\n";
return;
}
if(!CGAL::Polygon_mesh_processing::orient_polygon_soup(points, polygons))
std::cerr << "W: File does not describe a polygon mesh" << std::endl;
CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(points, polygons, sm);
}
else
{
std::cerr << "Unknown file type" << std::endl;
std::cerr << "Error: cannot read OFF mesh\n";
return;
}
}
@ -83,9 +41,7 @@ int main(int argc, char** argv)
const char* filename = argv[1];
read_mesh<Kernel>(filename, surface_mesh);
std::chrono::steady_clock::time_point start_time
= std::chrono::steady_clock::now();
std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now();
// In this example, the simplification stops when the number of undirected edges
// drops below 10% of the initial count
@ -93,20 +49,14 @@ int main(int argc, char** argv)
int r = SMS::edge_collapse(surface_mesh, stop);
std::chrono::steady_clock::time_point end_time
= std::chrono::steady_clock::now();
std::cout << "Time elapsed: "
<< std::chrono::duration_cast<std::chrono::milliseconds>(
end_time - start_time
).count() << "ms" << std::endl;
std::chrono::steady_clock::time_point end_time = std::chrono::steady_clock::now();
std::cout << "\nFinished...\n" << r << " edges removed.\n"
<< surface_mesh.number_of_edges() << " final edges.\n";
std::cout << "Time elapsed: "
<< std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count() << "ms" << std::endl;
std::ofstream os(argc > 2 ? argv[2] : "out.off");
os.precision(17);
os << surface_mesh;

View File

@ -1,6 +1,3 @@
#include <iostream>
#include <fstream>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
@ -13,6 +10,9 @@
// Stop-condition policy
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_ratio_stop_predicate.h>
#include <iostream>
#include <fstream>
typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 Point_3;