diff --git a/Surface_mesh_approximation/benchmark/Surface_mesh_approximation/vsa_timing_benchmark.cpp b/Surface_mesh_approximation/benchmark/Surface_mesh_approximation/vsa_timing_benchmark.cpp index c367d6eca99..363c79278fc 100644 --- a/Surface_mesh_approximation/benchmark/Surface_mesh_approximation/vsa_timing_benchmark.cpp +++ b/Surface_mesh_approximation/benchmark/Surface_mesh_approximation/vsa_timing_benchmark.cpp @@ -64,7 +64,19 @@ int main(int argc, char *argv[]) std::cerr << "start initialization" << std::endl; t0.reset(); t0.start(); - l21_vsa.init_proxies(num_proxies, static_cast(init)); + switch(init) { + case 0: + l21_vsa.seed_random(num_proxies); + break; + case 1: + l21_vsa.seed_incremental(num_proxies, 5); + break; + case 2: + l21_vsa.seed_hierarchical(num_proxies, 5); + break; + default: + return 1; + } t0.stop(); std::cerr << "initialization time " << t0.time() << " sec." << std::endl; diff --git a/Surface_mesh_approximation/examples/Surface_mesh_approximation/vsa_class_interface_example.cpp b/Surface_mesh_approximation/examples/Surface_mesh_approximation/vsa_class_interface_example.cpp index 6fbb1414f3e..09ca7ee24a1 100644 --- a/Surface_mesh_approximation/examples/Surface_mesh_approximation/vsa_class_interface_example.cpp +++ b/Surface_mesh_approximation/examples/Surface_mesh_approximation/vsa_class_interface_example.cpp @@ -35,7 +35,7 @@ int main() l21_approx.set_metric(metric, proxy_fitting); // initialize proxies randomly on the mesh - l21_approx.init_proxies(100, L21VSA::RandomInit); + l21_approx.seed_random(100); // run the iteration to minimize the error for (std::size_t i = 0; i < 30; ++i) diff --git a/Surface_mesh_approximation/examples/Surface_mesh_approximation/vsa_metric_example.cpp b/Surface_mesh_approximation/examples/Surface_mesh_approximation/vsa_metric_example.cpp index 2c8afb47c27..ec0fb35114d 100644 --- a/Surface_mesh_approximation/examples/Surface_mesh_approximation/vsa_metric_example.cpp +++ b/Surface_mesh_approximation/examples/Surface_mesh_approximation/vsa_metric_example.cpp @@ -108,7 +108,7 @@ int main() compact_approx.set_metric(metric, proxy_fitting); // using 200 proxies to approximate the shape - compact_approx.init_proxies(200, CompactVSA::HierarchicalInit); + compact_approx.seed_hierarchical(200, 5); for (std::size_t i = 0; i < 30; ++i) compact_approx.run_one_step(); diff --git a/Surface_mesh_approximation/include/CGAL/VSA_approximation.h b/Surface_mesh_approximation/include/CGAL/VSA_approximation.h index dffa5c88c82..59e647b0188 100644 --- a/Surface_mesh_approximation/include/CGAL/VSA_approximation.h +++ b/Surface_mesh_approximation/include/CGAL/VSA_approximation.h @@ -47,20 +47,28 @@ class VSA_approximation { // public typedefs public: // Default typdefs + /// GeomTraits typdef typedef typename CGAL::Default::Get< GeomTraits_, typename Kernel_traits< typename boost::property_traits::value_type >::Kernel >::type GeomTraits; + /// ErrorMetric typdef typedef typename CGAL::Default::Get >::type ErrorMetric; + /// ProxyFitting typdef typedef typename CGAL::Default::Get >::type ProxyFitting; + /// Proxy typdef typedef typename ErrorMetric::Proxy Proxy; + /// Enueration typdef enum Initialization { + /// Random initialization RandomInit, + /// Incremental initialization IncrementalInit, + /// Hierarchical initialization HierarchicalInit }; @@ -302,24 +310,81 @@ public: } /*! - * @brief Initialize by number of proxies. - * @param num_proxy number of proxies - * @param seeding_method select one of the seeding method: random, hierarchical, incremental + * @brief Random initialize proxies. + * @param num_seed number of proxies seed * @return number of proxies initialized */ - std::size_t init_proxies(const std::size_t num_proxy, const Initialization &seeding_method) { + std::size_t seed_random(const std::size_t num_seed) { proxies.clear(); - if (num_faces(*m_pmesh) < num_proxy) + if (num_faces(*m_pmesh) < num_seed) return 0; - switch (seeding_method) { - case IncrementalInit: - return seed_incremental(num_proxy); - case HierarchicalInit: - return seed_hierarchical(num_proxy); - default: - return seed_random(num_proxy); + const std::size_t interval = num_faces(*m_pmesh) / num_seed; + std::size_t index = 0; + BOOST_FOREACH(face_descriptor f, faces(*m_pmesh)) { + if ((index++) % interval == 0) { + proxies.push_back(fit_new_proxy(f)); + } + if (proxies.size() >= num_seed) + break; } + return proxies.size(); + } + + /*! + * @brief Incremental initialize proxies. + * @param num_seed number of proxies seed + * @param inner_iteration number of iterations of coarse re-fitting + * before each incremental proxy insertion + * @return number of proxies initialized + */ + std::size_t seed_incremental(const std::size_t num_seed, + const std::size_t inner_iteration = 5) { + proxies.clear(); + if (num_faces(*m_pmesh) < num_seed) + return 0; + + // initialize a proxy and the proxy map to prepare for the insertion + proxies.push_back(fit_new_proxy(*(faces(*m_pmesh).first))); + BOOST_FOREACH(face_descriptor f, faces(*m_pmesh)) + fproxy_map[f] = 0; + + insert_proxy_furthest(num_seed - 1, inner_iteration); + return proxies.size(); + } + + /*! + * @brief Hierarchical initialize proxies. + * @param num_seed number of proxies seed + * @param inner_iteration number of iterations of coarse re-fitting + * before each hierarchical proxy insertion + * @return number of proxies initialized + */ + std::size_t seed_hierarchical(const std::size_t num_seed, + const std::size_t inner_iteration = 5) { + proxies.clear(); + if (num_faces(*m_pmesh) < num_seed) + return 0; + + // initialize 2 proxy + typename boost::graph_traits::face_iterator + fitr = faces(*m_pmesh).first; + proxies.push_back(fit_new_proxy(*fitr)); + proxies.push_back(fit_new_proxy(*(++fitr))); + + while (proxies.size() < num_seed) { + for (std::size_t i = 0; i < inner_iteration; ++i) { + partition(); + fit(); + } + + // add proxies by error diffusion + const std::size_t num_proxies = proxies.size(); + const std::size_t num_proxies_to_be_added = + (num_proxies * 2 < num_seed) ? num_proxies : (num_seed - num_proxies); + insert_proxy_hierarchical(num_proxies_to_be_added); + } + return proxies.size(); } /*! @@ -837,71 +902,7 @@ public: // private member functions private: - /*! - * @brief Random initialize proxies. - * @param initial_px number of proxies - * @return number of proxies initialized - */ - std::size_t seed_random(const std::size_t initial_px) { - const std::size_t interval = num_faces(*m_pmesh) / initial_px; - std::size_t index = 0; - BOOST_FOREACH(face_descriptor f, faces(*m_pmesh)) { - if ((index++) % interval == 0) { - proxies.push_back(fit_new_proxy(f)); - } - if (proxies.size() >= initial_px) - break; - } - return proxies.size(); - } - - /*! - * @brief Incremental initialize proxies. - * @param initial_px number of proxies - * @param inner_iteration number of iterations of coarse re-fitting - * before each incremental proxy insertion - * @return number of proxies initialized - */ - std::size_t seed_incremental(const std::size_t initial_px, - const std::size_t inner_iteration = 5) { - // initialize a proxy and the proxy map to prepare for the insertion - proxies.push_back(fit_new_proxy(*(faces(*m_pmesh).first))); - BOOST_FOREACH(face_descriptor f, faces(*m_pmesh)) - fproxy_map[f] = 0; - - insert_proxy_furthest(initial_px - 1, inner_iteration); - return proxies.size(); - } - - /*! - * @brief Hierarchical initialize proxies. - * @param initial_px number of proxies - * @param inner_iteration number of iterations of coarse re-fitting - * before each hierarchical proxy insertion - * @return number of proxies initialized - */ - std::size_t seed_hierarchical(const std::size_t initial_px, - const std::size_t inner_iteration = 5) { - // initialize 2 proxy - typename boost::graph_traits::face_iterator - fitr = faces(*m_pmesh).first; - proxies.push_back(fit_new_proxy(*fitr)); - proxies.push_back(fit_new_proxy(*(++fitr))); - - while (proxies.size() < initial_px) { - for (std::size_t i = 0; i < inner_iteration; ++i) { - partition(); - fit(); - } - - // add proxies by error diffusion - const std::size_t num_proxies = proxies.size(); - const std::size_t num_proxies_to_be_added = - (num_proxies * 2 < initial_px) ? num_proxies : (initial_px - num_proxies); - insert_proxy_hierarchical(num_proxies_to_be_added); - } - return proxies.size(); - } + /*! * @brief Inserts a proxy at the furthest facet of the region with the maximum fitting error. diff --git a/Surface_mesh_approximation/include/CGAL/VSA_metrics.h b/Surface_mesh_approximation/include/CGAL/VSA_metrics.h index e827cf91ef8..b8c97bd70ce 100644 --- a/Surface_mesh_approximation/include/CGAL/VSA_metrics.h +++ b/Surface_mesh_approximation/include/CGAL/VSA_metrics.h @@ -531,9 +531,7 @@ private: const VertexPointMap point_pmap; }; -/*! - * Specialization. - */ +// specialization. template diff --git a/Surface_mesh_approximation/include/CGAL/vsa_mesh_approximation.h b/Surface_mesh_approximation/include/CGAL/vsa_mesh_approximation.h index 638b8bbe002..284160a58e0 100644 --- a/Surface_mesh_approximation/include/CGAL/vsa_mesh_approximation.h +++ b/Surface_mesh_approximation/include/CGAL/vsa_mesh_approximation.h @@ -92,11 +92,21 @@ bool vsa_mesh_approximation(const TriangleMesh &tm_in, std::size_t num_iterations = choose_param(get_param(np, internal_np::number_of_iterations), 10); std::cout << "#px = " << num_proxies << ", #itr = " << num_iterations << std::endl; - int init = choose_param(get_param(np, internal_np::init_method), 0); - if (init < 0 || init > 2) - return false; - - vsa_l21.init_proxies(num_proxies, static_cast(init)); + std::size_t init = choose_param(get_param(np, internal_np::init_method), 0); + switch (static_cast(init)) { + case VSAL21::RandomInit: + vsa_l21.seed_random(num_proxies); + break; + case VSAL21::IncrementalInit: + vsa_l21.seed_incremental(num_proxies, 5); + break; + case VSAL21::HierarchicalInit: + vsa_l21.seed_hierarchical(num_proxies, 5); + break; + default: + std::cout << "Error: invalid initialization method parameter." << std::endl; + return false; + } for (std::size_t i = 0; i < num_iterations; ++i) vsa_l21.run_one_step(); diff --git a/Surface_mesh_approximation/test/Surface_mesh_approximation/vsa_class_interface_test.cpp b/Surface_mesh_approximation/test/Surface_mesh_approximation/vsa_class_interface_test.cpp index fd2f8ce007c..4cff3e70723 100644 --- a/Surface_mesh_approximation/test/Surface_mesh_approximation/vsa_class_interface_test.cpp +++ b/Surface_mesh_approximation/test/Surface_mesh_approximation/vsa_class_interface_test.cpp @@ -53,7 +53,7 @@ int main() // random init and run std::cout << "random init and run" << std::endl; - l2_approx.init_proxies(10, L2VSA::RandomInit); + l2_approx.seed_random(10); for (std::size_t i = 0; i < 10; ++i) l2_approx.run_one_step(); if (l2_approx.get_proxies_size() != 10) diff --git a/Surface_mesh_approximation/test/Surface_mesh_approximation/vsa_error_decrease_test.cpp b/Surface_mesh_approximation/test/Surface_mesh_approximation/vsa_error_decrease_test.cpp index 40c670c726f..bc0208c6cd1 100644 --- a/Surface_mesh_approximation/test/Surface_mesh_approximation/vsa_error_decrease_test.cpp +++ b/Surface_mesh_approximation/test/Surface_mesh_approximation/vsa_error_decrease_test.cpp @@ -51,7 +51,7 @@ int main() L21ProxyFitting l21_fitting(mesh); vsa_l21.set_metric(l21_metric, l21_fitting); - vsa_l21.init_proxies(100, L21VSA::RandomInit); + vsa_l21.seed_random(100); std::vector error; for (std::size_t i = 0; i < 30; ++i) error.push_back(vsa_l21.run_one_step()); diff --git a/Surface_mesh_approximation/test/Surface_mesh_approximation/vsa_metric_test.cpp b/Surface_mesh_approximation/test/Surface_mesh_approximation/vsa_metric_test.cpp index 7b59f88ce43..f6b401b630e 100644 --- a/Surface_mesh_approximation/test/Surface_mesh_approximation/vsa_metric_test.cpp +++ b/Surface_mesh_approximation/test/Surface_mesh_approximation/vsa_metric_test.cpp @@ -99,7 +99,7 @@ int main() compact_approx.set_metric(metric, proxy_fitting); std::cout << "random init and run" << std::endl; - compact_approx.init_proxies(20, CompactVSA::RandomInit); + compact_approx.seed_random(20); for (std::size_t i = 0; i < 20; ++i) compact_approx.run_one_step(); if (compact_approx.get_proxies_size() != 20)