mirror of https://github.com/CGAL/cgal
Merge branch 'Mesh_3-compare_index-GF-old' into Mesh_3-compare_index-GF
Conflicts: Mesh_3/include/CGAL/Mesh_3/Detect_features_in_polyhedra.h Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h Mesh_3/include/CGAL/Mesh_polyhedron_3.h Mesh_3/test/Mesh_3/test_meshing_polylines_only.cpp STL_Extension/include/CGAL/Compact_container.h STL_Extension/test/STL_Extension/test_Compact_container.cpp
This commit is contained in:
commit
3fa09693a3
|
|
@ -1,3 +1,5 @@
|
||||||
|
#define CGAL_MESH_3_VERBOSE
|
||||||
|
|
||||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
|
||||||
#include <CGAL/Mesh_triangulation_3.h>
|
#include <CGAL/Mesh_triangulation_3.h>
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,8 @@ FT sphere_function (const Point& p)
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
// Domain (Warning: Sphere_3 constructor uses squared radius !)
|
// Domain (Warning: Sphere_3 constructor uses squared radius !)
|
||||||
Mesh_domain domain(sphere_function, K::Sphere_3(CGAL::ORIGIN, 2.));
|
Mesh_domain domain(sphere_function,
|
||||||
|
K::Sphere_3(CGAL::ORIGIN, 2.));
|
||||||
|
|
||||||
// Mesh criteria
|
// Mesh criteria
|
||||||
Mesh_criteria criteria(facet_angle=30, facet_size=0.1, facet_distance=0.025,
|
Mesh_criteria criteria(facet_angle=30, facet_size=0.1, facet_distance=0.025,
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,8 @@ FT sphere_function (const Point& p)
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
// Domain (Warning: Sphere_3 constructor uses squared radius !)
|
// Domain (Warning: Sphere_3 constructor uses squared radius !)
|
||||||
Mesh_domain domain(sphere_function, K::Sphere_3(CGAL::ORIGIN, 2.));
|
Mesh_domain domain(sphere_function,
|
||||||
|
K::Sphere_3(CGAL::ORIGIN, 2.));
|
||||||
|
|
||||||
// Mesh criteria
|
// Mesh criteria
|
||||||
Spherical_sizing_field size;
|
Spherical_sizing_field size;
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,8 @@ FT sphere_function (const Point& p)
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
// Domain (Warning: Sphere_3 constructor uses squared radius !)
|
// Domain (Warning: Sphere_3 constructor uses squared radius !)
|
||||||
Mesh_domain domain(sphere_function, K::Sphere_3(Point(1, 0, 0), 6.));
|
Mesh_domain domain(sphere_function,
|
||||||
|
K::Sphere_3(Point(1, 0, 0), 6.));
|
||||||
|
|
||||||
// Mesh criteria
|
// Mesh criteria
|
||||||
Mesh_criteria criteria(edge_size = 0.15,
|
Mesh_criteria criteria(edge_size = 0.15,
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@
|
||||||
#include <CGAL/basic.h>
|
#include <CGAL/basic.h>
|
||||||
#include <CGAL/triangulation_assertions.h>
|
#include <CGAL/triangulation_assertions.h>
|
||||||
#include <CGAL/internal/Dummy_tds_3.h>
|
#include <CGAL/internal/Dummy_tds_3.h>
|
||||||
|
#include <CGAL/tags.h>
|
||||||
|
#include <CGAL/Has_timestamp.h>
|
||||||
|
|
||||||
#include <CGAL/Regular_triangulation_cell_base_3.h>
|
#include <CGAL/Regular_triangulation_cell_base_3.h>
|
||||||
#include <CGAL/Mesh_3/io_signature.h>
|
#include <CGAL/Mesh_3/io_signature.h>
|
||||||
|
|
@ -89,13 +91,13 @@ public:
|
||||||
, next_intrusive_()
|
, next_intrusive_()
|
||||||
, previous_intrusive_()
|
, previous_intrusive_()
|
||||||
#endif
|
#endif
|
||||||
|
, time_stamp_(-1)
|
||||||
, surface_center_index_table_()
|
, surface_center_index_table_()
|
||||||
, sliver_value_(FT(0.))
|
, sliver_value_(FT(0.))
|
||||||
, subdomain_index_()
|
, subdomain_index_()
|
||||||
, bits_(0)
|
, bits_(0)
|
||||||
, sliver_cache_validity_(false)
|
, sliver_cache_validity_(false)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
Compact_mesh_cell_base_3(const Compact_mesh_cell_base_3& rhs)
|
Compact_mesh_cell_base_3(const Compact_mesh_cell_base_3& rhs)
|
||||||
: circumcenter_(NULL)
|
: circumcenter_(NULL)
|
||||||
|
|
@ -103,6 +105,7 @@ public:
|
||||||
, next_intrusive_(rhs.next_intrusive_)
|
, next_intrusive_(rhs.next_intrusive_)
|
||||||
, previous_intrusive_(rhs.previous_intrusive_)
|
, previous_intrusive_(rhs.previous_intrusive_)
|
||||||
#endif
|
#endif
|
||||||
|
, time_stamp_(rhs.time_stamp_)
|
||||||
, sliver_value_(rhs.sliver_value_)
|
, sliver_value_(rhs.sliver_value_)
|
||||||
, subdomain_index_(rhs.subdomain_index_)
|
, subdomain_index_(rhs.subdomain_index_)
|
||||||
, bits_(0)
|
, bits_(0)
|
||||||
|
|
@ -126,6 +129,7 @@ public:
|
||||||
, next_intrusive_()
|
, next_intrusive_()
|
||||||
, previous_intrusive_()
|
, previous_intrusive_()
|
||||||
#endif
|
#endif
|
||||||
|
, time_stamp_(-1)
|
||||||
, surface_center_index_table_()
|
, surface_center_index_table_()
|
||||||
, sliver_value_(FT(0.))
|
, sliver_value_(FT(0.))
|
||||||
, subdomain_index_()
|
, subdomain_index_()
|
||||||
|
|
@ -151,6 +155,7 @@ public:
|
||||||
, next_intrusive_()
|
, next_intrusive_()
|
||||||
, previous_intrusive_()
|
, previous_intrusive_()
|
||||||
#endif
|
#endif
|
||||||
|
, time_stamp_(-1)
|
||||||
, surface_center_index_table_()
|
, surface_center_index_table_()
|
||||||
, sliver_value_(FT(0.))
|
, sliver_value_(FT(0.))
|
||||||
, subdomain_index_()
|
, subdomain_index_()
|
||||||
|
|
@ -458,6 +463,17 @@ public:
|
||||||
}
|
}
|
||||||
#endif // CGAL_INTRUSIVE_LIST
|
#endif // CGAL_INTRUSIVE_LIST
|
||||||
|
|
||||||
|
/// For the determinism of Compact_container iterators
|
||||||
|
///@{
|
||||||
|
typedef Tag_true Has_timestamp;
|
||||||
|
|
||||||
|
std::size_t time_stamp() const {
|
||||||
|
return time_stamp_;
|
||||||
|
}
|
||||||
|
void set_time_stamp(const std::size_t& ts) {
|
||||||
|
time_stamp_ = ts;
|
||||||
|
}
|
||||||
|
///@}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
@ -476,6 +492,7 @@ private:
|
||||||
#ifdef CGAL_INTRUSIVE_LIST
|
#ifdef CGAL_INTRUSIVE_LIST
|
||||||
Cell_handle next_intrusive_, previous_intrusive_;
|
Cell_handle next_intrusive_, previous_intrusive_;
|
||||||
#endif
|
#endif
|
||||||
|
std::size_t time_stamp_;
|
||||||
|
|
||||||
CGAL::cpp11::array<Index, 4> surface_center_index_table_;
|
CGAL::cpp11::array<Index, 4> surface_center_index_table_;
|
||||||
/// Stores visited facets (4 first bits)
|
/// Stores visited facets (4 first bits)
|
||||||
|
|
@ -494,8 +511,6 @@ private:
|
||||||
|
|
||||||
}; // end class Compact_mesh_cell_base_3
|
}; // end class Compact_mesh_cell_base_3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template < class GT, class MT, class Cb >
|
template < class GT, class MT, class Cb >
|
||||||
std::istream&
|
std::istream&
|
||||||
operator>>(std::istream &is,
|
operator>>(std::istream &is,
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
# pragma warning(disable:4180) // qualifier applied to function type has no meaning; ignored
|
# pragma warning(disable:4180) // qualifier applied to function type has no meaning; ignored
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <CGAL/Random.h>
|
||||||
#include <CGAL/Mesh_3/Labeled_mesh_domain_3.h>
|
#include <CGAL/Mesh_3/Labeled_mesh_domain_3.h>
|
||||||
#include <CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h>
|
#include <CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h>
|
||||||
|
|
||||||
|
|
@ -47,7 +48,7 @@ template<class Function,
|
||||||
class BGT,
|
class BGT,
|
||||||
class Wrapper = Mesh_3::Implicit_to_labeled_function_wrapper<Function,BGT> >
|
class Wrapper = Mesh_3::Implicit_to_labeled_function_wrapper<Function,BGT> >
|
||||||
class Implicit_mesh_domain_3
|
class Implicit_mesh_domain_3
|
||||||
: public Mesh_3::Labeled_mesh_domain_3<Wrapper, BGT >
|
: public Mesh_3::Labeled_mesh_domain_3<Wrapper, BGT>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Base type
|
/// Base type
|
||||||
|
|
@ -66,8 +67,9 @@ public:
|
||||||
*/
|
*/
|
||||||
Implicit_mesh_domain_3(const Function& f,
|
Implicit_mesh_domain_3(const Function& f,
|
||||||
const Sphere_3& bounding_sphere,
|
const Sphere_3& bounding_sphere,
|
||||||
const FT& error_bound = FT(1e-3))
|
const FT& error_bound = FT(1e-3),
|
||||||
: Base(Wrapper(f), bounding_sphere, error_bound) {}
|
CGAL::Random* p_rng = NULL)
|
||||||
|
: Base(Wrapper(f), bounding_sphere, error_bound, p_rng) {}
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
virtual ~Implicit_mesh_domain_3() {}
|
virtual ~Implicit_mesh_domain_3() {}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
#ifndef CGAL_LABELED_IMAGE_MESH_DOMAIN_3_H
|
#ifndef CGAL_LABELED_IMAGE_MESH_DOMAIN_3_H
|
||||||
#define CGAL_LABELED_IMAGE_MESH_DOMAIN_3_H
|
#define CGAL_LABELED_IMAGE_MESH_DOMAIN_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Random.h>
|
||||||
#include <CGAL/Mesh_3/Labeled_mesh_domain_3.h>
|
#include <CGAL/Mesh_3/Labeled_mesh_domain_3.h>
|
||||||
#include <CGAL/Mesh_3/Image_to_labeled_function_wrapper.h>
|
#include <CGAL/Mesh_3/Image_to_labeled_function_wrapper.h>
|
||||||
|
|
||||||
|
|
@ -41,6 +41,7 @@ namespace CGAL {
|
||||||
*/
|
*/
|
||||||
template<class Image,
|
template<class Image,
|
||||||
class BGT,
|
class BGT,
|
||||||
|
|
||||||
class Wrapper = Mesh_3::Image_to_labeled_function_wrapper<Image, BGT> >
|
class Wrapper = Mesh_3::Image_to_labeled_function_wrapper<Image, BGT> >
|
||||||
class Labeled_image_mesh_domain_3
|
class Labeled_image_mesh_domain_3
|
||||||
: public Mesh_3::Labeled_mesh_domain_3<Wrapper, BGT>
|
: public Mesh_3::Labeled_mesh_domain_3<Wrapper, BGT>
|
||||||
|
|
@ -55,10 +56,12 @@ public:
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
Labeled_image_mesh_domain_3(const Image& image,
|
Labeled_image_mesh_domain_3(const Image& image,
|
||||||
const FT& error_bound = FT(1e-3))
|
const FT& error_bound = FT(1e-3),
|
||||||
|
CGAL::Random* p_rng = NULL)
|
||||||
: Base(Wrapper(image),
|
: Base(Wrapper(image),
|
||||||
compute_bounding_box(image),
|
compute_bounding_box(image),
|
||||||
error_bound)
|
error_bound,
|
||||||
|
p_rng)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,8 @@ public:
|
||||||
typedef typename Polyhedron::Facet Facet;
|
typedef typename Polyhedron::Facet Facet;
|
||||||
typedef typename Facet::Patch_id Patch_id;
|
typedef typename Facet::Patch_id Patch_id;
|
||||||
|
|
||||||
typedef std::set<Facet*> Facet_handle_set;
|
typedef std::set<Facet_handle> Facet_handle_set;
|
||||||
typedef std::set<Halfedge*> He_handle_set;
|
typedef std::set<Halfedge_handle> He_handle_set;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Detect_features_in_polyhedra() : current_surface_index_(1) {}
|
Detect_features_in_polyhedra() : current_surface_index_(1) {}
|
||||||
|
|
@ -69,7 +69,7 @@ public:
|
||||||
private:
|
private:
|
||||||
Vector_3 facet_normal(const Facet_handle& f) const;
|
Vector_3 facet_normal(const Facet_handle& f) const;
|
||||||
bool is_sharp(const Halfedge_handle& he, FT cos_angle) const;
|
bool is_sharp(const Halfedge_handle& he, FT cos_angle) const;
|
||||||
void flood(Facet& f, const Patch_id id,
|
void flood(Facet_handle f, const Patch_id id,
|
||||||
Facet_handle_set& unsorted_faces) const;
|
Facet_handle_set& unsorted_faces) const;
|
||||||
|
|
||||||
template <typename Int>
|
template <typename Int>
|
||||||
|
|
@ -143,18 +143,19 @@ detect_surface_patches(Polyhedron& polyhedron)
|
||||||
for ( typename Polyhedron::Facet_iterator fit = polyhedron.facets_begin(),
|
for ( typename Polyhedron::Facet_iterator fit = polyhedron.facets_begin(),
|
||||||
end = polyhedron.facets_end() ; fit != end ; ++fit )
|
end = polyhedron.facets_end() ; fit != end ; ++fit )
|
||||||
{
|
{
|
||||||
unsorted_faces.insert(&*fit);
|
Facet_handle fh = fit;
|
||||||
|
unsorted_faces.insert(fh);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flood
|
// Flood
|
||||||
while ( ! unsorted_faces.empty() )
|
while ( ! unsorted_faces.empty() )
|
||||||
{
|
{
|
||||||
Facet& f = **(unsorted_faces.begin());
|
Facet_handle f = *(unsorted_faces.begin());
|
||||||
unsorted_faces.erase(unsorted_faces.begin());
|
unsorted_faces.erase(unsorted_faces.begin());
|
||||||
|
|
||||||
const Patch_id patch_id = generate_patch_id(Patch_id(),
|
const Patch_id patch_id = generate_patch_id(Patch_id(),
|
||||||
current_surface_index_);
|
current_surface_index_);
|
||||||
f.set_patch_id(patch_id);
|
f->set_patch_id(patch_id);
|
||||||
flood(f,patch_id,unsorted_faces);
|
flood(f,patch_id,unsorted_faces);
|
||||||
++current_surface_index_;
|
++current_surface_index_;
|
||||||
}
|
}
|
||||||
|
|
@ -245,52 +246,52 @@ is_sharp(const Halfedge_handle& he, FT cos_angle) const
|
||||||
template <typename P_>
|
template <typename P_>
|
||||||
void
|
void
|
||||||
Detect_features_in_polyhedra<P_>::
|
Detect_features_in_polyhedra<P_>::
|
||||||
flood(Facet& f, const Patch_id patch_id, Facet_handle_set& unsorted_faces) const
|
flood(Facet_handle f, const Patch_id patch_id, Facet_handle_set& unsorted_faces) const
|
||||||
{
|
{
|
||||||
typedef typename Facet::Halfedge_around_facet_circulator Facet_he_circ;
|
typedef typename Facet::Halfedge_around_facet_circulator Facet_he_circ;
|
||||||
|
|
||||||
Facet_he_circ begin = f.facet_begin();
|
Facet_he_circ begin = f->facet_begin();
|
||||||
Facet_he_circ done = begin;
|
Facet_he_circ done = begin;
|
||||||
|
|
||||||
// Initialize he_to_explore with halfedges of the starting facet
|
// Initialize he_to_explore with halfedges of the starting facet
|
||||||
He_handle_set he_to_explore;
|
He_handle_set he_to_explore;
|
||||||
CGAL_For_all(begin,done)
|
CGAL_For_all(begin,done)
|
||||||
{
|
{
|
||||||
he_to_explore.insert(&*(begin->opposite()));
|
he_to_explore.insert(begin->opposite());
|
||||||
}
|
}
|
||||||
|
|
||||||
// While there is something to explore
|
// While there is something to explore
|
||||||
while ( ! he_to_explore.empty() )
|
while ( ! he_to_explore.empty() )
|
||||||
{
|
{
|
||||||
// Get next halfedge to explore
|
// Get next halfedge to explore
|
||||||
Halfedge& he = **(he_to_explore.begin());
|
Halfedge_handle he = *(he_to_explore.begin());
|
||||||
he_to_explore.erase(he_to_explore.begin());
|
he_to_explore.erase(he_to_explore.begin());
|
||||||
|
|
||||||
// If we don't go through a border of the patch
|
// If we don't go through a border of the patch
|
||||||
if ( ! he.is_feature_edge() && ! he.is_border() )
|
if ( ! he->is_feature_edge() && ! he->is_border() )
|
||||||
{
|
{
|
||||||
Facet& explored_facet = *(he.facet());
|
Facet_handle explored_facet = he->facet();
|
||||||
|
|
||||||
// Mark facet and delete it from unsorted
|
// Mark facet and delete it from unsorted
|
||||||
explored_facet.set_patch_id(patch_id);
|
explored_facet->set_patch_id(patch_id);
|
||||||
unsorted_faces.erase(&explored_facet);
|
unsorted_faces.erase(explored_facet);
|
||||||
|
|
||||||
// Add/Remove facet's halfedge to/from explore list
|
// Add/Remove facet's halfedge to/from explore list
|
||||||
Facet_he_circ he_begin = explored_facet.facet_begin();
|
Facet_he_circ he_begin = explored_facet->facet_begin();
|
||||||
Facet_he_circ he_done = he_begin;
|
Facet_he_circ he_done = he_begin;
|
||||||
|
|
||||||
CGAL_For_all(he_begin,he_done)
|
CGAL_For_all(he_begin,he_done)
|
||||||
{
|
{
|
||||||
Halfedge& current_he = *he_begin;
|
Halfedge_handle current_he = he_begin;
|
||||||
|
|
||||||
// do not explore heh again
|
// do not explore heh again
|
||||||
if ( ¤t_he == &he ) { continue; }
|
if ( current_he == he ) { continue; }
|
||||||
|
|
||||||
// if current_he is not in to_explore set, add it, otherwise remove it
|
// if current_he is not in to_explore set, add it, otherwise remove it
|
||||||
// (because we just explore the facet he_begin is pointing to)
|
// (because we just explore the facet he_begin is pointing to)
|
||||||
if ( he_to_explore.erase(¤t_he) == 0 )
|
if ( he_to_explore.erase(current_he) == 0 )
|
||||||
{
|
{
|
||||||
he_to_explore.insert(&*(current_he.opposite()));
|
he_to_explore.insert(current_he->opposite());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,15 +23,46 @@
|
||||||
#define CGAL_MESH_3_DETECT_POLYLINES_IN_POLYHEDRA_H
|
#define CGAL_MESH_3_DETECT_POLYLINES_IN_POLYHEDRA_H
|
||||||
|
|
||||||
#include <CGAL/Mesh_3/Detect_polylines_in_polyhedra_fwd.h>
|
#include <CGAL/Mesh_3/Detect_polylines_in_polyhedra_fwd.h>
|
||||||
|
#include <CGAL/Has_timestamp.h>
|
||||||
|
#include <CGAL/Default.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
#include <boost/mpl/if.hpp>
|
||||||
|
|
||||||
namespace CGAL { namespace Mesh_3 {
|
namespace CGAL { namespace Mesh_3 {
|
||||||
|
|
||||||
struct Detect_polyline_less {
|
template <typename Handle>
|
||||||
template <typename Handle>
|
struct CGAL_with_time_stamp
|
||||||
bool operator()(const Handle& va, const Handle& vb) const {
|
{
|
||||||
return &*va < &*vb;
|
public:
|
||||||
|
static bool less(Handle h1, Handle h2)
|
||||||
|
{
|
||||||
|
return h1->time_stamp() < h2->time_stamp();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Handle>
|
||||||
|
struct CGAL_no_time_stamp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool less(Handle h1, Handle h2)
|
||||||
|
{
|
||||||
|
return &*h1 < &*h2;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Detect_polyline_less
|
||||||
|
{
|
||||||
|
template<typename Handle>
|
||||||
|
bool operator()(const Handle& h1, const Handle& h2) const
|
||||||
|
{
|
||||||
|
typedef typename std::iterator_traits<Handle>::value_type Type;
|
||||||
|
typedef typename boost::mpl::if_c<
|
||||||
|
CGAL::internal::Has_timestamp<Type>::value,
|
||||||
|
CGAL_with_time_stamp<Handle>,
|
||||||
|
CGAL_no_time_stamp<Handle> >::type Comparator;
|
||||||
|
return Comparator::less(h1, h2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
#include <CGAL/tuple.h>
|
#include <CGAL/tuple.h>
|
||||||
#include <CGAL/Origin.h>
|
#include <CGAL/Origin.h>
|
||||||
|
#include <CGAL/Random.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
|
|
@ -55,7 +56,8 @@ namespace Mesh_3 {
|
||||||
* tags of it's incident subdomain.
|
* tags of it's incident subdomain.
|
||||||
* Thus, a boundary facet of the domain is labelled <0,b>, where b!=0.
|
* Thus, a boundary facet of the domain is labelled <0,b>, where b!=0.
|
||||||
*/
|
*/
|
||||||
template<class Function, class BGT>
|
template<class Function,
|
||||||
|
class BGT>
|
||||||
class Labeled_mesh_domain_3
|
class Labeled_mesh_domain_3
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -94,14 +96,20 @@ public:
|
||||||
*/
|
*/
|
||||||
Labeled_mesh_domain_3(const Function& f,
|
Labeled_mesh_domain_3(const Function& f,
|
||||||
const Sphere_3& bounding_sphere,
|
const Sphere_3& bounding_sphere,
|
||||||
const FT& error_bound = FT(1e-3));
|
const FT& error_bound = FT(1e-3),
|
||||||
|
CGAL::Random* p_rng = NULL);
|
||||||
|
|
||||||
Labeled_mesh_domain_3(const Function& f,
|
Labeled_mesh_domain_3(const Function& f,
|
||||||
const Bbox_3& bbox,
|
const Bbox_3& bbox,
|
||||||
const FT& error_bound = FT(1e-3));
|
const FT& error_bound = FT(1e-3),
|
||||||
|
CGAL::Random* p_rng = NULL);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
virtual ~Labeled_mesh_domain_3() {}
|
virtual ~Labeled_mesh_domain_3()
|
||||||
|
{
|
||||||
|
if(delete_rng_)
|
||||||
|
delete p_rng_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a set of \ccc{n} points on the surface, and output them to
|
* Constructs a set of \ccc{n} points on the surface, and output them to
|
||||||
|
|
@ -461,6 +469,9 @@ private:
|
||||||
const Function function_;
|
const Function function_;
|
||||||
/// The bounding box
|
/// The bounding box
|
||||||
const Iso_cuboid_3 bbox_;
|
const Iso_cuboid_3 bbox_;
|
||||||
|
/// The random number generator used by Construct_initial_points
|
||||||
|
CGAL::Random* p_rng_;
|
||||||
|
bool delete_rng_;
|
||||||
/// Error bound relative to sphere radius
|
/// Error bound relative to sphere radius
|
||||||
FT squared_error_bound_;
|
FT squared_error_bound_;
|
||||||
|
|
||||||
|
|
@ -483,24 +494,40 @@ template<class F, class BGT>
|
||||||
Labeled_mesh_domain_3<F,BGT>::Labeled_mesh_domain_3(
|
Labeled_mesh_domain_3<F,BGT>::Labeled_mesh_domain_3(
|
||||||
const F& f,
|
const F& f,
|
||||||
const Sphere_3& bounding_sphere,
|
const Sphere_3& bounding_sphere,
|
||||||
const FT& error_bound )
|
const FT& error_bound,
|
||||||
|
CGAL::Random* p_rng)
|
||||||
: function_(f)
|
: function_(f)
|
||||||
, bbox_(iso_cuboid(bounding_sphere.bbox()))
|
, bbox_(iso_cuboid(bounding_sphere.bbox()))
|
||||||
|
, p_rng_(p_rng)
|
||||||
|
, delete_rng_(false)
|
||||||
, squared_error_bound_(squared_error_bound(bounding_sphere,error_bound))
|
, squared_error_bound_(squared_error_bound(bounding_sphere,error_bound))
|
||||||
{
|
{
|
||||||
// TODO : CGAL_ASSERT(0 < f(bounding_sphere.get_center()) ) ?
|
// TODO : CGAL_ASSERT(0 < f(bounding_sphere.get_center()) ) ?
|
||||||
|
if(!p_rng_)
|
||||||
|
{
|
||||||
|
p_rng_ = new CGAL::Random(0);
|
||||||
|
delete_rng_ = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class F, class BGT>
|
template<class F, class BGT>
|
||||||
Labeled_mesh_domain_3<F,BGT>::Labeled_mesh_domain_3(
|
Labeled_mesh_domain_3<F,BGT>::Labeled_mesh_domain_3(
|
||||||
const F& f,
|
const F& f,
|
||||||
const Bbox_3& bbox,
|
const Bbox_3& bbox,
|
||||||
const FT& error_bound )
|
const FT& error_bound,
|
||||||
|
CGAL::Random* p_rng)
|
||||||
: function_(f)
|
: function_(f)
|
||||||
, bbox_(iso_cuboid(bbox))
|
, bbox_(iso_cuboid(bbox))
|
||||||
|
, p_rng_(p_rng)
|
||||||
|
, delete_rng_(false)
|
||||||
, squared_error_bound_(squared_error_bound(bbox_,error_bound))
|
, squared_error_bound_(squared_error_bound(bbox_,error_bound))
|
||||||
{
|
{
|
||||||
// TODO : CGAL_ASSERT(0 < f(bounding_sphere.get_center()) ) ?
|
// TODO : CGAL_ASSERT(0 < f(bounding_sphere.get_center()) ) ?
|
||||||
|
if(!p_rng_)
|
||||||
|
{
|
||||||
|
p_rng_ = new CGAL::Random(0);
|
||||||
|
delete_rng_ = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -522,8 +549,9 @@ Labeled_mesh_domain_3<F,BGT>::Construct_initial_points::operator()(
|
||||||
|
|
||||||
const double radius = std::sqrt(CGAL::to_double(squared_radius));
|
const double radius = std::sqrt(CGAL::to_double(squared_radius));
|
||||||
|
|
||||||
Random_points_on_sphere_3 random_point_on_sphere(radius);
|
CGAL::Random& rng = *(r_domain_.p_rng_);
|
||||||
Random_points_in_sphere_3 random_point_in_sphere(radius);
|
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
|
// Get some functors
|
||||||
typename BGT::Construct_segment_3 segment_3 =
|
typename BGT::Construct_segment_3 segment_3 =
|
||||||
|
|
|
||||||
|
|
@ -231,7 +231,7 @@ public:
|
||||||
Index index(const Vertex_handle& v) const { return v->index(); }
|
Index index(const Vertex_handle& v) const { return v->index(); }
|
||||||
|
|
||||||
/// Outputs the mesh to medit
|
/// Outputs the mesh to medit
|
||||||
void output_to_medit(std::ofstream& os,
|
void output_to_medit(std::ostream& os,
|
||||||
bool rebind = true,
|
bool rebind = true,
|
||||||
bool show_patches = false) const
|
bool show_patches = false) const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -918,6 +918,9 @@ insert_balls(const Vertex_handle& vp,
|
||||||
std::cerr << "Number of to-be-inserted balls is: "
|
std::cerr << "Number of to-be-inserted balls is: "
|
||||||
<< n << "\n between points ("
|
<< n << "\n between points ("
|
||||||
<< vp->point() << ") and (" << vq->point()
|
<< vp->point() << ") and (" << vq->point()
|
||||||
|
<< ") (geodesic distance: "
|
||||||
|
<< domain_.geodesic_distance(vp->point(), vq->point(),
|
||||||
|
curve_index)
|
||||||
<< ")\n";
|
<< ")\n";
|
||||||
#endif
|
#endif
|
||||||
const Bare_point new_point =
|
const Bare_point new_point =
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@
|
||||||
#include <CGAL/Timer.h>
|
#include <CGAL/Timer.h>
|
||||||
#include <CGAL/Mesh_3/Null_perturber_visitor.h>
|
#include <CGAL/Mesh_3/Null_perturber_visitor.h>
|
||||||
#include <CGAL/Mesh_3/sliver_criteria.h>
|
#include <CGAL/Mesh_3/sliver_criteria.h>
|
||||||
|
#include <CGAL/Has_timestamp.h>
|
||||||
|
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
#ifdef CGAL_MESH_3_USE_RELAXED_HEAP
|
#ifdef CGAL_MESH_3_USE_RELAXED_HEAP
|
||||||
|
|
@ -61,6 +62,29 @@
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
|
namespace internal { namespace Mesh_3 {
|
||||||
|
|
||||||
|
// Hash function for boost::unordered_map<Vertex_handle,...>
|
||||||
|
template <typename Tr, bool HasTimestamp>
|
||||||
|
struct VHash
|
||||||
|
{
|
||||||
|
typedef typename Tr::Vertex_handle Vertex_handle;
|
||||||
|
std::size_t operator()(Vertex_handle vh) const
|
||||||
|
{
|
||||||
|
return vh->time_stamp();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <typename Tr>
|
||||||
|
struct VHash<Tr, false>
|
||||||
|
{
|
||||||
|
typedef typename Tr::Vertex_handle Vertex_handle;
|
||||||
|
std::size_t operator()(Vertex_handle vh) const
|
||||||
|
{
|
||||||
|
return boost::hash_value(&*vh);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}} // end internal::Mesh_3
|
||||||
|
|
||||||
namespace Mesh_3 {
|
namespace Mesh_3 {
|
||||||
|
|
||||||
template < typename C3T3,
|
template < typename C3T3,
|
||||||
|
|
@ -250,14 +274,6 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct VHash
|
|
||||||
{
|
|
||||||
std::size_t operator()(Vertex_handle vh) const
|
|
||||||
{
|
|
||||||
return boost::hash_value(&*vh);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// Private methods
|
// Private methods
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
|
|
@ -651,7 +667,12 @@ build_priority_queue(const FT& sliver_bound, PQueue& pqueue) const
|
||||||
|
|
||||||
int pqueue_size = 0;
|
int pqueue_size = 0;
|
||||||
|
|
||||||
typedef boost::unordered_map<Vertex_handle,PVertex,VHash> M;
|
typedef typename std::iterator_traits<Vertex_handle>::value_type Vertex;
|
||||||
|
typedef CGAL::internal::Has_timestamp<Vertex> Vertex_has_timestamp;
|
||||||
|
using CGAL::internal::Mesh_3::VHash;
|
||||||
|
typedef VHash<Tr, Vertex_has_timestamp::value> Hash_fct;
|
||||||
|
typedef boost::unordered_map<Vertex_handle,PVertex,Hash_fct> M;
|
||||||
|
|
||||||
M vpm;
|
M vpm;
|
||||||
for ( typename Tr::Finite_cells_iterator cit = tr_.finite_cells_begin();
|
for ( typename Tr::Finite_cells_iterator cit = tr_.finite_cells_begin();
|
||||||
cit != tr_.finite_cells_end() ;
|
cit != tr_.finite_cells_end() ;
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
#include <CGAL/Regular_triangulation_cell_base_with_weighted_circumcenter_3.h>
|
#include <CGAL/Regular_triangulation_cell_base_with_weighted_circumcenter_3.h>
|
||||||
#include <CGAL/Mesh_3/Mesh_surface_cell_base_3.h>
|
#include <CGAL/Mesh_3/Mesh_surface_cell_base_3.h>
|
||||||
#include <CGAL/Mesh_3/io_signature.h>
|
#include <CGAL/Mesh_3/io_signature.h>
|
||||||
|
#include <CGAL/tags.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
|
|
@ -83,6 +84,7 @@ public:
|
||||||
, next_intrusive_()
|
, next_intrusive_()
|
||||||
, previous_intrusive_()
|
, previous_intrusive_()
|
||||||
#endif
|
#endif
|
||||||
|
, time_stamp_(-1)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Mesh_cell_base_3 (Vertex_handle v0,
|
Mesh_cell_base_3 (Vertex_handle v0,
|
||||||
|
|
@ -97,6 +99,7 @@ public:
|
||||||
, next_intrusive_()
|
, next_intrusive_()
|
||||||
, previous_intrusive_()
|
, previous_intrusive_()
|
||||||
#endif
|
#endif
|
||||||
|
, time_stamp_(-1)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Mesh_cell_base_3 (Vertex_handle v0,
|
Mesh_cell_base_3 (Vertex_handle v0,
|
||||||
|
|
@ -115,6 +118,7 @@ public:
|
||||||
, next_intrusive_()
|
, next_intrusive_()
|
||||||
, previous_intrusive_()
|
, previous_intrusive_()
|
||||||
#endif
|
#endif
|
||||||
|
, time_stamp_(-1)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// Default copy constructor and assignment operator are ok
|
// Default copy constructor and assignment operator are ok
|
||||||
|
|
@ -158,6 +162,18 @@ public:
|
||||||
}
|
}
|
||||||
#endif // CGAL_INTRUSIVE_LIST
|
#endif // CGAL_INTRUSIVE_LIST
|
||||||
|
|
||||||
|
/// For the determinism of Compact_container iterators
|
||||||
|
///@{
|
||||||
|
typedef Tag_true Has_timestamp;
|
||||||
|
|
||||||
|
std::size_t time_stamp() const {
|
||||||
|
return time_stamp_;
|
||||||
|
}
|
||||||
|
void set_time_stamp(const std::size_t& ts) {
|
||||||
|
time_stamp_ = ts;
|
||||||
|
}
|
||||||
|
///@}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The index of the cell of the input complex that contains me
|
// The index of the cell of the input complex that contains me
|
||||||
Subdomain_index subdomain_index_;
|
Subdomain_index subdomain_index_;
|
||||||
|
|
@ -168,11 +184,10 @@ private:
|
||||||
#ifdef CGAL_INTRUSIVE_LIST
|
#ifdef CGAL_INTRUSIVE_LIST
|
||||||
Cell_handle next_intrusive_, previous_intrusive_;
|
Cell_handle next_intrusive_, previous_intrusive_;
|
||||||
#endif
|
#endif
|
||||||
|
std::size_t time_stamp_;
|
||||||
|
|
||||||
}; // end class Mesh_cell_base_3
|
}; // end class Mesh_cell_base_3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template < class GT, class MT, class Cb >
|
template < class GT, class MT, class Cb >
|
||||||
std::istream&
|
std::istream&
|
||||||
operator>>(std::istream &is,
|
operator>>(std::istream &is,
|
||||||
|
|
|
||||||
|
|
@ -150,8 +150,8 @@ public:
|
||||||
else if ( distance > length() ) { distance -= length(); }
|
else if ( distance > length() ) { distance -= length(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
CGAL_assertion( distance > FT(0) );
|
CGAL_assertion( distance >= FT(0) );
|
||||||
CGAL_assertion( distance < length() );
|
CGAL_assertion( distance <= length() );
|
||||||
|
|
||||||
// Initialize iterators
|
// Initialize iterators
|
||||||
const_iterator pit = points_.begin();
|
const_iterator pit = points_.begin();
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@
|
||||||
|
|
||||||
#include <CGAL/Polyhedron_3.h>
|
#include <CGAL/Polyhedron_3.h>
|
||||||
#include <CGAL/Polyhedron_items_3.h>
|
#include <CGAL/Polyhedron_items_3.h>
|
||||||
|
#include <CGAL/Has_timestamp.h>
|
||||||
|
#include <CGAL/tags.h>
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
|
@ -44,6 +46,8 @@ private:
|
||||||
typedef CGAL::HalfedgeDS_vertex_base<Refs, Tag, Point> Pdv_base;
|
typedef CGAL::HalfedgeDS_vertex_base<Refs, Tag, Point> Pdv_base;
|
||||||
|
|
||||||
Set_of_indices indices;
|
Set_of_indices indices;
|
||||||
|
std::size_t time_stamp_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int nb_of_feature_edges;
|
int nb_of_feature_edges;
|
||||||
|
|
||||||
|
|
@ -59,6 +63,18 @@ public:
|
||||||
indices.insert(i);
|
indices.insert(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// For the determinism of Compact_container iterators
|
||||||
|
///@{
|
||||||
|
typedef Tag_true Has_timestamp;
|
||||||
|
|
||||||
|
std::size_t time_stamp() const {
|
||||||
|
return time_stamp_;
|
||||||
|
}
|
||||||
|
void set_time_stamp(const std::size_t& ts) {
|
||||||
|
time_stamp_ = ts;
|
||||||
|
}
|
||||||
|
///@}
|
||||||
|
|
||||||
const Set_of_indices&
|
const Set_of_indices&
|
||||||
incident_patches_ids_set() const {
|
incident_patches_ids_set() const {
|
||||||
return indices;
|
return indices;
|
||||||
|
|
@ -74,6 +90,8 @@ public CGAL::HalfedgeDS_halfedge_base<Refs,Tprev,Tvertex,Tface>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
bool feature_edge;
|
bool feature_edge;
|
||||||
|
std::size_t time_stamp_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Mesh_polyhedron_halfedge()
|
Mesh_polyhedron_halfedge()
|
||||||
|
|
@ -87,6 +105,18 @@ public:
|
||||||
feature_edge = b;
|
feature_edge = b;
|
||||||
this->opposite()->feature_edge = b;
|
this->opposite()->feature_edge = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// For the determinism of Compact_container iterators
|
||||||
|
///@{
|
||||||
|
typedef Tag_true Has_timestamp;
|
||||||
|
|
||||||
|
std::size_t time_stamp() const {
|
||||||
|
return time_stamp_;
|
||||||
|
}
|
||||||
|
void set_time_stamp(const std::size_t& ts) {
|
||||||
|
time_stamp_ = ts;
|
||||||
|
}
|
||||||
|
///@}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Integral>
|
template <typename Integral>
|
||||||
|
|
@ -108,6 +138,8 @@ public CGAL::HalfedgeDS_face_base<Refs,T_,Pln_>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Patch_id_ patch_id_;
|
Patch_id_ patch_id_;
|
||||||
|
std::size_t time_stamp_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef Patch_id_ Patch_id;
|
typedef Patch_id_ Patch_id;
|
||||||
|
|
@ -122,8 +154,22 @@ public:
|
||||||
void set_patch_id(const Patch_id& i) {
|
void set_patch_id(const Patch_id& i) {
|
||||||
patch_id_ = i;
|
patch_id_ = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// For the determinism of Compact_container iterators
|
||||||
|
///@{
|
||||||
|
typedef Tag_true Has_timestamp;
|
||||||
|
|
||||||
|
std::size_t time_stamp() const {
|
||||||
|
return time_stamp_;
|
||||||
|
}
|
||||||
|
void set_time_stamp(const std::size_t& ts) {
|
||||||
|
time_stamp_ = ts;
|
||||||
|
}
|
||||||
|
///@}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Patch_id>
|
template <typename Patch_id>
|
||||||
class Mesh_polyhedron_items : public CGAL::Polyhedron_items_3 {
|
class Mesh_polyhedron_items : public CGAL::Polyhedron_items_3 {
|
||||||
public:
|
public:
|
||||||
|
|
@ -166,7 +212,6 @@ struct Mesh_polyhedron_3
|
||||||
typedef type Type;
|
typedef type Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // end namespace CGAL
|
} // end namespace CGAL
|
||||||
|
|
||||||
#endif // CGAL_MESH_POLYHEDRON_3_H
|
#endif // CGAL_MESH_POLYHEDRON_3_H
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,10 @@
|
||||||
#define CGAL_COMPACT_MESH_VERTEX_BASE_3_H
|
#define CGAL_COMPACT_MESH_VERTEX_BASE_3_H
|
||||||
|
|
||||||
#include <CGAL/Triangulation_vertex_base_3.h>
|
#include <CGAL/Triangulation_vertex_base_3.h>
|
||||||
#include <CGAL/Mesh_3/Has_features.h>
|
|
||||||
#include <CGAL/internal/Mesh_3/get_index.h>
|
#include <CGAL/internal/Mesh_3/get_index.h>
|
||||||
#include <CGAL/Mesh_3/io_signature.h>
|
#include <CGAL/Mesh_3/io_signature.h>
|
||||||
|
#include <CGAL/Has_timestamp.h>
|
||||||
|
#include <CGAL/tags.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
|
|
@ -74,6 +75,7 @@ public:
|
||||||
, next_intrusive_()
|
, next_intrusive_()
|
||||||
, previous_intrusive_()
|
, previous_intrusive_()
|
||||||
#endif //CGAL_INTRUSIVE_LIST
|
#endif //CGAL_INTRUSIVE_LIST
|
||||||
|
, time_stamp_(-1)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// Default copy constructor and assignment operator are ok
|
// Default copy constructor and assignment operator are ok
|
||||||
|
|
@ -124,6 +126,18 @@ public:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// For the determinism of Compact_container iterators
|
||||||
|
///@{
|
||||||
|
typedef Tag_true Has_timestamp;
|
||||||
|
|
||||||
|
std::size_t time_stamp() const {
|
||||||
|
return time_stamp_;
|
||||||
|
}
|
||||||
|
void set_time_stamp(const std::size_t& ts) {
|
||||||
|
time_stamp_ = ts;
|
||||||
|
}
|
||||||
|
///@}
|
||||||
|
|
||||||
bool is_c2t3_cache_valid() const {
|
bool is_c2t3_cache_valid() const {
|
||||||
return cache_validity;
|
return cache_validity;
|
||||||
}
|
}
|
||||||
|
|
@ -179,12 +193,9 @@ private:
|
||||||
Vertex_handle next_intrusive_;
|
Vertex_handle next_intrusive_;
|
||||||
Vertex_handle previous_intrusive_;
|
Vertex_handle previous_intrusive_;
|
||||||
#endif
|
#endif
|
||||||
}; // end class Mesh_vertex_base_3
|
std::size_t time_stamp_;
|
||||||
|
|
||||||
namespace internal {
|
}; // end class Mesh_vertex_base_3
|
||||||
namespace Mesh_3 {
|
|
||||||
} // end namespace internal::Mesh_3
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
template<class GT,
|
template<class GT,
|
||||||
class MD,
|
class MD,
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@
|
||||||
#include <CGAL/AABB_traits.h>
|
#include <CGAL/AABB_traits.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <CGAL/Random.h>
|
||||||
#include <CGAL/point_generators_3.h>
|
#include <CGAL/point_generators_3.h>
|
||||||
#include <CGAL/Mesh_3/Creator_weighted_point_3.h>
|
#include <CGAL/Mesh_3/Creator_weighted_point_3.h>
|
||||||
#include <CGAL/Mesh_3/Profile_counter.h>
|
#include <CGAL/Mesh_3/Profile_counter.h>
|
||||||
|
|
@ -203,36 +204,57 @@ public:
|
||||||
Polyhedral_mesh_domain_3()
|
Polyhedral_mesh_domain_3()
|
||||||
: tree_()
|
: tree_()
|
||||||
, bounding_tree_(&tree_)
|
, bounding_tree_(&tree_)
|
||||||
, has_cache(false) {}
|
, has_cache(false)
|
||||||
|
, p_rng_(NULL)
|
||||||
|
, delete_rng_(true)
|
||||||
|
{
|
||||||
|
p_rng_ = new CGAL::Random(0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constructor. Contruction from a polyhedral surface
|
* @brief Constructor. Contruction from a polyhedral surface
|
||||||
* @param polyhedron the polyhedron describing the polyhedral surface
|
* @param polyhedron the polyhedron describing the polyhedral surface
|
||||||
*/
|
*/
|
||||||
Polyhedral_mesh_domain_3(const Polyhedron& p)
|
Polyhedral_mesh_domain_3(const Polyhedron& p,
|
||||||
|
CGAL::Random* p_rng = NULL)
|
||||||
: tree_(TriangleAccessor().triangles_begin(p),
|
: tree_(TriangleAccessor().triangles_begin(p),
|
||||||
TriangleAccessor().triangles_end(p)),
|
TriangleAccessor().triangles_end(p)),
|
||||||
bounding_tree_(&tree_) // the bounding tree is tree_
|
bounding_tree_(&tree_) // the bounding tree is tree_
|
||||||
, has_cache(false)
|
, has_cache(false)
|
||||||
|
, p_rng_(p_rng)
|
||||||
|
, delete_rng_(false)
|
||||||
{
|
{
|
||||||
if(!p.is_pure_triangle()) {
|
if(!p.is_pure_triangle()) {
|
||||||
std::cerr << "Your input polyhedron must be triangulated!\n";
|
std::cerr << "Your input polyhedron must be triangulated!\n";
|
||||||
CGAL_error_msg("Your input polyhedron must be triangulated!");
|
CGAL_error_msg("Your input polyhedron must be triangulated!");
|
||||||
}
|
}
|
||||||
|
if(!p_rng_)
|
||||||
|
{
|
||||||
|
p_rng_ = new CGAL::Random(0);
|
||||||
|
delete_rng_ = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Polyhedral_mesh_domain_3(const Polyhedron& p,
|
Polyhedral_mesh_domain_3(const Polyhedron& p,
|
||||||
const Polyhedron& bounding_polyhedron)
|
const Polyhedron& bounding_polyhedron,
|
||||||
|
CGAL::Random* p_rng = NULL)
|
||||||
: tree_(TriangleAccessor().triangles_begin(p),
|
: tree_(TriangleAccessor().triangles_begin(p),
|
||||||
TriangleAccessor().triangles_end(p))
|
TriangleAccessor().triangles_end(p))
|
||||||
, bounding_tree_(new AABB_tree_(TriangleAccessor().triangles_begin(bounding_polyhedron),
|
, bounding_tree_(new AABB_tree_(TriangleAccessor().triangles_begin(bounding_polyhedron),
|
||||||
TriangleAccessor().triangles_end(bounding_polyhedron)))
|
TriangleAccessor().triangles_end(bounding_polyhedron)))
|
||||||
, has_cache(false)
|
, has_cache(false)
|
||||||
|
, p_rng_(p_rng)
|
||||||
|
, delete_rng_(false)
|
||||||
{
|
{
|
||||||
tree_.insert(TriangleAccessor().triangles_begin(bounding_polyhedron),
|
tree_.insert(TriangleAccessor().triangles_begin(bounding_polyhedron),
|
||||||
TriangleAccessor().triangles_end(bounding_polyhedron));
|
TriangleAccessor().triangles_end(bounding_polyhedron));
|
||||||
tree_.build();
|
tree_.build();
|
||||||
bounding_tree_->build();
|
bounding_tree_->build();
|
||||||
|
if(!p_rng_)
|
||||||
|
{
|
||||||
|
p_rng_ = new CGAL::Random(0);
|
||||||
|
delete_rng_ = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -249,8 +271,11 @@ public:
|
||||||
template <typename InputPolyhedraPtrIterator>
|
template <typename InputPolyhedraPtrIterator>
|
||||||
Polyhedral_mesh_domain_3(InputPolyhedraPtrIterator begin,
|
Polyhedral_mesh_domain_3(InputPolyhedraPtrIterator begin,
|
||||||
InputPolyhedraPtrIterator end,
|
InputPolyhedraPtrIterator end,
|
||||||
const Polyhedron& bounding_polyhedron)
|
const Polyhedron& bounding_polyhedron,
|
||||||
|
CGAL::Random* p_rng = NULL)
|
||||||
: has_cache(false)
|
: has_cache(false)
|
||||||
|
, p_rng_(p_rng)
|
||||||
|
, delete_rng_(false)
|
||||||
{
|
{
|
||||||
if(begin != end) {
|
if(begin != end) {
|
||||||
for(; begin != end; ++begin) {
|
for(; begin != end; ++begin) {
|
||||||
|
|
@ -270,6 +295,11 @@ public:
|
||||||
TriangleAccessor().triangles_end(bounding_polyhedron));
|
TriangleAccessor().triangles_end(bounding_polyhedron));
|
||||||
bounding_tree_ = &tree_;
|
bounding_tree_ = &tree_;
|
||||||
}
|
}
|
||||||
|
if(!p_rng_)
|
||||||
|
{
|
||||||
|
p_rng_ = new CGAL::Random(0);
|
||||||
|
delete_rng_ = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -284,8 +314,11 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename InputPolyhedraPtrIterator>
|
template <typename InputPolyhedraPtrIterator>
|
||||||
Polyhedral_mesh_domain_3(InputPolyhedraPtrIterator begin,
|
Polyhedral_mesh_domain_3(InputPolyhedraPtrIterator begin,
|
||||||
InputPolyhedraPtrIterator end)
|
InputPolyhedraPtrIterator end,
|
||||||
|
CGAL::Random* p_rng = NULL)
|
||||||
: has_cache(false)
|
: has_cache(false)
|
||||||
|
, p_rng_(p_rng)
|
||||||
|
, delete_rng_(false)
|
||||||
{
|
{
|
||||||
if(begin != end) {
|
if(begin != end) {
|
||||||
for(; begin != end; ++begin) {
|
for(; begin != end; ++begin) {
|
||||||
|
|
@ -295,6 +328,11 @@ public:
|
||||||
tree_.build();
|
tree_.build();
|
||||||
}
|
}
|
||||||
bounding_tree_ = 0;
|
bounding_tree_ = 0;
|
||||||
|
if(!p_rng_)
|
||||||
|
{
|
||||||
|
p_rng_ = new CGAL::Random(0);
|
||||||
|
delete_rng_ = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
|
|
@ -302,6 +340,8 @@ public:
|
||||||
if(bounding_tree_ != 0 && bounding_tree_ != &tree_) {
|
if(bounding_tree_ != 0 && bounding_tree_ != &tree_) {
|
||||||
delete bounding_tree_;
|
delete bounding_tree_;
|
||||||
}
|
}
|
||||||
|
if(delete_rng_)
|
||||||
|
delete p_rng_;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -595,6 +635,10 @@ private:
|
||||||
mutable Cached_query cached_query;
|
mutable Cached_query cached_query;
|
||||||
mutable AABB_primitive_id cached_primitive_id;
|
mutable AABB_primitive_id cached_primitive_id;
|
||||||
|
|
||||||
|
//random number generator for Construct_initial_points
|
||||||
|
CGAL::Random* p_rng_;
|
||||||
|
bool delete_rng_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
template <typename Query>
|
template <typename Query>
|
||||||
|
|
@ -611,6 +655,20 @@ public:
|
||||||
return has_cache && (cached_query == Cached_query(q));
|
return has_cache && (cached_query == Cached_query(q));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_random_generator(CGAL::Random* p_rng)
|
||||||
|
{
|
||||||
|
if(delete_rng_) delete p_rng_;
|
||||||
|
if(!p_rng_)
|
||||||
|
{
|
||||||
|
p_rng_ = new CGAL::Random(0);
|
||||||
|
delete_rng_ = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p_rng_ = p_rng;
|
||||||
|
delete_rng_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Disabled copy constructor & assignment operator
|
// Disabled copy constructor & assignment operator
|
||||||
typedef Polyhedral_mesh_domain_3 Self;
|
typedef Polyhedral_mesh_domain_3 Self;
|
||||||
|
|
@ -623,7 +681,8 @@ private:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<typename P_, typename IGT_, typename TA, typename Tag, typename E_tag_>
|
template<typename P_, typename IGT_, typename TA,
|
||||||
|
typename Tag, typename E_tag_>
|
||||||
template<class OutputIterator>
|
template<class OutputIterator>
|
||||||
OutputIterator
|
OutputIterator
|
||||||
Polyhedral_mesh_domain_3<P_,IGT_,TA,Tag,E_tag_>::
|
Polyhedral_mesh_domain_3<P_,IGT_,TA,Tag,E_tag_>::
|
||||||
|
|
@ -638,7 +697,8 @@ Construct_initial_points::operator()(OutputIterator pts,
|
||||||
FT( (bbox.ymin() + bbox.ymax()) / 2),
|
FT( (bbox.ymin() + bbox.ymax()) / 2),
|
||||||
FT( (bbox.zmin() + bbox.zmax()) / 2) );
|
FT( (bbox.zmin() + bbox.zmax()) / 2) );
|
||||||
|
|
||||||
Random_points_on_sphere_3<Point_3> random_point(1.);
|
CGAL::Random& rng = *(r_domain_.p_rng_);
|
||||||
|
Random_points_on_sphere_3<Point_3> random_point(1., rng);
|
||||||
|
|
||||||
int i = n;
|
int i = n;
|
||||||
#ifdef CGAL_MESH_3_VERBOSE
|
#ifdef CGAL_MESH_3_VERBOSE
|
||||||
|
|
@ -678,7 +738,8 @@ Construct_initial_points::operator()(OutputIterator pts,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename P_, typename IGT_, typename TA, typename Tag, typename E_tag_>
|
template<typename P_, typename IGT_, typename TA,
|
||||||
|
typename Tag, typename E_tag_>
|
||||||
typename Polyhedral_mesh_domain_3<P_,IGT_,TA,Tag,E_tag_>::Subdomain
|
typename Polyhedral_mesh_domain_3<P_,IGT_,TA,Tag,E_tag_>::Subdomain
|
||||||
Polyhedral_mesh_domain_3<P_,IGT_,TA,Tag,E_tag_>::
|
Polyhedral_mesh_domain_3<P_,IGT_,TA,Tag,E_tag_>::
|
||||||
Is_in_domain::operator()(const Point_3& p) const
|
Is_in_domain::operator()(const Point_3& p) const
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,11 @@
|
||||||
|
|
||||||
#include <CGAL/Mesh_3/config.h>
|
#include <CGAL/Mesh_3/config.h>
|
||||||
|
|
||||||
|
#include <CGAL/Random.h>
|
||||||
#include <CGAL/Polyhedral_mesh_domain_3.h>
|
#include <CGAL/Polyhedral_mesh_domain_3.h>
|
||||||
#include <CGAL/Mesh_domain_with_polyline_features_3.h>
|
#include <CGAL/Mesh_domain_with_polyline_features_3.h>
|
||||||
#include <CGAL/Mesh_polyhedron_3.h>
|
#include <CGAL/Mesh_polyhedron_3.h>
|
||||||
|
|
||||||
#include <CGAL/Mesh_polyhedron_3.h>
|
|
||||||
#include <CGAL/Mesh_3/Detect_polylines_in_polyhedra.h>
|
#include <CGAL/Mesh_3/Detect_polylines_in_polyhedra.h>
|
||||||
#include <CGAL/Mesh_3/Polyline_with_context.h>
|
#include <CGAL/Mesh_3/Polyline_with_context.h>
|
||||||
#include <CGAL/Mesh_3/Detect_features_in_polyhedra.h>
|
#include <CGAL/Mesh_3/Detect_features_in_polyhedra.h>
|
||||||
|
|
@ -94,11 +94,10 @@ public:
|
||||||
typedef CGAL::Tag_true Has_features;
|
typedef CGAL::Tag_true Has_features;
|
||||||
|
|
||||||
/// Constructors
|
/// Constructors
|
||||||
Polyhedral_mesh_domain_with_features_3(const Polyhedron& p);
|
Polyhedral_mesh_domain_with_features_3(const Polyhedron& p,
|
||||||
Polyhedral_mesh_domain_with_features_3(const std::string& filename);
|
CGAL::Random* p_rng = NULL);
|
||||||
|
Polyhedral_mesh_domain_with_features_3(const std::string& filename,
|
||||||
template <typename T1, typename T2>
|
CGAL::Random* p_rng = NULL);
|
||||||
Polyhedral_mesh_domain_with_features_3(const T1& a, const T2& b) : Base(a, b) {}
|
|
||||||
|
|
||||||
template <typename T1, typename T2, typename T3>
|
template <typename T1, typename T2, typename T3>
|
||||||
Polyhedral_mesh_domain_with_features_3(const T1& a, const T2& b, const T3& c)
|
Polyhedral_mesh_domain_with_features_3(const T1& a, const T2& b, const T3& c)
|
||||||
|
|
@ -108,6 +107,8 @@ public:
|
||||||
~Polyhedral_mesh_domain_with_features_3() {}
|
~Polyhedral_mesh_domain_with_features_3() {}
|
||||||
|
|
||||||
/// Detect features
|
/// Detect features
|
||||||
|
void initialize_ts(Polyhedron& p);
|
||||||
|
|
||||||
void detect_features(FT angle_in_degree, Polyhedron& p);
|
void detect_features(FT angle_in_degree, Polyhedron& p);
|
||||||
void detect_features(FT angle_in_degree = FT(60)) { detect_features(angle_in_degree, polyhedron_); }
|
void detect_features(FT angle_in_degree = FT(60)) { detect_features(angle_in_degree, polyhedron_); }
|
||||||
|
|
||||||
|
|
@ -126,17 +127,20 @@ private:
|
||||||
template < typename GT_, typename P_, typename TA_,
|
template < typename GT_, typename P_, typename TA_,
|
||||||
typename Tag_, typename E_tag_>
|
typename Tag_, typename E_tag_>
|
||||||
Polyhedral_mesh_domain_with_features_3<GT_,P_,TA_,Tag_,E_tag_>::
|
Polyhedral_mesh_domain_with_features_3<GT_,P_,TA_,Tag_,E_tag_>::
|
||||||
Polyhedral_mesh_domain_with_features_3(const Polyhedron& p)
|
Polyhedral_mesh_domain_with_features_3(const Polyhedron& p,
|
||||||
|
CGAL::Random* p_rng)
|
||||||
: Base()
|
: Base()
|
||||||
, polyhedron_(p)
|
, polyhedron_(p)
|
||||||
{
|
{
|
||||||
this->add_primitives(polyhedron_);
|
this->add_primitives(polyhedron_);
|
||||||
|
this->set_random_generator(p_rng);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename GT_, typename P_, typename TA_,
|
template < typename GT_, typename P_, typename TA_,
|
||||||
typename Tag_, typename E_tag_>
|
typename Tag_, typename E_tag_>
|
||||||
Polyhedral_mesh_domain_with_features_3<GT_,P_,TA_,Tag_,E_tag_>::
|
Polyhedral_mesh_domain_with_features_3<GT_,P_,TA_,Tag_,E_tag_>::
|
||||||
Polyhedral_mesh_domain_with_features_3(const std::string& filename)
|
Polyhedral_mesh_domain_with_features_3(const std::string& filename,
|
||||||
|
CGAL::Random* p_rng)
|
||||||
: Base()
|
: Base()
|
||||||
, polyhedron_()
|
, polyhedron_()
|
||||||
{
|
{
|
||||||
|
|
@ -144,6 +148,32 @@ Polyhedral_mesh_domain_with_features_3(const std::string& filename)
|
||||||
std::ifstream input(filename.c_str());
|
std::ifstream input(filename.c_str());
|
||||||
input >> polyhedron_;
|
input >> polyhedron_;
|
||||||
this->add_primitives(polyhedron_);
|
this->add_primitives(polyhedron_);
|
||||||
|
this->set_random_generator(p_rng);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template < typename GT_, typename P_, typename TA_,
|
||||||
|
typename Tag_, typename E_tag_>
|
||||||
|
void
|
||||||
|
Polyhedral_mesh_domain_with_features_3<GT_,P_,TA_,Tag_,E_tag_>::
|
||||||
|
initialize_ts(Polyhedron& p)
|
||||||
|
{
|
||||||
|
std::size_t ts = 0;
|
||||||
|
for(typename Polyhedron::Vertex_iterator v = p.vertices_begin(),
|
||||||
|
end = p.vertices_end() ; v != end ; ++v)
|
||||||
|
{
|
||||||
|
v->set_time_stamp(ts++);
|
||||||
|
}
|
||||||
|
for(typename Polyhedron::Facet_iterator fit = p.facets_begin(),
|
||||||
|
end = p.facets_end() ; fit != end ; ++fit )
|
||||||
|
{
|
||||||
|
fit->set_time_stamp(ts++);
|
||||||
|
}
|
||||||
|
for(typename Polyhedron::Halfedge_iterator hit = p.halfedges_begin(),
|
||||||
|
end = p.halfedges_end() ; hit != end ; ++hit )
|
||||||
|
{
|
||||||
|
hit->set_time_stamp(ts++);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -153,6 +183,7 @@ void
|
||||||
Polyhedral_mesh_domain_with_features_3<GT_,P_,TA_,Tag_,E_tag_>::
|
Polyhedral_mesh_domain_with_features_3<GT_,P_,TA_,Tag_,E_tag_>::
|
||||||
detect_features(FT angle_in_degree, Polyhedron& p)
|
detect_features(FT angle_in_degree, Polyhedron& p)
|
||||||
{
|
{
|
||||||
|
initialize_ts(p);
|
||||||
// Get sharp features
|
// Get sharp features
|
||||||
Mesh_3::detect_features(p,angle_in_degree);
|
Mesh_3::detect_features(p,angle_in_degree);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ if ( CGAL_FOUND )
|
||||||
create_single_source_cgal_program( "test_meshing_polyhedron_with_features.cpp" )
|
create_single_source_cgal_program( "test_meshing_polyhedron_with_features.cpp" )
|
||||||
create_single_source_cgal_program( "test_meshing_unit_tetrahedron.cpp" )
|
create_single_source_cgal_program( "test_meshing_unit_tetrahedron.cpp" )
|
||||||
create_single_source_cgal_program( "test_robust_weighted_circumcenter.cpp" )
|
create_single_source_cgal_program( "test_robust_weighted_circumcenter.cpp" )
|
||||||
|
create_single_source_cgal_program( "test_meshing_determinism.cpp" )
|
||||||
|
|
||||||
else()
|
else()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -240,11 +240,8 @@ struct Test_c3t3_io {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef WIN32
|
#if 0
|
||||||
# ifdef _MSC_VER
|
// Note: The Triangulation_3 facets iterator order changes after a reload
|
||||||
# pragma message("Note: The Triangulation_3 facets iterator is not deterministic")
|
|
||||||
# endif
|
|
||||||
#else // not WIN32
|
|
||||||
for(typename Tr::Finite_facets_iterator
|
for(typename Tr::Finite_facets_iterator
|
||||||
fit1 = t1.finite_facets_begin(),
|
fit1 = t1.finite_facets_begin(),
|
||||||
fit2 = t2.finite_facets_begin(),
|
fit2 = t2.finite_facets_begin(),
|
||||||
|
|
@ -329,6 +326,10 @@ struct Test_c3t3_io {
|
||||||
<< c3t3_bis
|
<< c3t3_bis
|
||||||
<< "\n******end******" << std::endl;
|
<< "\n******end******" << std::endl;
|
||||||
assert(stream);
|
assert(stream);
|
||||||
|
std::ostringstream ss_c3t3, ss_c3t3_bis;
|
||||||
|
ss_c3t3 << c3t3;
|
||||||
|
ss_c3t3_bis << c3t3_bis;
|
||||||
|
assert(ss_c3t3.str() == ss_c3t3_bis.str());
|
||||||
return check_equality(c3t3, c3t3_bis);
|
return check_equality(c3t3, c3t3_bis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,10 @@ public:
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
Image image;
|
Image image;
|
||||||
image.read("data/liver.inr.gz");
|
image.read("data/liver.inr.gz");
|
||||||
Mesh_domain domain(image,1e-9);
|
|
||||||
|
std::cout << "\tSeed is\t"
|
||||||
|
<< CGAL::default_random.get_seed() << std::endl;
|
||||||
|
Mesh_domain domain(image, 1e-9, &CGAL::default_random);
|
||||||
|
|
||||||
// Set mesh criteria
|
// Set mesh criteria
|
||||||
Facet_criteria facet_criteria(25, 20*image.vx(), 5*image.vx());
|
Facet_criteria facet_criteria(25, 20*image.vx(), 5*image.vx());
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
#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/Polyhedral_mesh_domain_with_features_3.h>
|
||||||
|
#include <CGAL/make_mesh_3.h>
|
||||||
|
#include <CGAL/lloyd_optimize_mesh_3.h>
|
||||||
|
#include <CGAL/odt_optimize_mesh_3.h>
|
||||||
|
#include <CGAL/perturb_mesh_3.h>
|
||||||
|
#include <CGAL/exude_mesh_3.h>
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
// Domain
|
||||||
|
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||||
|
typedef CGAL::Polyhedral_mesh_domain_with_features_3<K> Mesh_domain;
|
||||||
|
|
||||||
|
// Triangulation
|
||||||
|
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
||||||
|
typedef CGAL::Mesh_complex_3_in_triangulation_3<
|
||||||
|
Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_segment_index> C3t3;
|
||||||
|
|
||||||
|
// Mesh Criteria
|
||||||
|
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
|
||||||
|
|
||||||
|
// To avoid verbose function and named parameters call
|
||||||
|
using namespace CGAL::parameters;
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
// Collect options
|
||||||
|
std::size_t nb_runs = 2;
|
||||||
|
unsigned int nb_lloyd = 2;
|
||||||
|
unsigned int nb_odt = 2;
|
||||||
|
double perturb_bound = 10.;
|
||||||
|
double exude_bound = 15.;
|
||||||
|
|
||||||
|
// Domain
|
||||||
|
std::cout << "\tSeed is\t 0" << std::endl;
|
||||||
|
Mesh_domain domain("data/cube.off");
|
||||||
|
//no random generator is given, so CGAL::Random(0) is used
|
||||||
|
|
||||||
|
// Get sharp features
|
||||||
|
domain.detect_features();
|
||||||
|
|
||||||
|
// Mesh criteria
|
||||||
|
Mesh_criteria criteria(edge_size = 0.2,
|
||||||
|
facet_angle = 25,
|
||||||
|
facet_size = 0.2,
|
||||||
|
facet_distance = 0.002,
|
||||||
|
cell_radius_edge_ratio = 3,
|
||||||
|
cell_size = 0.2);
|
||||||
|
|
||||||
|
// iterate
|
||||||
|
std::vector<std::string> output_c3t3;
|
||||||
|
output_c3t3.reserve(5 * nb_runs);
|
||||||
|
for(std::size_t i = 0; i < nb_runs; ++i)
|
||||||
|
{
|
||||||
|
std::cout << "------- Iteration " << (i+1) << " -------" << std::endl;
|
||||||
|
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria,
|
||||||
|
no_perturb(),
|
||||||
|
no_exude());
|
||||||
|
std::ostringstream oss;
|
||||||
|
c3t3.output_to_medit(oss);
|
||||||
|
output_c3t3.push_back(oss.str()); //[5*i]
|
||||||
|
oss.clear();
|
||||||
|
|
||||||
|
//LLOYD (1)
|
||||||
|
CGAL::lloyd_optimize_mesh_3(c3t3, domain, max_iteration_number = nb_lloyd);
|
||||||
|
c3t3.output_to_medit(oss);
|
||||||
|
output_c3t3.push_back(oss.str());//[i*5+1]
|
||||||
|
oss.clear();
|
||||||
|
|
||||||
|
//ODT (2)
|
||||||
|
CGAL::odt_optimize_mesh_3(c3t3, domain, max_iteration_number = nb_odt);
|
||||||
|
c3t3.output_to_medit(oss);
|
||||||
|
output_c3t3.push_back(oss.str());//[i*5+2]
|
||||||
|
oss.clear();
|
||||||
|
|
||||||
|
//PERTURB (3)
|
||||||
|
CGAL::perturb_mesh_3(c3t3, domain, sliver_bound=perturb_bound);
|
||||||
|
c3t3.output_to_medit(oss);
|
||||||
|
output_c3t3.push_back(oss.str());//[i*5+3]
|
||||||
|
oss.clear();
|
||||||
|
|
||||||
|
//EXUDE (4)
|
||||||
|
CGAL::exude_mesh_3(c3t3, sliver_bound=exude_bound);
|
||||||
|
c3t3.output_to_medit(oss);
|
||||||
|
output_c3t3.push_back(oss.str());//[i*5+4]
|
||||||
|
oss.clear();
|
||||||
|
|
||||||
|
if(i == 0)
|
||||||
|
continue;
|
||||||
|
//else check
|
||||||
|
for(std::size_t j = 0; j < 5; ++j)
|
||||||
|
{
|
||||||
|
if(0 != output_c3t3[5*(i-1)+j].compare(output_c3t3[5*i+j]))
|
||||||
|
{
|
||||||
|
std::cerr << "Meshing operation " << j << " is not deterministic.\n";
|
||||||
|
CGAL_assertion(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -57,8 +57,12 @@ struct Implicit_tester : public Tester<K>
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
// Data generation
|
// Data generation
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
|
std::cout << "\tSeed is\t"
|
||||||
|
<< CGAL::default_random.get_seed() << std::endl;
|
||||||
Mesh_domain domain(Implicit_tester<K>::sphere_function,
|
Mesh_domain domain(Implicit_tester<K>::sphere_function,
|
||||||
Sphere_3(CGAL::ORIGIN,2.));
|
Sphere_3(CGAL::ORIGIN,2.),
|
||||||
|
1e-3,
|
||||||
|
&CGAL::default_random);
|
||||||
|
|
||||||
// Set mesh criteria
|
// Set mesh criteria
|
||||||
Facet_criteria facet_criteria(0, 0, 0.3);
|
Facet_criteria facet_criteria(0, 0, 0.3);
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,9 @@ struct Polyhedron_tester : public Tester<K>
|
||||||
input >> polyhedron;
|
input >> polyhedron;
|
||||||
input.close();
|
input.close();
|
||||||
|
|
||||||
Mesh_domain domain(polyhedron);
|
std::cout << "\tSeed is\t"
|
||||||
|
<< CGAL::default_random.get_seed() << std::endl;
|
||||||
|
Mesh_domain domain(polyhedron, &CGAL::default_random);
|
||||||
|
|
||||||
// Set mesh criteria
|
// Set mesh criteria
|
||||||
Facet_criteria facet_criteria(30, 0.2, 0.02);
|
Facet_criteria facet_criteria(30, 0.2, 0.02);
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,9 @@ struct Polyhedron_with_features_tester : public Tester<K>
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
// Data generation
|
// Data generation
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
Mesh_domain domain("data/cube.off");
|
std::cout << "\tSeed is\t"
|
||||||
|
<< CGAL::default_random.get_seed() << std::endl;
|
||||||
|
Mesh_domain domain("data/cube.off", &CGAL::default_random);
|
||||||
domain.detect_features();
|
domain.detect_features();
|
||||||
|
|
||||||
// Set mesh criteria
|
// Set mesh criteria
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,9 @@ int main(int argc, char** argv)
|
||||||
Point(0, 1, 0),
|
Point(0, 1, 0),
|
||||||
Point(0, 0, 1));
|
Point(0, 0, 1));
|
||||||
|
|
||||||
Mesh_domain domain(p);
|
std::cout << "\tSeed is\t"
|
||||||
|
<< CGAL::default_random.get_seed() << std::endl;
|
||||||
|
Mesh_domain domain(p, &CGAL::default_random);
|
||||||
|
|
||||||
typedef std::vector<K::Point_3> Polyline;
|
typedef std::vector<K::Point_3> Polyline;
|
||||||
typedef std::vector<Polyline> Polylines;
|
typedef std::vector<Polyline> Polylines;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@
|
||||||
// surface mesh
|
// surface mesh
|
||||||
#include <CGAL/Polyhedron_3.h>
|
#include <CGAL/Polyhedron_3.h>
|
||||||
#include <CGAL/Polyhedron_items_3.h>
|
#include <CGAL/Polyhedron_items_3.h>
|
||||||
|
#include <CGAL/Has_timestamp.h>
|
||||||
|
#include <CGAL/tags.h>
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
|
@ -23,6 +25,8 @@ private:
|
||||||
|
|
||||||
Set_of_indices indices;
|
Set_of_indices indices;
|
||||||
std::size_t mID;
|
std::size_t mID;
|
||||||
|
std::size_t time_stamp_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int nb_of_feature_edges;
|
int nb_of_feature_edges;
|
||||||
|
|
||||||
|
|
@ -38,6 +42,18 @@ public:
|
||||||
indices.insert(i);
|
indices.insert(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// For the determinism of Compact_container iterators
|
||||||
|
///@{
|
||||||
|
typedef CGAL::Tag_true Has_timestamp;
|
||||||
|
|
||||||
|
std::size_t time_stamp() const {
|
||||||
|
return time_stamp_;
|
||||||
|
}
|
||||||
|
void set_time_stamp(const std::size_t& ts) {
|
||||||
|
time_stamp_ = ts;
|
||||||
|
}
|
||||||
|
///}@
|
||||||
|
|
||||||
const Set_of_indices&
|
const Set_of_indices&
|
||||||
incident_patches_ids_set() const {
|
incident_patches_ids_set() const {
|
||||||
return indices;
|
return indices;
|
||||||
|
|
@ -57,6 +73,8 @@ class Polyhedron_demo_halfedge :
|
||||||
private:
|
private:
|
||||||
bool feature_edge;
|
bool feature_edge;
|
||||||
std::size_t mID;
|
std::size_t mID;
|
||||||
|
std::size_t time_stamp_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Polyhedron_demo_halfedge()
|
Polyhedron_demo_halfedge()
|
||||||
|
|
@ -74,6 +92,17 @@ public:
|
||||||
std::size_t& id() { return mID; }
|
std::size_t& id() { return mID; }
|
||||||
std::size_t id() const { return mID; }
|
std::size_t id() const { return mID; }
|
||||||
|
|
||||||
|
/// For the determinism of Compact_container iterators
|
||||||
|
///@{
|
||||||
|
typedef CGAL::Tag_true Has_timestamp;
|
||||||
|
|
||||||
|
std::size_t time_stamp() const {
|
||||||
|
return time_stamp_;
|
||||||
|
}
|
||||||
|
void set_time_stamp(const std::size_t& ts) {
|
||||||
|
time_stamp_ = ts;
|
||||||
|
}
|
||||||
|
///@}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Refs, class T_, class Pln_, class Patch_id_>
|
template <class Refs, class T_, class Pln_, class Patch_id_>
|
||||||
|
|
@ -83,6 +112,8 @@ class Polyhedron_demo_face :
|
||||||
private:
|
private:
|
||||||
Patch_id_ patch_id_;
|
Patch_id_ patch_id_;
|
||||||
std::size_t mID;
|
std::size_t mID;
|
||||||
|
std::size_t time_stamp_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef Patch_id_ Patch_id;
|
typedef Patch_id_ Patch_id;
|
||||||
|
|
||||||
|
|
@ -100,6 +131,17 @@ public:
|
||||||
std::size_t& id() { return mID; }
|
std::size_t& id() { return mID; }
|
||||||
std::size_t id() const { return mID; }
|
std::size_t id() const { return mID; }
|
||||||
|
|
||||||
|
/// For the determinism of Compact_container iterators
|
||||||
|
///@{
|
||||||
|
typedef CGAL::Tag_true Has_timestamp;
|
||||||
|
|
||||||
|
std::size_t time_stamp() const {
|
||||||
|
return time_stamp_;
|
||||||
|
}
|
||||||
|
void set_time_stamp(const std::size_t& ts) {
|
||||||
|
time_stamp_ = ts;
|
||||||
|
}
|
||||||
|
///@}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Patch_id>
|
template <typename Patch_id>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright (c) 2003,2004,2007-2010 INRIA Sophia-Antipolis (France).
|
// Copyright (c) 2003,2004,2007-2010 INRIA Sophia-Antipolis (France).
|
||||||
|
// Copyright (c) 2014 GeometryFactory Sarl (France)
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
|
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
|
||||||
|
|
@ -30,8 +31,8 @@
|
||||||
|
|
||||||
#include <CGAL/memory.h>
|
#include <CGAL/memory.h>
|
||||||
#include <CGAL/iterator.h>
|
#include <CGAL/iterator.h>
|
||||||
|
#include <CGAL/Time_stamper.h>
|
||||||
|
|
||||||
#include <boost/mpl/if.hpp>
|
|
||||||
|
|
||||||
// An STL like container with the following properties :
|
// An STL like container with the following properties :
|
||||||
// - to achieve compactness, it requires access to a pointer stored in T,
|
// - to achieve compactness, it requires access to a pointer stored in T,
|
||||||
|
|
@ -163,17 +164,27 @@ namespace internal {
|
||||||
class CC_iterator;
|
class CC_iterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < class T, class Allocator_ = Default, class Increment_policy
|
template < class T,
|
||||||
=Addition_size_policy<CGAL_INIT_COMPACT_CONTAINER_BLOCK_SIZE,
|
class Allocator_ = Default,
|
||||||
CGAL_INCREMENT_COMPACT_CONTAINER_BLOCK_SIZE> >
|
class Increment_policy_ = Default,
|
||||||
|
class TimeStamper_ = Default >
|
||||||
class Compact_container
|
class Compact_container
|
||||||
{
|
{
|
||||||
typedef Allocator_ Al;
|
typedef Allocator_ Al;
|
||||||
typedef Increment_policy Incr_policy;
|
|
||||||
typedef typename Default::Get< Al, CGAL_ALLOCATOR(T) >::type Allocator;
|
typedef typename Default::Get< Al, CGAL_ALLOCATOR(T) >::type Allocator;
|
||||||
typedef Compact_container <T, Al, Increment_policy> Self;
|
typedef Increment_policy_ Ip;
|
||||||
|
typedef typename Default::Get< Ip,
|
||||||
|
Addition_size_policy<CGAL_INIT_COMPACT_CONTAINER_BLOCK_SIZE,
|
||||||
|
CGAL_INCREMENT_COMPACT_CONTAINER_BLOCK_SIZE>
|
||||||
|
>::type Increment_policy;
|
||||||
|
typedef TimeStamper_ Ts;
|
||||||
|
typedef Compact_container <T, Al, Ip, Ts> Self;
|
||||||
typedef Compact_container_traits <T> Traits;
|
typedef Compact_container_traits <T> Traits;
|
||||||
public:
|
public:
|
||||||
|
typedef typename Default::Get< TimeStamper_,
|
||||||
|
CGAL::Time_stamper_impl<T> >::type
|
||||||
|
Time_stamper_impl;
|
||||||
|
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
typedef Allocator allocator_type;
|
typedef Allocator allocator_type;
|
||||||
typedef typename Allocator::reference reference;
|
typedef typename Allocator::reference reference;
|
||||||
|
|
@ -196,6 +207,7 @@ public:
|
||||||
|
|
||||||
explicit Compact_container(const Allocator &a = Allocator())
|
explicit Compact_container(const Allocator &a = Allocator())
|
||||||
: alloc(a)
|
: alloc(a)
|
||||||
|
, time_stamper(new Time_stamper_impl())
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
@ -204,6 +216,7 @@ public:
|
||||||
Compact_container(InputIterator first, InputIterator last,
|
Compact_container(InputIterator first, InputIterator last,
|
||||||
const Allocator & a = Allocator())
|
const Allocator & a = Allocator())
|
||||||
: alloc(a)
|
: alloc(a)
|
||||||
|
, time_stamper(new Time_stamper_impl())
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
std::copy(first, last, CGAL::inserter(*this));
|
std::copy(first, last, CGAL::inserter(*this));
|
||||||
|
|
@ -212,9 +225,11 @@ public:
|
||||||
// The copy constructor and assignment operator preserve the iterator order
|
// The copy constructor and assignment operator preserve the iterator order
|
||||||
Compact_container(const Compact_container &c)
|
Compact_container(const Compact_container &c)
|
||||||
: alloc(c.get_allocator())
|
: alloc(c.get_allocator())
|
||||||
|
, time_stamper(new Time_stamper_impl())
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
block_size = c.block_size;
|
block_size = c.block_size;
|
||||||
|
*time_stamper = *c.time_stamper;
|
||||||
std::copy(c.begin(), c.end(), CGAL::inserter(*this));
|
std::copy(c.begin(), c.end(), CGAL::inserter(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -230,6 +245,7 @@ public:
|
||||||
~Compact_container()
|
~Compact_container()
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
delete time_stamper;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_used(size_type i) const
|
bool is_used(size_type i) const
|
||||||
|
|
@ -274,6 +290,7 @@ public:
|
||||||
std::swap(last_item, c.last_item);
|
std::swap(last_item, c.last_item);
|
||||||
std::swap(free_list, c.free_list);
|
std::swap(free_list, c.free_list);
|
||||||
all_items.swap(c.all_items);
|
all_items.swap(c.all_items);
|
||||||
|
std::swap(time_stamper, c.time_stamper);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator begin() { return iterator(first_item, 0, 0); }
|
iterator begin() { return iterator(first_item, 0, 0); }
|
||||||
|
|
@ -319,6 +336,7 @@ public:
|
||||||
new (ret) value_type(args...);
|
new (ret) value_type(args...);
|
||||||
CGAL_assertion(type(ret) == USED);
|
CGAL_assertion(type(ret) == USED);
|
||||||
++size_;
|
++size_;
|
||||||
|
time_stamper->set_time_stamp(ret);
|
||||||
return iterator(ret, 0);
|
return iterator(ret, 0);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
@ -333,6 +351,7 @@ public:
|
||||||
new (ret) value_type();
|
new (ret) value_type();
|
||||||
CGAL_assertion(type(ret) == USED);
|
CGAL_assertion(type(ret) == USED);
|
||||||
++size_;
|
++size_;
|
||||||
|
time_stamper->set_time_stamp(ret);
|
||||||
return iterator(ret, 0);
|
return iterator(ret, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -348,6 +367,7 @@ public:
|
||||||
new (ret) value_type(t1);
|
new (ret) value_type(t1);
|
||||||
CGAL_assertion(type(ret) == USED);
|
CGAL_assertion(type(ret) == USED);
|
||||||
++size_;
|
++size_;
|
||||||
|
time_stamper->set_time_stamp(ret);
|
||||||
return iterator(ret, 0);
|
return iterator(ret, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -363,6 +383,7 @@ public:
|
||||||
new (ret) value_type(t1, t2);
|
new (ret) value_type(t1, t2);
|
||||||
CGAL_assertion(type(ret) == USED);
|
CGAL_assertion(type(ret) == USED);
|
||||||
++size_;
|
++size_;
|
||||||
|
time_stamper->set_time_stamp(ret);
|
||||||
return iterator(ret, 0);
|
return iterator(ret, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -378,6 +399,7 @@ public:
|
||||||
new (ret) value_type(t1, t2, t3);
|
new (ret) value_type(t1, t2, t3);
|
||||||
CGAL_assertion(type(ret) == USED);
|
CGAL_assertion(type(ret) == USED);
|
||||||
++size_;
|
++size_;
|
||||||
|
time_stamper->set_time_stamp(ret);
|
||||||
return iterator(ret, 0);
|
return iterator(ret, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -393,6 +415,7 @@ public:
|
||||||
new (ret) value_type(t1, t2, t3, t4);
|
new (ret) value_type(t1, t2, t3, t4);
|
||||||
CGAL_assertion(type(ret) == USED);
|
CGAL_assertion(type(ret) == USED);
|
||||||
++size_;
|
++size_;
|
||||||
|
time_stamper->set_time_stamp(ret);
|
||||||
return iterator(ret, 0);
|
return iterator(ret, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -409,6 +432,7 @@ public:
|
||||||
new (ret) value_type(t1, t2, t3, t4, t5);
|
new (ret) value_type(t1, t2, t3, t4, t5);
|
||||||
CGAL_assertion(type(ret) == USED);
|
CGAL_assertion(type(ret) == USED);
|
||||||
++size_;
|
++size_;
|
||||||
|
time_stamper->set_time_stamp(ret);
|
||||||
return iterator(ret, 0);
|
return iterator(ret, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -426,6 +450,7 @@ public:
|
||||||
new (ret) value_type(t1, t2, t3, t4, t5, t6);
|
new (ret) value_type(t1, t2, t3, t4, t5, t6);
|
||||||
CGAL_assertion(type(ret) == USED);
|
CGAL_assertion(type(ret) == USED);
|
||||||
++size_;
|
++size_;
|
||||||
|
time_stamper->set_time_stamp(ret);
|
||||||
return iterator(ret, 0);
|
return iterator(ret, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -443,6 +468,7 @@ public:
|
||||||
new (ret) value_type(t1, t2, t3, t4, t5, t6, t7);
|
new (ret) value_type(t1, t2, t3, t4, t5, t6, t7);
|
||||||
CGAL_assertion(type(ret) == USED);
|
CGAL_assertion(type(ret) == USED);
|
||||||
++size_;
|
++size_;
|
||||||
|
time_stamper->set_time_stamp(ret);
|
||||||
return iterator(ret, 0);
|
return iterator(ret, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -460,6 +486,7 @@ public:
|
||||||
new (ret) value_type(t1, t2, t3, t4, t5, t6, t7, t8);
|
new (ret) value_type(t1, t2, t3, t4, t5, t6, t7, t8);
|
||||||
CGAL_assertion(type(ret) == USED);
|
CGAL_assertion(type(ret) == USED);
|
||||||
++size_;
|
++size_;
|
||||||
|
time_stamper->set_time_stamp(ret);
|
||||||
return iterator(ret, 0);
|
return iterator(ret, 0);
|
||||||
}
|
}
|
||||||
#endif // CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
|
#endif // CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
|
||||||
|
|
@ -474,6 +501,7 @@ public:
|
||||||
alloc.construct(ret, t);
|
alloc.construct(ret, t);
|
||||||
CGAL_assertion(type(ret) == USED);
|
CGAL_assertion(type(ret) == USED);
|
||||||
++size_;
|
++size_;
|
||||||
|
time_stamper->set_time_stamp(ret);
|
||||||
return iterator(ret, 0);
|
return iterator(ret, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -693,13 +721,14 @@ private:
|
||||||
|
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
block_size = Incr_policy::first_block_size;
|
block_size = Increment_policy::first_block_size;
|
||||||
capacity_ = 0;
|
capacity_ = 0;
|
||||||
size_ = 0;
|
size_ = 0;
|
||||||
free_list = NULL;
|
free_list = NULL;
|
||||||
first_item = NULL;
|
first_item = NULL;
|
||||||
last_item = NULL;
|
last_item = NULL;
|
||||||
all_items = All_items();
|
all_items = All_items();
|
||||||
|
time_stamper->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
allocator_type alloc;
|
allocator_type alloc;
|
||||||
|
|
@ -710,10 +739,14 @@ private:
|
||||||
pointer first_item;
|
pointer first_item;
|
||||||
pointer last_item;
|
pointer last_item;
|
||||||
All_items all_items;
|
All_items all_items;
|
||||||
|
|
||||||
|
// This is a pointer, so that the definition of Compact_container does
|
||||||
|
// not require a complete type `T`.
|
||||||
|
Time_stamper_impl* time_stamper;
|
||||||
};
|
};
|
||||||
|
|
||||||
template < class T, class Allocator, class Increment_policy >
|
template < class T, class Allocator, class Increment_policy, class TimeStamper >
|
||||||
void Compact_container<T, Allocator, Increment_policy>::merge(Self &d)
|
void Compact_container<T, Allocator, Increment_policy, TimeStamper>::merge(Self &d)
|
||||||
{
|
{
|
||||||
CGAL_precondition(&d != this);
|
CGAL_precondition(&d != this);
|
||||||
|
|
||||||
|
|
@ -749,8 +782,8 @@ void Compact_container<T, Allocator, Increment_policy>::merge(Self &d)
|
||||||
d.init();
|
d.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
template < class T, class Allocator, class Increment_policy >
|
template < class T, class Allocator, class Increment_policy, class TimeStamper >
|
||||||
void Compact_container<T, Allocator, Increment_policy>::clear()
|
void Compact_container<T, Allocator, Increment_policy, TimeStamper>::clear()
|
||||||
{
|
{
|
||||||
for (typename All_items::iterator it = all_items.begin(), itend = all_items.end();
|
for (typename All_items::iterator it = all_items.begin(), itend = all_items.end();
|
||||||
it != itend; ++it) {
|
it != itend; ++it) {
|
||||||
|
|
@ -765,8 +798,8 @@ void Compact_container<T, Allocator, Increment_policy>::clear()
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
template < class T, class Allocator, class Increment_policy >
|
template < class T, class Allocator, class Increment_policy, class TimeStamper >
|
||||||
void Compact_container<T, Allocator, Increment_policy>::allocate_new_block()
|
void Compact_container<T, Allocator, Increment_policy, TimeStamper>::allocate_new_block()
|
||||||
{
|
{
|
||||||
pointer new_block = alloc.allocate(block_size + 2);
|
pointer new_block = alloc.allocate(block_size + 2);
|
||||||
all_items.push_back(std::make_pair(new_block, block_size + 2));
|
all_items.push_back(std::make_pair(new_block, block_size + 2));
|
||||||
|
|
@ -794,52 +827,52 @@ void Compact_container<T, Allocator, Increment_policy>::allocate_new_block()
|
||||||
Increment_policy::increase_size(*this);
|
Increment_policy::increase_size(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < class T, class Allocator, class Increment_policy >
|
template < class T, class Allocator, class Increment_policy, class TimeStamper >
|
||||||
inline
|
inline
|
||||||
bool operator==(const Compact_container<T, Allocator, Increment_policy> &lhs,
|
bool operator==(const Compact_container<T, Allocator, Increment_policy, TimeStamper> &lhs,
|
||||||
const Compact_container<T, Allocator, Increment_policy> &rhs)
|
const Compact_container<T, Allocator, Increment_policy, TimeStamper> &rhs)
|
||||||
{
|
{
|
||||||
return lhs.size() == rhs.size() &&
|
return lhs.size() == rhs.size() &&
|
||||||
std::equal(lhs.begin(), lhs.end(), rhs.begin());
|
std::equal(lhs.begin(), lhs.end(), rhs.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
template < class T, class Allocator, class Increment_policy >
|
template < class T, class Allocator, class Increment_policy, class TimeStamper >
|
||||||
inline
|
inline
|
||||||
bool operator!=(const Compact_container<T, Allocator, Increment_policy> &lhs,
|
bool operator!=(const Compact_container<T, Allocator, Increment_policy, TimeStamper> &lhs,
|
||||||
const Compact_container<T, Allocator, Increment_policy> &rhs)
|
const Compact_container<T, Allocator, Increment_policy, TimeStamper> &rhs)
|
||||||
{
|
{
|
||||||
return ! (lhs == rhs);
|
return ! (lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < class T, class Allocator, class Increment_policy >
|
template < class T, class Allocator, class Increment_policy, class TimeStamper >
|
||||||
inline
|
inline
|
||||||
bool operator< (const Compact_container<T, Allocator, Increment_policy> &lhs,
|
bool operator< (const Compact_container<T, Allocator, Increment_policy, TimeStamper> &lhs,
|
||||||
const Compact_container<T, Allocator, Increment_policy> &rhs)
|
const Compact_container<T, Allocator, Increment_policy, TimeStamper> &rhs)
|
||||||
{
|
{
|
||||||
return std::lexicographical_compare(lhs.begin(), lhs.end(),
|
return std::lexicographical_compare(lhs.begin(), lhs.end(),
|
||||||
rhs.begin(), rhs.end());
|
rhs.begin(), rhs.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
template < class T, class Allocator, class Increment_policy >
|
template < class T, class Allocator, class Increment_policy, class TimeStamper >
|
||||||
inline
|
inline
|
||||||
bool operator> (const Compact_container<T, Allocator, Increment_policy> &lhs,
|
bool operator> (const Compact_container<T, Allocator, Increment_policy, TimeStamper> &lhs,
|
||||||
const Compact_container<T, Allocator, Increment_policy> &rhs)
|
const Compact_container<T, Allocator, Increment_policy, TimeStamper> &rhs)
|
||||||
{
|
{
|
||||||
return rhs < lhs;
|
return rhs < lhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < class T, class Allocator, class Increment_policy >
|
template < class T, class Allocator, class Increment_policy, class TimeStamper >
|
||||||
inline
|
inline
|
||||||
bool operator<=(const Compact_container<T, Allocator, Increment_policy> &lhs,
|
bool operator<=(const Compact_container<T, Allocator, Increment_policy, TimeStamper> &lhs,
|
||||||
const Compact_container<T, Allocator, Increment_policy> &rhs)
|
const Compact_container<T, Allocator, Increment_policy, TimeStamper> &rhs)
|
||||||
{
|
{
|
||||||
return ! (lhs > rhs);
|
return ! (lhs > rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < class T, class Allocator, class Increment_policy >
|
template < class T, class Allocator, class Increment_policy, class TimeStamper >
|
||||||
inline
|
inline
|
||||||
bool operator>=(const Compact_container<T, Allocator, Increment_policy> &lhs,
|
bool operator>=(const Compact_container<T, Allocator, Increment_policy, TimeStamper> &lhs,
|
||||||
const Compact_container<T, Allocator, Increment_policy> &rhs)
|
const Compact_container<T, Allocator, Increment_policy, TimeStamper> &rhs)
|
||||||
{
|
{
|
||||||
return ! (lhs < rhs);
|
return ! (lhs < rhs);
|
||||||
}
|
}
|
||||||
|
|
@ -890,14 +923,19 @@ namespace internal {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
typedef typename DSC::Time_stamper_impl Time_stamper_impl;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
pointer p;
|
pointer p;
|
||||||
void *vp;
|
void *vp;
|
||||||
} m_ptr;
|
} m_ptr;
|
||||||
|
|
||||||
// Only Compact_container should access these constructors.
|
// Only Compact_container should access these constructors.
|
||||||
friend class Compact_container<value_type, typename DSC::Al,
|
friend class Compact_container<value_type,
|
||||||
typename DSC::Incr_policy>;
|
typename DSC::Al,
|
||||||
|
typename DSC::Ip,
|
||||||
|
typename DSC::Ts>;
|
||||||
|
|
||||||
|
|
||||||
// For begin()
|
// For begin()
|
||||||
CC_iterator(pointer ptr, int, int)
|
CC_iterator(pointer ptr, int, int)
|
||||||
|
|
@ -991,22 +1029,24 @@ namespace internal {
|
||||||
// For std::less...
|
// For std::less...
|
||||||
bool operator<(const CC_iterator& other) const
|
bool operator<(const CC_iterator& other) const
|
||||||
{
|
{
|
||||||
return (m_ptr.p < other.m_ptr.p);
|
return Time_stamper_impl::less(m_ptr.p, other.m_ptr.p);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator>(const CC_iterator& other) const
|
bool operator>(const CC_iterator& other) const
|
||||||
{
|
{
|
||||||
return (m_ptr.p > other.m_ptr.p);
|
return Time_stamper_impl::less(other.m_ptr.p, m_ptr.p);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<=(const CC_iterator& other) const
|
bool operator<=(const CC_iterator& other) const
|
||||||
{
|
{
|
||||||
return (m_ptr.p <= other.m_ptr.p);
|
return Time_stamper_impl::less(m_ptr.p, other.m_ptr.p)
|
||||||
|
|| (*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator>=(const CC_iterator& other) const
|
bool operator>=(const CC_iterator& other) const
|
||||||
{
|
{
|
||||||
return (m_ptr.p >= other.m_ptr.p);
|
return Time_stamper_impl::less(other.m_ptr.p, m_ptr.p)
|
||||||
|
|| (*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can itself be used for bit-squatting.
|
// Can itself be used for bit-squatting.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
// Copyright (c) 2014 GeometryFactory Sarl (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.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Jane Tournois
|
||||||
|
|
||||||
|
#ifndef CGAL_HAS_TIMESTAMP_H
|
||||||
|
#define CGAL_HAS_TIMESTAMP_H
|
||||||
|
|
||||||
|
#include <boost/mpl/has_xxx.hpp>
|
||||||
|
#include <CGAL/tags.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
BOOST_MPL_HAS_XXX_TRAIT_DEF(Has_timestamp)
|
||||||
|
|
||||||
|
// Used by Compact container to make the comparison of iterator
|
||||||
|
// depending on the insertion order rather than the object address
|
||||||
|
// when the object class defines a Has_timestamp tag
|
||||||
|
// This is for example used in to make Mesh_3 deterministic, see
|
||||||
|
// classes implementing concepts MeshCellBase_3 and MeshVertexBase_3
|
||||||
|
template <typename T, bool has_ts = has_Has_timestamp<T>::value>
|
||||||
|
struct Has_timestamp : public T::Has_timestamp
|
||||||
|
// when T has a Has_timestamp tag
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Has_timestamp<T, false> : public Tag_false
|
||||||
|
// when T does not have a Has_timestamp tag
|
||||||
|
{};
|
||||||
|
|
||||||
|
} // end namespace internal
|
||||||
|
} // end namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_HAS_TIMESTAMP_H
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <CGAL/memory.h>
|
#include <CGAL/memory.h>
|
||||||
|
#include <CGAL/Time_stamper.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
|
|
@ -87,10 +88,10 @@ namespace internal {
|
||||||
|
|
||||||
bool operator==( const Self& x) const { return node == x.node; }
|
bool operator==( const Self& x) const { return node == x.node; }
|
||||||
bool operator!=( const Self& x) const { return node != x.node; }
|
bool operator!=( const Self& x) const { return node != x.node; }
|
||||||
bool operator< ( const Self& x) const { return node< x.node; }
|
bool operator< ( const Self& x) const { return Get_time_stamper<T>::type::less(node, x.node); }
|
||||||
bool operator<=( const Self& x) const { return node<= x.node; }
|
bool operator<=( const Self& x) const { return Get_time_stamper<T>::type::less(node, x.node) || node==x.node; }
|
||||||
bool operator> ( const Self& x) const { return node> x.node; }
|
bool operator> ( const Self& x) const { return Get_time_stamper<T>::type::less(x.node, node); }
|
||||||
bool operator>=( const Self& x) const { return node>= x.node; }
|
bool operator>=( const Self& x) const { return Get_time_stamper<T>::type::less(x.node, node) || node==x.node; }
|
||||||
T& operator*() const { return *node; }
|
T& operator*() const { return *node; }
|
||||||
T* operator->() const { return node; }
|
T* operator->() const { return node; }
|
||||||
Self& operator++() {
|
Self& operator++() {
|
||||||
|
|
@ -138,12 +139,12 @@ namespace internal {
|
||||||
In_place_list_const_iterator( Iterator i) : node(&*i) {}
|
In_place_list_const_iterator( Iterator i) : node(&*i) {}
|
||||||
In_place_list_const_iterator(const T* x) : node(x) {}
|
In_place_list_const_iterator(const T* x) : node(x) {}
|
||||||
|
|
||||||
bool operator==( const Self& x) const { return node == x.node; }
|
bool operator==( const Self& x) const { return node == x.node; }
|
||||||
bool operator!=( const Self& x) const { return node != x.node; }
|
bool operator!=( const Self& x) const { return node != x.node; }
|
||||||
bool operator< ( const Self& x) const { return node< x.node; }
|
bool operator< ( const Self& x) const { return Get_time_stamper<T>::type::less(node, x.node); }
|
||||||
bool operator<=( const Self& x) const { return node<= x.node; }
|
bool operator<=( const Self& x) const { return Get_time_stamper<T>::type::less(node, x.node) || node==x.node; }
|
||||||
bool operator> ( const Self& x) const { return node> x.node; }
|
bool operator> ( const Self& x) const { return Get_time_stamper<T>::type::less(x.node, node); }
|
||||||
bool operator>=( const Self& x) const { return node>= x.node; }
|
bool operator>=( const Self& x) const { return Get_time_stamper<T>::type::less(x.node, node) || node==x.node; }
|
||||||
const T& operator*() const { return *node; }
|
const T& operator*() const { return *node; }
|
||||||
const T* operator->() const { return node; }
|
const T* operator->() const { return node; }
|
||||||
Self& operator++() {
|
Self& operator++() {
|
||||||
|
|
@ -233,6 +234,7 @@ protected:
|
||||||
pointer node;
|
pointer node;
|
||||||
size_type length;
|
size_type length;
|
||||||
|
|
||||||
|
Time_stamper_impl<T>* time_stamper_ptr;
|
||||||
// These are the only places where the allocator gets called.
|
// These are the only places where the allocator gets called.
|
||||||
pointer get_node() {
|
pointer get_node() {
|
||||||
pointer p = allocator.allocate(1);
|
pointer p = allocator.allocate(1);
|
||||||
|
|
@ -265,8 +267,10 @@ public:
|
||||||
// CREATION
|
// CREATION
|
||||||
//
|
//
|
||||||
// New creation variable is: `l'
|
// New creation variable is: `l'
|
||||||
|
explicit In_place_list()
|
||||||
explicit In_place_list() : length(0) {
|
: length(0)
|
||||||
|
, time_stamper_ptr(new Time_stamper_impl<T>())
|
||||||
|
{
|
||||||
// introduces an empty list.
|
// introduces an empty list.
|
||||||
node = get_node();
|
node = get_node();
|
||||||
(*node).next_link = node;
|
(*node).next_link = node;
|
||||||
|
|
@ -314,6 +318,7 @@ public:
|
||||||
(*((*position.node).prev_link)).next_link = &x;
|
(*((*position.node).prev_link)).next_link = &x;
|
||||||
(*position.node).prev_link = &x;
|
(*position.node).prev_link = &x;
|
||||||
++length;
|
++length;
|
||||||
|
time_stamper_ptr->set_time_stamp(&x);
|
||||||
return &x;
|
return &x;
|
||||||
}
|
}
|
||||||
iterator insert(T* pos, T& x) {
|
iterator insert(T* pos, T& x) {
|
||||||
|
|
@ -385,11 +390,17 @@ public:
|
||||||
erase( iterator(first), iterator(last));
|
erase( iterator(first), iterator(last));
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() { erase( begin(), end()); }
|
void clear() {
|
||||||
|
erase( begin(), end());
|
||||||
|
time_stamper_ptr->reset();
|
||||||
|
}
|
||||||
|
|
||||||
// CREATION (Continued)
|
// CREATION (Continued)
|
||||||
|
|
||||||
explicit In_place_list(size_type n, const T& value = T()) : length(0) {
|
explicit In_place_list(size_type n, const T& value = T())
|
||||||
|
: length(0)
|
||||||
|
, time_stamper_ptr(new Time_stamper_impl<T>())
|
||||||
|
{
|
||||||
// introduces a list with n items, all initialized with copies of
|
// introduces a list with n items, all initialized with copies of
|
||||||
// value.
|
// value.
|
||||||
node = get_node();
|
node = get_node();
|
||||||
|
|
@ -399,7 +410,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class InputIterator>
|
template <class InputIterator>
|
||||||
In_place_list( InputIterator first, InputIterator last) : length(0) {
|
In_place_list( InputIterator first, InputIterator last)
|
||||||
|
: length(0)
|
||||||
|
, time_stamper_ptr(new Time_stamper_impl<T>())
|
||||||
|
{
|
||||||
// a list with copies from the range [`first,last').
|
// a list with copies from the range [`first,last').
|
||||||
node = get_node();
|
node = get_node();
|
||||||
(*node).next_link = node;
|
(*node).next_link = node;
|
||||||
|
|
@ -407,14 +421,21 @@ public:
|
||||||
insert( begin(), first, last);
|
insert( begin(), first, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
In_place_list(const T* first, const T* last) : length(0) {
|
In_place_list(const T* first, const T* last)
|
||||||
|
: length(0)
|
||||||
|
, time_stamper_ptr(new Time_stamper_impl<T>())
|
||||||
|
{
|
||||||
// a list with copies from the range [`first,last').
|
// a list with copies from the range [`first,last').
|
||||||
node = get_node();
|
node = get_node();
|
||||||
(*node).next_link = node;
|
(*node).next_link = node;
|
||||||
(*node).prev_link = node;
|
(*node).prev_link = node;
|
||||||
insert(begin(), first, last);
|
insert(begin(), first, last);
|
||||||
}
|
}
|
||||||
In_place_list(const Self& x) : length(0) {
|
|
||||||
|
In_place_list(const Self& x)
|
||||||
|
: length(0)
|
||||||
|
, time_stamper_ptr(new Time_stamper_impl<T>())
|
||||||
|
{
|
||||||
// copy constructor. Each item in `l1' is copied.
|
// copy constructor. Each item in `l1' is copied.
|
||||||
node = get_node();
|
node = get_node();
|
||||||
(*node).next_link = node;
|
(*node).next_link = node;
|
||||||
|
|
@ -424,6 +445,7 @@ public:
|
||||||
~In_place_list() {
|
~In_place_list() {
|
||||||
erase(begin(), end());
|
erase(begin(), end());
|
||||||
put_node(node);
|
put_node(node);
|
||||||
|
delete time_stamper_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Self& operator=(const Self& x);
|
Self& operator=(const Self& x);
|
||||||
|
|
@ -486,6 +508,8 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void splice(iterator position, Self& x) {
|
void splice(iterator position, Self& x) {
|
||||||
|
// make sure splice is not called if time stamps are used
|
||||||
|
CGAL_static_assertion( !internal::Has_timestamp<T>::value );
|
||||||
// inserts the list x before position `pos' and x becomes empty.
|
// inserts the list x before position `pos' and x becomes empty.
|
||||||
// It takes constant time. Precondition: `&l != &x'.
|
// It takes constant time. Precondition: `&l != &x'.
|
||||||
if (!x.empty()) {
|
if (!x.empty()) {
|
||||||
|
|
@ -498,6 +522,8 @@ public:
|
||||||
splice( iterator(position), x);
|
splice( iterator(position), x);
|
||||||
}
|
}
|
||||||
void splice( iterator position, Self& x, iterator i) {
|
void splice( iterator position, Self& x, iterator i) {
|
||||||
|
// make sure splice is not called if time stamps are used
|
||||||
|
CGAL_static_assertion( !internal::Has_timestamp<T>::value );
|
||||||
// inserts an element pointed to by i from list x before position
|
// inserts an element pointed to by i from list x before position
|
||||||
// `pos' and removes the element from x. It takes constant time. i
|
// `pos' and removes the element from x. It takes constant time. i
|
||||||
// is a valid dereferenceable iterator of x. The result is
|
// is a valid dereferenceable iterator of x. The result is
|
||||||
|
|
@ -512,6 +538,8 @@ public:
|
||||||
splice( iterator(position), x, iterator(i));
|
splice( iterator(position), x, iterator(i));
|
||||||
}
|
}
|
||||||
void splice(iterator pos, Self& x, iterator first, iterator last) {
|
void splice(iterator pos, Self& x, iterator first, iterator last) {
|
||||||
|
// make sure splice is not called if time stamps are used
|
||||||
|
CGAL_static_assertion( !internal::Has_timestamp<T>::value );
|
||||||
// inserts elements in the range [`first, last') before position
|
// inserts elements in the range [`first, last') before position
|
||||||
// `pos' and removes the elements from x. It takes constant time
|
// `pos' and removes the elements from x. It takes constant time
|
||||||
// if `&x == $l'; otherwise, it takes linear time. [`first,
|
// if `&x == $l'; otherwise, it takes linear time. [`first,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
// Copyright (c) 2014 GeometryFactory Sarl (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.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Jane Tournois
|
||||||
|
|
||||||
|
#include <CGAL/Has_timestamp.h>
|
||||||
|
|
||||||
|
#ifndef CGAL_TIME_STAMPER_H
|
||||||
|
#define CGAL_TIME_STAMPER_H
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Time_stamper
|
||||||
|
{
|
||||||
|
Time_stamper()
|
||||||
|
: time_stamp_(0) {}
|
||||||
|
|
||||||
|
Time_stamper(const Time_stamper& ts)
|
||||||
|
: time_stamp_(ts.time_stamp_) {}
|
||||||
|
|
||||||
|
void set_time_stamp(T* pt) {
|
||||||
|
pt->set_time_stamp(time_stamp_++);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool less(T* p_t1, T* p_t2) {
|
||||||
|
if(p_t1 == NULL) return (p_t2 != NULL);
|
||||||
|
else if(p_t2 == NULL) return false;
|
||||||
|
else return p_t1->time_stamp() < p_t2->time_stamp();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
time_stamp_ = 0;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::size_t time_stamp_;
|
||||||
|
}; // end class template Time_stamper<T>
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct No_time_stamp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void set_time_stamp(T*) {}
|
||||||
|
static bool less(T* p_t1, T* p_t2) {
|
||||||
|
return p_t1 < p_t2;
|
||||||
|
}
|
||||||
|
void reset() {}
|
||||||
|
}; // end class template No_time_stamp<T>
|
||||||
|
|
||||||
|
// That class template is an auxiliary class. It has a
|
||||||
|
// specialization for the case where `T::Has_timestamp` does not exists.
|
||||||
|
// The non-specialized template, when `T::Has_timestamp` exists, derives
|
||||||
|
// from `Time_stamper<T>` or `No_time_stamp<T>` depending on the
|
||||||
|
// value of the Boolean constant `T::Has_timestamp`.
|
||||||
|
// The declaration of that class template requires `T` to be a complete type.
|
||||||
|
template <class T, bool has_timestamp = internal::Has_timestamp<T>::value>
|
||||||
|
struct Get_time_stamper{
|
||||||
|
typedef Time_stamper<T> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialization when `T::Has_timestamp` does not exist, derives from
|
||||||
|
// `TimeStamper_`, or from `No_time_stamp<T>`.
|
||||||
|
template <class T>
|
||||||
|
struct Get_time_stamper<T,false>{
|
||||||
|
typedef No_time_stamp<T> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Implementation of the timestamp policy. It is very important that the
|
||||||
|
// declaration of that class template does not require `T` to be a complete
|
||||||
|
// type. That way, the declaration of a pointer of type `Time_stamper_impl<T, Ts>
|
||||||
|
// in `Compact_container` for example is possible with an incomplete type.
|
||||||
|
template <class T>
|
||||||
|
struct Time_stamper_impl : public Get_time_stamper<T>::type {};
|
||||||
|
|
||||||
|
} //end of namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_TIME_STAMPER_H
|
||||||
|
|
@ -9,15 +9,32 @@
|
||||||
#include <CGAL/Random.h>
|
#include <CGAL/Random.h>
|
||||||
#include <CGAL/Testsuite/use.h>
|
#include <CGAL/Testsuite/use.h>
|
||||||
|
|
||||||
|
#include <CGAL/tags.h>
|
||||||
#include <CGAL/use.h>
|
#include <CGAL/use.h>
|
||||||
|
#include <CGAL/assertions.h>
|
||||||
|
|
||||||
|
#include <boost/type_traits/is_base_of.hpp>
|
||||||
|
|
||||||
|
template <typename Has_timestamp_ = CGAL::Tag_true>
|
||||||
struct Node_1
|
struct Node_1
|
||||||
: public CGAL::Compact_container_base
|
: public CGAL::Compact_container_base
|
||||||
{
|
{
|
||||||
bool operator==(const Node_1 &) const { return true; }
|
bool operator==(const Node_1 &) const { return true; }
|
||||||
bool operator!=(const Node_1 &) const { return false; }
|
bool operator!=(const Node_1 &) const { return false; }
|
||||||
bool operator< (const Node_1 &) const { return false; }
|
bool operator< (const Node_1 &) const { return false; }
|
||||||
|
|
||||||
|
/// For the determinism of Compact_container iterators
|
||||||
|
///@{
|
||||||
|
typedef Has_timestamp_ Has_timestamp;
|
||||||
|
|
||||||
|
std::size_t time_stamp() const {
|
||||||
|
return time_stamp_;
|
||||||
|
}
|
||||||
|
void set_time_stamp(const std::size_t& ts) {
|
||||||
|
time_stamp_ = ts;
|
||||||
|
}
|
||||||
|
///@}
|
||||||
|
std::size_t time_stamp_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Node_2
|
class Node_2
|
||||||
|
|
@ -241,19 +258,62 @@ void test_index(const Cont &C)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Incomplete_struct;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
CGAL::Compact_container<Node_1> C1;
|
|
||||||
CGAL::Compact_container<Node_2> C2;
|
|
||||||
test(C1);
|
|
||||||
test(C2);
|
|
||||||
|
|
||||||
CGAL::Compact_container<Node_2, CGAL::Default, CGAL::Constant_size_policy<1024> > C3;
|
typedef Node_1<CGAL::Tag_true > T1;
|
||||||
CGAL::Compact_container<Node_2, CGAL::Default, CGAL::Addition_size_policy<14,16> > C4;
|
typedef CGAL::Compact_container<T1> C1; // with timestamps
|
||||||
|
|
||||||
test_index(C3);
|
typedef Node_1<CGAL::Tag_false> T2;
|
||||||
test_index(C4);
|
typedef CGAL::Compact_container<T2> C2; // without timestamps
|
||||||
|
|
||||||
|
typedef CGAL::Compact_container<T2,
|
||||||
|
CGAL::Default,
|
||||||
|
CGAL::Default,
|
||||||
|
CGAL::Time_stamper<T2> > C4;
|
||||||
|
// with timestamps
|
||||||
|
|
||||||
|
typedef Node_2 T3;
|
||||||
|
typedef CGAL::Compact_container<T3> C3; // without timestamps
|
||||||
|
|
||||||
|
C1 c1; test(c1);
|
||||||
|
C2 c2; test(c2);
|
||||||
|
C3 c3; test(c3);
|
||||||
|
C4 c4; test(c4);
|
||||||
|
|
||||||
|
// Check the time stamper policies
|
||||||
|
if(! boost::is_base_of<CGAL::Time_stamper<T1>,
|
||||||
|
C1::Time_stamper_impl>::value)
|
||||||
|
{
|
||||||
|
std::cerr << "Error timestamper of C1\n"; return 1;
|
||||||
|
}
|
||||||
|
if(! boost::is_base_of<CGAL::No_time_stamp<T2>,
|
||||||
|
C2::Time_stamper_impl>::value)
|
||||||
|
{
|
||||||
|
std::cerr << "Error timestamper of C2\n"; return 1;
|
||||||
|
}
|
||||||
|
if(! boost::is_base_of<CGAL::No_time_stamp<T3>,
|
||||||
|
C3::Time_stamper_impl>::value)
|
||||||
|
{
|
||||||
|
std::cerr << "Error timestamper of C3\n"; return 1;
|
||||||
|
}
|
||||||
|
if(! boost::is_base_of<CGAL::Time_stamper<T2>,
|
||||||
|
C4::Time_stamper_impl>::value)
|
||||||
|
{
|
||||||
|
std::cerr << "Error timestamper of C4\n"; return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that Compact_container does not require a complete type.
|
||||||
|
CGAL_static_assertion(sizeof(CGAL::Compact_container<Incomplete_struct>) > 0);
|
||||||
|
|
||||||
|
// Test increment policy
|
||||||
|
CGAL::Compact_container<Node_2, CGAL::Default, CGAL::Constant_size_policy<1024> > C5;
|
||||||
|
CGAL::Compact_container<Node_2, CGAL::Default, CGAL::Addition_size_policy<14,16> > C6;
|
||||||
|
|
||||||
|
test_index(C5);
|
||||||
|
test_index(C6);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// EOF //
|
// EOF //
|
||||||
|
|
|
||||||
|
|
@ -3300,11 +3300,11 @@ void
|
||||||
Triangulation_3<Gt,Tds>::
|
Triangulation_3<Gt,Tds>::
|
||||||
make_canonical(Vertex_triple& t) const
|
make_canonical(Vertex_triple& t) const
|
||||||
{
|
{
|
||||||
int i = (&*(t.first) < &*(t.second))? 0 : 1;
|
int i = (t.first < t.second) ? 0 : 1;
|
||||||
if(i==0) {
|
if(i==0) {
|
||||||
i = (&*(t.first) < &*(t.third))? 0 : 2;
|
i = (t.first < t.third) ? 0 : 2;
|
||||||
} else {
|
} else {
|
||||||
i = (&*(t.second) < &*(t.third))? 1 : 2;
|
i = (t.second < t.third) ? 1 : 2;
|
||||||
}
|
}
|
||||||
Vertex_handle tmp;
|
Vertex_handle tmp;
|
||||||
switch(i){
|
switch(i){
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue