From cbacf07fe69219a27f316319c611bf9fcf1b33b7 Mon Sep 17 00:00:00 2001 From: Lingjie Zhu Date: Mon, 4 Sep 2017 23:06:43 +0800 Subject: [PATCH] improve named parameters --- .../named_function_params.h | 2 + .../named_params_helper.h | 76 ++++++------ .../parameters_interface.h | 18 +-- .../include/CGAL/vsa_mesh_approximation.h | 114 ++++++++++-------- .../vsa_free_function_test.cpp | 19 ++- 5 files changed, 131 insertions(+), 98 deletions(-) diff --git a/Surface_mesh_approximation/include/CGAL/internal/Surface_mesh_approximation/named_function_params.h b/Surface_mesh_approximation/include/CGAL/internal/Surface_mesh_approximation/named_function_params.h index 544f7504e82..db81b750c67 100644 --- a/Surface_mesh_approximation/include/CGAL/internal/Surface_mesh_approximation/named_function_params.h +++ b/Surface_mesh_approximation/include/CGAL/internal/Surface_mesh_approximation/named_function_params.h @@ -6,6 +6,8 @@ namespace CGAL{ namespace internal_np{ + enum vsa_no_output_t { vsa_no_output }; + // define enum types and values for new named parameters #define CGAL_add_named_parameter(X, Y, Z) \ enum X { Y }; diff --git a/Surface_mesh_approximation/include/CGAL/internal/Surface_mesh_approximation/named_params_helper.h b/Surface_mesh_approximation/include/CGAL/internal/Surface_mesh_approximation/named_params_helper.h index 70b4b397828..e37245fd9a5 100644 --- a/Surface_mesh_approximation/include/CGAL/internal/Surface_mesh_approximation/named_params_helper.h +++ b/Surface_mesh_approximation/include/CGAL/internal/Surface_mesh_approximation/named_params_helper.h @@ -131,48 +131,46 @@ get_const_property_map(const PropertyTag& p, const PolygonMesh& pmesh) return pms.get_const_pmap(p, pmesh); } -template -class GetFaceIndexMap -{ - typedef typename property_map_selector::type DefaultMap; - typedef typename property_map_selector::const_type DefaultMap_const; -public: - typedef typename boost::lookup_named_param_def < - internal_np::face_index_t, - NamedParameters, - DefaultMap - > ::type type; - typedef typename boost::lookup_named_param_def < - internal_np::face_index_t, - NamedParameters, - DefaultMap_const - > ::type const_type; - typedef typename boost::is_same::type Is_internal_map; - typedef typename boost::is_same::type Is_internal_map_const; -}; +// output helper functions +template +void get_proxy_map(const Approximation &approx, FacetProxyMap fproxymap) { + approx.get_proxy_map(fproxymap); +} -template -class GetFaceNormalMap -{ - struct DummyNormalPmap - { - typedef typename boost::graph_traits::face_descriptor key_type; - typedef typename GetGeomTraits::type::Vector_3 value_type; - typedef value_type reference; - typedef boost::readable_property_map_tag category; +template +void get_proxy_map(const Approximation &approx, internal_np::vsa_no_output_t) {} - typedef DummyNormalPmap Self; - friend reference get(const Self&, const key_type&) { return CGAL::NULL_VECTOR; } - }; +template +void get_anchor_vertices(const Approximation &approx, OutputIterator out_itr) { + approx.get_anchor_vertices(out_itr); +} -public: - typedef DummyNormalPmap NoMap; - typedef typename boost::lookup_named_param_def < - internal_np::face_normal_t, - NamedParameters, - DummyNormalPmap//default - > ::type type; -}; +template +void get_anchor_vertices(const Approximation &approx, internal_np::vsa_no_output_t) {} + +template +void get_anchor_points(const Approximation &approx, OutputIterator out_itr) { + approx.get_anchor_points(out_itr); +} + +template +void get_anchor_points(const Approximation &approx, internal_np::vsa_no_output_t) {} + +template +void get_indexed_triangles(const Approximation &approx, OutputIterator out_itr) { + approx.get_indexed_triangles(out_itr); +} + +template +void get_indexed_triangles(const Approximation &approx, internal_np::vsa_no_output_t) {} + +template +void get_proxies(const Approximation &approx, OutputIterator out_itr) { + approx.get_proxies(out_itr); +} + +template +void get_proxies(const Approximation &approx, internal_np::vsa_no_output_t) {} } //end of namespace CGAL diff --git a/Surface_mesh_approximation/include/CGAL/internal/Surface_mesh_approximation/parameters_interface.h b/Surface_mesh_approximation/include/CGAL/internal/Surface_mesh_approximation/parameters_interface.h index 4c0f7df1fa3..a9f1d317671 100644 --- a/Surface_mesh_approximation/include/CGAL/internal/Surface_mesh_approximation/parameters_interface.h +++ b/Surface_mesh_approximation/include/CGAL/internal/Surface_mesh_approximation/parameters_interface.h @@ -1,15 +1,17 @@ // List of named parameters used in the Polygon Mesh Processing package CGAL_add_named_parameter(geom_traits_t, geom_traits, geom_traits) -CGAL_add_named_parameter(init_method_t, init_method, init_method) -CGAL_add_named_parameter(number_of_iterations_t, number_of_iterations, number_of_iterations) -CGAL_add_named_parameter(number_of_proxies_t, number_of_proxies, number_of_proxies) -CGAL_add_named_parameter(chord_subdivide_t, chord_subdivide, chord_subdivide) -CGAL_add_named_parameter(pca_plane_t, pca_plane, pca_plane) -CGAL_add_named_parameter(face_area_t, face_area, face_area_map) -CGAL_add_named_parameter(face_normal_t, face_normal, face_normal_map) -CGAL_add_named_parameter(face_proxy_t, face_proxy, face_proxy_map) +// approximation parameters +CGAL_add_named_parameter(init_method_t, init_method, init_method) +CGAL_add_named_parameter(seeding_by_number_t, seeding_by_number, seeding_by_number) +CGAL_add_named_parameter(seeding_by_error_t, seeding_by_error, seeding_by_error) +CGAL_add_named_parameter(iterations_t, iterations, iterations) +CGAL_add_named_parameter(inner_iterations_t, inner_iterations, inner_iterations) +CGAL_add_named_parameter(chord_subdivide_t, chord_subdivide, chord_subdivide) + // output parameters +CGAL_add_named_parameter(facet_proxy_map_t, facet_proxy_map, facet_proxy_map) +CGAL_add_named_parameter(proxies_t, proxies, proxies) CGAL_add_named_parameter(anchor_vertex_t, anchor_vertex, anchor_vertex) CGAL_add_named_parameter(anchor_point_t, anchor_point, anchor_point) CGAL_add_named_parameter(indexed_triangles_t, indexed_triangles, indexed_triangles) diff --git a/Surface_mesh_approximation/include/CGAL/vsa_mesh_approximation.h b/Surface_mesh_approximation/include/CGAL/vsa_mesh_approximation.h index 04474d27261..dd949c4df11 100644 --- a/Surface_mesh_approximation/include/CGAL/vsa_mesh_approximation.h +++ b/Surface_mesh_approximation/include/CGAL/vsa_mesh_approximation.h @@ -41,14 +41,20 @@ namespace CGAL * \cgalParamEnd * \cgalParamBegin{init_method} the selection of seed initialization method. * \cgalParamEnd - * \cgalParamBegin{number_of_proxies} the number of proxies to approximate the geometry. + * \cgalParamBegin{seeding_by_number} the number of proxies to approximate the geometry. * \cgalParamEnd - * \cgalParamBegin{number_of_iterations} the relaxation iterations. + * \cgalParamBegin{seeding_by_error} the error drop of the approximation. + * \cgalParamEnd + * \cgalParamBegin{iterations} the relaxation iterations after seeding. + * \cgalParamEnd + * \cgalParamBegin{inner_iterations} the relaxation iterations when seeding. * \cgalParamEnd * \cgalParamBegin{chord_subdivide} the threshold of chord subdivision. * \cgalParamEnd * \cgalParamBegin{face_proxy_map} a property map containing the assigned proxy index of each face of `tm_in` * \cgalParamEnd + * \cgalParamBegin{proxies} the plane proxies + * \cgalParamEnd * \cgalParamBegin{anchor_vertex} the anchor verteices output iterator * \cgalParamEnd * \cgalParamBegin{anchor_point} the anchor points output iterator @@ -75,8 +81,7 @@ bool vsa_mesh_approximation(const TriangleMesh &tm_in, typedef typename GetVertexPointMap::type VPMap; VPMap point_pmap = choose_param(get_param(np, internal_np::vertex_point), - get(boost::vertex_point, const_cast(tm_in))); - // get_property_map(vertex_point, tm_in)); + get_property_map(vertex_point, const_cast(tm_in))); typedef CGAL::VSA_approximation VSAL21; typedef typename VSAL21::ErrorMetric L21Metric; @@ -87,59 +92,72 @@ bool vsa_mesh_approximation(const TriangleMesh &tm_in, L21ProxyFitting l21_fitting(tm_in); vsa_l21.set_metric(l21_metric, l21_fitting); - std::size_t num_proxies = choose_param(get_param(np, internal_np::number_of_proxies), - num_faces(tm_in) / 100); - 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; - + // default random initialization int init = choose_param(get_param(np, internal_np::init_method), 0); - vsa_l21.seeding_by_number( - static_cast(init), num_proxies, 5); - for (std::size_t i = 0; i < num_iterations; ++i) + std::size_t num_proxies = choose_param(get_param(np, internal_np::seeding_by_number), 0); + std::size_t inner_iterations = choose_param(get_param(np, internal_np::inner_iterations), 10); + if (num_proxies == 0 || num_proxies > num_faces(tm_in)) { + FT drop = choose_param(get_param(np, internal_np::seeding_by_error), FT(0.01)); + vsa_l21.seeding_by_error( + static_cast(init), drop, inner_iterations); + } + else { + vsa_l21.seeding_by_number( + static_cast(init), num_proxies, inner_iterations); + } + + std::size_t iterations = choose_param(get_param(np, internal_np::iterations), 10); + for (std::size_t i = 0; i < iterations; ++i) vsa_l21.run_one_step(); - bool pca_plane = choose_param(get_param(np, internal_np::pca_plane) , false); +#ifdef CGAL_SURFACE_MESH_APPROXIMATION_DEBUG + std::cout << "#px = " << num_proxies + << ", #itr = " << iterations + << ", #inner_itr = " << inner_iterations << std::endl; +#endif + + typedef typename boost::lookup_named_param_def< + internal_np::facet_proxy_map_t, + NamedParameters, + internal_np::vsa_no_output_t>::type FPMap; + FPMap fproxymap = choose_param( + get_param(np, internal_np::facet_proxy_map), internal_np::vsa_no_output); + get_proxy_map(vsa_l21, fproxymap); + FT split_criterion = choose_param(get_param(np, internal_np::chord_subdivide), FT(1)); - bool is_manifold = vsa_l21.meshing(tm_out, split_criterion, pca_plane); + bool is_manifold = vsa_l21.meshing(tm_out, split_criterion); - // vsa_l21.get_proxy_map(); + typedef typename boost::lookup_named_param_def< + internal_np::anchor_vertex_t, + NamedParameters, + internal_np::vsa_no_output_t>::type AnchorVertexOutItr; + AnchorVertexOutItr avtx_out_itr = choose_param( + get_param(np, internal_np::anchor_vertex) , internal_np::vsa_no_output); + get_anchor_vertices(vsa_l21, avtx_out_itr); + + typedef typename boost::lookup_named_param_def< + internal_np::anchor_point_t, + NamedParameters, + internal_np::vsa_no_output_t >::type AnchorPointOutItr; + AnchorPointOutItr apts_out_itr = choose_param( + get_param(np, internal_np::anchor_point), internal_np::vsa_no_output); + get_anchor_points(vsa_l21, apts_out_itr); typedef typename boost::lookup_named_param_def < - internal_np::anchor_vertex_t, - NamedParameters, - std::back_insert_iterator > - > ::type AnchorVertexOutItr; - AnchorVertexOutItr avtx_out_itr = choose_param(get_param(np, internal_np::anchor_vertex) - , std::back_inserter(*(new std::vector()))); - vsa_l21.get_anchor_vertices(avtx_out_itr); + internal_np::indexed_triangles_t, + NamedParameters, + internal_np::vsa_no_output_t>::type IndexedTrisOutItr; + IndexedTrisOutItr itris_out_itr = choose_param( + get_param(np, internal_np::indexed_triangles), internal_np::vsa_no_output); + get_indexed_triangles(vsa_l21, itris_out_itr); typedef typename boost::lookup_named_param_def < - internal_np::anchor_point_t, - NamedParameters, - std::back_insert_iterator > - > ::type AnchorPointOutItr; - AnchorPointOutItr apts_out_itr = choose_param(get_param(np, internal_np::anchor_point) - , std::back_inserter(*(new std::vector()))); - vsa_l21.get_anchor_points(apts_out_itr); - - typedef typename boost::lookup_named_param_def < - internal_np::indexed_triangles_t, - NamedParameters, - std::back_insert_iterator > - > ::type IndexedTrisOutItr; - IndexedTrisOutItr itris_out_itr = choose_param(get_param(np, internal_np::indexed_triangles) - , std::back_inserter(*(new std::vector()))); - vsa_l21.get_indexed_triangles(itris_out_itr); - - - // typedef typename boost::lookup_named_param_def < - // internal_np::proxies_t, - // NamedParameters, - // std::back_insert_iterator > - // > ::type ProxiesOutItr; - // ProxiesOutItr pxies_out_itr = choose_param(get_param(np, internal_np::proxies) - // , std::back_inserter(*(new std::vector()))); - // vsa_l21.get_proxies(pxies_out_itr); + internal_np::proxies_t, + NamedParameters, + internal_np::vsa_no_output_t>::type ProxiesOutItr; + ProxiesOutItr pxies_out_itr = choose_param( + get_param(np, internal_np::proxies), internal_np::vsa_no_output); + get_proxies(vsa_l21, pxies_out_itr); return is_manifold; } diff --git a/Surface_mesh_approximation/test/Surface_mesh_approximation/vsa_free_function_test.cpp b/Surface_mesh_approximation/test/Surface_mesh_approximation/vsa_free_function_test.cpp index ab57ca93f53..0faf12fe6b0 100644 --- a/Surface_mesh_approximation/test/Surface_mesh_approximation/vsa_free_function_test.cpp +++ b/Surface_mesh_approximation/test/Surface_mesh_approximation/vsa_free_function_test.cpp @@ -26,12 +26,25 @@ int main() std::vector tris; std::vector anchor_pos; std::list anchor_vtx; + std::vector > proxies; + std::map fidxmap; + boost::associative_property_map > fpxmap(fidxmap); CGAL::vsa_mesh_approximation(mesh, out_mesh, - CGAL::VSA::parameters::number_of_proxies(6). - number_of_iterations(30). + CGAL::VSA::parameters::seeding_by_number(6). + iterations(30). + inner_iterations(5). + chord_subdivide(0.5). + facet_proxy_map(fpxmap). anchor_vertex(std::back_inserter(anchor_vtx)). anchor_point(std::back_inserter(anchor_pos)). - indexed_triangles(std::back_inserter(tris))); + indexed_triangles(std::back_inserter(tris)). + proxies(std::back_inserter(proxies))); + + std::cout << "#tris " << tris.size() << std::endl; + std::cout << "#anchor_pos " << anchor_pos.size() << std::endl; + std::cout << "#anchor_vtx " << anchor_vtx.size() << std::endl; + std::cout << "#proxies " << proxies.size() << std::endl; + std::cout << "#fpxmap " << fidxmap.size() << std::endl; return EXIT_SUCCESS; }