From c15ff1c19c0e5afa2c77f916bd725c5e526456bd Mon Sep 17 00:00:00 2001 From: Aymeric PELLE Date: Wed, 26 Mar 2014 19:02:27 +0100 Subject: [PATCH] New implementation of Implicit_multi_domain_to_labeling_function_wrapper. The user can indicate more precisely which components he wants. For each component that the user want, he must provide the matching vector of signs. All these vector of positions must be put in a vector passed as second parameter to the constructor of that wrapper. Doc and examples are updated. --- .../Implicit_to_labeling_function_wrapper.h | 42 +++-- .../doc/Mesh_3/CGAL/Labeled_mesh_domain_3.h | 31 ++-- .../Mesh_3/mesh_cubes_intersection.cpp | 5 +- .../mesh_cubes_intersection_with_features.cpp | 5 +- .../Mesh_3/mesh_implicit_domains_2.cpp | 5 +- .../Implicit_to_labeling_function_wrapper.h | 152 +++++++++++------- 6 files changed, 141 insertions(+), 99 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/CGAL/Implicit_to_labeling_function_wrapper.h b/Mesh_3/doc/Mesh_3/CGAL/Implicit_to_labeling_function_wrapper.h index 43248cae0c3..f982ac51ee3 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Implicit_to_labeling_function_wrapper.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Implicit_to_labeling_function_wrapper.h @@ -3,27 +3,26 @@ namespace CGAL { /*! \ingroup PkgMesh_3Domains -The class `Implicit_multi_domain_to_labeling_function_wrapper` wraps several implicit functions [f1,f2,...] to one labeling function F -that takes its values into N. This wrapper allows the user to define several domains from implicit functions and a vector of sign. -Implicit functions must take a point as input parameter and return an arithmetic value. - -We associate a power of two to each implicit function of the set. -For each implicit function f, we look at the sign \e s of f(p). If \e s is the same as -the sign given in the vector of signs, we add the power of two associated to f to F(p). +The class `Implicit_multi_domain_to_labeling_function_wrapper` is an helping class to get a function with integer values +labeling the components of a multi-domain. This wrapper class can be passed to `Labeled_mesh_domain_3` as first template parameter. +Each component corresponds to a sign vector [s1, s2, ..., sn] where si is the sign of the function fi(p) at a point p of the component. \par Example
 \e Creation \e of \e the \e wrapper\n
     [f1, f2, f3]
-    [ -,  -,  +]
+    [
+      [ -,  -,  +]
+      [ +,  -,  +]
+    ]
 \e Input\n
-    Point_3 p
+    %Point_3 p
 \e Output\n
-    int N = 0b00...00( f1(p)<0 )( f2(p)<0 )( f3(p)>0 )
+    int N = 1  if f1(p)<0 and f2(p)<0 and f3(p)>0
+            2  if f1(p)>0 and f2(p)<0 and f3(p)>0
+            0  else
 
-This wrapper class can be passed to `Labeled_mesh_domain_3` as first template parameter. - \tparam Function is the type of the input implicit functions. \tparam BGT is a geometric traits class that provides @@ -33,7 +32,6 @@ through a bisection method. This parameter must be instantiated with a model of the concept `BisectionGeometricTraits_3`. \sa `Implicit_mesh_domain_3`. -\sa `Sign` */ template @@ -53,25 +51,23 @@ public: /*! * \brief Construction from a vector of implicit functions. * \param implicit_functions the vector of implicit functions. - * - * The array of signs is built automatically with `NEGATIVE` signs. - * \sa Sign */ - Implicit_multi_domain_to_labeling_function_wrapper(const std::vector& implicit_functions); + Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& implicit_functions); /*! - * \brief Construction from a vector of implicit functions. + * \brief Construction from a vector of implicit functions and a vector of vector of signs. * \param implicit_functions the vector of implicit functions. - * \param mask the vector of signs expected by the user. + * \param positions_vectors the vector of vector of signs. + * \sa `Sign` */ - Implicit_multi_domain_to_labeling_function_wrapper (const std::vector& implicit_functions, const std::vector& mask); + Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& implicit_functions, const std::vector >& positions_vectors); /*! - * \brief Construction from a vector of implicit functions. + * \brief Construction from a vector of implicit functions and a vector of strings. * \param implicit_functions the vector of implicit functions. - * \param mask_str a string from which the vector of signs will be built. It must contains '+' or '-' only. + * \param positions_strings the vector of string. The strings contained in this vector must contain '+' or '-' only. */ - Implicit_multi_domain_to_labeling_function_wrapper (const std::vector& implicit_functions, const std::string& mask_str); + Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& implicit_functions, const std::vector& positions_strings); /// @} }; /* end Implicit_multi_domain_to_labeling_function_wrapper */ diff --git a/Mesh_3/doc/Mesh_3/CGAL/Labeled_mesh_domain_3.h b/Mesh_3/doc/Mesh_3/CGAL/Labeled_mesh_domain_3.h index d24c2842e9b..e443e011564 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Labeled_mesh_domain_3.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Labeled_mesh_domain_3.h @@ -8,6 +8,7 @@ Labeling function f must take its values into N. Let p be a Point. - f(p)=0 means that p is outside domain. - f(p)=a, a!=0 means that p is inside subdomain a. + This class is a model of concept `MeshDomain_3`. Any boundary facet is labeled , a vps; + vps.push_back("--"); + // Domain (Warning: Sphere_3 constructor uses square radius !) - Mesh_domain domain(Function_wrapper(v, "--"), K::Sphere_3(CGAL::ORIGIN, 5.*5.)); + Mesh_domain domain(Function_wrapper(v, vps), K::Sphere_3(CGAL::ORIGIN, 5.*5.)); // Set mesh criteria Mesh_criteria criteria(edge_size = 0.15, diff --git a/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp index 09840fa91e9..e12e8f8e93d 100644 --- a/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp @@ -152,8 +152,11 @@ int main() v.push_back(f1); v.push_back(f2); + std::vector vps; + vps.push_back("--"); + // Domain (Warning: Sphere_3 constructor uses square radius !) - Mesh_domain_with_features domain(Function_wrapper(v, "--"), K::Sphere_3(CGAL::ORIGIN, 5.*5.)); + Mesh_domain_with_features domain(Function_wrapper(v, vps), K::Sphere_3(CGAL::ORIGIN, 5.*5.)); Polylines polylines; create_polylines(polylines); domain.add_features(polylines.begin(),polylines.end()); diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp index faf938fba3d..52e4818f341 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp @@ -52,8 +52,11 @@ int main() v.push_back(f1); v.push_back(f2); + std::vector vps; + vps.push_back("--"); + // Domain (Warning: Sphere_3 constructor uses square radius !) - Mesh_domain domain(Function_wrapper(v, "--"), K::Sphere_3(CGAL::ORIGIN, 5.*5.)); + Mesh_domain domain(Function_wrapper(v, vps), K::Sphere_3(CGAL::ORIGIN, 5.*5.)); // Set mesh criteria Facet_criteria facet_criteria(30, 0.2, 0.02); // angle, size, approximation diff --git a/Mesh_3/include/CGAL/Mesh_3/Implicit_to_labeling_function_wrapper.h b/Mesh_3/include/CGAL/Mesh_3/Implicit_to_labeling_function_wrapper.h index d646cb679c3..661c5d69028 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Implicit_to_labeling_function_wrapper.h +++ b/Mesh_3/include/CGAL/Mesh_3/Implicit_to_labeling_function_wrapper.h @@ -139,76 +139,112 @@ private: }; // end class Implicit_to_labeling_function_wrapper -template +template class Implicit_multi_domain_to_labeling_function_wrapper { public: - // Types typedef int return_type; typedef typename BGT::Point_3 Point_3; - typedef Function_ Function; - typedef std::vector Function_vector; + typedef ImplicitFunction Function; + typedef std::vector Function_vector; private: - std::vector funcs; - std::vector mask; + std::vector funcs; + std::vector > bmasks; public: - Implicit_multi_domain_to_labeling_function_wrapper (const std::vector& funcs) - : funcs(funcs), mask(funcs.size(), NEGATIVE) + Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& vf, const std::vector >& vps) + : funcs(vf), bmasks(vps.size(), boost::dynamic_bitset<>(funcs.size() * 2, false)) + { + std::size_t mask_index = 0; + for (std::vector >::const_iterator mask_iter = vps.begin(), mask_end_iter = vps.end(); + mask_iter != mask_end_iter; + ++mask_iter) { + const std::vector& mask = *mask_iter; + assert(funcs.size() == mask.size()); + boost::dynamic_bitset<>& bmask = bmasks[mask_index++]; + + std::size_t bit_index = 0; + for (std::vector::const_iterator iter = mask.begin(), endIter = mask.end(); iter != endIter; ++iter) + { + std::string::value_type character = *iter; + assert(character == POSITIVE || character == NEGATIVE); + + bmask[bit_index] = character == POSITIVE; + ++bit_index; + bmask[bit_index] = character == NEGATIVE; + ++bit_index; + } + } + std::sort(bmasks.begin(), bmasks.end()); + } + + Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& vf) + : funcs(vf), bmasks(vf.size(), boost::dynamic_bitset<>(funcs.size() * 2, false)) + { + for (std::size_t mask_index = 0; mask_index < bmasks.size(); ++mask_index) + { + boost::dynamic_bitset<>& bmask = bmasks[mask_index]; + + std::size_t bound = ((mask_index+1) * 2); + for (std::size_t i = 1; i < bound; i += 2) + bmask[i] = true; + for (std::size_t i = bound; i < bmask.size(); i += 2) + bmask[i] = true; + } + } + + Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& vf, const std::vector& vps) + : funcs(vf), bmasks(vps.size(), boost::dynamic_bitset<>(funcs.size() * 2, false)) + { + std::size_t mask_index = 0; + for (std::vector::const_iterator mask_iter = vps.begin(), mask_end_iter = vps.end(); + mask_iter != mask_end_iter; + ++mask_iter) + { + const std::string& mask_str = *mask_iter; + assert(funcs.size() == mask_str.length()); + boost::dynamic_bitset<>& bmask = bmasks[mask_index++]; + + std::size_t bit_index = 0; + for (std::string::const_iterator iter = mask_str.begin(), endIter = mask_str.end(); iter != endIter; ++iter) + { + std::string::value_type character = *iter; + assert(character == '+' || character == '-'); + + bmask[bit_index] = character == '+'; + ++bit_index; + bmask[bit_index] = character == '-'; + ++bit_index; + } + } + std::sort(bmasks.begin(), bmasks.end()); + } + + return_type operator() (const Point_3& p, const bool = true) const + { + boost::dynamic_bitset<> bmask(funcs.size() * 2, false); + + std::size_t i = 0; + for (typename std::vector::const_iterator iter = funcs.begin(), endIter = funcs.end(); + iter != endIter; + ++iter) + { + const Function& function = *iter; + + double fres = function(p); + bmask[i] = fres > 0; + ++i; + bmask[i] = fres < 0; + ++i; } - Implicit_multi_domain_to_labeling_function_wrapper (const std::vector& funcs, const std::vector& mask) - : funcs(funcs), mask(mask) - { - assert(funcs.size() == mask.size()); - } - - Implicit_multi_domain_to_labeling_function_wrapper (const std::vector& funcs, const std::string& mask_str) - : funcs(funcs), mask() - { - assert(funcs.size() == mask_str.length()); - - mask.reserve(mask_str.length()); - Sign table [256]; - table['+'] = POSITIVE; - table['-'] = NEGATIVE; - - for (std::string::const_iterator iter = mask_str.begin(), endIter = mask_str.end(); iter != endIter; ++iter) - { - std::string::value_type character = *iter; - assert(character == '+' || character == '-'); - mask.push_back(table[character]); - } - } - - return_type operator()(const Point_3& p, const bool = true) const - { - boost::dynamic_bitset<> result(funcs.size()); - - typename std::vector::const_iterator iter = funcs.begin(), endIter = funcs.end(); - typename std::vector::const_iterator it = mask.begin(), endIt = mask.end(); - boost::dynamic_bitset<> bit(funcs.size(), true); - - for (; iter != endIter; ++iter, ++it, bit <<= 1) - { - const Function& function = *iter; - Sign mask_item = *it; - - double fres = function(p); - Sign sres = ZERO; - if (fres < 0) - sres = NEGATIVE; - else if (fres > 0) - sres = POSITIVE; - - if (sres == mask_item) - result |= bit; - } - - return static_cast(result.to_ulong()); - } + std::vector >::const_iterator iter = std::lower_bound(bmasks.begin(), bmasks.end(), bmask); + if (iter != bmasks.end() && *iter == bmask) + return 1 + (iter - bmasks.begin()); + return 0; + } }; } // end namespace Mesh_3