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