mirror of https://github.com/CGAL/cgal
Merge branch 'Periodic_3_mesh_3-Extended_mesh_3-MBogdanov'
This small feature adds a new constructor in Labeled_mesh_domain_3 and a new function wrapper. A Labeled_mesh_domain_3 can be built from an Iso_cuboid_3 now. (cf. https://cgal.geometryfactory.com/CGAL/Members/wiki/Features/Small_Features/New_constructor_in_Label_mesh_domain_3_and_new_function_wrapper) The new wrapper, Implicit_multi_domain_to_labeling_function_wrapper, is a helping class to get a function with integer values labeling the components of a multi-domain. This small feature was successfully tested in the internal release CGAL-4.5-Ic-45. Approved by the Release Manager. Conflicts: Installation/changes.html
This commit is contained in:
commit
9f11f46077
|
|
@ -148,6 +148,14 @@ and <code>src/</code> directories).
|
|||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3>3D Mesh Generation</h3>
|
||||
<ul>
|
||||
<li>Add a new constructor for the class <code>Labeled_mesh_domain_3</code> which
|
||||
takes an <code>Iso_cuboid_3</code>.</li>
|
||||
<li>Add a new labeling function wrapper for meshing multi-domain.</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<h2 id="release4.4">Release 4.4 </h2>
|
||||
|
|
@ -158,7 +166,7 @@ and <code>src/</code> directories).
|
|||
<li>Additional supported platforms:
|
||||
<ul>
|
||||
<li>The Apple Clang compiler version 5.0 is now supported on
|
||||
OS X Mavericks.</li>
|
||||
OSXMavericks.</li>
|
||||
<li>The Microsoft Windows Visual C++ compiler 2013 (VC12) is now
|
||||
supported.</li>
|
||||
</ul>
|
||||
|
|
@ -298,7 +306,7 @@ and <code>src/</code> directories).
|
|||
<ul>
|
||||
<li> Better description of the demo ipelets in the user manual </li>
|
||||
<li> New ipelet for pencils of circles</li>
|
||||
<li> New ipelet for hyperbolic geometry in Poincaré model</li>
|
||||
<li> New ipelet for hyperbolic geometry in Poincar model</li>
|
||||
<li> The generator ipelet now generates point in a selected zone</li>
|
||||
<li> Hilbert sort ipelet implements two policies</li>
|
||||
</ul>
|
||||
|
|
@ -340,7 +348,7 @@ and <code>src/</code> directories).
|
|||
constructor added to <code>CGAL::Object</code>. However, it is
|
||||
recommended to upgrade your code. The previous behavior can be
|
||||
restored by defining the
|
||||
macro <code>CGAL_INTERSECTION_VERSION</code> to 1.
|
||||
macro <code>CGAL_INTERSECTION_VERSION</code> to1.
|
||||
</li>
|
||||
</ul>
|
||||
<h4>2D Arrangements</h4>
|
||||
|
|
@ -663,7 +671,7 @@ and <code>src/</code> directories).
|
|||
<li>Additional supported platforms:
|
||||
<ul>
|
||||
<li>The Apple Clang compiler versions 3.1 and 3.2 are now supported on
|
||||
Mac OS X.</li>
|
||||
MacOSX.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Improved configuration for essential and optional external third party software</li>
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -26,15 +26,15 @@
|
|||
//******************************************************************************
|
||||
|
||||
|
||||
#include <debug.h>
|
||||
#include "debug.h"
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Mesh_triangulation_3.h>
|
||||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||
#include <CGAL/Mesh_criteria_3.h>
|
||||
|
||||
#include <CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h>
|
||||
#include <CGAL/Mesh_3/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Implicit_to_labeling_function_wrapper.h>
|
||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/make_mesh_3.h>
|
||||
#include "../examples/Mesh_3/implicit_functions.h"
|
||||
|
||||
|
|
@ -51,10 +51,10 @@ using namespace CGAL::parameters;
|
|||
// Domain
|
||||
struct K: public CGAL::Exact_predicates_inexact_constructions_kernel {};
|
||||
typedef FT_to_point_function_wrapper<K::FT, K::Point_3> Function;
|
||||
typedef CGAL::Mesh_3::Implicit_vector_to_labeled_function_wrapper<Function, K>
|
||||
typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper<Function>
|
||||
Function_wrapper;
|
||||
typedef Function_wrapper::Function_vector Function_vector;
|
||||
typedef CGAL::Mesh_3::Labeled_mesh_domain_3<Function_wrapper, K> Mesh_domain;
|
||||
typedef CGAL::Labeled_mesh_domain_3<Function_wrapper, K> Mesh_domain;
|
||||
|
||||
// Triangulation
|
||||
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
||||
|
|
@ -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 << " ";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@
|
|||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||
#include <CGAL/Mesh_criteria_3.h>
|
||||
// Implicit domain
|
||||
#include <CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h>
|
||||
#include <CGAL/Mesh_3/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Implicit_to_labeling_function_wrapper.h>
|
||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||
|
||||
#include <CGAL/make_mesh_3.h>
|
||||
#include "../examples/Mesh_3/implicit_functions.h"
|
||||
|
|
@ -63,9 +63,9 @@ typedef CGAL::Polyhedron_3<Geom_traits> Polyhedron;
|
|||
typedef CGAL::Polyhedral_mesh_domain_3<Polyhedron, Geom_traits> Polyhedral_domain;
|
||||
// Implicit domain
|
||||
typedef FT_to_point_function_wrapper<K::FT, K::Point_3> I_Function;
|
||||
typedef CGAL::Mesh_3::Implicit_vector_to_labeled_function_wrapper<I_Function, K> I_Function_wrapper;
|
||||
typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper<I_Function> I_Function_wrapper;
|
||||
typedef I_Function_wrapper::Function_vector I_Function_vector;
|
||||
typedef CGAL::Mesh_3::Labeled_mesh_domain_3<I_Function_wrapper, K> Implicit_domain;
|
||||
typedef CGAL::Labeled_mesh_domain_3<I_Function_wrapper, K> Implicit_domain;
|
||||
// 3D Image
|
||||
typedef CGAL::Image_3 Image;
|
||||
typedef CGAL::Labeled_image_mesh_domain_3<Image,K> Image_domain;
|
||||
|
|
@ -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> domain_builder(it->string());
|
||||
Domain_builder<Domain> domain_builder(it->path().string());
|
||||
std::cout <<"done (" << timer.time() << "s) ******\n\n";
|
||||
|
||||
while(std::getline(file_param,line_param))
|
||||
|
|
|
|||
|
|
@ -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<Domain_builder<Domain> > pdomain_builder(new Domain_builder<Domain>(it->string()));
|
||||
std::tr1::shared_ptr<Domain_builder<Domain> > pdomain_builder(new Domain_builder<Domain>(it->path().string()));
|
||||
cout_loc << "done (" << timer.time() << "s)\n";
|
||||
std::cout << cout_loc.str();
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ typedef CGAL::Polyhedral_mesh_domain_with_features_3<Kernel,
|
|||
|
||||
typedef CGAL::Labeled_image_mesh_domain_3<Image,Kernel> Image_mesh_domain;
|
||||
typedef Wrapper<Kernel> Function_wrapper;
|
||||
typedef CGAL::Mesh_3::Labeled_mesh_domain_3<Function_wrapper, Kernel> Function_mesh_domain;
|
||||
typedef CGAL::Labeled_mesh_domain_3<Function_wrapper, Kernel> Function_mesh_domain;
|
||||
|
||||
// Triangulation
|
||||
typedef CGAL::Mesh_triangulation_3<Polyhedral_mesh_domain>::type Tr;
|
||||
|
|
|
|||
|
|
@ -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.<br />
|
||||
The first one matches the locus of points satisfying f1(p)<0 and f2(p)<0 and f3(p)>0.<br />
|
||||
The second one matches the locus of points satisfying f1(p)>0 and f2(p)<0 and f3(p)>0.<br />
|
||||
|
||||
\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 Function>
|
||||
class Implicit_multi_domain_to_labeling_function_wrapper
|
||||
{
|
||||
public:
|
||||
/// \name Types
|
||||
/// @{
|
||||
//!
|
||||
typedef std::vector<Function*> 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<std::vector<Sign> >& 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<std::string>& positions_strings);
|
||||
/// @}
|
||||
|
||||
}; /* end Implicit_multi_domain_to_labeling_function_wrapper */
|
||||
/// @}
|
||||
} /* end namespace CGAL */
|
||||
|
|
@ -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,b>, a<b, where a and b are the
|
||||
tags of its incident subdomain.
|
||||
Thus, a boundary facet of the domain is labeled <0,b>, 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.<br />
|
||||
This parameter stands for a model of the concept ImplicitFunction described in the surface mesh generation package.<br />
|
||||
Labeling function f must return 0 if the point isn't located in any subdomain. Usually, the return type of labeling functions are integer.<br />
|
||||
Let p be a Point.
|
||||
<ul>
|
||||
<li>f(p)=0 means that p is outside domain.</li>
|
||||
<li>f(p)=a, a!=0 means that p is inside subdomain a.</li>
|
||||
</ul>
|
||||
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 LabelingFunction, class BGT>
|
||||
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 */
|
||||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -24,12 +24,13 @@ double sphere_function (double x, double y, double z) // (c=(0,0,0), r=Sq_radius
|
|||
|
||||
|
||||
|
||||
template <typename FT, typename Point>
|
||||
class FT_to_point_function_wrapper : public std::unary_function<Point, FT>
|
||||
template <typename FT, typename P>
|
||||
class FT_to_point_function_wrapper : public std::unary_function<P, FT>
|
||||
{
|
||||
typedef FT (*Implicit_function)(FT, FT, FT);
|
||||
Implicit_function function;
|
||||
public:
|
||||
typedef P Point;
|
||||
FT_to_point_function_wrapper(Implicit_function f) : function(f) {}
|
||||
FT operator()(Point p) const { return function(p.x(), p.y(), p.z()); }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,97 @@
|
|||
|
||||
//******************************************************************************
|
||||
// File Description :
|
||||
// Outputs to out.mesh a mesh of implicit domains.
|
||||
//******************************************************************************
|
||||
|
||||
|
||||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Mesh_triangulation_3.h>
|
||||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||
#include <CGAL/Mesh_criteria_3.h>
|
||||
|
||||
#include <CGAL/Implicit_to_labeling_function_wrapper.h>
|
||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/make_mesh_3.h>
|
||||
|
||||
// IO
|
||||
#include <CGAL/IO/File_medit.h>
|
||||
|
||||
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::Implicit_multi_domain_to_labeling_function_wrapper<Function>
|
||||
Function_wrapper;
|
||||
typedef Function_wrapper::Function_vector Function_vector;
|
||||
typedef CGAL::Labeled_mesh_domain_3<Function_wrapper, K> Mesh_domain;
|
||||
|
||||
// Triangulation
|
||||
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
||||
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
||||
|
||||
// Mesh Criteria
|
||||
typedef CGAL::Mesh_criteria_3<Tr> 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<std::string> 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<C3t3>(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;
|
||||
}
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
|
||||
//******************************************************************************
|
||||
// File Description :
|
||||
// Outputs to out.mesh a mesh of implicit domains.
|
||||
//******************************************************************************
|
||||
|
||||
|
||||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Mesh_triangulation_3.h>
|
||||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||
#include <CGAL/Mesh_criteria_3.h>
|
||||
|
||||
#include <CGAL/Implicit_to_labeling_function_wrapper.h>
|
||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Mesh_domain_with_polyline_features_3.h>
|
||||
#include <CGAL/make_mesh_3.h>
|
||||
|
||||
// IO
|
||||
#include <CGAL/IO/File_medit.h>
|
||||
|
||||
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::Implicit_multi_domain_to_labeling_function_wrapper<Function>
|
||||
Function_wrapper;
|
||||
typedef Function_wrapper::Function_vector Function_vector;
|
||||
typedef CGAL::Labeled_mesh_domain_3<Function_wrapper, K> Mesh_domain;
|
||||
typedef CGAL::Mesh_domain_with_polyline_features_3<Mesh_domain> Mesh_domain_with_features;
|
||||
|
||||
// Triangulation
|
||||
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
||||
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
||||
|
||||
// Mesh Criteria
|
||||
typedef CGAL::Mesh_criteria_3<Tr> 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<Point> Polyline_3;
|
||||
typedef std::list<Polyline_3> 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<std::string> 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<C3t3>(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;
|
||||
}
|
||||
|
|
@ -8,15 +8,15 @@
|
|||
|
||||
|
||||
|
||||
#include <debug.h>
|
||||
#include "debug.h"
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Mesh_triangulation_3.h>
|
||||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||
#include <CGAL/Mesh_criteria_3.h>
|
||||
|
||||
#include <CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h>
|
||||
#include <CGAL/Mesh_3/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Implicit_to_labeling_function_wrapper.h>
|
||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/make_mesh_3.h>
|
||||
#include "implicit_functions.h"
|
||||
|
||||
|
|
@ -28,10 +28,10 @@ using namespace CGAL::parameters;
|
|||
// Domain
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef FT_to_point_function_wrapper<K::FT, K::Point_3> Function;
|
||||
typedef CGAL::Mesh_3::Implicit_vector_to_labeled_function_wrapper<Function, K>
|
||||
typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper<Function>
|
||||
Function_wrapper;
|
||||
typedef Function_wrapper::Function_vector Function_vector;
|
||||
typedef CGAL::Mesh_3::Labeled_mesh_domain_3<Function_wrapper, K> Mesh_domain;
|
||||
typedef CGAL::Labeled_mesh_domain_3<Function_wrapper, K> Mesh_domain;
|
||||
|
||||
// Triangulation
|
||||
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
||||
|
|
@ -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 !)
|
||||
|
|
|
|||
|
|
@ -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 <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Mesh_triangulation_3.h>
|
||||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||
#include <CGAL/Mesh_criteria_3.h>
|
||||
|
||||
#include <CGAL/Implicit_to_labeling_function_wrapper.h>
|
||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/make_mesh_3.h>
|
||||
#include "implicit_functions.h"
|
||||
|
||||
// IO
|
||||
#include <CGAL/IO/File_medit.h>
|
||||
|
||||
using namespace CGAL::parameters;
|
||||
|
||||
// Domain
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef FT_to_point_function_wrapper<K::FT, K::Point_3> Function;
|
||||
typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper<Function>
|
||||
Function_wrapper;
|
||||
typedef Function_wrapper::Function_vector Function_vector;
|
||||
typedef CGAL::Labeled_mesh_domain_3<Function_wrapper, K> Mesh_domain;
|
||||
|
||||
// Triangulation
|
||||
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
||||
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
||||
|
||||
// Mesh Criteria
|
||||
typedef CGAL::Mesh_criteria_3<Tr> 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<std::string> 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<C3t3>(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;
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||
#include <CGAL/Mesh_criteria_3.h>
|
||||
|
||||
#include <CGAL/Mesh_3/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Mesh_3/polyhedral_to_labeled_function_wrapper.h>
|
||||
#include <CGAL/make_mesh_3.h>
|
||||
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef CGAL::Polyhedron_3<K> Polyhedron;
|
||||
typedef CGAL::Mesh_3::Polyhedral_edge_tolerance_to_labeled_function_wrapper<Polyhedron, K> Polyhedral_wrapper;
|
||||
typedef CGAL::Mesh_3::Labeled_mesh_domain_3<Polyhedral_wrapper, K> Mesh_domain;
|
||||
typedef CGAL::Labeled_mesh_domain_3<Polyhedral_wrapper, K> Mesh_domain;
|
||||
|
||||
// Triangulation
|
||||
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||
#include <CGAL/Mesh_criteria_3.h>
|
||||
|
||||
#include <CGAL/Mesh_3/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Mesh_3/polyhedral_to_labeled_function_wrapper.h>
|
||||
#include <CGAL/make_mesh_3.h>
|
||||
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
struct K: public CGAL::Exact_predicates_inexact_constructions_kernel {};
|
||||
typedef CGAL::Polyhedron_3<K> Polyhedron;
|
||||
typedef CGAL::Mesh_3::Polyhedral_to_labeled_function_wrapper<Polyhedron, K> Polyhedral_wrapper;
|
||||
typedef CGAL::Mesh_3::Labeled_mesh_domain_3<Polyhedral_wrapper, K> Mesh_domain;
|
||||
typedef CGAL::Labeled_mesh_domain_3<Polyhedral_wrapper, K> Mesh_domain;
|
||||
|
||||
// Triangulation
|
||||
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||
#include <CGAL/Mesh_criteria_3.h>
|
||||
|
||||
#include <CGAL/Mesh_3/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Mesh_3/polyhedral_to_labeled_function_wrapper.h>
|
||||
#include <CGAL/make_mesh_3.h>
|
||||
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef CGAL::Polyhedron_3<K> Polyhedron;
|
||||
typedef CGAL::Mesh_3::Polyhedral_tolerance_to_labeled_function_wrapper<Polyhedron, K> Polyhedral_wrapper;
|
||||
typedef CGAL::Mesh_3::Labeled_mesh_domain_3<Polyhedral_wrapper, K> Mesh_domain;
|
||||
typedef CGAL::Labeled_mesh_domain_3<Polyhedral_wrapper, K> Mesh_domain;
|
||||
|
||||
// Triangulation
|
||||
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@
|
|||
# pragma warning(disable:4180) // qualifier applied to function type has no meaning; ignored
|
||||
#endif
|
||||
|
||||
#include <CGAL/Mesh_3/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h>
|
||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Implicit_to_labeling_function_wrapper.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
|
@ -45,13 +45,13 @@ namespace CGAL {
|
|||
*/
|
||||
template<class Function,
|
||||
class BGT,
|
||||
class Wrapper = Mesh_3::Implicit_to_labeled_function_wrapper<Function,BGT> >
|
||||
class Wrapper = Implicit_to_labeling_function_wrapper<Function,BGT> >
|
||||
class Implicit_mesh_domain_3
|
||||
: public Mesh_3::Labeled_mesh_domain_3<Wrapper, BGT >
|
||||
: public Labeled_mesh_domain_3<Wrapper, BGT >
|
||||
{
|
||||
public:
|
||||
/// Base type
|
||||
typedef Mesh_3::Labeled_mesh_domain_3<Wrapper, BGT> Base;
|
||||
typedef Labeled_mesh_domain_3<Wrapper, BGT> Base;
|
||||
|
||||
/// Public types
|
||||
typedef typename Base::Sphere_3 Sphere_3;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,286 @@
|
|||
// 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, Aymeric PELLE
|
||||
//
|
||||
//******************************************************************************
|
||||
// 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_IMPLICIT_TO_LABELING_FUNCTION_WRAPPER_H
|
||||
#define CGAL_IMPLICIT_TO_LABELING_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 <boost/dynamic_bitset.hpp>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
#include <CGAL/config.h>
|
||||
|
||||
/**
|
||||
* @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 Function_, class BGT>
|
||||
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 Function_, class BGT>
|
||||
class Implicit_vector_to_labeling_function_wrapper
|
||||
{
|
||||
public:
|
||||
// Types
|
||||
typedef int return_type;
|
||||
typedef std::vector<Function_*> Function_vector;
|
||||
typedef typename BGT::Point_3 Point_3;
|
||||
|
||||
/// Constructor
|
||||
Implicit_vector_to_labeling_function_wrapper(const std::vector<Function_*>& 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<return_type>(bits) );
|
||||
}
|
||||
|
||||
private:
|
||||
/// Functions to wrap
|
||||
const Function_vector function_vector_;
|
||||
|
||||
}; // end class Implicit_to_labeling_function_wrapper
|
||||
|
||||
template <class ImplicitFunction>
|
||||
class Implicit_multi_domain_to_labeling_function_wrapper
|
||||
{
|
||||
template <class T_>
|
||||
class Implicit_function_traits
|
||||
{
|
||||
public:
|
||||
typedef typename T_::Point Point;
|
||||
};
|
||||
|
||||
template <class RT_, class Point_>
|
||||
class Implicit_function_traits<RT_ (*)(Point_)>
|
||||
{
|
||||
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<ImplicitFunction>::Point Point_3;
|
||||
typedef std::vector<Function> Function_vector;
|
||||
|
||||
private:
|
||||
std::vector<Function> funcs;
|
||||
std::vector<boost::dynamic_bitset<> > bmasks;
|
||||
|
||||
public:
|
||||
Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& vf, const std::vector<std::vector<Sign> >& vps)
|
||||
: funcs(vf), bmasks(vps.size(), boost::dynamic_bitset<>(funcs.size() * 2, false))
|
||||
{
|
||||
assert(funcs.size());
|
||||
|
||||
std::size_t mask_index = 0;
|
||||
for (std::vector<std::vector<Sign> >::const_iterator mask_iter = vps.begin(), mask_end_iter = vps.end();
|
||||
mask_iter != mask_end_iter;
|
||||
++mask_iter)
|
||||
{
|
||||
const std::vector<Sign>& mask = *mask_iter;
|
||||
assert(funcs.size() == mask.size());
|
||||
boost::dynamic_bitset<>& bmask = bmasks[mask_index++];
|
||||
|
||||
std::size_t bit_index = 0;
|
||||
for (std::vector<Sign>::const_iterator iter = mask.begin(), endIter = mask.end(); iter != endIter; ++iter)
|
||||
{
|
||||
std::string::value_type character = *iter;
|
||||
assert(character == POSITIVE || character == NEGATIVE);
|
||||
|
||||
bmask[bit_index] = character == POSITIVE;
|
||||
++bit_index;
|
||||
bmask[bit_index] = character == NEGATIVE;
|
||||
++bit_index;
|
||||
}
|
||||
}
|
||||
std::sort(bmasks.begin(), bmasks.end());
|
||||
}
|
||||
|
||||
Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& vf)
|
||||
: funcs(vf)
|
||||
{
|
||||
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<std::string>& 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<std::string>::const_iterator mask_iter = vps.begin(), mask_end_iter = vps.end();
|
||||
mask_iter != mask_end_iter;
|
||||
++mask_iter)
|
||||
{
|
||||
const std::string& mask_str = *mask_iter;
|
||||
assert(funcs.size() == mask_str.length());
|
||||
boost::dynamic_bitset<>& bmask = bmasks[mask_index++];
|
||||
|
||||
std::size_t bit_index = 0;
|
||||
for (std::string::const_iterator iter = mask_str.begin(), endIter = mask_str.end(); iter != endIter; ++iter)
|
||||
{
|
||||
std::string::value_type character = *iter;
|
||||
assert(character == '+' || character == '-');
|
||||
|
||||
bmask[bit_index] = character == '+';
|
||||
++bit_index;
|
||||
bmask[bit_index] = character == '-';
|
||||
++bit_index;
|
||||
}
|
||||
}
|
||||
std::sort(bmasks.begin(), bmasks.end());
|
||||
}
|
||||
|
||||
return_type operator() (const Point_3& p, const bool = true) const
|
||||
{
|
||||
boost::dynamic_bitset<> bmask(funcs.size() * 2, false);
|
||||
|
||||
std::size_t i = 0;
|
||||
for (typename std::vector<Function>::const_iterator iter = funcs.begin(), endIter = funcs.end();
|
||||
iter != endIter;
|
||||
++iter)
|
||||
{
|
||||
const Function& function = *iter;
|
||||
|
||||
double fres = function(p);
|
||||
bmask[i] = fres > 0;
|
||||
++i;
|
||||
bmask[i] = fres < 0;
|
||||
++i;
|
||||
}
|
||||
|
||||
std::vector<boost::dynamic_bitset<> >::const_iterator iter = std::lower_bound(bmasks.begin(), bmasks.end(), bmask);
|
||||
if (iter != bmasks.end() && *iter == bmask)
|
||||
return static_cast<return_type>(1 + (iter - bmasks.begin()));
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace CGAL
|
||||
|
||||
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // CGAL_IMPLICIT_TO_LABELING_FUNCTION_WRAPPER_H
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
#define CGAL_LABELED_IMAGE_MESH_DOMAIN_3_H
|
||||
|
||||
|
||||
#include <CGAL/Mesh_3/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Mesh_3/Image_to_labeled_function_wrapper.h>
|
||||
|
||||
|
||||
|
|
@ -43,10 +43,10 @@ template<class Image,
|
|||
class BGT,
|
||||
class Wrapper = Mesh_3::Image_to_labeled_function_wrapper<Image, BGT> >
|
||||
class Labeled_image_mesh_domain_3
|
||||
: public Mesh_3::Labeled_mesh_domain_3<Wrapper, BGT>
|
||||
: public Labeled_mesh_domain_3<Wrapper, BGT>
|
||||
{
|
||||
public:
|
||||
typedef Mesh_3::Labeled_mesh_domain_3<Wrapper, BGT> Base;
|
||||
typedef Labeled_mesh_domain_3<Wrapper, BGT> Base;
|
||||
|
||||
typedef typename Base::Sphere_3 Sphere_3;
|
||||
typedef typename Base::FT FT;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,605 @@
|
|||
// 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, Aymeric PELLE
|
||||
//
|
||||
//******************************************************************************
|
||||
// File Description :
|
||||
// class Labeled_mesh_domain_3. See class description.
|
||||
//******************************************************************************
|
||||
|
||||
#ifndef CGAL_LABELED_MESH_DOMAIN_3_H
|
||||
#define CGAL_LABELED_MESH_DOMAIN_3_H
|
||||
|
||||
#include <CGAL/Mesh_3/config.h>
|
||||
|
||||
#include <CGAL/Bbox_3.h>
|
||||
|
||||
#include <CGAL/point_generators_3.h>
|
||||
#include <CGAL/Mesh_3/Creator_weighted_point_3.h>
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <CGAL/tuple.h>
|
||||
#include <CGAL/Origin.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
/**
|
||||
* \class Labeled_mesh_domain_3
|
||||
*
|
||||
* Function f must take his values into N.
|
||||
* Let p be a Point.
|
||||
* - f(p)=0 means that p is outside domain.
|
||||
* - f(p)=a, a!=0 means that p is inside subdomain a.
|
||||
*
|
||||
* Any boundary facet is labelled <a,b>, a<b, where a and b are the
|
||||
* tags of it's incident subdomain.
|
||||
* Thus, a boundary facet of the domain is labelled <0,b>, where b!=0.
|
||||
*/
|
||||
template<class Function, class BGT>
|
||||
class Labeled_mesh_domain_3
|
||||
{
|
||||
public:
|
||||
/// Geometric object types
|
||||
typedef typename BGT::Point_3 Point_3;
|
||||
typedef typename BGT::Segment_3 Segment_3;
|
||||
typedef typename BGT::Ray_3 Ray_3;
|
||||
typedef typename BGT::Line_3 Line_3;
|
||||
typedef typename BGT::Vector_3 Vector_3;
|
||||
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;
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Index Types
|
||||
//-------------------------------------------------------
|
||||
/// Type of indexes for cells of the input complex
|
||||
typedef typename Function::return_type Subdomain_index;
|
||||
typedef boost::optional<Subdomain_index> Subdomain;
|
||||
/// Type of indexes for surface patch of the input complex
|
||||
typedef std::pair<Subdomain_index, Subdomain_index> Surface_patch_index;
|
||||
typedef boost::optional<Surface_patch_index> Surface_patch;
|
||||
/// Type of indexes to characterize the lowest dimensional face of the input
|
||||
/// complex on which a vertex lie
|
||||
typedef boost::variant<Subdomain_index, Surface_patch_index> Index;
|
||||
typedef CGAL::cpp11::tuple<Point_3,Index,int> Intersection;
|
||||
|
||||
|
||||
typedef typename BGT::FT FT;
|
||||
typedef BGT Geom_traits;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
Labeled_mesh_domain_3(const Function& f,
|
||||
const Sphere_3& bounding_sphere,
|
||||
const FT& error_bound = FT(1e-3));
|
||||
|
||||
Labeled_mesh_domain_3(const Function& f,
|
||||
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() {}
|
||||
|
||||
/**
|
||||
* Constructs a set of \ccc{n} points on the surface, and output them to
|
||||
* the output iterator \ccc{pts} whose value type is required to be
|
||||
* \ccc{std::pair<Points_3, Index>}.
|
||||
*/
|
||||
struct Construct_initial_points
|
||||
{
|
||||
Construct_initial_points(const Labeled_mesh_domain_3& domain)
|
||||
: r_domain_(domain) {}
|
||||
|
||||
template<class OutputIterator>
|
||||
OutputIterator operator()(OutputIterator pts, const int n = 12) const;
|
||||
|
||||
private:
|
||||
const Labeled_mesh_domain_3& r_domain_;
|
||||
};
|
||||
|
||||
/// Returns Construct_initial_points object
|
||||
Construct_initial_points construct_initial_points_object() const
|
||||
{
|
||||
return Construct_initial_points(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if point~\ccc{p} is in the domain. If \ccc{p} is in the
|
||||
* domain, the parameter index is set to the index of the subdomain
|
||||
* including $p$. It is set to the default value otherwise.
|
||||
*/
|
||||
struct Is_in_domain
|
||||
{
|
||||
Is_in_domain(const Labeled_mesh_domain_3& domain) : r_domain_(domain) {}
|
||||
|
||||
Subdomain operator()(const Point_3& p) const
|
||||
{
|
||||
// f(p)==0 means p is outside the domain
|
||||
Subdomain_index index = (r_domain_.function_)(p);
|
||||
if ( Subdomain_index() == index )
|
||||
return Subdomain();
|
||||
else
|
||||
return Subdomain(index);
|
||||
}
|
||||
private:
|
||||
const Labeled_mesh_domain_3& r_domain_;
|
||||
};
|
||||
|
||||
/// Returns Is_in_domain object
|
||||
Is_in_domain is_in_domain_object() const { return Is_in_domain(*this); }
|
||||
|
||||
/**
|
||||
* Returns true is the element \ccc{type} intersect properly any of the
|
||||
* surface patches describing the either the domain boundary or some
|
||||
* subdomain boundary.
|
||||
* \ccc{Type} is either \ccc{Segment_3}, \ccc{Ray_3} or \ccc{Line_3}.
|
||||
* Parameter index is set to the index of the intersected surface patch
|
||||
* if \ccc{true} is returned and to the default \ccc{Surface_patch_index}
|
||||
* value otherwise.
|
||||
*/
|
||||
struct Do_intersect_surface
|
||||
{
|
||||
Do_intersect_surface(const Labeled_mesh_domain_3& domain)
|
||||
: r_domain_(domain) {}
|
||||
|
||||
Surface_patch operator()(const Segment_3& s) const
|
||||
{
|
||||
return this->operator()(s.source(), s.target());
|
||||
}
|
||||
|
||||
Surface_patch operator()(const Ray_3& r) const
|
||||
{
|
||||
return clip_to_segment(r);
|
||||
}
|
||||
|
||||
Surface_patch operator()(const Line_3& l) const
|
||||
{
|
||||
return clip_to_segment(l);
|
||||
}
|
||||
|
||||
private:
|
||||
/// Returns true if points \c a & \c b do not belong to the same subdomain
|
||||
/// \c index is set to the surface index of subdomains f(a), f(b)
|
||||
Surface_patch operator()(const Point_3& a, const Point_3& b) const
|
||||
{
|
||||
// If f(a) != f(b), then [a,b] intersects some surface. Here we consider
|
||||
// [a,b] intersects surface_patch labelled <f(a),f(b)> (or <f(b),f(a)>).
|
||||
// It may be false, further rafinement will improve precision
|
||||
const Subdomain_index value_a = r_domain_.function_(a);
|
||||
const Subdomain_index value_b = r_domain_.function_(b);
|
||||
|
||||
if ( value_a != value_b )
|
||||
return Surface_patch(r_domain_.make_surface_index(value_a, value_b));
|
||||
else
|
||||
return Surface_patch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clips \c query to a segment \c s, and call operator()(s)
|
||||
*/
|
||||
template<typename Query>
|
||||
Surface_patch clip_to_segment(const Query& query) const
|
||||
{
|
||||
typename cpp11::result_of<typename BGT::Intersect_3(Query, Iso_cuboid_3)>::type
|
||||
clipped = CGAL::intersection(query, r_domain_.bbox_);
|
||||
|
||||
if(clipped)
|
||||
#if CGAL_INTERSECTION_VERSION > 1
|
||||
if(const Segment_3* s = boost::get<Segment_3>(&*clipped))
|
||||
return this->operator()(*s);
|
||||
#else
|
||||
if(const Segment_3* s = object_cast<Segment_3>(&clipped))
|
||||
return this->operator()(*s);
|
||||
#endif
|
||||
|
||||
return Surface_patch();
|
||||
}
|
||||
|
||||
private:
|
||||
const Labeled_mesh_domain_3& r_domain_;
|
||||
};
|
||||
|
||||
/// Returns Do_intersect_surface object
|
||||
Do_intersect_surface do_intersect_surface_object() const
|
||||
{
|
||||
return Do_intersect_surface(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a point in the intersection of the primitive \ccc{type}
|
||||
* with some boundary surface.
|
||||
* \ccc{Type1} is either \ccc{Segment_3}, \ccc{Ray_3} or \ccc{Line_3}.
|
||||
* The integer \ccc{dimension} is set to the dimension of the lowest
|
||||
* dimensional face in the input complex containing the returned point, and
|
||||
* \ccc{index} is set to the index to be stored at a mesh vertex lying
|
||||
* on this face.
|
||||
*/
|
||||
struct Construct_intersection
|
||||
{
|
||||
Construct_intersection(const Labeled_mesh_domain_3& domain)
|
||||
: r_domain_(domain) {}
|
||||
|
||||
Intersection operator()(const Segment_3& s) const
|
||||
{
|
||||
#ifndef CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3
|
||||
CGAL_precondition(r_domain_.do_intersect_surface_object()(s));
|
||||
#endif // NOT CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3
|
||||
return this->operator()(s.source(),s.target());
|
||||
}
|
||||
|
||||
Intersection operator()(const Ray_3& r) const
|
||||
{
|
||||
return clip_to_segment(r);
|
||||
}
|
||||
|
||||
Intersection operator()(const Line_3& l) const
|
||||
{
|
||||
return clip_to_segment(l);
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Returns a point in the intersection of [a,b] with the surface
|
||||
* \c a must be the source point, and \c b the out point. It's important
|
||||
* because it drives bisection cuts.
|
||||
* Indeed, the returned point is the first intersection from \c [a,b]
|
||||
* with a subdomain surface.
|
||||
*/
|
||||
Intersection operator()(const Point_3& a, const Point_3& b) const
|
||||
{
|
||||
// Functors
|
||||
typename BGT::Compute_squared_distance_3 squared_distance =
|
||||
BGT().compute_squared_distance_3_object();
|
||||
typename BGT::Construct_midpoint_3 midpoint =
|
||||
BGT().construct_midpoint_3_object();
|
||||
|
||||
// Non const points
|
||||
Point_3 p1 = a;
|
||||
Point_3 p2 = b;
|
||||
Point_3 mid = midpoint(p1, p2);
|
||||
|
||||
// Cannot be const: those values are modified below.
|
||||
Subdomain_index value_at_p1 = r_domain_.function_(p1);
|
||||
Subdomain_index value_at_p2 = r_domain_.function_(p2);
|
||||
Subdomain_index value_at_mid = r_domain_.function_(mid,true);
|
||||
|
||||
// If both extremities are in the same subdomain,
|
||||
// there is no intersection.
|
||||
// This should not happen...
|
||||
if( value_at_p1 == value_at_p2 )
|
||||
{
|
||||
return Intersection();
|
||||
}
|
||||
|
||||
// Construct the surface patch index and index from the values at 'a'
|
||||
// and 'b'. Even if the bissection find out a different pair of
|
||||
// values, the reported index will be constructed from the initial
|
||||
// values.
|
||||
const Surface_patch_index sp_index =
|
||||
r_domain_.make_surface_index(value_at_p1, value_at_p2);
|
||||
const Index index = r_domain_.index_from_surface_patch_index(sp_index);
|
||||
|
||||
// Else lets find a point (by bisection)
|
||||
// Bisection ends when the point is near than error bound from surface
|
||||
while(true)
|
||||
{
|
||||
// If the two points are enough close, then we return midpoint
|
||||
if ( squared_distance(p1, p2) < r_domain_.squared_error_bound_ )
|
||||
{
|
||||
CGAL_assertion(value_at_p1 != value_at_p2);
|
||||
return Intersection(mid, index, 2);
|
||||
}
|
||||
|
||||
// Else we must go on
|
||||
// Here we consider that p1(a) is the source point. Thus, we keep p1 and
|
||||
// change p2 if f(p1)!=f(p2).
|
||||
// That allows us to find the first intersection from a of [a,b] with
|
||||
// a surface.
|
||||
if ( value_at_p1 != value_at_mid )
|
||||
{
|
||||
p2 = mid;
|
||||
value_at_p2 = value_at_mid;
|
||||
}
|
||||
else
|
||||
{
|
||||
p1 = mid;
|
||||
value_at_p1 = value_at_mid;
|
||||
}
|
||||
|
||||
mid = midpoint(p1, p2);
|
||||
value_at_mid = r_domain_.function_(mid,true);
|
||||
}
|
||||
}
|
||||
|
||||
/// Clips \c query to a segment \c s, and call operator()(s)
|
||||
template<typename Query>
|
||||
Intersection clip_to_segment(const Query& query) const
|
||||
{
|
||||
typename cpp11::result_of<typename BGT::Intersect_3(Query, Iso_cuboid_3)>::type
|
||||
clipped = CGAL::intersection(query, r_domain_.bbox_);
|
||||
|
||||
if(clipped)
|
||||
#if CGAL_INTERSECTION_VERSION > 1
|
||||
if(const Segment_3* s = boost::get<Segment_3>(&*clipped))
|
||||
return this->operator()(*s);
|
||||
#else
|
||||
if(const Segment_3* s = object_cast<Segment_3>(&clipped))
|
||||
return this->operator()(*s);
|
||||
#endif
|
||||
|
||||
return Intersection();
|
||||
}
|
||||
|
||||
private:
|
||||
const Labeled_mesh_domain_3& r_domain_;
|
||||
};
|
||||
|
||||
/// Returns Construct_intersection object
|
||||
Construct_intersection construct_intersection_object() const
|
||||
{
|
||||
return Construct_intersection(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index to be stored in a vertex lying on the surface identified
|
||||
* by \c index.
|
||||
*/
|
||||
Index index_from_surface_patch_index(const Surface_patch_index& index) const
|
||||
{ return Index(index); }
|
||||
|
||||
/**
|
||||
* Returns the index to be stored in a vertex lying in the subdomain
|
||||
* identified by \c index.
|
||||
*/
|
||||
Index index_from_subdomain_index(const Subdomain_index& index) const
|
||||
{ return Index(index); }
|
||||
|
||||
/**
|
||||
* Returns the \c Surface_patch_index of the surface patch
|
||||
* where lies a vertex with dimension 2 and index \c index.
|
||||
*/
|
||||
Surface_patch_index surface_patch_index(const Index& index) const
|
||||
{ return boost::get<Surface_patch_index>(index); }
|
||||
|
||||
/**
|
||||
* Returns the index of the subdomain containing a vertex
|
||||
* with dimension 3 and index \c index.
|
||||
*/
|
||||
Subdomain_index subdomain_index(const Index& index) const
|
||||
{ return boost::get<Subdomain_index>(index); }
|
||||
|
||||
// -----------------------------------
|
||||
// Backward Compatibility
|
||||
// -----------------------------------
|
||||
#ifndef CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX
|
||||
typedef Surface_patch_index Surface_index;
|
||||
|
||||
Index index_from_surface_index(const Surface_index& index) const
|
||||
{ return index_from_surface_patch_index(index); }
|
||||
|
||||
Surface_index surface_index(const Index& index) const
|
||||
{ return surface_patch_index(index); }
|
||||
#endif // CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX
|
||||
// -----------------------------------
|
||||
// End backward Compatibility
|
||||
// -----------------------------------
|
||||
|
||||
|
||||
private:
|
||||
/// Returns Surface_patch_index from \c i and \c j
|
||||
Surface_patch_index make_surface_index(const Subdomain_index i,
|
||||
const Subdomain_index j) const
|
||||
{
|
||||
if ( i < j ) return Surface_patch_index(i,j);
|
||||
else return Surface_patch_index(j,i);
|
||||
}
|
||||
|
||||
/// Returns squared error bound from \c bbox and \c error
|
||||
FT squared_error_bound(const Iso_cuboid_3& bbox, const FT& error) const
|
||||
{
|
||||
typename BGT::Compute_squared_distance_3 squared_distance =
|
||||
BGT().compute_squared_distance_3_object();
|
||||
return squared_distance((bbox.min)(), (bbox.max)())*error*error/4;
|
||||
}
|
||||
|
||||
/// Returns squared error bound from \c sphere and \c error
|
||||
FT squared_error_bound(const Sphere_3& sphere, const FT& error) const
|
||||
{
|
||||
typename BGT::Compute_squared_radius_3 squared_radius =
|
||||
BGT().compute_squared_radius_3_object();
|
||||
return squared_radius(sphere)*error*error;
|
||||
}
|
||||
|
||||
/// Returns the bounding sphere of an Iso_cuboid_3
|
||||
Sphere_3 bounding_sphere(const Iso_cuboid_3& bbox) const
|
||||
{
|
||||
typename BGT::Construct_sphere_3 sphere = BGT().construct_sphere_3_object();
|
||||
return sphere((bbox.min)(), (bbox.max)());
|
||||
}
|
||||
|
||||
/// Returns and Iso_cuboid_3 from a Bbox_3
|
||||
Iso_cuboid_3 iso_cuboid(const Bbox_3& bbox)
|
||||
{
|
||||
const Point_3 p_min(bbox.xmin(), bbox.ymin(), bbox.zmin());
|
||||
const Point_3 p_max(bbox.xmax(), bbox.ymax(), bbox.zmax());
|
||||
|
||||
return Iso_cuboid_3(p_min,p_max);
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Returns bounding box
|
||||
const Iso_cuboid_3& bounding_box() const { return bbox_; }
|
||||
|
||||
private:
|
||||
/// The function which answers subdomain queries
|
||||
const Function function_;
|
||||
/// The bounding box
|
||||
const Iso_cuboid_3 bbox_;
|
||||
/// Error bound relative to sphere radius
|
||||
FT squared_error_bound_;
|
||||
|
||||
|
||||
private:
|
||||
// Disabled copy constructor & assignment operator
|
||||
typedef Labeled_mesh_domain_3<Function,BGT> Self;
|
||||
Labeled_mesh_domain_3(const Self& src);
|
||||
Self& operator=(const Self& src);
|
||||
|
||||
}; // end class Labeled_mesh_domain_3
|
||||
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Method implementation
|
||||
//-------------------------------------------------------
|
||||
template<class F, class BGT>
|
||||
Labeled_mesh_domain_3<F,BGT>::Labeled_mesh_domain_3(
|
||||
const F& f,
|
||||
const Sphere_3& bounding_sphere,
|
||||
const FT& error_bound )
|
||||
: function_(f)
|
||||
, bbox_(iso_cuboid(bounding_sphere.bbox()))
|
||||
, squared_error_bound_(squared_error_bound(bounding_sphere,error_bound))
|
||||
{
|
||||
// TODO : CGAL_ASSERT(0 < f(bounding_sphere.get_center()) ) ?
|
||||
}
|
||||
|
||||
template<class F, class BGT>
|
||||
Labeled_mesh_domain_3<F,BGT>::Labeled_mesh_domain_3(
|
||||
const F& f,
|
||||
const Bbox_3& bbox,
|
||||
const FT& error_bound )
|
||||
: function_(f)
|
||||
, bbox_(iso_cuboid(bbox))
|
||||
, squared_error_bound_(squared_error_bound(bbox_,error_bound))
|
||||
{
|
||||
// TODO : CGAL_ASSERT(0 < f(bounding_sphere.get_center()) ) ?
|
||||
}
|
||||
|
||||
template<class F, class BGT>
|
||||
Labeled_mesh_domain_3<F,BGT>::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<class F, class BGT>
|
||||
template<class OutputIterator>
|
||||
OutputIterator
|
||||
Labeled_mesh_domain_3<F,BGT>::Construct_initial_points::operator()(
|
||||
OutputIterator pts,
|
||||
const int nb_points) const
|
||||
{
|
||||
// Create point_iterator on and in bounding_sphere
|
||||
typedef Random_points_on_sphere_3<Point_3> Random_points_on_sphere_3;
|
||||
typedef Random_points_in_sphere_3<Point_3> Random_points_in_sphere_3;
|
||||
|
||||
|
||||
const FT squared_radius = BGT().compute_squared_radius_3_object()(
|
||||
r_domain_.bounding_sphere(r_domain_.bbox_));
|
||||
|
||||
const double radius = std::sqrt(CGAL::to_double(squared_radius));
|
||||
|
||||
Random_points_on_sphere_3 random_point_on_sphere(radius);
|
||||
Random_points_in_sphere_3 random_point_in_sphere(radius);
|
||||
|
||||
// Get some functors
|
||||
typename BGT::Construct_segment_3 segment_3 =
|
||||
BGT().construct_segment_3_object();
|
||||
typename BGT::Construct_vector_3 vector_3 =
|
||||
BGT().construct_vector_3_object();
|
||||
typename BGT::Construct_translated_point_3 translate =
|
||||
BGT().construct_translated_point_3_object();
|
||||
typename BGT::Construct_center_3 center = BGT().construct_center_3_object();
|
||||
|
||||
// Get translation from origin to sphere center
|
||||
Point_3 center_pt = center(r_domain_.bounding_sphere(r_domain_.bbox_));
|
||||
const Vector_3 sphere_translation = vector_3(CGAL::ORIGIN, center_pt);
|
||||
|
||||
// Create nb_point points
|
||||
int n = nb_points;
|
||||
#ifdef CGAL_MESH_3_VERBOSE
|
||||
std::cerr << "construct initial points:\n";
|
||||
#endif
|
||||
while ( 0 != n )
|
||||
{
|
||||
// Get a random segment
|
||||
const Point_3 random_point = translate(*random_point_on_sphere,
|
||||
sphere_translation);
|
||||
const Segment_3 random_seg = segment_3(center_pt, random_point);
|
||||
|
||||
// Add the intersection to the output if it exists
|
||||
Surface_patch surface = r_domain_.do_intersect_surface_object()(random_seg);
|
||||
if ( surface )
|
||||
{
|
||||
const Point_3 intersect_pt = CGAL::cpp11::get<0>(
|
||||
r_domain_.construct_intersection_object()(random_seg));
|
||||
*pts++ = std::make_pair(intersect_pt,
|
||||
r_domain_.index_from_surface_patch_index(*surface));
|
||||
--n;
|
||||
|
||||
#ifdef CGAL_MESH_3_VERBOSE
|
||||
std::cerr << boost::format("\r \r"
|
||||
"%1%/%2% initial point(s) found...")
|
||||
% (nb_points - n)
|
||||
% nb_points;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get a new random point into sphere as center of object
|
||||
// It may be necessary if the center of the domain is empty, e.g. torus
|
||||
// In general case, it is good for input point dispersion
|
||||
++random_point_in_sphere;
|
||||
center_pt = translate(*random_point_in_sphere, sphere_translation);
|
||||
}
|
||||
++random_point_on_sphere;
|
||||
}
|
||||
|
||||
#ifdef CGAL_MESH_3_VERBOSE
|
||||
std::cerr << "\n";
|
||||
#endif
|
||||
return pts;
|
||||
}
|
||||
|
||||
|
||||
} // end namespace CGAL
|
||||
|
||||
#endif // LABELLED_MESH_TRAITS_3_H_
|
||||
|
|
@ -20,8 +20,8 @@
|
|||
//
|
||||
//******************************************************************************
|
||||
// File Description :
|
||||
// Implicit_to_labeled_function_wrapper and
|
||||
// Implicit_vector_to_labeled_function_wrapper class declaration
|
||||
// Implicit_to_labeling_function_wrapper and
|
||||
// Implicit_vector_to_labeling_function_wrapper class declaration
|
||||
// and implementation.
|
||||
//
|
||||
// See classes description to have more information.
|
||||
|
|
@ -30,12 +30,17 @@
|
|||
#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
|
||||
|
||||
#define CGAL_DEPRECATED_HEADER "<CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h>"
|
||||
#define CGAL_REPLACEMENT_HEADER "<CGAL/Implicit_to_labeling_function_wrapper.h>"
|
||||
#include <CGAL/internal/deprecation_warning.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
namespace Mesh_3 {
|
||||
|
|
@ -81,6 +86,8 @@ private:
|
|||
|
||||
|
||||
/**
|
||||
* \deprecated
|
||||
*
|
||||
* @class Implicit_vector_to_labeled_function_wrapper
|
||||
*
|
||||
* Wraps a set of implicit function [f1,f2,...] to one function F which
|
||||
|
|
@ -112,7 +119,7 @@ public:
|
|||
/// Operator ()
|
||||
return_type operator()(const Point_3& p, const bool = true) const
|
||||
{
|
||||
int nb_func = function_vector_.size();
|
||||
int nb_func = static_cast<int>(function_vector_.size());
|
||||
if ( nb_func > 8 )
|
||||
{
|
||||
CGAL_error_msg("We support at most 8 functions !");
|
||||
|
|
@ -135,7 +142,6 @@ private:
|
|||
|
||||
}; // end class Implicit_to_labeled_function_wrapper
|
||||
|
||||
|
||||
} // end namespace Mesh_3
|
||||
|
||||
} // end namespace CGAL
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@
|
|||
#ifndef CGAL_MESH_3_LABELED_MESH_DOMAIN_3_H
|
||||
#define CGAL_MESH_3_LABELED_MESH_DOMAIN_3_H
|
||||
|
||||
#define CGAL_DEPRECATED_HEADER "<CGAL/Mesh_3/Labeled_mesh_domain_3.h>"
|
||||
#define CGAL_REPLACEMENT_HEADER "<CGAL/Labeled_mesh_domain_3.h>"
|
||||
#include <CGAL/internal/deprecation_warning.h>
|
||||
|
||||
#include <CGAL/Mesh_3/config.h>
|
||||
|
||||
#include <CGAL/Bbox_3.h>
|
||||
|
|
@ -68,6 +72,9 @@ public:
|
|||
typedef typename BGT::Sphere_3 Sphere_3;
|
||||
typedef CGAL::Bbox_3 Bbox_3;
|
||||
|
||||
typedef typename BGT::Iso_cuboid_3 Iso_cuboid_3;
|
||||
|
||||
public:
|
||||
// Kernel_traits compatibility
|
||||
typedef BGT R;
|
||||
|
||||
|
|
@ -408,9 +415,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,
|
||||
|
|
@ -504,7 +508,6 @@ Labeled_mesh_domain_3<F,BGT>::Labeled_mesh_domain_3(
|
|||
}
|
||||
|
||||
|
||||
|
||||
template<class F, class BGT>
|
||||
template<class OutputIterator>
|
||||
OutputIterator
|
||||
|
|
|
|||
|
|
@ -25,10 +25,15 @@ 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_mesh_3_implicit_vector_to_labeled_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_mesh_3_labeled_mesh_domain_3.cpp" )
|
||||
create_single_source_cgal_program( "test_mesh_implicit_domains.cpp" "implicit_functions.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" )
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
#ifdef BENCH
|
||||
# define NDEBUG
|
||||
#endif
|
||||
|
||||
#define CGAL_MESH_3_DEBUG_BEFORE_CONFLICTS 0
|
||||
#define CGAL_MESH_3_DEBUG_AFTER_NO_INSERTION 0
|
||||
#define CGAL_MESH_3_DEBUG_AFTER_INSERTION 0
|
||||
#define CGAL_MESH_3_DEBUG_DOUBLE_MAP 0
|
||||
|
||||
// #define CGAL_MESHES_NO_OUTPUT
|
||||
|
||||
// #define CGAL_SURFACE_MESHER_EDGES_DEBUG_INTERSECTION
|
||||
// #define CGAL_SURFACE_MESHER_DEBUG_POLYHEDRAL_SURFACE_CONSTRUCTION
|
||||
// #define CGAL_SURFACE_MESHER_VERBOSE
|
||||
// #define CGAL_POLYHEDRAL_SURFACE_VERBOSE_CONSTRUCTION
|
||||
// #define CGAL_SURFACE_MESHER_EDGES_DEBUG_INSERTIONS
|
||||
// #define CGAL_MESHES_DEBUG_REFINEMENT_POINTS
|
||||
// #define CGAL_DEBUG_OCTREE_CONSTRUCTION
|
||||
|
||||
#define CGAL_MESH_3_VERBOSE
|
||||
#define CGAL_MESH_3_IO_VERBOSE
|
||||
|
||||
// #define OPTIMIZE_INTERSECTION
|
||||
|
|
@ -0,0 +1,303 @@
|
|||
///////////////// Code for functions of famous surfaces /////////////////
|
||||
|
||||
|
||||
// Sphere (r=1)
|
||||
|
||||
double sphere_function (double x, double y, double z) {
|
||||
double x2=x*x, y2=y*y, z2=z*z;
|
||||
|
||||
return x2+y2+z2-1;
|
||||
}
|
||||
|
||||
|
||||
// Ellipsoid (r=1)
|
||||
|
||||
double ellipsoid_function (double x, double y, double z) {
|
||||
double x2=x*x, y2=y*y, z2=z*z;
|
||||
|
||||
return x2+2*y2+4*z2-1;
|
||||
}
|
||||
|
||||
|
||||
// Torus (r=2)
|
||||
|
||||
double torus_function (double x, double y, double z) {
|
||||
double x2=x*x, y2=y*y, z2=z*z;
|
||||
double x4=x2*x2, y4=y2*y2, z4=z2*z2;
|
||||
|
||||
return x4 + y4 + z4 + 2 *x2* y2 + 2*
|
||||
x2*z2 + 2*y2* z2 - 5 *x2 + 4* y2 - 5*z2+4;
|
||||
}
|
||||
|
||||
|
||||
// "Chair" (r=6)
|
||||
|
||||
double chair_function (double x, double y, double z) {
|
||||
double x2=x*x, y2=y*y, z2=z*z;
|
||||
double x4=x2*x2, y4=y2*y2, z4=z2*z2;
|
||||
|
||||
return x4-1.2*x2*y2+3.6*x2*z2-7.50*x2+y4+3.6*y2*z2-7.50*y2+.2*z4-7.50*z2+64.0625-16.0*z*y2+16.0*x2*z;
|
||||
}
|
||||
|
||||
|
||||
// "Tanglecube" (r=4)
|
||||
|
||||
double tanglecube_function (double x, double y, double z) {
|
||||
double x2=x*x, y2=y*y, z2=z*z;
|
||||
double x4=x2*x2, y4=y2*y2, z4=z2*z2;
|
||||
|
||||
return x4 - 5*x2 + y4 - 5*y2 + z4 - 5*z2 + 11.8;
|
||||
}
|
||||
|
||||
double cube_function (double x, double y, double z){
|
||||
if( x < 1 && -x < 1 &&
|
||||
y < 1 && -y < 1 &&
|
||||
z < 1 && -z < 1 )
|
||||
return -1.;
|
||||
return 1.;
|
||||
}
|
||||
|
||||
// Barth's octic surface (degree 8)
|
||||
|
||||
double octic_function (double x, double y, double z) { // r=2
|
||||
double x2=x*x, y2=y*y, z2=z*z;
|
||||
double x4=x2*x2, y4=y2*y2, z4=z2*z2;
|
||||
double x6=x4*x2, y6=y4*y2, z6=z4*z2;
|
||||
double x8=x4*x4, y8=y4*y4, z8=z4*z4;
|
||||
|
||||
return 43.30495169 *x2* y2 + 43.30495169 *x2* z2 + 43.30495169 *y2 * z2 + 44.36067980 *x6* y2 + 44.36067980* x6 * z2 + 66.54101970* x4* y4 + 66.54101970* x4 * z4 + 44.36067980 *x2 * y6 - 11.70820393* x2 - 11.70820393* y2 - 11.70820393* z2 + 37.65247585 *x4 + 37.65247585 *y4 + 37.65247585* z4 + 11.09016995* x8 + 11.09016995 *y8 + 11.09016995* z8 + 133.0820394 *x2* y4* z2 + 133.0820394 *x2 * y2 * z4 + 44.36067980* x2 * z6 + 44.36067980 *y6 * z2 + 66.54101970 *y4 * z4 + 44.36067980 *y2 * z6 + 133.0820394* x4* y2 * z2 - 91.95742756 *x4 * y2 - 91.95742756 *x4 *z2 - 91.95742756* x2 * y4 - 91.95742756 *x2 *z4 - 91.95742756* y4 * z2 - 183.9148551* x2 *y2 *z2 - 30.65247585 *x6 - 30.65247585* y6 - 91.95742756 *y2 * z4 - 30.65247585* z6 + 1.618033988;
|
||||
}
|
||||
|
||||
|
||||
// "Heart"
|
||||
|
||||
double heart_function (double x, double y, double z) { // radius = 2
|
||||
|
||||
return (2*x*x+y*y+z*z-1)*(2*x*x+y*y+z*z-1)*(2*x*x+y*y+z*z-1) - (0.1*x*x+y*y)*z*z*z;
|
||||
}
|
||||
|
||||
|
||||
// Klein's bottle
|
||||
|
||||
double klein_function (double x, double y, double z) { // radius = 4
|
||||
|
||||
return (x*x+y*y+z*z+2*y-1)*((x*x+y*y+z*z-2*y-1)*(x*x+y*y+z*z-2*y-1)-8*z*z)+16*x*z*(x*x+y*y+z*z-2*y-1);
|
||||
}
|
||||
|
||||
|
||||
// Ring
|
||||
|
||||
double ring_function (double x, double y, double z) { // radius = ?
|
||||
double e=0.1;
|
||||
|
||||
double f1 = x*x+y*y+z*z-1;
|
||||
double f2 = x;
|
||||
|
||||
f1 = f1*f1-e*e;
|
||||
f2 = f2*f2-e*e;
|
||||
|
||||
if (f1 < 0 && f2 < 0)
|
||||
return -1.;
|
||||
else if (f1 > 0 || f2 > 0)
|
||||
return 1.;
|
||||
else
|
||||
return 0.;
|
||||
}
|
||||
|
||||
|
||||
// False knot
|
||||
|
||||
double false_knot_function (double x, double y, double z) { // radius = 1
|
||||
double d=1.2, e=0.1;
|
||||
|
||||
double f1 = x*(x*x-z*z)-2*x*z*z-y*y+d*d-x*x-z*z-y*y;
|
||||
|
||||
double m2 = z*(x*x-z*z)+2*x*x*z;
|
||||
double f2 = 4*y*y*(d*d-x*x-z*z-y*y) - m2*m2;
|
||||
|
||||
f1 = f1*f1-e*e;
|
||||
f2 = f2*f2-e*e;
|
||||
|
||||
if (f1 < 0 && f2 < 0)
|
||||
return -1.;
|
||||
else if (f1 > 0 || f2 > 0)
|
||||
return 1.;
|
||||
else
|
||||
return 0.;
|
||||
}
|
||||
|
||||
|
||||
// Knot 1
|
||||
|
||||
void puiss(double& x, double& y, int n) {
|
||||
|
||||
double xx = 1, yy = 0;
|
||||
|
||||
while(n>0) {
|
||||
if (n&1) {
|
||||
double xxx = xx, yyy = yy;
|
||||
xx = xxx*x - yyy*y;
|
||||
yy = xxx*y + yyy*x;
|
||||
}
|
||||
|
||||
double xxx = x, yyy = y;
|
||||
x=xxx*xxx-yyy*yyy;
|
||||
y=2*xxx*yyy;
|
||||
|
||||
n/=2;
|
||||
}
|
||||
|
||||
x = xx;
|
||||
y = yy;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double knot1_function (double a, double b, double c) { // radius = 4
|
||||
double e=0.1;
|
||||
|
||||
double x, y, z, t, den;
|
||||
den=1+a*a+b*b+c*c;
|
||||
x=2*a/den;
|
||||
y=2*b/den;
|
||||
z=2*c/den;
|
||||
t=(1-a*a-b*b-c*c)/den;
|
||||
|
||||
double x3=x, y3=y, z2=z, t2=t;
|
||||
puiss(x3,y3,3);
|
||||
puiss(z2,t2,2);
|
||||
|
||||
double f1 = z2-x3;
|
||||
double f2 = t2-y3;
|
||||
|
||||
f1 = f1*f1;
|
||||
f2 = f2*f2;
|
||||
e=e*e/(den-1);
|
||||
|
||||
if (f1+f2-e < 0)
|
||||
return -1.;
|
||||
else if (f1+f2-e > 0)
|
||||
return 1.;
|
||||
else
|
||||
return 0.;
|
||||
}
|
||||
|
||||
/*
|
||||
double knot1_function (double x, double y, double z) { // radius = 4
|
||||
double e=0.1;
|
||||
|
||||
double c1, c2, c3, c4, den;
|
||||
den=1+x*x+y*y+z*z;
|
||||
c1=2*x/den;
|
||||
c2=2*y/den;
|
||||
c3=2*z/den;
|
||||
c4=(1-x*x-y*y-z*z)/den;
|
||||
|
||||
double f1 = c1*(c1*c1-c2*c2)-2*c1*c2*c2-c3*c3+c4*c4;
|
||||
double f2 = c2*(c1*c1-c2*c2)+2*c1*c1*c2-2*c3*c4;
|
||||
|
||||
f1 = f1*f1;
|
||||
f2 = f2*f2;
|
||||
e=e*e/(den-1);
|
||||
|
||||
if (f1+f2-e < 0)
|
||||
return -1.;
|
||||
else if (f1+f2-e > 0)
|
||||
return 1.;
|
||||
else
|
||||
return 0.;
|
||||
}
|
||||
*/
|
||||
|
||||
double knot1_surf1_function (double x, double y, double z) { // radius = 4
|
||||
double c1, c2, c3, c4, den;
|
||||
den=1+x*x+y*y+z*z;
|
||||
c1=2*x/den;
|
||||
c2=2*y/den;
|
||||
c3=2*z/den;
|
||||
c4=(1-x*x-y*y-z*z)/den;
|
||||
|
||||
return c1*(c1*c1-c2*c2)-2*c1*c2*c2-c3*c3+c4*c4;
|
||||
}
|
||||
|
||||
|
||||
double knot1_surf2_function (double x, double y, double z) { // radius = 4
|
||||
double c1, c2, c3, c4, den;
|
||||
den=1+x*x+y*y+z*z;
|
||||
c1=2*x/den;
|
||||
c2=2*y/den;
|
||||
c3=2*z/den;
|
||||
c4=(1-x*x-y*y-z*z)/den;
|
||||
|
||||
return c2*(c1*c1-c2*c2)+2*c1*c1*c2-2*c3*c4;
|
||||
}
|
||||
|
||||
|
||||
// Knot 2
|
||||
|
||||
double knot2_function (double a, double b, double c) { // radius = 4
|
||||
double e=0.025;
|
||||
|
||||
double x, y, z, t, den;
|
||||
den=1+a*a+b*b+c*c;
|
||||
x=2*a/den;
|
||||
y=2*b/den;
|
||||
z=2*c/den;
|
||||
t=(1-a*a-b*b-c*c)/den;
|
||||
|
||||
double x7=x, y7=y, x13=x, y13=y;
|
||||
puiss(x7,y7,7);
|
||||
puiss(x13,y13,13);
|
||||
|
||||
double z3=z, t3=t;
|
||||
puiss(z3,t3,3);
|
||||
|
||||
double f1t = (z3-x7)*(z3-x7+100*x13) - (t3-y7)*(t3-y7+100*y13);
|
||||
double f2t = (z3-x7)*(t3-y7+100*y13) + (t3-y7)*(z3-x7+100*x13);
|
||||
double f1 = f1t*(z3-x7-100*x13) - f2t*(t3-y7-100*y13);
|
||||
double f2 = f1t*(t3-y7-100*y13) + f2t*(z3-x7-100*x13);
|
||||
|
||||
f1 = f1*f1;
|
||||
f2 = f2*f2;
|
||||
e=e*e/(den-1);
|
||||
|
||||
if (f1+f2-e < 0)
|
||||
return -1.;
|
||||
else if (f1+f2-e > 0)
|
||||
return 1.;
|
||||
else
|
||||
return 0.;
|
||||
}
|
||||
|
||||
|
||||
// Knot 3
|
||||
|
||||
|
||||
double knot3_function (double a, double b, double c) { // radius = 4
|
||||
double e=0.025;
|
||||
|
||||
double x, y, z, t, den;
|
||||
den=1+a*a+b*b+c*c;
|
||||
x=2*a/den;
|
||||
y=2*b/den;
|
||||
z=2*c/den;
|
||||
t=(1-a*a-b*b-c*c)/den;
|
||||
|
||||
double x19=x, y19=y, z17=z, t17=t;
|
||||
puiss(x19,y19,19);
|
||||
puiss(z17,t17,17);
|
||||
|
||||
double f1 = z17-x19;
|
||||
double f2 = t17-y19;
|
||||
|
||||
f1 = f1*f1;
|
||||
f2 = f2*f2;
|
||||
e=e*e/(den-1);
|
||||
|
||||
if (f1+f2-e < 0)
|
||||
return -1.;
|
||||
else if (f1+f2-e > 0)
|
||||
return 1.;
|
||||
else
|
||||
return 0.;
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
///////////////// Definitions of several famous surfaces /////////////////
|
||||
double sphere_function (double, double, double); // (c=(0,0,0), r=1)
|
||||
double ellipsoid_function (double, double, double); // (c=(0,0,0), r=1)
|
||||
double torus_function (double, double, double); // (c=(0,0,0), r=2)
|
||||
double chair_function (double, double, double); // (c=(0,0,0), r=6)
|
||||
double tanglecube_function (double, double, double); // (c=(0,0,0), r=4)
|
||||
double octic_function (double, double, double); // (c=(0,0,0), r=2)
|
||||
double heart_function (double, double, double); // (c=(0,0,0), r=2)
|
||||
double klein_function (double, double, double); // (c=(0,0,0), r=4)
|
||||
double ring_function (double, double, double); // (c=(0,0,0), r=?)
|
||||
double false_knot_function (double, double, double); // (c=(0,0,0), r=1)
|
||||
double knot1_function (double, double, double); // (c=(0,0,0), r=4)
|
||||
double knot2_function (double, double, double); // (c=(0,0,0), r=4)
|
||||
double knot3_function (double, double, double); // (c=(0,0,0), r=4)
|
||||
double cube_function (double, double, double); // (c=(0,0,0), r=2)
|
||||
|
||||
|
||||
template <int Sq_radius>
|
||||
double sphere_function (double x, double y, double z) // (c=(0,0,0), r=Sq_radius)
|
||||
{
|
||||
double x2=x*x, y2=y*y, z2=z*z;
|
||||
return (x2+y2+z2)/Sq_radius - 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename FT, typename P>
|
||||
class FT_to_point_function_wrapper : public std::unary_function<P, FT>
|
||||
{
|
||||
typedef FT (*Implicit_function)(FT, FT, FT);
|
||||
Implicit_function function;
|
||||
public:
|
||||
typedef P Point;
|
||||
FT_to_point_function_wrapper(Implicit_function f) : function(f) {}
|
||||
FT operator()(Point p) const { return function(p.x(), p.y(), p.z()); }
|
||||
};
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Implicit_to_labeling_function_wrapper.h>
|
||||
|
||||
|
||||
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::Implicit_multi_domain_to_labeling_function_wrapper<Function*> 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<std::vector<CGAL::Sign> > vvpos;
|
||||
std::vector<CGAL::Sign> vpos1;
|
||||
vpos1.push_back(CGAL::NEGATIVE);
|
||||
vpos1.push_back(CGAL::POSITIVE);
|
||||
vvpos.push_back(vpos1);
|
||||
std::vector<CGAL::Sign> vpos2;
|
||||
vpos2.push_back(CGAL::POSITIVE);
|
||||
vpos2.push_back(CGAL::NEGATIVE);
|
||||
vvpos.push_back(vpos2);
|
||||
std::vector<CGAL::Sign> 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<std::string> 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,271 @@
|
|||
// 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 <CGAL/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Implicit_to_labeling_function_wrapper.h>
|
||||
|
||||
|
||||
template <typename K>
|
||||
struct LM3_tester
|
||||
{
|
||||
typedef typename K::Point_3 Point_3;
|
||||
typedef typename K::FT FT;
|
||||
|
||||
struct Function
|
||||
{
|
||||
typedef Point_3 Point;
|
||||
typedef FT (*Func)(const Point_3&);
|
||||
|
||||
Function (Func f) : f_(f) {}
|
||||
FT operator() (const Point_3& p) const { return f_(p); }
|
||||
|
||||
private:
|
||||
Func f_;
|
||||
};
|
||||
|
||||
typedef CGAL::Implicit_to_labeling_function_wrapper<Function, K> Function_wrapper;
|
||||
typedef CGAL::Labeled_mesh_domain_3<Function_wrapper, K> 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 <class BoundingShape>
|
||||
void test_domain (const BoundingShape& bounding_shape) const
|
||||
{
|
||||
FT error_bound(1e-3);
|
||||
|
||||
Function f_sphere(&sphere_function);
|
||||
Function_wrapper wrapper_1(f_sphere);
|
||||
Mesh_domain domain(wrapper_1, bounding_shape, error_bound);
|
||||
test_construct_initial_points(domain, error_bound);
|
||||
|
||||
Function f_shape(&shape_function);
|
||||
Function_wrapper wrapper_2(f_shape);
|
||||
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<std::pair<Point_3, Index> >::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<std::pair<Point_3, Index> > 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<Surface_patch_index>(&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<Subdomain_index>(&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<Surface_patch_index>(&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<Subdomain_index>(&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<Surface_patch_index>(&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<Subdomain_index>(&ii));
|
||||
assert(CGAL::cpp11::get<2>(i) == 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int main ()
|
||||
{
|
||||
LM3_tester<K_e_i> test_epic;
|
||||
test_epic();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
#define CGAL_NO_DEPRECATION_WARNINGS 1
|
||||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h>
|
||||
|
||||
|
||||
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_vector_to_labeled_function_wrapper<Function, K_e_i> 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);
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
test_constructor_vfunc();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,270 @@
|
|||
// 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) : Aymeric PELLE
|
||||
//
|
||||
//******************************************************************************
|
||||
// File Description :
|
||||
//******************************************************************************
|
||||
|
||||
#define CGAL_NO_DEPRECATION_WARNINGS 1
|
||||
|
||||
#include "test_meshing_utilities.h"
|
||||
#include <CGAL/Mesh_3/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h>
|
||||
|
||||
template <typename K>
|
||||
struct LM3_tester
|
||||
{
|
||||
typedef typename K::Point_3 Point_3;
|
||||
typedef typename K::FT FT;
|
||||
|
||||
struct Function
|
||||
{
|
||||
typedef Point_3 Point;
|
||||
typedef FT (*Func)(const Point_3&);
|
||||
|
||||
Function (Func f) : f_(f) {}
|
||||
FT operator() (const Point_3& p) const { return f_(p); }
|
||||
|
||||
private:
|
||||
Func f_;
|
||||
};
|
||||
|
||||
typedef CGAL::Mesh_3::Implicit_to_labeled_function_wrapper<Function, K> Function_wrapper;
|
||||
typedef CGAL::Mesh_3::Labeled_mesh_domain_3<Function_wrapper, K> 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;
|
||||
|
||||
test_domain(Sphere_3(CGAL::ORIGIN, 4.));
|
||||
test_domain(CGAL::Bbox_3(-2.,-2.,-2., 2.,2.,2.));
|
||||
}
|
||||
|
||||
private:
|
||||
template <class BoundingShape>
|
||||
void test_domain (const BoundingShape& bounding_shape) const
|
||||
{
|
||||
FT error_bound(1e-3);
|
||||
|
||||
Function f_sphere(&sphere_function);
|
||||
Function_wrapper wrapper_1(f_sphere);
|
||||
Mesh_domain domain(wrapper_1, bounding_shape, error_bound);
|
||||
test_construct_initial_points(domain, error_bound);
|
||||
|
||||
Function f_shape(&shape_function);
|
||||
Function_wrapper wrapper_2(f_shape);
|
||||
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<std::pair<Point_3, Index> >::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<std::pair<Point_3, Index> > 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<Surface_patch_index>(&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<Subdomain_index>(&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<Surface_patch_index>(&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<Subdomain_index>(&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<Surface_patch_index>(&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<Subdomain_index>(&ii));
|
||||
assert(CGAL::cpp11::get<2>(i) == 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int main ()
|
||||
{
|
||||
LM3_tester<K_e_i> test_epic;
|
||||
test_epic();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
|
||||
//******************************************************************************
|
||||
// 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.
|
||||
//******************************************************************************
|
||||
|
||||
|
||||
#define CGAL_NO_DEPRECATION_WARNINGS 1
|
||||
|
||||
#include "debug.h"
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Mesh_triangulation_3.h>
|
||||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||
#include <CGAL/Mesh_criteria_3.h>
|
||||
|
||||
#include <CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h>
|
||||
#include <CGAL/Mesh_3/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/make_mesh_3.h>
|
||||
#include "implicit_functions.h"
|
||||
|
||||
// IO
|
||||
#include <CGAL/IO/File_medit.h>
|
||||
|
||||
using namespace CGAL::parameters;
|
||||
|
||||
// Domain
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef FT_to_point_function_wrapper<K::FT, K::Point_3> Function;
|
||||
typedef CGAL::Mesh_3::Implicit_vector_to_labeled_function_wrapper<Function, K>
|
||||
Function_wrapper;
|
||||
typedef Function_wrapper::Function_vector Function_vector;
|
||||
typedef CGAL::Mesh_3::Labeled_mesh_domain_3<Function_wrapper, K> Mesh_domain;
|
||||
|
||||
// Triangulation
|
||||
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
||||
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
||||
|
||||
// Mesh Criteria
|
||||
typedef CGAL::Mesh_criteria_3<Tr> 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 f3(&sphere_function<2>);
|
||||
|
||||
Function_vector v;
|
||||
v.push_back(&f1);
|
||||
v.push_back(&f2);
|
||||
//v.push_back(&f3);
|
||||
|
||||
// Domain (Warning: Sphere_3 constructor uses square radius !)
|
||||
Mesh_domain domain(v, K::Sphere_3(CGAL::ORIGIN, 5.*5.), 1e-6);
|
||||
|
||||
// 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<C3t3>(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;
|
||||
}
|
||||
|
|
@ -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<Traits, Function>`
|
||||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue