diff --git a/Installation/changes.html b/Installation/changes.html index f9fffa21871..c8e021832b8 100644 --- a/Installation/changes.html +++ b/Installation/changes.html @@ -251,6 +251,9 @@ and src/ directories). (re)compute circumcenters and sliver criterion values only when needed. +
  • Add a new constructor for the class Labeled_mesh_domain_3 which takes an Iso_cuboid_3. + Add a new labeling function wrapper for meshing multi-domain. +
  • Triangulated Surface Mesh Simplification

    diff --git a/Mesh_3/applications/CMakeLists.txt b/Mesh_3/applications/CMakeLists.txt index 94144bcbafa..7324e7ef359 100644 --- a/Mesh_3/applications/CMakeLists.txt +++ b/Mesh_3/applications/CMakeLists.txt @@ -38,7 +38,7 @@ if ( CGAL_FOUND ) endif() create_single_source_cgal_program( "mesh_polyhedral_domain.cpp" ) create_single_source_cgal_program( "output_distribution_to_stdout.cpp" ) -# create_single_source_cgal_program( "mesher_tester.cpp" "../examples/Mesh_3/implicit_functions.cpp" ) + create_single_source_cgal_program( "mesher_tester.cpp" "../examples/Mesh_3/implicit_functions.cpp" ) create_single_source_cgal_program( "mesher_tester_image.cpp" ) create_single_source_cgal_program( "mesher_tester_polyhedron.cpp" ) else() diff --git a/Mesh_3/applications/mesh_implicit_domains.cpp b/Mesh_3/applications/mesh_implicit_domains.cpp index 0902c39bded..6b79b66c626 100644 --- a/Mesh_3/applications/mesh_implicit_domains.cpp +++ b/Mesh_3/applications/mesh_implicit_domains.cpp @@ -26,15 +26,15 @@ //****************************************************************************** -#include +#include "debug.h" #include #include #include #include -#include -#include +#include +#include #include #include "../examples/Mesh_3/implicit_functions.h" @@ -51,7 +51,7 @@ using namespace CGAL::parameters; // Domain struct K: public CGAL::Exact_predicates_inexact_constructions_kernel {}; 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; @@ -95,7 +95,7 @@ void set_function(Function_vector& v, { if ( vm.count(function_name) ) { - v.push_back(&f); + v.push_back(f); std::cout << function_name << " "; } } diff --git a/Mesh_3/applications/mesher_tester.cpp b/Mesh_3/applications/mesher_tester.cpp index 3e89a3932d3..ff27fe9ad12 100644 --- a/Mesh_3/applications/mesher_tester.cpp +++ b/Mesh_3/applications/mesher_tester.cpp @@ -14,8 +14,8 @@ #include #include // Implicit domain -#include -#include +#include +#include #include #include "../examples/Mesh_3/implicit_functions.h" @@ -63,7 +63,7 @@ typedef CGAL::Polyhedron_3 Polyhedron; typedef CGAL::Polyhedral_mesh_domain_3 Polyhedral_domain; // Implicit domain typedef FT_to_point_function_wrapper I_Function; -typedef CGAL::Mesh_3::Implicit_vector_to_labeled_function_wrapper I_Function_wrapper; +typedef CGAL::Mesh_3::Implicit_multi_domain_to_labeling_function_wrapper I_Function_wrapper; typedef I_Function_wrapper::Function_vector I_Function_vector; typedef CGAL::Mesh_3::Labeled_mesh_domain_3 Implicit_domain; // 3D Image @@ -121,7 +121,7 @@ void set_implicit_function(I_Function_vector& v, { if(vm.count(function_name)) { - v.push_back(&f); + v.push_back(f); std::cout << function_name << " "; } } @@ -398,7 +398,7 @@ void mesh(const std::string& data, const po::variables_map& vm) //Load the domain std::cout << "****** [" << filename << "] Create domain..."; std::flush(std::cout); - Domain_builder domain_builder(it->string()); + Domain_builder domain_builder(it->path().string()); std::cout <<"done (" << timer.time() << "s) ******\n\n"; while(std::getline(file_param,line_param)) diff --git a/Mesh_3/applications/mesher_tester.h b/Mesh_3/applications/mesher_tester.h index 9f5d9960603..12dd8c36823 100644 --- a/Mesh_3/applications/mesher_tester.h +++ b/Mesh_3/applications/mesher_tester.h @@ -570,7 +570,7 @@ void mesh(const std::string& data, const std::string& output_dir, const int nb_t //Load the domain std::stringstream cout_loc; cout_loc << "+ [" << filename << "] Create domain..."; - std::tr1::shared_ptr > pdomain_builder(new Domain_builder(it->string())); + std::tr1::shared_ptr > pdomain_builder(new Domain_builder(it->path().string())); cout_loc << "done (" << timer.time() << "s)\n"; std::cout << cout_loc.str(); 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 new file mode 100644 index 00000000000..d506857fde8 --- /dev/null +++ b/Mesh_3/doc/Mesh_3/CGAL/Implicit_to_labeling_function_wrapper.h @@ -0,0 +1,64 @@ +namespace CGAL { + +/*! +\ingroup PkgMesh_3Domains + +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. The multidomain is described through a set of function {fi(p), i=1, ...n}. +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. +This wrapper class can be passed to `Labeled_mesh_domain_3` as first template parameter. + +\par Example +For example, the multidomain described by the three funstions [f1,f2,f3] and the two sign vectors [-,-,+] and [+,-,+] + includes two components.
    +The first one matches the locus of points satisfying f1(p)<0 and f2(p)<0 and f3(p)>0.
    +The second one matches the locus of points satisfying f1(p)>0 and f2(p)<0 and f3(p)>0.
    + +\tparam Function provides the definition of the function. +This parameter stands for a model of the concept ImplicitFunction described in the surface mesh generation package. +The number types Function::FT and BGT::FT are required to match. + +\sa `Implicit_mesh_domain_3`. + +*/ +template +class Implicit_multi_domain_to_labeling_function_wrapper +{ +public: + /// \name Types + /// @{ + //! + typedef std::vector Function_vector; + //! + typedef typename Function::Point Point_3; + /// @} + + /// \name Creation + /// @{ + /*! + * \brief Construction from a vector of implicit functions. + * \param implicit_functions the vector of implicit functions. + * + * Poistions vectors are built automatically so that the union of components equals the union of the functions. + */ + Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& 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 positions_vectors the vector of vector of signs. Each vector of position describes a component. + * \sa `Sign` + */ + 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 and a vector of strings. + * \param implicit_functions the vector of implicit functions. + * \param positions_strings the vector of string. The strings contained in this vector must contain '+' or '-' only. Each string (vector of positions) describes a component. + */ + 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 */ +/// @} +} /* end namespace CGAL */ 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 new file mode 100644 index 00000000000..8755edeeb8c --- /dev/null +++ b/Mesh_3/doc/Mesh_3/CGAL/Labeled_mesh_domain_3.h @@ -0,0 +1,96 @@ +namespace CGAL { + +/*! +\ingroup PkgMesh_3Domains + +\brief The class `Labeled_mesh_domain_3` implements indexed domains. + +This class is a model of concept `MeshDomain_3`. + +Any boundary facet is labeled , a, where b!=0. + +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 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 +a relative error bound passed as argument to the constructor of `Labeled_mesh_domain_3`. + +Implicit_mesh_domain_3 is a heir of Labeled_mesh_domain_3. It uses a satisfying labeling function if there is only one component to mesh. + +\tparam LabelingFunction is the type of the input function.
    +This parameter stands for a model of the concept ImplicitFunction described in the surface mesh generation package.
    +Labeling function f must return 0 if the point isn't located in any subdomain. Usually, the return type of labeling functions are integer.
    +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.
    • +
    +Implicit_multi_domain_to_labeling_function_wrapper is a good candidate for this template parameter +if there are several components to mesh. + +\tparam BGT is a geometric traits class that provides +the basic operations to implement +intersection tests and intersection computations +through a bisection method. This parameter must be instantiated +with a model of the concept `BisectionGeometricTraits_3`. + +\cgalModels MeshDomain_3 + +\sa `Implicit_mesh_domain_3` +\sa `Implicit_multi_domain_to_labeling_function_wrapper` +\sa `CGAL::make_mesh_3()`. + +*/ +template +class Labeled_mesh_domain_3 +{ +public: + +/// \name Creation +/// @{ + +/*! +\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 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 LabelingFunction& f, + const Sphere_3& bounding_sphere, + const FT& relative_error_bound = FT(1e-3)); + +/*! +\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 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 LabelingFunction& f, + const Bbox_3& bbox, + const FT& relative_error_bound = FT(1e-3)); + +/*! +\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 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 LabelingFunction& f, + const Iso_cuboid_3& bbox, + const FT& relative_error_bound = FT(1e-3)); + +/// @} + +}; /* end Labeled_mesh_domain_3 */ +} /* end namespace CGAL */ diff --git a/Mesh_3/examples/Mesh_3/CMakeLists.txt b/Mesh_3/examples/Mesh_3/CMakeLists.txt index 6dd0cd0837f..e973b4f6bb4 100644 --- a/Mesh_3/examples/Mesh_3/CMakeLists.txt +++ b/Mesh_3/examples/Mesh_3/CMakeLists.txt @@ -35,7 +35,10 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "mesh_implicit_sphere.cpp" ) create_single_source_cgal_program( "mesh_implicit_sphere_variable_size.cpp" ) create_single_source_cgal_program( "mesh_two_implicit_spheres_with_balls.cpp" ) -# create_single_source_cgal_program( "mesh_implicit_domains.cpp" "implicit_functions.cpp" ) + create_single_source_cgal_program( "mesh_implicit_domains_2.cpp" "implicit_functions.cpp" ) + create_single_source_cgal_program( "mesh_cubes_intersection.cpp" ) + create_single_source_cgal_program( "mesh_cubes_intersection_with_features.cpp" ) + create_single_source_cgal_program( "mesh_implicit_domains.cpp" "implicit_functions.cpp" ) create_single_source_cgal_program( "mesh_polyhedral_domain.cpp" ) create_single_source_cgal_program( "mesh_polyhedral_domain_with_features.cpp" ) if( WITH_CGAL_ImageIO ) diff --git a/Mesh_3/examples/Mesh_3/implicit_functions.h b/Mesh_3/examples/Mesh_3/implicit_functions.h index c8cfd5bc9bd..9ac2f0c1b4e 100644 --- a/Mesh_3/examples/Mesh_3/implicit_functions.h +++ b/Mesh_3/examples/Mesh_3/implicit_functions.h @@ -24,9 +24,13 @@ double sphere_function (double x, double y, double z) // (c=(0,0,0), r=Sq_radius -template -class FT_to_point_function_wrapper : public std::unary_function +template +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 */