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