mirror of https://github.com/CGAL/cgal
Reworked Periodic 3 mesh domain classes
No need to duplicate Labeled_mesh_domain_3 anymore: a wrapper is used.
This commit is contained in:
parent
7ea3a8044e
commit
d97d388ef4
|
|
@ -923,14 +923,12 @@ protected:
|
|||
return functor;
|
||||
}
|
||||
|
||||
public:
|
||||
/// Returns bounding box
|
||||
const Iso_cuboid_3& bounding_box() const { return this->bbox_; }
|
||||
|
||||
}; // end class Labeled_mesh_domain_3
|
||||
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Method implementation
|
||||
//-------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1,67 +0,0 @@
|
|||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\ingroup PkgPeriodic_3_mesh_3Domains
|
||||
|
||||
The class `Implicit_periodic_3_mesh_domain_3` implements a periodic domain
|
||||
whose bounding surface is described implicitly as the zero level set
|
||||
of a function defined over the three dimensional flat torus. In practice,
|
||||
the domain of definition of the function must contain the input canonical cube,
|
||||
see Section \ref Periodic_3_mesh_3InputDomain.
|
||||
The domain to be discretized is assumed to be the domain where
|
||||
the function has negative values.
|
||||
|
||||
This class is a model of the concept `Periodic_3MeshDomain_3`.
|
||||
|
||||
\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.
|
||||
|
||||
\tparam BGT is a geometric traits which provides the basic operations to implement
|
||||
intersection tests and computations through a bisection method.
|
||||
This parameter must be instantiated with a model of the concept
|
||||
`BisectionGeometricTraits_3`.
|
||||
|
||||
The constructor of `Implicit_periodic_3_mesh_domain_3` takes as argument
|
||||
a cuboid (the canonical cube) in which
|
||||
we construct the mesh (see \ref PkgPeriodic_3_mesh_3).
|
||||
This domain constructs intersection points between the surface and
|
||||
segments (duals of a facet) by bisection. It requires an `error_bound`
|
||||
such that the bisection process is stopped when the query segment is smaller
|
||||
than the error bound. The `error_bound`, passed as argument to the domain constructor,
|
||||
is a relative error bound expressed as a ratio of the longest space diagonal
|
||||
of the cuboid.
|
||||
|
||||
\cgalModels `Periodic_3MeshDomain_3`
|
||||
|
||||
\sa `CGAL::make_periodic_3_mesh_3()`.
|
||||
\sa `Labeled_periodic_3_mesh_domain_3`
|
||||
|
||||
\sa `BisectionGeometricTraits_3`
|
||||
\sa `Implicit_mesh_domain_3`
|
||||
|
||||
*/
|
||||
template< typename Function, typename BGT >
|
||||
class Implicit_periodic_3_mesh_domain_3 {
|
||||
public:
|
||||
|
||||
/// \name Creation
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
\param f is the object of type `Function` that represents the implicit surface
|
||||
\param cuboid is the canonical cube
|
||||
\param error_bound is the relative error bound used to compute intersection
|
||||
points between the implicit surface and query segments. The bisection
|
||||
is stopped when the length of the intersected segment is less than
|
||||
the product of `error_bound` by the diagonal of `cuboid`.
|
||||
*/
|
||||
Implicit_periodic_3_mesh_domain_3(Function f,
|
||||
BGT::Iso_cuboid_3 cuboid,
|
||||
BGT::FT error_bound = FT(1e-6));
|
||||
|
||||
/// @}
|
||||
|
||||
}; /* end Implicit_periodic_3_mesh_domain_3 */
|
||||
} /* end namespace CGAL */
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\ingroup PkgPeriodic_3_mesh_3Domains
|
||||
|
||||
\brief The class `Labeled_periodic_3_mesh_domain_3` implements indexed periodic domains.
|
||||
|
||||
This class is a model of concept `Periodic_3MeshDomain_3`.
|
||||
|
||||
Any boundary facet is labeled `<a,b>`, with `a<b`, where `a` and `b` are the
|
||||
tags of its incident subdomains.
|
||||
Thus, a boundary facet of the domain is labeled `<0,b>`, where `b!=0`.
|
||||
|
||||
This class includes a function that provides the index of the subdomain
|
||||
in which any query point lies. 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 cuboid
|
||||
(in world coordinates) and a relative error bound passed as argument
|
||||
to the constructor of `Labeled_periodic_3_mesh_domain_3`.
|
||||
|
||||
`Implicit_periodic_3_mesh_domain_3` is derived from `Labeled_periodic_3_mesh_domain_3`.
|
||||
It uses a satisfactory 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 />
|
||||
The function is defined over the canonical representation of the three dimensional flat torus,
|
||||
the input canonical cube (see Section \ref Periodic_3_mesh_3InputDomain).
|
||||
The labeling function `f` must return `0` if the point isn't located in any subdomain.
|
||||
Usually, the return types 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 the 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 Periodic_3MeshDomain_3
|
||||
|
||||
\sa `CGAL::make_periodic_3_mesh_3()`.
|
||||
\sa `Implicit_periodic_3_mesh_domain_3`
|
||||
|
||||
\sa `Labeled_mesh_domain_3`
|
||||
\sa `Implicit_mesh_domain_3`
|
||||
|
||||
*/
|
||||
template<class LabelingFunction, class BGT>
|
||||
class Labeled_periodic_3_mesh_domain_3
|
||||
{
|
||||
public:
|
||||
typedef typename BGT::Iso_cuboid_3 Iso_cuboid_3;
|
||||
|
||||
/// \name Creation
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
\brief Construction from a function, a cube, and a relative error bound.
|
||||
|
||||
\param f is the function.
|
||||
\param cuboid is the canonical cube in which we construct the mesh.
|
||||
\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 `cuboid`.
|
||||
*/
|
||||
Labeled_periodic_3_mesh_domain_3(const LabelingFunction& f,
|
||||
const BGT::Iso_cuboid_3& cuboid,
|
||||
const BGT::FT& relative_error_bound = FT(1e-6));
|
||||
|
||||
/// @}
|
||||
|
||||
/*!
|
||||
* \brief Return the user-chosen cube that is the canonical instance of the flat torus.
|
||||
*/
|
||||
const Iso_cuboid_3& canonical_periodic_domain();
|
||||
|
||||
}; /* end Labeled_periodic_3_mesh_domain_3 */
|
||||
} /* end namespace CGAL */
|
||||
|
|
@ -2,12 +2,13 @@
|
|||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Periodic_3_mesh_3/IO/File_medit.h>
|
||||
#include <CGAL/Labeled_periodic_3_mesh_domain_3.h>
|
||||
#include <CGAL/make_periodic_3_mesh_3.h>
|
||||
#include <CGAL/Periodic_3_mesh_3/IO/File_medit.h>
|
||||
#include <CGAL/Periodic_3_mesh_triangulation_3.h>
|
||||
#include <CGAL/Periodic_3_wrapper.h>
|
||||
|
||||
#include <CGAL/Implicit_to_labeling_function_wrapper.h>
|
||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||
#include <CGAL/Mesh_criteria_3.h>
|
||||
|
||||
|
|
@ -23,33 +24,37 @@
|
|||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef K::FT FT;
|
||||
typedef K::Point_3 Point;
|
||||
|
||||
// Function
|
||||
typedef FT (*Function)(const Point&);
|
||||
typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper<Function> Wrapper;
|
||||
typedef K::Iso_cuboid_3 Iso_cuboid;
|
||||
|
||||
// Domain
|
||||
typedef CGAL::Labeled_periodic_3_mesh_domain_3<Wrapper, K> Periodic_mesh_domain;
|
||||
typedef FT (*Function)(const Point&);
|
||||
// This wrapper is needed to make 'sphere_function' periodic.
|
||||
typedef CGAL::Periodic_3_wrapper<Function, K> Periodic_function;
|
||||
typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper<Periodic_function> Multi_domain_wrapper;
|
||||
typedef CGAL::Labeled_mesh_domain_3<K> Periodic_mesh_domain;
|
||||
|
||||
// Triangulation
|
||||
typedef CGAL::Periodic_3_mesh_triangulation_3<Periodic_mesh_domain>::type Tr;
|
||||
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
||||
|
||||
// Criteria
|
||||
typedef CGAL::Mesh_criteria_3<Tr> Periodic_mesh_criteria;
|
||||
typedef CGAL::Mesh_criteria_3<Tr> Periodic_mesh_criteria;
|
||||
|
||||
// To avoid verbose function and named parameters call
|
||||
using namespace CGAL::parameters;
|
||||
|
||||
// Implicit functions
|
||||
FT sphere_function(const Point& p)
|
||||
{ return CGAL::squared_distance(p, Point(0.5, 0.5, 0.5)) - 0.15; }
|
||||
{
|
||||
return CGAL::squared_distance(p, Point(0.5, 0.5, 0.5)) - 0.15;
|
||||
}
|
||||
|
||||
FT schwarz_p(const Point& p)
|
||||
{
|
||||
const FT x2 = std::cos( p.x() * 2 * CGAL_PI ),
|
||||
y2 = std::cos( p.y() * 2 * CGAL_PI ),
|
||||
z2 = std::cos( p.z() * 2 * CGAL_PI );
|
||||
|
||||
return x2 + y2 + z2;
|
||||
}
|
||||
|
||||
|
|
@ -58,17 +63,20 @@ int main(int argc, char** argv)
|
|||
int domain_size = (argc > 1) ? atoi(argv[1]) : 1;
|
||||
int number_of_copies_in_output = (argc > 2) ? atoi(argv[2]) : 4; // can be 1, 2, 4, or 8
|
||||
|
||||
std::vector<Function> funcs;
|
||||
funcs.push_back(&schwarz_p);
|
||||
funcs.push_back(&sphere_function);
|
||||
Iso_cuboid canonical_cube(0, 0, 0, domain_size, domain_size, domain_size);
|
||||
|
||||
// The vector of vectors of sign is passed as a vector of strings (a string
|
||||
// being a vector of chars)
|
||||
std::vector<Periodic_function> funcs;
|
||||
funcs.push_back(CGAL::make_periodic_3_wrapper<K>(&schwarz_p, canonical_cube));
|
||||
funcs.push_back(CGAL::make_periodic_3_wrapper<K>(&sphere_function, canonical_cube));
|
||||
|
||||
// The vector of vectors of sign is passed as a vector of strings (since a string
|
||||
// is a vector of chars)
|
||||
std::vector<std::string> vps;
|
||||
vps.push_back("--");
|
||||
vps.push_back("-+");
|
||||
Wrapper wrapper(funcs, vps);
|
||||
Periodic_mesh_domain domain(wrapper, CGAL::Iso_cuboid_3<K>(0, 0, 0, domain_size, domain_size, domain_size));
|
||||
|
||||
Multi_domain_wrapper multi_domain_function(funcs, vps);
|
||||
Periodic_mesh_domain domain(multi_domain_function, canonical_cube);
|
||||
|
||||
Periodic_mesh_criteria criteria(facet_angle = 30,
|
||||
facet_size = 0.04,
|
||||
|
|
@ -81,9 +89,9 @@ int main(int argc, char** argv)
|
|||
|
||||
// Output
|
||||
std::ofstream medit_file("output_multi_domain.mesh");
|
||||
CGAL::output_to_medit(medit_file, c3t3, number_of_copies_in_output,
|
||||
false /*do not associate different colors to each copy*/,
|
||||
false /*do not rebind*/, true /*show patches*/);
|
||||
CGAL::output_to_medit<C3t3>(medit_file, c3t3, number_of_copies_in_output,
|
||||
false /*do not associate different colors to each copy*/,
|
||||
false /*do not rebind*/, true /*show patches*/);
|
||||
|
||||
std::cout << "EXIT SUCCESS" << std::endl;
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -2,12 +2,13 @@
|
|||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Periodic_3_mesh_3/IO/File_medit.h>
|
||||
#include <CGAL/Implicit_periodic_3_mesh_domain_3.h>
|
||||
#include <CGAL/make_periodic_3_mesh_3.h>
|
||||
#include <CGAL/optimize_periodic_3_mesh_3.h>
|
||||
#include <CGAL/Periodic_3_mesh_3/IO/File_medit.h>
|
||||
#include <CGAL/Periodic_3_mesh_triangulation_3.h>
|
||||
#include <CGAL/Periodic_3_wrapper.h>
|
||||
|
||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||
#include <CGAL/Mesh_criteria_3.h>
|
||||
|
||||
|
|
@ -17,25 +18,28 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
// Domain
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef K::FT FT;
|
||||
typedef K::Point_3 Point;
|
||||
typedef K::Iso_cuboid_3 Iso_cuboid;
|
||||
|
||||
// Domain
|
||||
typedef FT (Function)(const Point&);
|
||||
typedef CGAL::Implicit_periodic_3_mesh_domain_3<Function,K> Periodic_mesh_domain;
|
||||
typedef CGAL::Labeled_mesh_domain_3<K> Periodic_mesh_domain;
|
||||
|
||||
// Triangulation
|
||||
typedef CGAL::Periodic_3_mesh_triangulation_3<Periodic_mesh_domain>::type Tr;
|
||||
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
||||
|
||||
// Criteria
|
||||
typedef CGAL::Mesh_criteria_3<Tr> Periodic_mesh_criteria;
|
||||
typedef CGAL::Mesh_criteria_3<Tr> Periodic_mesh_criteria;
|
||||
|
||||
// To avoid verbose function and named parameters call
|
||||
using namespace CGAL::parameters;
|
||||
|
||||
// Implicit function
|
||||
FT schwarz_p(const Point& p) {
|
||||
FT schwarz_p(const Point& p)
|
||||
{
|
||||
const FT x2 = std::cos( p.x() * 2 * CGAL_PI ),
|
||||
y2 = std::cos( p.y() * 2 * CGAL_PI ),
|
||||
z2 = std::cos( p.z() * 2 * CGAL_PI );
|
||||
|
|
@ -49,7 +53,10 @@ int main(int argc, char** argv)
|
|||
int domain_size = (argc > 1) ? atoi(argv[1]) : 1;
|
||||
int number_of_copies_in_output = (argc > 2) ? atoi(argv[2]) : 4; // can be 1, 2, 4, or 8
|
||||
|
||||
Periodic_mesh_domain domain(schwarz_p, CGAL::Iso_cuboid_3<K>(0, 0, 0, domain_size, domain_size, domain_size));
|
||||
Iso_cuboid canonical_cube(0, 0, 0, domain_size, domain_size, domain_size);
|
||||
|
||||
Periodic_mesh_domain domain =
|
||||
Periodic_mesh_domain::create_implicit_mesh_domain(schwarz_p, canonical_cube);
|
||||
|
||||
Periodic_mesh_criteria criteria(facet_angle = 30,
|
||||
facet_size = 0.05 * domain_size,
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Periodic_3_mesh_3/IO/File_medit.h>
|
||||
#include <CGAL/Implicit_periodic_3_mesh_domain_3.h>
|
||||
#include <CGAL/make_periodic_3_mesh_3.h>
|
||||
#include <CGAL/optimize_periodic_3_mesh_3.h>
|
||||
#include <CGAL/Periodic_3_mesh_triangulation_3.h>
|
||||
#include <CGAL/Periodic_3_mesh_3/IO/File_medit.h>
|
||||
|
||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||
#include <CGAL/Mesh_criteria_3.h>
|
||||
|
||||
|
|
@ -17,19 +17,21 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
// Domain
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef K::FT FT;
|
||||
typedef K::Point_3 Point;
|
||||
typedef K::Iso_cuboid_3 Iso_cuboid;
|
||||
|
||||
// Domain
|
||||
typedef FT (Function)(const Point&);
|
||||
typedef CGAL::Implicit_periodic_3_mesh_domain_3<Function,K> Periodic_mesh_domain;
|
||||
typedef CGAL::Labeled_mesh_domain_3<K> Periodic_mesh_domain;
|
||||
|
||||
// Triangulation
|
||||
typedef CGAL::Periodic_3_mesh_triangulation_3<Periodic_mesh_domain>::type Tr;
|
||||
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
||||
|
||||
// Criteria
|
||||
typedef CGAL::Mesh_criteria_3<Tr> Periodic_mesh_criteria;
|
||||
typedef CGAL::Mesh_criteria_3<Tr> Periodic_mesh_criteria;
|
||||
|
||||
// To avoid verbose function and named parameters call
|
||||
using namespace CGAL::parameters;
|
||||
|
|
@ -43,7 +45,8 @@ FT double_p(const Point& p)
|
|||
const FT c2x = std::cos(4 * CGAL_PI * p.x()),
|
||||
c2y = std::cos(4 * CGAL_PI * p.y()),
|
||||
c2z = std::cos(4 * CGAL_PI * p.z());
|
||||
return 0.5 * (cx * cy + cy * cz + cz * cx ) + 0.2*(c2x + c2y + c2z);
|
||||
|
||||
return 0.5 * (cx*cy + cy*cz + cz*cx) + 0.2 * (c2x + c2y + c2z);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
|
|
@ -53,7 +56,11 @@ int main(int argc, char** argv)
|
|||
int domain_size = (argc > 1) ? atoi(argv[1]) : 1;
|
||||
int number_of_copies_in_output = (argc > 2) ? atoi(argv[2]) : 8; // can be 1, 2, 4, or 8
|
||||
|
||||
Periodic_mesh_domain domain(double_p, CGAL::Iso_cuboid_3<K>(0, 0, 0, domain_size, domain_size, domain_size));
|
||||
Iso_cuboid canonical_cube(0, 0, 0, domain_size, domain_size, domain_size);
|
||||
|
||||
// there is no need for periodicity... ?
|
||||
Periodic_mesh_domain domain =
|
||||
Periodic_mesh_domain::create_implicit_mesh_domain(double_p, canonical_cube);
|
||||
|
||||
Periodic_mesh_criteria criteria(facet_angle = 30,
|
||||
facet_size = 0.05 * domain_size,
|
||||
|
|
@ -68,7 +75,7 @@ int main(int argc, char** argv)
|
|||
perturb(sliver_bound=10, time_limit=30),
|
||||
exude(sliver_bound=10, time_limit=0));
|
||||
|
||||
std::ofstream medit_file("output_implicit_shape.mesh");
|
||||
std::ofstream medit_file("output_implicit_shape_optimized.mesh");
|
||||
CGAL::output_to_medit(medit_file, c3t3);
|
||||
|
||||
// Below, the mesh generation and the optimizations are done in several calls
|
||||
|
|
|
|||
|
|
@ -2,11 +2,12 @@
|
|||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Periodic_3_mesh_3/IO/File_medit.h>
|
||||
#include <CGAL/Implicit_periodic_3_mesh_domain_3.h>
|
||||
#include <CGAL/make_periodic_3_mesh_3.h>
|
||||
#include <CGAL/Periodic_3_mesh_3/IO/File_medit.h>
|
||||
#include <CGAL/Periodic_3_mesh_triangulation_3.h>
|
||||
#include <CGAL/Periodic_3_wrapper.h>
|
||||
|
||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||
#include <CGAL/Mesh_criteria_3.h>
|
||||
|
||||
|
|
@ -28,21 +29,20 @@ typedef K::Point_3 Point;
|
|||
typedef K::Iso_cuboid_3 Iso_cuboid;
|
||||
|
||||
typedef FT (Function)(const Point&);
|
||||
typedef CGAL::Mesh_domain_with_polyline_features_3<
|
||||
CGAL::Implicit_periodic_3_mesh_domain_3<Function,K> > Mesh_domain;
|
||||
typedef CGAL::Mesh_domain_with_polyline_features_3<CGAL::Labeled_mesh_domain_3<K> > Periodic_mesh_domain;
|
||||
|
||||
// Polyline
|
||||
typedef std::vector<Point> Polyline_3;
|
||||
typedef std::list<Polyline_3> Polylines;
|
||||
|
||||
// Triangulation
|
||||
typedef CGAL::Periodic_3_mesh_triangulation_3<Mesh_domain>::type Tr;
|
||||
typedef CGAL::Periodic_3_mesh_triangulation_3<Periodic_mesh_domain>::type Tr;
|
||||
|
||||
typedef CGAL::Mesh_complex_3_in_triangulation_3<
|
||||
Tr, Mesh_domain::Corner_index, Mesh_domain::Curve_index> C3t3;
|
||||
Tr, Periodic_mesh_domain::Corner_index, Periodic_mesh_domain::Curve_index> C3t3;
|
||||
|
||||
// Criteria
|
||||
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
|
||||
typedef CGAL::Mesh_criteria_3<Tr> Periodic_mesh_criteria;
|
||||
|
||||
// To avoid verbose function and named parameters call
|
||||
using namespace CGAL::parameters;
|
||||
|
|
@ -67,7 +67,7 @@ void cone_polylines(Polylines& polylines)
|
|||
const FT radius_at_z = CGAL::sqrt(scale * cz * cz);
|
||||
|
||||
Polyline_3 polyline;
|
||||
for(int i = 0; i < 360; ++i)
|
||||
for(int i=0; i<360; ++i)
|
||||
{
|
||||
polyline.push_back(Point(cx + radius_at_z * std::sin(i*CGAL_PI/180),
|
||||
cy + radius_at_z * std::cos(i*CGAL_PI/180),
|
||||
|
|
@ -84,14 +84,18 @@ int main(int argc, char** argv)
|
|||
|
||||
// Domain
|
||||
const int domain_size = 1;
|
||||
Mesh_domain domain(cone_function,
|
||||
CGAL::Iso_cuboid_3<K>(0, 0, 0, domain_size, domain_size, domain_size));
|
||||
Iso_cuboid canonical_cube(0, 0, 0, domain_size, domain_size, domain_size);
|
||||
|
||||
Periodic_mesh_domain domain =
|
||||
Periodic_mesh_domain::create_implicit_mesh_domain(
|
||||
CGAL::make_periodic_3_wrapper<K>(cone_function, canonical_cube), canonical_cube);
|
||||
|
||||
// Mesh criteria
|
||||
Mesh_criteria criteria(edge_size = 0.02 * domain_size,
|
||||
facet_angle = 0.05 * domain_size,
|
||||
facet_size = 0.02 * domain_size,
|
||||
cell_radius_edge_ratio = 2, cell_size = 0.5);
|
||||
Periodic_mesh_criteria criteria(edge_size = 0.02 * domain_size,
|
||||
facet_angle = 0.05 * domain_size,
|
||||
facet_size = 0.02 * domain_size,
|
||||
cell_radius_edge_ratio = 2,
|
||||
cell_size = 0.5);
|
||||
|
||||
// Create the features that we want to preserve
|
||||
Polylines polylines;
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Periodic_3_mesh_3/IO/File_medit.h>
|
||||
#include <CGAL/Implicit_periodic_3_mesh_domain_3.h>
|
||||
#include <CGAL/Implicit_to_labeled_subdomains_function_wrapper.h>
|
||||
#include <CGAL/make_periodic_3_mesh_3.h>
|
||||
#include <CGAL/Periodic_3_mesh_3/IO/File_medit.h>
|
||||
#include <CGAL/Periodic_3_mesh_triangulation_3.h>
|
||||
|
||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Mesh_criteria_3.h>
|
||||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||
#include <CGAL/Mesh_constant_domain_field_3.h>
|
||||
|
|
@ -21,11 +21,12 @@
|
|||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef K::FT FT;
|
||||
typedef K::Point_3 Point;
|
||||
typedef K::Iso_cuboid_3 Iso_cuboid;
|
||||
|
||||
// Domain
|
||||
typedef FT (Function)(const Point&);
|
||||
typedef CGAL::Implicit_to_labeled_subdomains_function_wrapper<Function, K> Function_wrapper;
|
||||
typedef CGAL::Implicit_periodic_3_mesh_domain_3<Function, K, Function_wrapper> Periodic_mesh_domain;
|
||||
typedef CGAL::Labeled_mesh_domain_3<K> Periodic_mesh_domain;
|
||||
|
||||
// Triangulation
|
||||
typedef CGAL::Periodic_3_mesh_triangulation_3<Periodic_mesh_domain>::type Tr;
|
||||
|
|
@ -38,10 +39,12 @@ typedef CGAL::Mesh_criteria_3<Tr> Periodic_mesh_criteria;
|
|||
using namespace CGAL::parameters;
|
||||
|
||||
// Function
|
||||
FT schwarz_p(const Point& p) {
|
||||
FT schwarz_p(const Point& p)
|
||||
{
|
||||
const FT x2 = std::cos( p.x() * 2 * CGAL_PI ),
|
||||
y2 = std::cos( p.y() * 2 * CGAL_PI ),
|
||||
z2 = std::cos( p.z() * 2 * CGAL_PI );
|
||||
|
||||
return x2 + y2 + z2;
|
||||
}
|
||||
|
||||
|
|
@ -53,7 +56,10 @@ int main(int argc, char** argv)
|
|||
{
|
||||
int number_of_copies_in_output = (argc > 1) ? atoi(argv[1]) : 4; // can be 1, 2, 4, or 8
|
||||
|
||||
Periodic_mesh_domain domain(schwarz_p, CGAL::Iso_cuboid_3<K>(0, 0, 0, 1, 1, 1));
|
||||
Iso_cuboid canonical_cube(0, 0, 0, 1, 1, 1);
|
||||
|
||||
Function_wrapper wrapper(schwarz_p);
|
||||
Periodic_mesh_domain domain(wrapper, canonical_cube);
|
||||
|
||||
// Write the two different sizing fields for cells
|
||||
int volume_dimension = 3;
|
||||
|
|
|
|||
|
|
@ -1,88 +0,0 @@
|
|||
// Copyright (c) 2009 INRIA Sophia-Antipolis (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
// You can redistribute it and/or modify it under the terms of the GNU
|
||||
// General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
//
|
||||
// Author(s) : Mikhail Bogdanov
|
||||
//
|
||||
#ifndef CGAL_PERIODIC_3_MESH_3_IMPLICIT_PERIODIC_3_MESH_DOMAIN_3_H
|
||||
#define CGAL_PERIODIC_3_MESH_3_IMPLICIT_PERIODIC_3_MESH_DOMAIN_3_H
|
||||
|
||||
#include <CGAL/license/Periodic_3_mesh_3.h>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4180) // qualifier applied to function type has no meaning; ignored
|
||||
#endif
|
||||
|
||||
#include <CGAL/Periodic_3_mesh_3/config.h>
|
||||
|
||||
#include <CGAL/Labeled_periodic_3_mesh_domain_3.h>
|
||||
#include <CGAL/Implicit_to_labeling_function_wrapper.h>
|
||||
|
||||
namespace CGAL {
|
||||
/**
|
||||
* @class Implicit_periodic_3_mesh_domain_3
|
||||
*
|
||||
* Implements mesh_traits for a domain defined as the negative values of
|
||||
* an implicit function.
|
||||
*/
|
||||
template<class Function,
|
||||
class BGT,
|
||||
class Wrapper = Implicit_to_labeling_function_wrapper<Function,BGT> >
|
||||
class Implicit_periodic_3_mesh_domain_3
|
||||
: public Labeled_periodic_3_mesh_domain_3<Wrapper, BGT >
|
||||
{
|
||||
public:
|
||||
/// Base type
|
||||
typedef Labeled_periodic_3_mesh_domain_3<Wrapper, BGT> Base;
|
||||
|
||||
/// Public types
|
||||
typedef typename Base::Bbox_3 Bbox_3;
|
||||
typedef typename Base::FT FT;
|
||||
typedef BGT Geom_traits;
|
||||
typedef typename BGT::Iso_cuboid_3 Iso_cuboid_3;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param f the function which negative values defines the domain
|
||||
* @param cuboid the fundamental domain
|
||||
* @param error_bound the error bound relative to the sphere radius
|
||||
*/
|
||||
Implicit_periodic_3_mesh_domain_3(const Function& f,
|
||||
const Iso_cuboid_3& cuboid,
|
||||
FT error_bound = FT(1e-6))
|
||||
: Base(Wrapper(f), cuboid, error_bound)
|
||||
{ }
|
||||
|
||||
/// Destructor
|
||||
virtual ~Implicit_periodic_3_mesh_domain_3() { }
|
||||
|
||||
private:
|
||||
// Disabled copy constructor & assignment operator
|
||||
typedef Implicit_periodic_3_mesh_domain_3<Function,BGT> Self;
|
||||
Implicit_periodic_3_mesh_domain_3(const Self& src);
|
||||
Self& operator=(const Self& src);
|
||||
|
||||
};
|
||||
|
||||
} // end namespace CGAL
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // CGAL_PERIODIC_3_MESH_3_IMPLICIT_PERIODIC_3_MESH_DOMAIN_3_H
|
||||
|
|
@ -51,6 +51,7 @@ public:
|
|||
/// Operator ()
|
||||
return_type operator()(const Point_3& p, const bool = true) const
|
||||
{
|
||||
// here is the important part : both > 0 ---> mesh both the interior and the exterior
|
||||
return ( (r_f_(p)<0) ? 1 : 2 );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,599 +0,0 @@
|
|||
// Copyright (c) 2014 INRIA Sophia-Antipolis (France).
|
||||
// Copyright (c) 2017 GeometryFactory (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$
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
//
|
||||
// Author(s) : Stéphane Tayeb,
|
||||
// Aymeric Pellé
|
||||
//
|
||||
#ifndef CGAL_PERIODIC_3_MESH_3_LABELED_PERIODIC_3_MESH_DOMAIN_3_H
|
||||
#define CGAL_PERIODIC_3_MESH_3_LABELED_PERIODIC_3_MESH_DOMAIN_3_H
|
||||
|
||||
#include <CGAL/license/Periodic_3_mesh_3.h>
|
||||
|
||||
#include <CGAL/Periodic_3_mesh_3/config.h>
|
||||
|
||||
#include <CGAL/Periodic_3_mesh_triangulation_3.h>
|
||||
#include <CGAL/internal/canonicalize_helper.h>
|
||||
|
||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/intersections.h>
|
||||
#include <CGAL/result_of.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace CGAL
|
||||
{
|
||||
|
||||
/**
|
||||
* \class Labeled_periodic_3_mesh_domain_3
|
||||
*
|
||||
* Function `f` must be defined over the fundamental domain and 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>`, with `a<b`, where `a` and `b` are the
|
||||
* tags of its incident subdomain.
|
||||
* Thus, a boundary facet of the domain is labelled `<0,b>`, where `b!=0`.
|
||||
*/
|
||||
// The difference with Mesh_3's is very tiny if 'CGAL_PERIODIC_CANONICALIZE_DUAL_INTERSECTIONS'
|
||||
// is not enabled: it resides in the call to label() which canonicalizes the point
|
||||
// (that is, send them to the fundamental domain) before evaluation.
|
||||
//
|
||||
// This could be simplified with a virtual function label() (in Mesh_3)?
|
||||
// Leaving this simplification to be done when other types of domains are added to P3M3.
|
||||
template<class Function, class BGT, class Null_subdomain_index = Default>
|
||||
class Labeled_periodic_3_mesh_domain_3
|
||||
: public Labeled_mesh_domain_3<Function, BGT,
|
||||
typename Default::Get<Null_subdomain_index,
|
||||
CGAL::Null_subdomain_index>::type>
|
||||
{
|
||||
public:
|
||||
/// Null subdomain type
|
||||
typedef typename Default::Get<Null_subdomain_index,
|
||||
CGAL::Null_subdomain_index>::type Null;
|
||||
|
||||
/// Base type
|
||||
typedef Labeled_mesh_domain_3<Function, BGT, Null> Base;
|
||||
|
||||
/// Geometric object types
|
||||
typedef typename Base::Point_3 Point_3;
|
||||
typedef typename Base::Segment_3 Segment_3;
|
||||
typedef typename Base::Ray_3 Ray_3;
|
||||
typedef typename Base::Line_3 Line_3;
|
||||
typedef typename Base::Vector_3 Vector_3;
|
||||
typedef typename Base::Iso_cuboid_3 Iso_cuboid_3;
|
||||
typedef typename Base::Bbox_3 Bbox_3;
|
||||
typedef typename Base::Sphere_3 Sphere_3;
|
||||
|
||||
/// Type of indexes for surface patch of the input complex
|
||||
typedef typename Base::Surface_patch Surface_patch;
|
||||
typedef typename Base::Surface_patch_index Surface_patch_index;
|
||||
|
||||
/// Type of indexes to characterize the lowest dimensional face of the input
|
||||
/// complex on which a vertex lie
|
||||
typedef typename Base::Index Index;
|
||||
typedef typename Base::Intersection Intersection;
|
||||
|
||||
/// Type of indexes for cells of the input complex
|
||||
typedef typename Base::Subdomain_index Subdomain_index;
|
||||
typedef typename Base::Subdomain Subdomain;
|
||||
|
||||
/// Public types
|
||||
typedef typename Base::FT FT;
|
||||
typedef BGT Geom_traits;
|
||||
|
||||
/// Periodic traits used in the canonicalization of the points
|
||||
typedef typename details::Periodic_3_mesh_geom_traits_generator<BGT>::type Periodic_geom_traits;
|
||||
|
||||
Labeled_periodic_3_mesh_domain_3(const Function& f,
|
||||
const Iso_cuboid_3& bbox,
|
||||
const FT& error_bound = FT(1e-6),
|
||||
Null null = Null(),
|
||||
CGAL::Random* p_rng = NULL)
|
||||
: Base(f, bbox, error_bound, null, p_rng),
|
||||
pgt(bbox)
|
||||
{ }
|
||||
|
||||
const Iso_cuboid_3& canonical_periodic_domain() const { return Base::bounding_box(); }
|
||||
const Periodic_geom_traits& periodic_geom_traits() const { return pgt; }
|
||||
|
||||
Subdomain_index label(const Point_3& p) const {
|
||||
return Base::labeling_function()(P3T3::internal::robust_canonicalize_point(p, pgt));
|
||||
}
|
||||
Subdomain_index label(const Point_3& p, const bool b) const {
|
||||
return Base::labeling_function()(P3T3::internal::robust_canonicalize_point(p, pgt), b);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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>}.
|
||||
*/
|
||||
// This is a complete copy paste from the base class because Do_intersect
|
||||
// needs to be the nested class' and not the base class'.
|
||||
// To be simplified...
|
||||
struct Construct_initial_points
|
||||
{
|
||||
Construct_initial_points(const Labeled_periodic_3_mesh_domain_3& domain)
|
||||
: r_domain_(domain) {}
|
||||
|
||||
template<class OutputIterator>
|
||||
OutputIterator operator()(OutputIterator pts, const int nb_points = 12) 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_.bounding_box()));
|
||||
|
||||
const double radius = std::sqrt(CGAL::to_double(squared_radius));
|
||||
|
||||
CGAL::Random& rng = *(r_domain_.random_number_generator());
|
||||
Random_points_on_sphere_3 random_point_on_sphere(radius, rng);
|
||||
Random_points_in_sphere_3 random_point_in_sphere(radius, rng);
|
||||
|
||||
// Get some functors
|
||||
typename Periodic_geom_traits::Construct_segment_3 segment_3 =
|
||||
r_domain_.periodic_geom_traits().construct_segment_3_object();
|
||||
typename Periodic_geom_traits::Construct_vector_3 vector_3 =
|
||||
r_domain_.periodic_geom_traits().construct_vector_3_object();
|
||||
typename Periodic_geom_traits::Construct_translated_point_3 translate =
|
||||
r_domain_.periodic_geom_traits().construct_translated_point_3_object();
|
||||
typename Periodic_geom_traits::Construct_center_3 center =
|
||||
r_domain_.periodic_geom_traits().construct_center_3_object();
|
||||
|
||||
// Get translation from origin to sphere center
|
||||
Point_3 center_pt = center(r_domain_.bounding_sphere(r_domain_.bounding_box()));
|
||||
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 (nb_points: " << nb_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;
|
||||
}
|
||||
|
||||
private:
|
||||
const Labeled_periodic_3_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_periodic_3_mesh_domain_3& domain)
|
||||
: r_domain_(domain) {}
|
||||
|
||||
Subdomain operator()(const Point_3& p) const
|
||||
{
|
||||
// null(f(p)) means p is outside the domain
|
||||
Subdomain_index index = r_domain_.label(p);
|
||||
if ( r_domain_.null_function()(index) )
|
||||
return Subdomain();
|
||||
else
|
||||
return Subdomain(index);
|
||||
}
|
||||
private:
|
||||
const Labeled_periodic_3_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 if the element \ccc{type} intersect properly any of the
|
||||
* surface patches describing the either the boundary of the domain
|
||||
* 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_periodic_3_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 the 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
|
||||
|
||||
// This whole canonicalization of offsets process seems useless... Hiding it behind macros.
|
||||
#ifdef CGAL_PERIODIC_CANONICALIZE_DUAL_INTERSECTIONS
|
||||
Iso_cuboid_3 pbb = r_domain_.canonical_periodic_domain();
|
||||
FT dimension [3] = { pbb.xmax()-pbb.xmin(),
|
||||
pbb.ymax()-pbb.ymin(),
|
||||
pbb.zmax()-pbb.zmin() };
|
||||
FT a_t [3] = { a.x(), a.y(), a.z() };
|
||||
FT b_t [3] = { b.x(), b.y(), b.z() };
|
||||
a_t[0] -= pbb.xmin();
|
||||
a_t[1] -= pbb.ymin();
|
||||
a_t[2] -= pbb.zmin();
|
||||
b_t[0] -= pbb.xmin();
|
||||
b_t[1] -= pbb.ymin();
|
||||
b_t[2] -= pbb.zmin();
|
||||
int o1 [3] = { static_cast<int>(a_t[0] / dimension[0]),
|
||||
static_cast<int>(a_t[1] / dimension[1]),
|
||||
static_cast<int>(a_t[2] / dimension[2]) };
|
||||
int o2 [3] = { static_cast<int>(b_t[0] / dimension[0]),
|
||||
static_cast<int>(b_t[1] / dimension[1]),
|
||||
static_cast<int>(b_t[2] / dimension[2]) };
|
||||
FT a_min [3] = { a.x(), a.y(), a.z() };
|
||||
FT b_min [3] = { b.x(), b.y(), b.z() };
|
||||
|
||||
for (unsigned idx = 0; idx < 3; ++idx)
|
||||
{
|
||||
FT offset = dimension[idx] * static_cast<FT>((std::min)(o1[idx], o2[idx]));
|
||||
a_min[idx] -= offset;
|
||||
b_min[idx] -= offset;
|
||||
}
|
||||
|
||||
const Point_3 pa(a_min[0], a_min[1], a_min[2]);
|
||||
const Point_3 pb(b_min[0], b_min[1], b_min[2]);
|
||||
Subdomain_index value_a = r_domain_.label(pa);
|
||||
Subdomain_index value_b = r_domain_.label(pb);
|
||||
#else
|
||||
Subdomain_index value_a = r_domain_.label(a);
|
||||
Subdomain_index value_b = r_domain_.label(b);
|
||||
#endif
|
||||
|
||||
if ( value_a != value_b )
|
||||
{
|
||||
if( r_domain_.null_function()(value_a) && r_domain_.null_function()(value_b) )
|
||||
return Surface_patch();
|
||||
else
|
||||
return Surface_patch(r_domain_.make_surface_index(value_a, value_b));
|
||||
}
|
||||
|
||||
#ifdef CGAL_PERIODIC_CANONICALIZE_DUAL_INTERSECTIONS
|
||||
FT a_max [3] = { a.x(), a.y(), a.z() };
|
||||
FT b_max [3] = { b.x(), b.y(), b.z() };
|
||||
|
||||
for (unsigned idx = 0; idx < 3; ++idx)
|
||||
{
|
||||
FT offset = dimension[idx] * static_cast<FT>((std::max)(o1[idx], o2[idx]));
|
||||
a_max[idx] -= offset;
|
||||
b_max[idx] -= offset;
|
||||
}
|
||||
|
||||
pa = Point_3(a_max[0], a_max[1], a_max[2]);
|
||||
pb = Point_3(b_max[0], b_max[1], b_max[2]);
|
||||
value_a = r_domain_.label(pa);
|
||||
value_b = r_domain_.label(pb);
|
||||
if ( value_a != value_b )
|
||||
{
|
||||
if( r_domain_.null_function()(value_a) && r_domain_.null_function()(value_b) )
|
||||
return Surface_patch();
|
||||
else
|
||||
return Surface_patch(r_domain_.make_surface_index(value_a, value_b));
|
||||
}
|
||||
#endif
|
||||
|
||||
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_.bounding_box());
|
||||
|
||||
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_periodic_3_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_periodic_3_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 target point. It's important
|
||||
* because it drives bisection cuts.
|
||||
* Indeed, the returned point is the first intersection from \c a on \c [a,b]
|
||||
* with a subdomain surface.
|
||||
*/
|
||||
Intersection operator()(const Point_3& a, const Point_3& b) const
|
||||
{
|
||||
// Functors
|
||||
typename Periodic_geom_traits::Compute_squared_distance_3 squared_distance =
|
||||
r_domain_.periodic_geom_traits().compute_squared_distance_3_object();
|
||||
typename Periodic_geom_traits::Construct_midpoint_3 midpoint =
|
||||
r_domain_.periodic_geom_traits().construct_midpoint_3_object();
|
||||
|
||||
#ifdef CGAL_PERIODIC_CANONICALIZE_DUAL_INTERSECTIONS
|
||||
Iso_cuboid_3 pbb = r_domain_.canonical_periodic_domain();
|
||||
FT dimension [3] = { pbb.xmax() - pbb.xmin(),
|
||||
pbb.ymax() - pbb.ymin(),
|
||||
pbb.zmax() - pbb.zmin() };
|
||||
FT a_t [3] = { a.x(), a.y(), a.z() };
|
||||
FT b_t [3] = { b.x(), b.y(), b.z() };
|
||||
a_t[0] -= pbb.xmin();
|
||||
a_t[1] -= pbb.ymin();
|
||||
a_t[2] -= pbb.zmin();
|
||||
b_t[0] -= pbb.xmin();
|
||||
b_t[1] -= pbb.ymin();
|
||||
b_t[2] -= pbb.zmin();
|
||||
|
||||
int o1 [3] = { static_cast<int>(a_t[0] / dimension[0]),
|
||||
static_cast<int>(a_t[1] / dimension[1]),
|
||||
static_cast<int>(a_t[2] / dimension[2]) };
|
||||
int o2 [3] = { static_cast<int>(b_t[0] / dimension[0]),
|
||||
static_cast<int>(b_t[1] / dimension[1]),
|
||||
static_cast<int>(b_t[2] / dimension[2]) };
|
||||
|
||||
FT a_min [3] = { a.x(), a.y(), a.z() };
|
||||
FT b_min [3] = { b.x(), b.y(), b.z() };
|
||||
for (unsigned idx = 0; idx < 3; ++idx)
|
||||
{
|
||||
FT offset = dimension[idx] * static_cast<FT>((std::min)(o1[idx], o2[idx]));
|
||||
a_min[idx] -= offset;
|
||||
b_min[idx] -= offset;
|
||||
}
|
||||
|
||||
// Non const points
|
||||
Point_3 p1(a_min[0], a_min[1], a_min[2]);
|
||||
Point_3 p2(b_min[0], b_min[1], b_min[2]);
|
||||
#else
|
||||
Point_3 p1 = a;
|
||||
Point_3 p2 = b;
|
||||
#endif
|
||||
|
||||
Point_3 mid = midpoint(p1, p2);
|
||||
|
||||
// Cannot be const: those values are modified below.
|
||||
Subdomain_index value_at_p1 = r_domain_.label(p1);
|
||||
Subdomain_index value_at_p2 = r_domain_.label(p2);
|
||||
Subdomain_index value_at_mid = r_domain_.label(mid, true);
|
||||
|
||||
// If both extremities are in the same subdomain, then there is no intersection.
|
||||
// This should not happen...
|
||||
if( value_at_p1 == value_at_p2 )
|
||||
{
|
||||
#ifdef CGAL_PERIODIC_CANONICALIZE_DUAL_INTERSECTIONS
|
||||
FT a_max [3] = { a.x(), a.y(), a.z() };
|
||||
FT b_max [3] = { b.x(), b.y(), b.z() };
|
||||
for (unsigned idx = 0; idx < 3; ++idx)
|
||||
{
|
||||
FT offset = dimension[idx] * static_cast<FT>((std::max)(o1[idx], o2[idx]));
|
||||
a_max[idx] -= offset;
|
||||
b_max[idx] -= offset;
|
||||
}
|
||||
|
||||
p1 = Point_3(a_max[0], a_max[1], a_max[2]);
|
||||
p2 = Point_3(b_max[0], b_max[1], b_max[2]);
|
||||
mid = midpoint(p1, p2);
|
||||
|
||||
value_at_p1 = r_domain_.label(p1);
|
||||
value_at_p2 = r_domain_.label(p2);
|
||||
value_at_mid = r_domain_.label(mid, true);
|
||||
|
||||
if( value_at_p1 == value_at_p2 )
|
||||
#endif
|
||||
return Intersection();
|
||||
}
|
||||
|
||||
if( r_domain_.null_function()(value_at_p1) && r_domain_.null_function()(value_at_p2) ) {
|
||||
return Intersection();
|
||||
}
|
||||
|
||||
// Else lets find a point (by bisection)
|
||||
// Bisection ends when the point is closer to the surface than the error bound
|
||||
while(true)
|
||||
{
|
||||
// If the two points are sufficiently close, then we return the midpoint
|
||||
if ( squared_distance(p1, p2) < r_domain_.squared_error_bound_value() )
|
||||
{
|
||||
CGAL_assertion(value_at_p1 != value_at_p2 &&
|
||||
! ( r_domain_.null_function()(value_at_p1) && r_domain_.null_function()(value_at_p2) ) );
|
||||
|
||||
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);
|
||||
|
||||
return Intersection(mid, index, 2);
|
||||
}
|
||||
|
||||
// Otherwise, 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 &&
|
||||
! ( r_domain_.null_function()(value_at_p1) && r_domain_.null_function()(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_.label(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_.bounding_box());
|
||||
|
||||
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_periodic_3_mesh_domain_3& r_domain_;
|
||||
};
|
||||
|
||||
Construct_intersection construct_intersection_object() const
|
||||
{
|
||||
return Construct_intersection(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
// The domain must know the periodic fundamental domain, which is in the traits.
|
||||
//
|
||||
// Note that the fundamental domain is also known through 'bounding_box()', but
|
||||
// a full geometric traits class is needed for 'construct_point()'
|
||||
// in canonicalization functions.
|
||||
Periodic_geom_traits pgt;
|
||||
|
||||
private:
|
||||
// Disabled copy constructor & assignment operator
|
||||
Labeled_periodic_3_mesh_domain_3(const Labeled_periodic_3_mesh_domain_3&);
|
||||
Labeled_periodic_3_mesh_domain_3& operator=(const Labeled_periodic_3_mesh_domain_3&);
|
||||
};
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_PERIODIC_3_MESH_3_LABELED_PERIODIC_3_MESH_DOMAIN_3_H
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
// Copyright (c) 2018 GeometryFactory (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$
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
//
|
||||
// Author(s) : Mael Rouxel-Labbé
|
||||
//
|
||||
#ifndef CGAL_PERIODIC_3_MESH_3_PERIODIC_3_WRAPPER_H
|
||||
#define CGAL_PERIODIC_3_MESH_3_PERIODIC_3_WRAPPER_H
|
||||
|
||||
#include <CGAL/license/Periodic_3_mesh_3.h>
|
||||
|
||||
#include <CGAL/internal/canonicalize_helper.h>
|
||||
#include <CGAL/Periodic_3_mesh_triangulation_3.h>
|
||||
|
||||
#include <boost/type_traits/is_function.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
/**
|
||||
* @class Periodic_3_wrapper
|
||||
*
|
||||
* @todo
|
||||
*/
|
||||
template<class Function_, typename BGT_>
|
||||
class Periodic_3_wrapper
|
||||
{
|
||||
public:
|
||||
// Types
|
||||
typedef typename BGT_::FT FT;
|
||||
typedef typename BGT_::Point_3 Point;
|
||||
typedef typename BGT_::Point_3 Point_3;
|
||||
typedef typename BGT_::Iso_cuboid_3 Iso_cuboid_3;
|
||||
|
||||
typedef FT return_type;
|
||||
|
||||
typedef typename details::Periodic_3_mesh_geom_traits_generator<BGT_>::type Geom_traits;
|
||||
|
||||
/// Constructor
|
||||
// the domain is not marked 'const' only to prevent a temporary from being passed
|
||||
// @todo test that
|
||||
// @todo count copies of the domain
|
||||
Periodic_3_wrapper(const Function_& f, Iso_cuboid_3& domain) : f_(f), gt_(domain) { }
|
||||
|
||||
/// Operator ()
|
||||
return_type operator()(const Point_3& p) const {
|
||||
return f_(P3T3::internal::robust_canonicalize_point(p, gt_));
|
||||
}
|
||||
|
||||
private:
|
||||
typedef typename boost::mpl::if_<boost::is_function<Function_>,
|
||||
Function_*,
|
||||
Function_>::type Stored_function;
|
||||
|
||||
/// Function to wrap
|
||||
Stored_function f_;
|
||||
Geom_traits gt_;
|
||||
};
|
||||
|
||||
template<typename BGT_, typename Function_>
|
||||
Periodic_3_wrapper<Function_, BGT_>
|
||||
make_periodic_3_wrapper(const Function_& f, typename BGT_::Iso_cuboid_3& domain)
|
||||
{
|
||||
return Periodic_3_wrapper<Function_, BGT_>(f, domain);
|
||||
}
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_PERIODIC_3_MESH_3_PERIODIC_3_WRAPPER_H
|
||||
|
|
@ -35,14 +35,12 @@
|
|||
#include <CGAL/refine_periodic_3_mesh_3.h>
|
||||
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/boost/parameter.h>
|
||||
#include <CGAL/make_mesh_3.h>
|
||||
#include <CGAL/Mesh_3/C3T3_helpers.h>
|
||||
#include <CGAL/Mesh_3/global_parameters.h>
|
||||
|
||||
#include <boost/parameter/preprocessor.hpp>
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Periodic_3_mesh_3 {
|
||||
namespace internal {
|
||||
|
|
@ -98,7 +96,7 @@ struct C3t3_initializer_base
|
|||
bool nonlinear = false,
|
||||
const int nb_initial_points = -1)
|
||||
{
|
||||
c3t3.triangulation().set_domain(domain.canonical_periodic_domain());
|
||||
c3t3.triangulation().set_domain(domain.bounding_box());
|
||||
c3t3.triangulation().insert_dummy_points();
|
||||
mark_dummy_points(c3t3);
|
||||
|
||||
|
|
@ -249,8 +247,8 @@ C3T3 make_periodic_3_mesh_3(const MD& md, const MC& mc,
|
|||
|
||||
// see <CGAL/config.h>
|
||||
CGAL_PRAGMA_DIAG_PUSH
|
||||
// see <CGAL/Mesh_3/config.h>
|
||||
CGAL_MESH_3_IGNORE_BOOST_PARAMETER_NAME_WARNINGS
|
||||
// see <CGAL/boost/parameter.h>
|
||||
CGAL_IGNORE_BOOST_PARAMETER_NAME_WARNINGS
|
||||
|
||||
BOOST_PARAMETER_FUNCTION(
|
||||
(void),
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ namespace CGAL {
|
|||
|
||||
// see <CGAL/config.h>
|
||||
CGAL_PRAGMA_DIAG_PUSH
|
||||
// see <CGAL/Mesh_3/config.h>
|
||||
CGAL_MESH_3_IGNORE_BOOST_PARAMETER_NAME_WARNINGS
|
||||
// see <CGAL/boost/parameter.h>
|
||||
CGAL_IGNORE_BOOST_PARAMETER_NAME_WARNINGS
|
||||
|
||||
// ---------------------------------- pertuber ---------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@
|
|||
#include <boost/unordered_set.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
|
@ -144,8 +146,8 @@ void project_points(C3T3& c3t3,
|
|||
|
||||
// see <CGAL/config.h>
|
||||
CGAL_PRAGMA_DIAG_PUSH
|
||||
// see <CGAL/Mesh_3/config.h>
|
||||
CGAL_MESH_3_IGNORE_BOOST_PARAMETER_NAME_WARNINGS
|
||||
// see <CGAL/boost/parameter.h>
|
||||
CGAL_IGNORE_BOOST_PARAMETER_NAME_WARNINGS
|
||||
|
||||
BOOST_PARAMETER_FUNCTION(
|
||||
(void),
|
||||
|
|
|
|||
Loading…
Reference in New Issue