mirror of https://github.com/CGAL/cgal
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.
This commit is contained in:
parent
31767a8411
commit
c15ff1c19c
|
|
@ -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
|
||||
<pre>
|
||||
\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
|
||||
</pre>
|
||||
|
||||
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<class Function, class BGT>
|
||||
|
|
@ -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<Function>& 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<Function>& implicit_functions, const std::vector<Sign>& mask);
|
||||
Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& implicit_functions, const std::vector<std::vector<Sign> >& 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<Function>& implicit_functions, const std::string& mask_str);
|
||||
Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& implicit_functions, const std::vector<std::string>& positions_strings);
|
||||
/// @}
|
||||
|
||||
}; /* end Implicit_multi_domain_to_labeling_function_wrapper */
|
||||
|
|
|
|||
|
|
@ -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,b>, a<b, where a and b are the
|
||||
|
|
@ -18,10 +19,10 @@ This class includes a function that provides, the subdomain index of any
|
|||
query point. An intersection between a segment and bounding
|
||||
surfaces is detected when both segment endpoints are associated with different
|
||||
values of subdomain indices. The intersection is then constructed by bisection.
|
||||
The bisection stops when the query segment is shorter than a given error bound
|
||||
`e`. This error bound is given by `e=d`\f$ \times\f$`error_bound` where `d` is the
|
||||
The bisection stops when the query segment is shorter than an error bound
|
||||
`e` given by the product of the
|
||||
length of the diagonal of the bounding box (in world coordinates), or the radius of the bounding sphere, and
|
||||
`error_bound` is the argument passed to the constructor of `Labeled_mesh_domain_3`.
|
||||
a relative error bound passed as argument to the constructor of `Labeled_mesh_domain_3`.
|
||||
|
||||
|
||||
\tparam Labeling_function is the type of the input function.
|
||||
|
|
@ -46,40 +47,40 @@ public:
|
|||
/// @{
|
||||
|
||||
/*!
|
||||
\brief Construction from a labeling function and a Sphere as bounding space.
|
||||
\brief Construction from a labeling function, a bounding Sphere and a relative error bound.
|
||||
\param f the labeling function.
|
||||
\param bounding_sphere the bounding sphere of the meshable space.
|
||||
\param error_bound is the relative error bound used to compute intersection points between the implicit surface and query segments. The
|
||||
bisection is stopped when the length of the intersected segment is less than the product of `bound` by the radius of
|
||||
\param relative_error_bound is the relative error bound used to compute intersection points between the implicit surface and query segments. The
|
||||
bisection is stopped when the length of the intersected segment is less than the product of `relative_error_bound` by the radius of
|
||||
`bounding_sphere`.
|
||||
*/
|
||||
Labeled_mesh_domain_3(const Labeling_function& f,
|
||||
const Sphere_3& bounding_sphere,
|
||||
const FT& error_bound = FT(1e-3));
|
||||
const FT& relative_error_bound = FT(1e-3));
|
||||
|
||||
/*!
|
||||
\brief Construction from a labeling function and a Bbox_3 as bounding space.
|
||||
\brief Construction from a labeling function, a bounding box and a relative error bound.
|
||||
\param f the labeling function.
|
||||
\param bbox the bounding box of the meshable space.
|
||||
\param error_bound is the relative error bound used to compute intersection points between the implicit surface and query segments. The
|
||||
bisection is stopped when the length of the intersected segment is less than the product of `bound` by the diagonal of
|
||||
\param relative_error_bound is the relative error bound used to compute intersection points between the implicit surface and query segments. The
|
||||
bisection is stopped when the length of the intersected segment is less than the product of `relative_error_bound` by the diagonal of
|
||||
`bounding_box`.
|
||||
*/
|
||||
Labeled_mesh_domain_3(const Labeling_function& f,
|
||||
const Bbox_3& bbox,
|
||||
const FT& error_bound = FT(1e-3));
|
||||
const FT& relative_error_bound = FT(1e-3));
|
||||
|
||||
/*!
|
||||
\brief Construction from a function and an Iso_cuboid_3 as bounding space.
|
||||
\brief Construction from a function, a bounding Iso_cuboid_3 and a relative error bound.
|
||||
\param f the function.
|
||||
\param bbox the bounding box of the meshable space.
|
||||
\param error_bound is the relative error bound used to compute intersection points between the implicit surface and query segments. The
|
||||
bisection is stopped when the length of the intersected segment is less than the product of `bound` by the diagonal of
|
||||
\param relative_error_bound is the relative error bound used to compute intersection points between the implicit surface and query segments. The
|
||||
bisection is stopped when the length of the intersected segment is less than the product of `relative_error_bound` by the diagonal of
|
||||
`bounding_box`.
|
||||
*/
|
||||
Labeled_mesh_domain_3(const Labeling_function& f,
|
||||
const Iso_cuboid_3& bbox,
|
||||
const FT& error_bound = FT(1e-3));
|
||||
const FT& relative_error_bound = FT(1e-3));
|
||||
|
||||
/// @}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,8 +69,11 @@ int main()
|
|||
v.push_back(f1);
|
||||
v.push_back(f2);
|
||||
|
||||
std::vector<std::string> 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,
|
||||
|
|
|
|||
|
|
@ -152,8 +152,11 @@ int main()
|
|||
v.push_back(f1);
|
||||
v.push_back(f2);
|
||||
|
||||
std::vector<std::string> 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());
|
||||
|
|
|
|||
|
|
@ -52,8 +52,11 @@ int main()
|
|||
v.push_back(f1);
|
||||
v.push_back(f2);
|
||||
|
||||
std::vector<std::string> 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
|
||||
|
|
|
|||
|
|
@ -139,76 +139,112 @@ private:
|
|||
|
||||
}; // end class Implicit_to_labeling_function_wrapper
|
||||
|
||||
template<class Function_, class BGT>
|
||||
template <class ImplicitFunction, class BGT>
|
||||
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_> Function_vector;
|
||||
typedef ImplicitFunction Function;
|
||||
typedef std::vector<Function> Function_vector;
|
||||
|
||||
private:
|
||||
std::vector<Function> funcs;
|
||||
std::vector<Sign> mask;
|
||||
std::vector<Function> funcs;
|
||||
std::vector<boost::dynamic_bitset<> > bmasks;
|
||||
|
||||
public:
|
||||
Implicit_multi_domain_to_labeling_function_wrapper (const std::vector<Function>& funcs)
|
||||
: funcs(funcs), mask(funcs.size(), NEGATIVE)
|
||||
Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& vf, const std::vector<std::vector<Sign> >& vps)
|
||||
: funcs(vf), bmasks(vps.size(), boost::dynamic_bitset<>(funcs.size() * 2, false))
|
||||
{
|
||||
std::size_t mask_index = 0;
|
||||
for (std::vector<std::vector<Sign> >::const_iterator mask_iter = vps.begin(), mask_end_iter = vps.end();
|
||||
mask_iter != mask_end_iter;
|
||||
++mask_iter)
|
||||
{
|
||||
const std::vector<Sign>& mask = *mask_iter;
|
||||
assert(funcs.size() == mask.size());
|
||||
boost::dynamic_bitset<>& bmask = bmasks[mask_index++];
|
||||
|
||||
std::size_t bit_index = 0;
|
||||
for (std::vector<Sign>::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<std::string>& vps)
|
||||
: funcs(vf), bmasks(vps.size(), boost::dynamic_bitset<>(funcs.size() * 2, false))
|
||||
{
|
||||
std::size_t mask_index = 0;
|
||||
for (std::vector<std::string>::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<Function>::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<Function>& funcs, const std::vector<Sign>& mask)
|
||||
: funcs(funcs), mask(mask)
|
||||
{
|
||||
assert(funcs.size() == mask.size());
|
||||
}
|
||||
|
||||
Implicit_multi_domain_to_labeling_function_wrapper (const std::vector<Function>& 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<Function>::const_iterator iter = funcs.begin(), endIter = funcs.end();
|
||||
typename std::vector<Sign>::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<return_type>(result.to_ulong());
|
||||
}
|
||||
std::vector<boost::dynamic_bitset<> >::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
|
||||
|
|
|
|||
Loading…
Reference in New Issue