One pass on examples
This commit is contained in:
Pierre Alliez 2017-11-12 11:09:08 +01:00
parent aa695bdf6a
commit a57c658ca7
4 changed files with 26 additions and 23 deletions

View File

@ -3,7 +3,6 @@
project( Surface_mesh_approximation ) project( Surface_mesh_approximation )
cmake_minimum_required(VERSION 2.8.11) cmake_minimum_required(VERSION 2.8.11)
# CGAL and its components # CGAL and its components
@ -44,10 +43,10 @@ include_directories( BEFORE ../../include )
include( CGAL_CreateSingleSourceCGALProgram ) include( CGAL_CreateSingleSourceCGALProgram )
create_single_source_cgal_program( "vsa_class_interface_example.cpp" )
create_single_source_cgal_program( "vsa_example.cpp" ) create_single_source_cgal_program( "vsa_example.cpp" )
create_single_source_cgal_program( "vsa_class_interface_example.cpp" )
create_single_source_cgal_program( "vsa_metric_example.cpp" ) create_single_source_cgal_program( "vsa_metric_example.cpp" )

View File

@ -18,7 +18,7 @@ typedef L21VSA::ProxyFitting L21ProxyFitting;
int main() int main()
{ {
// read Polyhedron // create polyhedral surface and read input mesh
Polyhedron input; Polyhedron input;
std::ifstream file("data/bear.off"); std::ifstream file("data/bear.off");
if (!file || !(file >> input) || input.empty()) { if (!file || !(file >> input) || input.empty()) {
@ -29,24 +29,26 @@ int main()
// create VSA L21 metric approximation algorithm instance // create VSA L21 metric approximation algorithm instance
L21VSA l21_approx(input, L21VSA l21_approx(input,
get(boost::vertex_point, const_cast<Polyhedron &>(input))); get(boost::vertex_point, const_cast<Polyhedron &>(input)));
// set error and fitting functors // set error and fitting functors
L21Metric metric(input); L21Metric metric(input);
L21ProxyFitting proxy_fitting(input); L21ProxyFitting proxy_fitting(input);
l21_approx.set_metric(metric, proxy_fitting); l21_approx.set_metric(metric, proxy_fitting);
// initialize proxies randomly on the mesh // initialize 100 random proxies
l21_approx.init_by_number(CGAL::VSA_seeding::Random, 100); l21_approx.init_by_number(CGAL::VSA_seeding::Random, 100);
// run the iteration to minimize the error // run 30 iterations to reduce the approximation error
for (std::size_t i = 0; i < 30; ++i) for (std::size_t i = 0; i < 30; ++i)
l21_approx.run_one_step(); l21_approx.run_one_step();
// add proxies to the one with the maximum fitting error // add proxies to the one with the maximum fitting error
// and run 10 iterations
l21_approx.add_proxies_furthest(3, 5); l21_approx.add_proxies_furthest(3, 5);
for (std::size_t i = 0; i < 10; ++i) for (std::size_t i = 0; i < 10; ++i)
l21_approx.run_one_step(); l21_approx.run_one_step();
// merge and teleport the proxies from local minimal // teleport 2 proxies from local minima
l21_approx.teleport_proxies(2); l21_approx.teleport_proxies(2);
for (std::size_t i = 0; i < 10; ++i) for (std::size_t i = 0; i < 10; ++i)
l21_approx.run_one_step(); l21_approx.run_one_step();

View File

@ -12,7 +12,7 @@ typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
int main() int main()
{ {
// create and read Polyhedron // create polyhedral surface and read input mesh
Polyhedron input; Polyhedron input;
std::ifstream file("data/bear.off"); std::ifstream file("data/bear.off");
if (!file || !(file >> input) || input.empty()) { if (!file || !(file >> input) || input.empty()) {
@ -20,7 +20,7 @@ int main()
return EXIT_FAILURE; return EXIT_FAILURE;
} }
// output data // output polyhedral surface and triangle soup
Polyhedron output; Polyhedron output;
std::vector<std::size_t> triangles; std::vector<std::size_t> triangles;
std::vector<Kernel::Point_3> anchors; std::vector<Kernel::Point_3> anchors;
@ -30,10 +30,10 @@ int main()
CGAL::VSA::parameters::init_by_number(200). // seeding by target number of proxies CGAL::VSA::parameters::init_by_number(200). // seeding by target number of proxies
init_method(CGAL::VSA_seeding::Hierarchical). // hierarchical init init_method(CGAL::VSA_seeding::Hierarchical). // hierarchical init
iterations(30). // number of relaxation iterations after seeding iterations(30). // number of relaxation iterations after seeding
anchor_point(std::back_inserter(anchors)). // get anchor points anchor_point(std::back_inserter(anchors)). // get anchor vertices
indexed_triangles(std::back_inserter(triangles))); // get indexed triangles indexed_triangles(std::back_inserter(triangles))); // get indexed triangles
std::cout << "#anchors: " << anchors.size() << std::endl; std::cout << "#anchor vertices: " << anchors.size() << std::endl;
std::cout << "#triangles: " << triangles.size() << std::endl; std::cout << "#triangles: " << triangles.size() << std::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;

View File

@ -23,19 +23,20 @@ typedef boost::property_map<Polyhedron, boost::vertex_point_t>::type VertexPoint
typedef boost::associative_property_map<std::map<Facet_handle, FT> > FacetAreaMap; typedef boost::associative_property_map<std::map<Facet_handle, FT> > FacetAreaMap;
typedef boost::associative_property_map<std::map<Facet_handle, Point> > FacetCenterMap; typedef boost::associative_property_map<std::map<Facet_handle, Point> > FacetCenterMap;
// use a point as proxy // use point as proxy
typedef Point PointProxy; typedef Point PointProxy;
// user defined point-wise compact metric // user-defined "compact" error metric
struct CompactMetric { struct CompactMetric {
typedef PointProxy Proxy; typedef PointProxy Proxy;
// keeping a precomputed property map to speed up the computation // we keep a precomputed property map to speed up computations
CompactMetric(const FacetCenterMap &_center_pmap) CompactMetric(const FacetCenterMap &_center_pmap)
: center_pmap(_center_pmap) {} : center_pmap(_center_pmap) {}
// calculate the error of a facet to a proxy // compute and return error from a facet to a proxy,
// here is just the Euclidean distance // defined as the Euclidean distance between
// the facet center of mass and proxy point.
FT operator()(const Facet_handle &f, const Proxy &px) const { FT operator()(const Facet_handle &f, const Proxy &px) const {
return FT(std::sqrt(CGAL::to_double( return FT(std::sqrt(CGAL::to_double(
CGAL::squared_distance(center_pmap[f], px)))); CGAL::squared_distance(center_pmap[f], px))));
@ -48,21 +49,22 @@ struct CompactMetric {
struct PointProxyFitting { struct PointProxyFitting {
typedef PointProxy Proxy; typedef PointProxy Proxy;
// keeping precomputed property maps to speed up the computation // we keep a precomputed property map to speed up computations
PointProxyFitting(const FacetCenterMap &_center_pmap, const FacetAreaMap &_area_pmap) PointProxyFitting(const FacetCenterMap &_center_pmap, const FacetAreaMap &_area_pmap)
: center_pmap(_center_pmap), area_pmap(_area_pmap) {} : center_pmap(_center_pmap), area_pmap(_area_pmap) {}
// a template functor fit a new proxy from a range of facets // template functor to compute a best-fit
// proxy from a range of facets
template<typename FacetIterator> template<typename FacetIterator>
Proxy operator()(const FacetIterator beg, const FacetIterator end) const { Proxy operator()(const FacetIterator beg, const FacetIterator end) const {
// fitting center // fitting center
Vector center = CGAL::NULL_VECTOR; Vector center = CGAL::NULL_VECTOR;
FT area = FT(0.0); FT sum_areas = FT(0.0);
for (FacetIterator fitr = beg; fitr != end; ++fitr) { for (FacetIterator fitr = beg; fitr != end; ++fitr) {
center = center + (center_pmap[*fitr] - CGAL::ORIGIN) * area_pmap[*fitr]; center = center + (center_pmap[*fitr] - CGAL::ORIGIN) * area_pmap[*fitr];
area += area_pmap[*fitr]; sum_areas += area_pmap[*fitr];
} }
center = center / area; center = center / sum_areas;
return CGAL::ORIGIN + center; return CGAL::ORIGIN + center;
} }
@ -74,7 +76,7 @@ typedef CGAL::VSA_approximation<Polyhedron, VertexPointMap,
int main() int main()
{ {
// create and read Polyhedron // create polyhedral surface and read input mesh
Polyhedron input; Polyhedron input;
std::ifstream file("data/bear.off"); std::ifstream file("data/bear.off");
if (!file || !(file >> input) || input.empty()) { if (!file || !(file >> input) || input.empty()) {
@ -107,7 +109,7 @@ int main()
PointProxyFitting proxy_fitting(center_pmap, area_pmap); PointProxyFitting proxy_fitting(center_pmap, area_pmap);
compact_approx.set_metric(metric, proxy_fitting); compact_approx.set_metric(metric, proxy_fitting);
// using 200 proxies to approximate the shape // approximation via 200 proxies and 30 iterations
compact_approx.init_by_number(CGAL::VSA_seeding::Hierarchical, 200); compact_approx.init_by_number(CGAL::VSA_seeding::Hierarchical, 200);
for (std::size_t i = 0; i < 30; ++i) for (std::size_t i = 0; i < 30; ++i)
compact_approx.run_one_step(); compact_approx.run_one_step();