+class FT_to_point_function_wrapper : public std::unary_function
{
+public:
+ typedef FType FT;
+ typedef P Point;
+private:
typedef FT (*Implicit_function)(FT, FT, FT);
Implicit_function function;
public:
diff --git a/Mesh_3/examples/Mesh_3/mesh_cubes_intersection.cpp b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection.cpp
new file mode 100644
index 00000000000..4e5aa2072df
--- /dev/null
+++ b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection.cpp
@@ -0,0 +1,97 @@
+
+//******************************************************************************
+// File Description :
+// Outputs to out.mesh a mesh of implicit domains.
+//******************************************************************************
+
+
+
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+// IO
+#include
+
+using namespace CGAL::parameters;
+
+// Domain
+typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
+typedef K::Point_3 Point;
+typedef K::FT FT;
+typedef FT (*Function)(const Point&);
+typedef CGAL::Mesh_3::Implicit_multi_domain_to_labeling_function_wrapper
+ Function_wrapper;
+typedef Function_wrapper::Function_vector Function_vector;
+typedef CGAL::Mesh_3::Labeled_mesh_domain_3 Mesh_domain;
+
+// Triangulation
+typedef CGAL::Mesh_triangulation_3::type Tr;
+typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3;
+
+// Mesh Criteria
+typedef CGAL::Mesh_criteria_3
Mesh_criteria;
+typedef Mesh_criteria::Facet_criteria Facet_criteria;
+typedef Mesh_criteria::Cell_criteria Cell_criteria;
+
+
+double cube_function_1 (const Point& p)
+{
+ if( p.x() >= 0 && p.x() <= 2 &&
+ p.y() >= 0 && p.y() <= 2 &&
+ p.z() >= 0 && p.z() <= 2 )
+ return -1.;
+ return 1.;
+}
+
+double cube_function_2 (const Point& p)
+{
+ if( p.x() >= 1 && p.x() <= 3 &&
+ p.y() >= 1 && p.y() <= 3 &&
+ p.z() >= 1 && p.z() <= 3 )
+ return -1.;
+ return 1.;
+}
+
+int main()
+{
+ // Define functions
+ Function f1 = cube_function_1;
+ Function f2 = cube_function_2;
+
+ Function_vector v;
+ 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, vps), K::Sphere_3(CGAL::ORIGIN, 5.*5.));
+
+ // Set mesh criteria
+ Mesh_criteria criteria(edge_size = 0.15,
+ facet_angle = 30, facet_size = 0.2,
+ cell_radius_edge_ratio = 2, cell_size = 0.4);
+
+ // Mesh generation
+ C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, no_exude(), no_perturb());
+
+ // Perturbation (maximum cpu time: 10s, targeted dihedral angle: default)
+ CGAL::perturb_mesh_3(c3t3, domain, time_limit = 10);
+
+ // Exudation
+ CGAL::exude_mesh_3(c3t3,12);
+
+ // Output
+ std::ofstream medit_file("out_cubes_intersection.mesh");
+ CGAL::output_to_medit(medit_file, c3t3);
+
+ return 0;
+}
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
new file mode 100644
index 00000000000..53b4116e71c
--- /dev/null
+++ b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp
@@ -0,0 +1,184 @@
+
+//******************************************************************************
+// File Description :
+// Outputs to out.mesh a mesh of implicit domains.
+//******************************************************************************
+
+
+
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+// IO
+#include
+
+using namespace CGAL::parameters;
+
+// Domain
+typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
+typedef K::Point_3 Point;
+typedef K::FT FT;
+typedef FT (*Function)(const Point&);
+typedef CGAL::Mesh_3::Implicit_multi_domain_to_labeling_function_wrapper
+ Function_wrapper;
+typedef Function_wrapper::Function_vector Function_vector;
+typedef CGAL::Mesh_3::Labeled_mesh_domain_3 Mesh_domain;
+typedef CGAL::Mesh_domain_with_polyline_features_3 Mesh_domain_with_features;
+
+// Triangulation
+typedef CGAL::Mesh_triangulation_3::type Tr;
+typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3;
+
+// Mesh Criteria
+typedef CGAL::Mesh_criteria_3
Mesh_criteria;
+typedef Mesh_criteria::Facet_criteria Facet_criteria;
+typedef Mesh_criteria::Cell_criteria Cell_criteria;
+
+
+double cube_function_1 (const Point& p)
+{
+ if( p.x() >= 0 && p.x() <= 2 &&
+ p.y() >= 0 && p.y() <= 2 &&
+ p.z() >= 0 && p.z() <= 2 )
+ return -1.;
+ return 1.;
+}
+
+double cube_function_2 (const Point& p)
+{
+ if( p.x() >= 1 && p.x() <= 3 &&
+ p.y() >= 1 && p.y() <= 3 &&
+ p.z() >= 1 && p.z() <= 3 )
+ return -1.;
+ return 1.;
+}
+
+// Polyline
+typedef std::vector Polyline_3;
+typedef std::list Polylines;
+
+void create_polylines (Polylines& polylines)
+{
+ {
+ Polyline_3 polyline;
+ polyline.push_back(Point(1,1,1));
+ polyline.push_back(Point(2,1,1));
+ polylines.push_back(polyline);
+ }
+ {
+ Polyline_3 polyline;
+ polyline.push_back(Point(2,1,1));
+ polyline.push_back(Point(2,2,1));
+ polylines.push_back(polyline);
+ }
+ {
+ Polyline_3 polyline;
+ polyline.push_back(Point(2,2,1));
+ polyline.push_back(Point(1,2,1));
+ polylines.push_back(polyline);
+ }
+ {
+ Polyline_3 polyline;
+ polyline.push_back(Point(1,2,1));
+ polyline.push_back(Point(1,1,1));
+ polylines.push_back(polyline);
+ }
+//----------
+ {
+ Polyline_3 polyline;
+ polyline.push_back(Point(1,1,2));
+ polyline.push_back(Point(2,1,2));
+ polylines.push_back(polyline);
+ }
+ {
+ Polyline_3 polyline;
+ polyline.push_back(Point(2,1,2));
+ polyline.push_back(Point(2,2,2));
+ polylines.push_back(polyline);
+ }
+ {
+ Polyline_3 polyline;
+ polyline.push_back(Point(2,2,2));
+ polyline.push_back(Point(1,2,2));
+ polylines.push_back(polyline);
+ }
+ {
+ Polyline_3 polyline;
+ polyline.push_back(Point(1,2,2));
+ polyline.push_back(Point(1,1,2));
+ polylines.push_back(polyline);
+ }
+ //----------
+ {
+ Polyline_3 polyline;
+ polyline.push_back(Point(1,1,1));
+ polyline.push_back(Point(1,1,2));
+ polylines.push_back(polyline);
+ }
+ {
+ Polyline_3 polyline;
+ polyline.push_back(Point(2,1,1));
+ polyline.push_back(Point(2,1,2));
+ polylines.push_back(polyline);
+ }
+ {
+ Polyline_3 polyline;
+ polyline.push_back(Point(2,2,1));
+ polyline.push_back(Point(2,2,2));
+ polylines.push_back(polyline);
+ }
+ {
+ Polyline_3 polyline;
+ polyline.push_back(Point(1,2,1));
+ polyline.push_back(Point(1,2,2));
+ polylines.push_back(polyline);
+ }
+}
+
+int main()
+{
+ // Define functions
+ Function f1 = cube_function_1;
+ Function f2 = cube_function_2;
+
+ Function_vector v;
+ 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, vps), K::Sphere_3(CGAL::ORIGIN, 5.*5.));
+ Polylines polylines;
+ create_polylines(polylines);
+ domain.add_features(polylines.begin(),polylines.end());
+
+ // Set mesh criteria
+ Mesh_criteria criteria(edge_size = 0.15,
+ facet_angle = 30, facet_size = 0.2,
+ cell_radius_edge_ratio = 2, cell_size = 0.4);
+
+ // Mesh generation
+ C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, no_exude(), no_perturb());
+
+ // Perturbation (maximum cpu time: 10s, targeted dihedral angle: default)
+ CGAL::perturb_mesh_3(c3t3, domain, time_limit = 10);
+
+ // Exudation
+ CGAL::exude_mesh_3(c3t3,12);
+
+ // Output
+ std::ofstream medit_file("out_cubes_intersection_with_features.mesh");
+ CGAL::output_to_medit(medit_file, c3t3);
+
+ return 0;
+}
diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_domains.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_domains.cpp
index 5e62f176986..01867de9d81 100644
--- a/Mesh_3/examples/Mesh_3/mesh_implicit_domains.cpp
+++ b/Mesh_3/examples/Mesh_3/mesh_implicit_domains.cpp
@@ -8,15 +8,15 @@
-#include
+#include "debug.h"
#include
#include
#include
#include
-#include
-#include
+#include
+#include
#include
#include "implicit_functions.h"
@@ -28,7 +28,7 @@ using namespace CGAL::parameters;
// Domain
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef FT_to_point_function_wrapper Function;
-typedef CGAL::Mesh_3::Implicit_vector_to_labeled_function_wrapper
+typedef CGAL::Mesh_3::Implicit_multi_domain_to_labeling_function_wrapper
Function_wrapper;
typedef Function_wrapper::Function_vector Function_vector;
typedef CGAL::Mesh_3::Labeled_mesh_domain_3 Mesh_domain;
@@ -51,8 +51,8 @@ int main()
Function f3(&sphere_function<2>);
Function_vector v;
- v.push_back(&f1);
- v.push_back(&f2);
+ v.push_back(f1);
+ v.push_back(f2);
//v.push_back(&f3);
// Domain (Warning: Sphere_3 constructor uses square radius !)
diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp
new file mode 100644
index 00000000000..9c1cc224f7e
--- /dev/null
+++ b/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp
@@ -0,0 +1,80 @@
+
+//******************************************************************************
+// File Description :
+// Outputs to out.mesh a mesh of implicit domains. These domains are defined
+// by a vector of functions. Each n-uplet of sign of function values defines a
+// subdomain.
+//******************************************************************************
+
+
+
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include "implicit_functions.h"
+
+// IO
+#include
+
+using namespace CGAL::parameters;
+
+// Domain
+typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
+typedef FT_to_point_function_wrapper Function;
+typedef CGAL::Mesh_3::Implicit_multi_domain_to_labeling_function_wrapper
+ Function_wrapper;
+typedef Function_wrapper::Function_vector Function_vector;
+typedef CGAL::Mesh_3::Labeled_mesh_domain_3 Mesh_domain;
+
+// Triangulation
+typedef CGAL::Mesh_triangulation_3::type Tr;
+typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3;
+
+// Mesh Criteria
+typedef CGAL::Mesh_criteria_3
Mesh_criteria;
+typedef Mesh_criteria::Facet_criteria Facet_criteria;
+typedef Mesh_criteria::Cell_criteria Cell_criteria;
+
+
+int main()
+{
+ // Define functions
+ Function f1(&torus_function);
+ Function f2(&sphere_function<5>);
+
+ Function_vector v;
+ 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, vps), K::Sphere_3(CGAL::ORIGIN, 5.*5.));
+
+ // Set mesh criteria
+ Facet_criteria facet_criteria(30, 0.2, 0.02); // angle, size, approximation
+ Cell_criteria cell_criteria(2., 0.4); // radius-edge ratio, size
+ Mesh_criteria criteria(facet_criteria, cell_criteria);
+
+ // Mesh generation
+ C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, no_exude(), no_perturb());
+
+ // Perturbation (maximum cpu time: 10s, targeted dihedral angle: default)
+ CGAL::perturb_mesh_3(c3t3, domain, time_limit = 10);
+
+ // Exudation
+ CGAL::exude_mesh_3(c3t3,12);
+
+ // Output
+ std::ofstream medit_file("out.mesh");
+ CGAL::output_to_medit(medit_file, c3t3);
+
+ return 0;
+}
diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_edge_tolerance_region.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_edge_tolerance_region.cpp
index 2b6fbacffa0..d833c7bc9f3 100644
--- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_edge_tolerance_region.cpp
+++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_edge_tolerance_region.cpp
@@ -15,7 +15,7 @@
#include
#include
-#include
+#include
#include
#include
diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_implicit_function.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_implicit_function.cpp
index b260c1bf2d1..fc9eb9eac0e 100644
--- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_implicit_function.cpp
+++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_implicit_function.cpp
@@ -13,7 +13,7 @@
#include
#include
-#include
+#include
#include
#include
diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_surface_tolerance_region.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_surface_tolerance_region.cpp
index 826d1432a62..5c30a8bde48 100644
--- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_surface_tolerance_region.cpp
+++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_surface_tolerance_region.cpp
@@ -14,7 +14,7 @@
#include
#include
-#include
+#include
#include
#include
diff --git a/Mesh_3/include/CGAL/Implicit_mesh_domain_3.h b/Mesh_3/include/CGAL/Implicit_mesh_domain_3.h
index 16238012a35..3fbd8932ffa 100644
--- a/Mesh_3/include/CGAL/Implicit_mesh_domain_3.h
+++ b/Mesh_3/include/CGAL/Implicit_mesh_domain_3.h
@@ -31,8 +31,8 @@
# pragma warning(disable:4180) // qualifier applied to function type has no meaning; ignored
#endif
-#include
-#include
+#include
+#include
namespace CGAL {
@@ -45,7 +45,7 @@ namespace CGAL {
*/
template >
+ class Wrapper = Mesh_3::Implicit_to_labeling_function_wrapper >
class Implicit_mesh_domain_3
: public Mesh_3::Labeled_mesh_domain_3
{
diff --git a/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h b/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h
new file mode 100644
index 00000000000..07423353e39
--- /dev/null
+++ b/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h
@@ -0,0 +1,290 @@
+// Copyright (c) 2009 INRIA Sophia-Antipolis (France).
+// All rights reserved.
+//
+// This file is part of CGAL (www.cgal.org).
+// You can redistribute it and/or modify it under the terms of the GNU
+// General Public License as published by the Free Software Foundation,
+// either version 3 of the License, or (at your option) any later version.
+//
+// Licensees holding a valid commercial license may use this file in
+// accordance with the commercial license agreement provided with the software.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $URL$
+// $Id$
+//
+//
+// Author(s) : Stéphane Tayeb
+//
+//******************************************************************************
+// File Description :
+// Implicit_to_labeling_function_wrapper and
+// Implicit_vector_to_labeling_function_wrapper class declaration
+// and implementation.
+//
+// See classes description to have more information.
+//******************************************************************************
+
+#ifndef CGAL_MESH_3_IMPLICIT_TO_LABELED_FUNCTION_WRAPPER_H
+#define CGAL_MESH_3_IMPLICIT_TO_LABELED_FUNCTION_WRAPPER_H
+
+
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable:4180) // qualifier applied to function type has no meaning; ignored
+#endif
+
+#include
+
+namespace CGAL {
+
+namespace Mesh_3 {
+
+#include
+
+/**
+ * @class Implicit_to_labeling_function_wrapper
+ *
+ * This class is designed to wrap an implicit function which describes a domain
+ * by [p is inside if f(p)<0] to a function which takes its values into {0,1}.
+ * f(p)=0 means that p is outside the domain.
+ */
+template
+class Implicit_to_labeling_function_wrapper
+{
+public:
+ // Types
+ typedef int return_type;
+ typedef typename BGT::Point_3 Point_3;
+
+ /// Constructor
+ Implicit_to_labeling_function_wrapper(const Function_& f)
+ : r_f_(f) {}
+
+ // Default copy constructor and assignment operator are ok
+
+ /// Destructor
+ ~Implicit_to_labeling_function_wrapper() {}
+
+ /// Operator ()
+ return_type operator()(const Point_3& p, const bool = true) const
+ {
+ return ( (r_f_(p)<0) ? 1 : 0 );
+ }
+
+private:
+ /// Function to wrap
+ const Function_& r_f_;
+
+}; // end class Implicit_to_labeling_function_wrapper
+
+
+
+/**
+ * \deprecated
+ *
+ * @class Implicit_vector_to_labeling_function_wrapper
+ *
+ * Wraps a set of implicit function [f1,f2,...] to one function F which
+ * takes its values into N.
+ *
+ * Let p be a point.
+ * F(p) = 0b000000(f2(p)<0)(f1(p)<0)
+ *
+ * It can handle at most 8 functions.
+ */
+template
+class Implicit_vector_to_labeling_function_wrapper
+{
+public:
+ // Types
+ typedef int return_type;
+ typedef std::vector Function_vector;
+ typedef typename BGT::Point_3 Point_3;
+
+ /// Constructor
+ Implicit_vector_to_labeling_function_wrapper(const std::vector& v)
+ : function_vector_(v) {}
+
+ // Default copy constructor and assignment operator are ok
+
+ /// Destructor
+ ~Implicit_vector_to_labeling_function_wrapper() {}
+
+ /// Operator ()
+ return_type operator()(const Point_3& p, const bool = true) const
+ {
+ int nb_func = function_vector_.size();
+ if ( nb_func > 8 )
+ {
+ CGAL_error_msg("We support at most 8 functions !");
+ }
+
+ char bits = 0;
+ for ( int i = 0 ; i < nb_func ; ++i )
+ {
+ // Insert value into bits : we compute fi(p) and insert result at
+ // bit i of bits
+ bits |= ( ((*function_vector_[i])(p) < 0) << i );
+ }
+
+ return ( static_cast(bits) );
+ }
+
+private:
+ /// Functions to wrap
+ const Function_vector function_vector_;
+
+}; // end class Implicit_to_labeling_function_wrapper
+
+template
+class Implicit_multi_domain_to_labeling_function_wrapper
+{
+ template
+ class Implicit_function_traits
+ {
+ public:
+ typedef typename T_::Point Point;
+ };
+
+ template
+ class Implicit_function_traits
+ {
+ public:
+ typedef typename boost::remove_reference<
+ typename boost::remove_cv< Point_ >::type>::type Point;
+ };
+
+public:
+ typedef int return_type;
+ typedef ImplicitFunction Function;
+ typedef typename Implicit_function_traits::Point Point_3;
+ typedef std::vector Function_vector;
+
+private:
+ std::vector funcs;
+ std::vector > bmasks;
+
+public:
+ 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))
+ {
+ assert(funcs.size());
+
+ 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)
+ {
+ assert(funcs.size());
+
+ bmasks.reserve((1 << funcs.size()) - 1);
+ bmasks.push_back(boost::dynamic_bitset<>(std::string("10")));
+ bmasks.push_back(boost::dynamic_bitset<>(std::string("01")));
+
+ for (std::size_t i = 0; i < funcs.size()-1; ++i)
+ {
+ std::size_t c_size = bmasks.size();
+ for (std::size_t index = 0; index < c_size; ++index)
+ {
+ boost::dynamic_bitset<> aux = bmasks[index];
+ aux.push_back(true);
+ aux.push_back(false);
+ bmasks.push_back(aux);
+ bmasks[index].push_back(false);
+ bmasks[index].push_back(true);
+ }
+ }
+ bmasks.pop_back();
+ std::sort(bmasks.begin(), bmasks.end());
+ }
+
+ 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))
+ {
+ assert(funcs.size());
+
+ 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;
+ }
+
+ std::vector >::const_iterator iter = std::lower_bound(bmasks.begin(), bmasks.end(), bmask);
+ if (iter != bmasks.end() && *iter == bmask)
+ return static_cast(1 + (iter - bmasks.begin()));
+ return 0;
+ }
+};
+
+} // end namespace Mesh_3
+
+} // end namespace CGAL
+
+
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif // CGAL_MESH_3_IMPLICIT_TO_LABELED_FUNCTION_WRAPPER_H
diff --git a/Mesh_3/include/CGAL/Labeled_image_mesh_domain_3.h b/Mesh_3/include/CGAL/Labeled_image_mesh_domain_3.h
index 74fba59dfd7..a8da575e9be 100644
--- a/Mesh_3/include/CGAL/Labeled_image_mesh_domain_3.h
+++ b/Mesh_3/include/CGAL/Labeled_image_mesh_domain_3.h
@@ -28,7 +28,7 @@
#define CGAL_LABELED_IMAGE_MESH_DOMAIN_3_H
-#include
+#include
#include
diff --git a/Mesh_3/include/CGAL/Mesh_3/Labeled_mesh_domain_3.h b/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h
similarity index 97%
rename from Mesh_3/include/CGAL/Mesh_3/Labeled_mesh_domain_3.h
rename to Mesh_3/include/CGAL/Labeled_mesh_domain_3.h
index 92062a7c1c7..921cfec98e7 100644
--- a/Mesh_3/include/CGAL/Mesh_3/Labeled_mesh_domain_3.h
+++ b/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h
@@ -68,6 +68,10 @@ public:
typedef typename BGT::Sphere_3 Sphere_3;
typedef CGAL::Bbox_3 Bbox_3;
+protected:
+ typedef typename BGT::Iso_cuboid_3 Iso_cuboid_3;
+
+public:
// Kernel_traits compatibility
typedef BGT R;
@@ -100,6 +104,10 @@ public:
const Bbox_3& bbox,
const FT& error_bound = FT(1e-3));
+ Labeled_mesh_domain_3(const Function& f,
+ const Iso_cuboid_3& bbox,
+ const FT& error_bound = FT(1e-3));
+
/// Destructor
virtual ~Labeled_mesh_domain_3() {}
@@ -408,9 +416,6 @@ public:
// -----------------------------------
-private:
- typedef typename BGT::Iso_cuboid_3 Iso_cuboid_3;
-
private:
/// Returns Surface_patch_index from \c i and \c j
Surface_patch_index make_surface_index(const Subdomain_index i,
@@ -451,7 +456,7 @@ private:
return Iso_cuboid_3(p_min,p_max);
}
-
+
protected:
/// Returns bounding box
const Iso_cuboid_3& bounding_box() const { return bbox_; }
@@ -503,6 +508,18 @@ Labeled_mesh_domain_3::Labeled_mesh_domain_3(
// TODO : CGAL_ASSERT(0 < f(bounding_sphere.get_center()) ) ?
}
+template
+Labeled_mesh_domain_3::Labeled_mesh_domain_3(
+ const F& f,
+ const Iso_cuboid_3& bbox,
+ const FT& error_bound )
+: function_(f)
+, bbox_(bbox)
+, squared_error_bound_(squared_error_bound(bbox_,error_bound))
+{
+ // TODO : CGAL_ASSERT(0 < f( bbox.get_center()) ) ?
+}
+
template
diff --git a/Mesh_3/include/CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h b/Mesh_3/include/CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h
deleted file mode 100644
index ef0eab9f6cb..00000000000
--- a/Mesh_3/include/CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright (c) 2009 INRIA Sophia-Antipolis (France).
-// All rights reserved.
-//
-// This file is part of CGAL (www.cgal.org).
-// You can redistribute it and/or modify it under the terms of the GNU
-// General Public License as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// Licensees holding a valid commercial license may use this file in
-// accordance with the commercial license agreement provided with the software.
-//
-// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
-// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-//
-// $URL$
-// $Id$
-//
-//
-// Author(s) : Stéphane Tayeb
-//
-//******************************************************************************
-// File Description :
-// Implicit_to_labeled_function_wrapper and
-// Implicit_vector_to_labeled_function_wrapper class declaration
-// and implementation.
-//
-// See classes description to have more information.
-//******************************************************************************
-
-#ifndef CGAL_MESH_3_IMPLICIT_TO_LABELED_FUNCTION_WRAPPER_H
-#define CGAL_MESH_3_IMPLICIT_TO_LABELED_FUNCTION_WRAPPER_H
-
-
-#if defined(BOOST_MSVC)
-# pragma warning(push)
-# pragma warning(disable:4180) // qualifier applied to function type has no meaning; ignored
-#endif
-
-namespace CGAL {
-
-namespace Mesh_3 {
-
-#include
-
-/**
- * @class Implicit_to_labeled_function_wrapper
- *
- * This class is designed to wrap an implicit function which describes a domain
- * by [p is inside if f(p)<0] to a function which takes its values into {0,1}.
- * f(p)=0 means that p is outside the domain.
- */
-template
-class Implicit_to_labeled_function_wrapper
-{
-public:
- // Types
- typedef int return_type;
- typedef typename BGT::Point_3 Point_3;
-
- /// Constructor
- Implicit_to_labeled_function_wrapper(const Function_& f)
- : r_f_(f) {}
-
- // Default copy constructor and assignment operator are ok
-
- /// Destructor
- ~Implicit_to_labeled_function_wrapper() {}
-
- /// Operator ()
- return_type operator()(const Point_3& p, const bool = true) const
- {
- return ( (r_f_(p)<0) ? 1 : 0 );
- }
-
-private:
- /// Function to wrap
- const Function_& r_f_;
-
-}; // end class Implicit_to_labeled_function_wrapper
-
-
-
-/**
- * @class Implicit_vector_to_labeled_function_wrapper
- *
- * Wraps a set of implicit function [f1,f2,...] to one function F which
- * takes its values into N.
- *
- * Let p be a point.
- * F(p) = 0b000000(f2(p)<0)(f1(p)<0)
- *
- * It can handle at most 8 functions.
- */
-template
-class Implicit_vector_to_labeled_function_wrapper
-{
-public:
- // Types
- typedef int return_type;
- typedef std::vector Function_vector;
- typedef typename BGT::Point_3 Point_3;
-
- /// Constructor
- Implicit_vector_to_labeled_function_wrapper(const std::vector& v)
- : function_vector_(v) {}
-
- // Default copy constructor and assignment operator are ok
-
- /// Destructor
- ~Implicit_vector_to_labeled_function_wrapper() {}
-
- /// Operator ()
- return_type operator()(const Point_3& p, const bool = true) const
- {
- int nb_func = function_vector_.size();
- if ( nb_func > 8 )
- {
- CGAL_error_msg("We support at most 8 functions !");
- }
-
- char bits = 0;
- for ( int i = 0 ; i < nb_func ; ++i )
- {
- // Insert value into bits : we compute fi(p) and insert result at
- // bit i of bits
- bits |= ( ((*function_vector_[i])(p) < 0) << i );
- }
-
- return ( static_cast(bits) );
- }
-
-private:
- /// Functions to wrap
- const Function_vector function_vector_;
-
-}; // end class Implicit_to_labeled_function_wrapper
-
-
-} // end namespace Mesh_3
-
-} // end namespace CGAL
-
-
-
-#if defined(BOOST_MSVC)
-# pragma warning(pop)
-#endif
-
-#endif // CGAL_MESH_3_IMPLICIT_TO_LABELED_FUNCTION_WRAPPER_H
diff --git a/Mesh_3/test/Mesh_3/CMakeLists.txt b/Mesh_3/test/Mesh_3/CMakeLists.txt
index 547412ea87f..b8cf9421043 100644
--- a/Mesh_3/test/Mesh_3/CMakeLists.txt
+++ b/Mesh_3/test/Mesh_3/CMakeLists.txt
@@ -25,10 +25,12 @@ if ( CGAL_FOUND )
create_single_source_cgal_program( "test_backward_compatibility.cpp" )
create_single_source_cgal_program( "test_boost_has_xxx.cpp" )
create_single_source_cgal_program( "test_c3t3.cpp" )
+ create_single_source_cgal_program( "test_implicit_multi_domain_to_labeling_function_wrapper.cpp" )
create_single_source_cgal_program( "test_c3t3_io.cpp" )
create_single_source_cgal_program( "test_c3t3_with_features.cpp" )
create_single_source_cgal_program( "test_criteria.cpp" )
create_single_source_cgal_program( "test_domain_with_polyline_features.cpp" )
+ create_single_source_cgal_program( "test_labeled_mesh_domain_3.cpp" )
create_single_source_cgal_program( "test_mesh_criteria_creation.cpp" )
if(CGAL_ImageIO_USE_ZLIB)
create_single_source_cgal_program( "test_meshing_3D_image.cpp" )
diff --git a/Mesh_3/test/Mesh_3/test_implicit_multi_domain_to_labeling_function_wrapper.cpp b/Mesh_3/test/Mesh_3/test_implicit_multi_domain_to_labeling_function_wrapper.cpp
new file mode 100644
index 00000000000..41b001d01c8
--- /dev/null
+++ b/Mesh_3/test/Mesh_3/test_implicit_multi_domain_to_labeling_function_wrapper.cpp
@@ -0,0 +1,141 @@
+#include
+#include
+
+
+typedef CGAL::Exact_predicates_inexact_constructions_kernel K_e_i;
+typedef K_e_i::Point_3 Point_3;
+typedef double (Function) (const Point_3&);
+
+typedef CGAL::Mesh_3::Implicit_multi_domain_to_labeling_function_wrapper Labeling_function;
+typedef Labeling_function::Function_vector Function_vector;
+
+
+double cube_function_1 (const Point_3& p)
+{
+ if( p.x() > 0 && p.x() < 2 &&
+ p.y() > 0 && p.y() < 2 &&
+ p.z() > 0 && p.z() < 2 )
+ return -1.;
+ return 1.;
+}
+
+double cube_function_2 (const Point_3& p)
+{
+ if( p.x() > 1 && p.x() < 3 &&
+ p.y() > 1 && p.y() < 3 &&
+ p.z() > 1 && p.z() < 3 )
+ return -1.;
+ return 1.;
+}
+
+
+void test_constructor_vfunc ()
+{
+ Function_vector vfunc;
+ vfunc.push_back(cube_function_1);
+ vfunc.push_back(cube_function_2);
+
+ Labeling_function lfunc(vfunc);
+
+ Point_3 p1(0.5, 0.5, 0.5);
+ Point_3 p2(2.5, 2.5, 2.5);
+ Point_3 p3(1.5, 1.5, 1.5);
+ Point_3 p_out(4., 4., 4.);
+
+ Labeling_function::return_type rp1 = lfunc(p1);
+ Labeling_function::return_type rp2 = lfunc(p2);
+ Labeling_function::return_type rp3 = lfunc(p3);
+ Labeling_function::return_type rp_out = lfunc(p_out);
+
+ assert(rp1 != 0);
+ assert(rp2 != 0);
+ assert(rp3 != 0);
+ assert(rp_out == 0);
+
+ assert(rp1 != rp2);
+ assert(rp1 != rp3);
+ assert(rp2 != rp3);
+}
+
+void test_constructor_vfunc_vvpos ()
+{
+ Function_vector vfunc;
+ vfunc.push_back(cube_function_1);
+ vfunc.push_back(cube_function_2);
+
+ std::vector > vvpos;
+ std::vector vpos1;
+ vpos1.push_back(CGAL::NEGATIVE);
+ vpos1.push_back(CGAL::POSITIVE);
+ vvpos.push_back(vpos1);
+ std::vector vpos2;
+ vpos2.push_back(CGAL::POSITIVE);
+ vpos2.push_back(CGAL::NEGATIVE);
+ vvpos.push_back(vpos2);
+ std::vector vpos3;
+ vpos3.push_back(CGAL::NEGATIVE);
+ vpos3.push_back(CGAL::NEGATIVE);
+ vvpos.push_back(vpos3);
+
+ Labeling_function lfunc(vfunc, vvpos);
+
+ Point_3 p1(0.5, 0.5, 0.5);
+ Point_3 p2(2.5, 2.5, 2.5);
+ Point_3 p3(1.5, 1.5, 1.5);
+ Point_3 p_out(4., 4., 4.);
+
+ Labeling_function::return_type rp1 = lfunc(p1);
+ Labeling_function::return_type rp2 = lfunc(p2);
+ Labeling_function::return_type rp3 = lfunc(p3);
+ Labeling_function::return_type rp_out = lfunc(p_out);
+
+ assert(rp1 != 0);
+ assert(rp2 != 0);
+ assert(rp3 != 0);
+ assert(rp_out == 0);
+
+ assert(rp1 != rp2);
+ assert(rp1 != rp3);
+ assert(rp2 != rp3);
+}
+
+void test_constructor_vfunc_vstr ()
+{
+ Function_vector vfunc;
+ vfunc.push_back(cube_function_1);
+ vfunc.push_back(cube_function_2);
+
+ std::vector vstr;
+ vstr.push_back("-+");
+ vstr.push_back("+-");
+ vstr.push_back("--");
+
+ Labeling_function lfunc(vfunc, vstr);
+
+ Point_3 p1(0.5, 0.5, 0.5);
+ Point_3 p2(2.5, 2.5, 2.5);
+ Point_3 p3(1.5, 1.5, 1.5);
+ Point_3 p_out(4., 4., 4.);
+
+ Labeling_function::return_type rp1 = lfunc(p1);
+ Labeling_function::return_type rp2 = lfunc(p2);
+ Labeling_function::return_type rp3 = lfunc(p3);
+ Labeling_function::return_type rp_out = lfunc(p_out);
+
+ assert(rp1 != 0);
+ assert(rp2 != 0);
+ assert(rp3 != 0);
+ assert(rp_out == 0);
+
+ assert(rp1 != rp2);
+ assert(rp1 != rp3);
+ assert(rp2 != rp3);
+}
+
+int main ()
+{
+ test_constructor_vfunc();
+ test_constructor_vfunc_vvpos();
+ test_constructor_vfunc_vstr();
+ return 0;
+}
diff --git a/Mesh_3/test/Mesh_3/test_labeled_mesh_domain_3.cpp b/Mesh_3/test/Mesh_3/test_labeled_mesh_domain_3.cpp
new file mode 100644
index 00000000000..8f85dd71492
--- /dev/null
+++ b/Mesh_3/test/Mesh_3/test_labeled_mesh_domain_3.cpp
@@ -0,0 +1,258 @@
+// Copyright (c) 2009 INRIA Sophia-Antipolis (France).
+// All rights reserved.
+//
+// This file is part of CGAL (www.cgal.org).
+// You can redistribute it and/or modify it under the terms of the GNU
+// General Public License as published by the Free Software Foundation,
+// either version 3 of the License, or (at your option) any later version.
+//
+// Licensees holding a valid commercial license may use this file in
+// accordance with the commercial license agreement provided with the software.
+//
+// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// $URL$
+// $Id$
+//
+//
+// Author(s) : Stephane Tayeb
+//
+//******************************************************************************
+// File Description :
+//******************************************************************************
+
+#include "test_meshing_utilities.h"
+#include
+#include
+
+
+template
+struct LM3_tester
+{
+ typedef typename K::Point_3 Point_3;
+ typedef typename K::FT FT;
+
+ typedef FT (Function)(const Point_3&);
+ typedef CGAL::Mesh_3::Implicit_to_labeling_function_wrapper Function_wrapper;
+ typedef CGAL::Mesh_3::Labeled_mesh_domain_3 Mesh_domain;
+
+ static FT shape_function (const Point_3& p)
+ {
+ if (p.x() < 0)
+ return -1;
+ const FT x2=p.x()*p.x(), y2=p.y()*p.y(), z2=p.z()*p.z();
+ return x2 + y2 + z2 - 1;
+ }
+
+ static FT sphere_function (const Point_3& p)
+ {
+ const FT x2=p.x()*p.x(), y2=p.y()*p.y(), z2=p.z()*p.z();
+ return x2 + y2 + z2 - 1;
+ }
+
+ void operator() () const
+ {
+ typedef typename K::Sphere_3 Sphere_3;
+ typedef typename K::Iso_cuboid_3 Iso_cuboid_3;
+
+ test_domain(Sphere_3(CGAL::ORIGIN, 4.));
+ test_domain(CGAL::Bbox_3(-2.,-2.,-2., 2.,2.,2.));
+ test_domain(Iso_cuboid_3(Point_3(-2.,-2.,-2.), Point_3(2.,2.,2.)));
+ }
+
+private:
+ template
+ void test_domain (const BoundingShape& bounding_shape) const
+ {
+ FT error_bound(1e-3);
+
+ Function_wrapper wrapper_1(sphere_function);
+ Mesh_domain domain(wrapper_1, bounding_shape, error_bound);
+ test_construct_initial_points(domain, error_bound);
+
+ Function_wrapper wrapper_2(shape_function);
+ Mesh_domain domain_2(wrapper_2, bounding_shape, error_bound);
+ test_is_in_domain(domain_2);
+ test_do_intersect_surface(domain_2);
+ test_construct_intersection(domain_2);
+ }
+
+ void test_construct_initial_points (const Mesh_domain& domain, FT error_bound) const
+ {
+ typedef typename Mesh_domain::Construct_initial_points Construct_initial_points;
+ typedef typename Mesh_domain::Index Index;
+ typedef typename std::vector >::const_iterator Points_const_iterator;
+ typedef typename K::Compute_squared_distance_3 Compute_squared_distance_3;
+
+ Compute_squared_distance_3 squared_distance = K().compute_squared_distance_3_object();
+
+ Construct_initial_points construct_initial_points = domain.construct_initial_points_object();
+ std::vector > points;
+ int point_count = 12;
+ construct_initial_points(std::back_inserter(points), point_count);
+
+ for (Points_const_iterator iter = points.begin(), end_iter = points.end(); iter != end_iter; ++iter)
+ {
+ const Point_3& p = iter->first;
+
+ FT sd = squared_distance(CGAL::ORIGIN, p);
+ FT diff = sd - 1;
+ if (diff < FT(0.))
+ diff = -diff;
+ assert(diff <= error_bound);
+ }
+ }
+
+ void test_is_in_domain (const Mesh_domain& domain) const
+ {
+ typedef typename Mesh_domain::Is_in_domain Is_in_domain;
+ typedef typename Mesh_domain::Subdomain Subdomain;
+ typedef typename Mesh_domain::Subdomain_index Subdomain_index;
+
+ Is_in_domain is_in_domain = domain.is_in_domain_object();
+
+ {
+ Subdomain subdomain = is_in_domain(Point_3(CGAL::ORIGIN));
+ assert(subdomain);
+ Subdomain_index subdomain_index = *subdomain;
+ assert(subdomain_index == 1);
+ }
+
+ {
+ Subdomain subdomain = is_in_domain(Point_3(1.5, 0., 0.));
+ assert(!subdomain);
+ }
+ }
+
+ void test_do_intersect_surface (const Mesh_domain& domain) const
+ {
+ typedef typename Mesh_domain::Do_intersect_surface Do_intersect_surface;
+ typedef typename Mesh_domain::Surface_patch Surface_patch;
+ typedef typename Mesh_domain::Surface_patch_index Surface_patch_index;
+ typedef typename Mesh_domain::Segment_3 Segment_3;
+ typedef typename Mesh_domain::Ray_3 Ray_3;
+ typedef typename Mesh_domain::Line_3 Line_3;
+ typedef typename Mesh_domain::Vector_3 Vector_3;
+
+ Do_intersect_surface do_intersect_surface = domain.do_intersect_surface_object();
+
+ {
+ Segment_3 s(Point_3(CGAL::ORIGIN), Point_3(1.5, 0., 0.));
+ Surface_patch p = do_intersect_surface(s);
+ assert(p);
+ Surface_patch_index pi = *p;
+ assert(pi.first == 0 && pi.second == 1);
+ }
+
+ {
+ Segment_3 s(Point_3(1.5, 1.5, 0.), Point_3(1.5, 0., 0.));
+ Surface_patch p = do_intersect_surface(s);
+ assert(!p);
+ }
+
+ {
+ Ray_3 r(Point_3(CGAL::ORIGIN), Vector_3(1., 0., 0.));
+ Surface_patch p = do_intersect_surface(r);
+ assert(p);
+ Surface_patch_index pi = *p;
+ assert(pi.first == 0 && pi.second == 1);
+ }
+
+ {
+ Ray_3 r(Point_3(1.5, 0., 0.), Vector_3(0., 1., 0.));
+ Surface_patch p = do_intersect_surface(r);
+ assert(!p);
+ }
+
+ {
+ Line_3 l(Point_3(CGAL::ORIGIN), Point_3(1.5, 0., 0.));
+ Surface_patch p = do_intersect_surface(l);
+ assert(p);
+ Surface_patch_index pi = *p;
+ assert(pi.first == 0 && pi.second == 1);
+ }
+
+ {
+ Line_3 l(Point_3(1.5, 0., 0.), Point_3(1.5, 0.5, 0.));
+ Surface_patch p = do_intersect_surface(l);
+ assert(!p);
+ }
+ }
+
+
+ void test_construct_intersection (const Mesh_domain& domain) const
+ {
+ typedef typename Mesh_domain::Construct_intersection Construct_intersection;
+ typedef typename Mesh_domain::Intersection Intersection;
+ typedef typename Mesh_domain::Subdomain_index Subdomain_index;
+ typedef typename Mesh_domain::Surface_patch_index Surface_patch_index;
+ typedef typename Mesh_domain::Index Index;
+ typedef typename Mesh_domain::Segment_3 Segment_3;
+ typedef typename Mesh_domain::Ray_3 Ray_3;
+ typedef typename Mesh_domain::Line_3 Line_3;
+ typedef typename Mesh_domain::Vector_3 Vector_3;
+
+ Construct_intersection construct_intersection = domain.construct_intersection_object();
+
+ {
+ Segment_3 s(Point_3(CGAL::ORIGIN), Point_3(1.5, 0., 0.));
+ Intersection i = construct_intersection(s);
+ assert(CGAL::cpp11::get<0>(i) != Point_3(1., 0., 0.));
+ Index ii = CGAL::cpp11::get<1>(i);
+ assert(boost::get(&ii));
+ assert(CGAL::cpp11::get<2>(i) == 2);
+ }
+
+ {
+ Segment_3 s(Point_3(1.5, 1.5, 0.), Point_3(1.5, 0., 0.));
+ Intersection i = construct_intersection(s);
+ Index ii = CGAL::cpp11::get<1>(i);
+ assert(boost::get(&ii));
+ assert(CGAL::cpp11::get<2>(i) == 0);
+ }
+
+ {
+ Ray_3 r(Point_3(CGAL::ORIGIN), Vector_3(1., 0., 0.));
+ Intersection i = construct_intersection(r);
+ assert(CGAL::cpp11::get<0>(i) != Point_3(1., 0., 0.));
+ Index ii = CGAL::cpp11::get<1>(i);
+ assert(boost::get(&ii));
+ assert(CGAL::cpp11::get<2>(i) == 2);
+ }
+
+ {
+ Ray_3 r(Point_3(1.5, 0., 0.), Vector_3(0., 1., 0.));
+ Intersection i = construct_intersection(r);
+ Index ii = CGAL::cpp11::get<1>(i);
+ assert(boost::get(&ii));
+ assert(CGAL::cpp11::get<2>(i) == 0);
+ }
+
+ {
+ Line_3 l(Point_3(CGAL::ORIGIN), Point_3(1.5, 0., 0.));
+ Intersection i = construct_intersection(l);
+ assert(CGAL::cpp11::get<0>(i) != Point_3(1., 0., 0.));
+ Index ii = CGAL::cpp11::get<1>(i);
+ assert(boost::get(&ii));
+ assert(CGAL::cpp11::get<2>(i) == 2);
+ }
+
+ {
+ Line_3 l(Point_3(1.5, 0., 0.), Point_3(1.5, 0.5, 0.));
+ Intersection i = construct_intersection(l);
+ Index ii = CGAL::cpp11::get<1>(i);
+ assert(boost::get(&ii));
+ assert(CGAL::cpp11::get<2>(i) == 0);
+ }
+ }
+};
+
+
+int main ()
+{
+ LM3_tester test_epic;
+ test_epic();
+
+ return EXIT_SUCCESS;
+}
diff --git a/Surface_mesher/doc/Surface_mesher/Concepts/ImplicitFunction.h b/Surface_mesher/doc/Surface_mesher/Concepts/ImplicitFunction.h
index 1df71a27491..1af848f7d31 100644
--- a/Surface_mesher/doc/Surface_mesher/Concepts/ImplicitFunction.h
+++ b/Surface_mesher/doc/Surface_mesher/Concepts/ImplicitFunction.h
@@ -7,7 +7,7 @@ The concept `ImplicitFunction` describes a function object
whose `operator()` computes the values of a function
\f$ f : \mathbb{R}^3 \longrightarrow \mathbb{R}\f$.
-\cgalHasModel `CGAL::Gray_level_image_3`
+\cgalHasModel CGAL::Gray_level_image_3
\cgalHasModel any pointer to a function of type `FT (*)(Point)`
\sa `CGAL::Implicit_surface_3`
@@ -20,7 +20,7 @@ public:
/// \name Types
/// @{
-
+///The following types aren't required for any pointer to a function of type `FT (*)(Point)`.
/*!
Number type
*/