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/Mesh_triangulation_3.h>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ FT sphere_function (const Point& p)
|
|||
int main()
|
||||
{
|
||||
// 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 criteria(facet_angle=30, facet_size=0.1, facet_distance=0.025,
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ FT sphere_function (const Point& p)
|
|||
int main()
|
||||
{
|
||||
// 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
|
||||
Spherical_sizing_field size;
|
||||
|
|
|
|||
|
|
@ -53,7 +53,8 @@ FT sphere_function (const Point& p)
|
|||
int main()
|
||||
{
|
||||
// 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 criteria(edge_size = 0.15,
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
#include <CGAL/basic.h>
|
||||
#include <CGAL/triangulation_assertions.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/Mesh_3/io_signature.h>
|
||||
|
|
@ -89,13 +91,13 @@ public:
|
|||
, next_intrusive_()
|
||||
, previous_intrusive_()
|
||||
#endif
|
||||
, time_stamp_(-1)
|
||||
, surface_center_index_table_()
|
||||
, sliver_value_(FT(0.))
|
||||
, subdomain_index_()
|
||||
, bits_(0)
|
||||
, sliver_cache_validity_(false)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
Compact_mesh_cell_base_3(const Compact_mesh_cell_base_3& rhs)
|
||||
: circumcenter_(NULL)
|
||||
|
|
@ -103,6 +105,7 @@ public:
|
|||
, next_intrusive_(rhs.next_intrusive_)
|
||||
, previous_intrusive_(rhs.previous_intrusive_)
|
||||
#endif
|
||||
, time_stamp_(rhs.time_stamp_)
|
||||
, sliver_value_(rhs.sliver_value_)
|
||||
, subdomain_index_(rhs.subdomain_index_)
|
||||
, bits_(0)
|
||||
|
|
@ -126,6 +129,7 @@ public:
|
|||
, next_intrusive_()
|
||||
, previous_intrusive_()
|
||||
#endif
|
||||
, time_stamp_(-1)
|
||||
, surface_center_index_table_()
|
||||
, sliver_value_(FT(0.))
|
||||
, subdomain_index_()
|
||||
|
|
@ -151,6 +155,7 @@ public:
|
|||
, next_intrusive_()
|
||||
, previous_intrusive_()
|
||||
#endif
|
||||
, time_stamp_(-1)
|
||||
, surface_center_index_table_()
|
||||
, sliver_value_(FT(0.))
|
||||
, subdomain_index_()
|
||||
|
|
@ -458,6 +463,17 @@ public:
|
|||
}
|
||||
#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:
|
||||
|
||||
|
|
@ -476,6 +492,7 @@ private:
|
|||
#ifdef CGAL_INTRUSIVE_LIST
|
||||
Cell_handle next_intrusive_, previous_intrusive_;
|
||||
#endif
|
||||
std::size_t time_stamp_;
|
||||
|
||||
CGAL::cpp11::array<Index, 4> surface_center_index_table_;
|
||||
/// Stores visited facets (4 first bits)
|
||||
|
|
@ -494,8 +511,6 @@ private:
|
|||
|
||||
}; // end class Compact_mesh_cell_base_3
|
||||
|
||||
|
||||
|
||||
template < class GT, class MT, class Cb >
|
||||
std::istream&
|
||||
operator>>(std::istream &is,
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
# pragma warning(disable:4180) // qualifier applied to function type has no meaning; ignored
|
||||
#endif
|
||||
|
||||
#include <CGAL/Random.h>
|
||||
#include <CGAL/Mesh_3/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h>
|
||||
|
||||
|
|
@ -47,7 +48,7 @@ template<class Function,
|
|||
class BGT,
|
||||
class Wrapper = Mesh_3::Implicit_to_labeled_function_wrapper<Function,BGT> >
|
||||
class Implicit_mesh_domain_3
|
||||
: public Mesh_3::Labeled_mesh_domain_3<Wrapper, BGT >
|
||||
: public Mesh_3::Labeled_mesh_domain_3<Wrapper, BGT>
|
||||
{
|
||||
public:
|
||||
/// Base type
|
||||
|
|
@ -66,8 +67,9 @@ public:
|
|||
*/
|
||||
Implicit_mesh_domain_3(const Function& f,
|
||||
const Sphere_3& bounding_sphere,
|
||||
const FT& error_bound = FT(1e-3))
|
||||
: Base(Wrapper(f), bounding_sphere, error_bound) {}
|
||||
const FT& error_bound = FT(1e-3),
|
||||
CGAL::Random* p_rng = NULL)
|
||||
: Base(Wrapper(f), bounding_sphere, error_bound, p_rng) {}
|
||||
|
||||
/// Destructor
|
||||
virtual ~Implicit_mesh_domain_3() {}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#ifndef 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/Image_to_labeled_function_wrapper.h>
|
||||
|
||||
|
|
@ -41,6 +41,7 @@ namespace CGAL {
|
|||
*/
|
||||
template<class Image,
|
||||
class BGT,
|
||||
|
||||
class Wrapper = Mesh_3::Image_to_labeled_function_wrapper<Image, BGT> >
|
||||
class Labeled_image_mesh_domain_3
|
||||
: public Mesh_3::Labeled_mesh_domain_3<Wrapper, BGT>
|
||||
|
|
@ -55,10 +56,12 @@ public:
|
|||
|
||||
/// Constructor
|
||||
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),
|
||||
compute_bounding_box(image),
|
||||
error_bound)
|
||||
error_bound,
|
||||
p_rng)
|
||||
{}
|
||||
|
||||
/// Destructor
|
||||
|
|
|
|||
|
|
@ -55,8 +55,8 @@ public:
|
|||
typedef typename Polyhedron::Facet Facet;
|
||||
typedef typename Facet::Patch_id Patch_id;
|
||||
|
||||
typedef std::set<Facet*> Facet_handle_set;
|
||||
typedef std::set<Halfedge*> He_handle_set;
|
||||
typedef std::set<Facet_handle> Facet_handle_set;
|
||||
typedef std::set<Halfedge_handle> He_handle_set;
|
||||
|
||||
public:
|
||||
Detect_features_in_polyhedra() : current_surface_index_(1) {}
|
||||
|
|
@ -69,7 +69,7 @@ public:
|
|||
private:
|
||||
Vector_3 facet_normal(const Facet_handle& f) 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;
|
||||
|
||||
template <typename Int>
|
||||
|
|
@ -143,18 +143,19 @@ detect_surface_patches(Polyhedron& polyhedron)
|
|||
for ( typename Polyhedron::Facet_iterator fit = polyhedron.facets_begin(),
|
||||
end = polyhedron.facets_end() ; fit != end ; ++fit )
|
||||
{
|
||||
unsorted_faces.insert(&*fit);
|
||||
Facet_handle fh = fit;
|
||||
unsorted_faces.insert(fh);
|
||||
}
|
||||
|
||||
// Flood
|
||||
while ( ! unsorted_faces.empty() )
|
||||
{
|
||||
Facet& f = **(unsorted_faces.begin());
|
||||
Facet_handle f = *(unsorted_faces.begin());
|
||||
unsorted_faces.erase(unsorted_faces.begin());
|
||||
|
||||
const Patch_id patch_id = generate_patch_id(Patch_id(),
|
||||
current_surface_index_);
|
||||
f.set_patch_id(patch_id);
|
||||
f->set_patch_id(patch_id);
|
||||
flood(f,patch_id,unsorted_faces);
|
||||
++current_surface_index_;
|
||||
}
|
||||
|
|
@ -245,52 +246,52 @@ is_sharp(const Halfedge_handle& he, FT cos_angle) const
|
|||
template <typename P_>
|
||||
void
|
||||
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;
|
||||
|
||||
Facet_he_circ begin = f.facet_begin();
|
||||
Facet_he_circ begin = f->facet_begin();
|
||||
Facet_he_circ done = begin;
|
||||
|
||||
// Initialize he_to_explore with halfedges of the starting facet
|
||||
He_handle_set he_to_explore;
|
||||
CGAL_For_all(begin,done)
|
||||
{
|
||||
he_to_explore.insert(&*(begin->opposite()));
|
||||
he_to_explore.insert(begin->opposite());
|
||||
}
|
||||
|
||||
// While there is something to explore
|
||||
while ( ! he_to_explore.empty() )
|
||||
{
|
||||
// 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());
|
||||
|
||||
// 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
|
||||
explored_facet.set_patch_id(patch_id);
|
||||
unsorted_faces.erase(&explored_facet);
|
||||
explored_facet->set_patch_id(patch_id);
|
||||
unsorted_faces.erase(explored_facet);
|
||||
|
||||
// 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;
|
||||
|
||||
CGAL_For_all(he_begin,he_done)
|
||||
{
|
||||
Halfedge& current_he = *he_begin;
|
||||
Halfedge_handle current_he = he_begin;
|
||||
|
||||
// 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
|
||||
// (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
|
||||
|
||||
#include <CGAL/Mesh_3/Detect_polylines_in_polyhedra_fwd.h>
|
||||
#include <CGAL/Has_timestamp.h>
|
||||
#include <CGAL/Default.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
namespace CGAL { namespace Mesh_3 {
|
||||
|
||||
struct Detect_polyline_less {
|
||||
template <typename Handle>
|
||||
bool operator()(const Handle& va, const Handle& vb) const {
|
||||
return &*va < &*vb;
|
||||
template <typename Handle>
|
||||
struct CGAL_with_time_stamp
|
||||
{
|
||||
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 <CGAL/tuple.h>
|
||||
#include <CGAL/Origin.h>
|
||||
#include <CGAL/Random.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
|
@ -55,7 +56,8 @@ namespace Mesh_3 {
|
|||
* tags of it's incident subdomain.
|
||||
* Thus, a boundary facet of the domain is labelled <0,b>, where b!=0.
|
||||
*/
|
||||
template<class Function, class BGT>
|
||||
template<class Function,
|
||||
class BGT>
|
||||
class Labeled_mesh_domain_3
|
||||
{
|
||||
public:
|
||||
|
|
@ -94,14 +96,20 @@ public:
|
|||
*/
|
||||
Labeled_mesh_domain_3(const Function& f,
|
||||
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,
|
||||
const Bbox_3& bbox,
|
||||
const FT& error_bound = FT(1e-3));
|
||||
const FT& error_bound = FT(1e-3),
|
||||
CGAL::Random* p_rng = NULL);
|
||||
|
||||
/// 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
|
||||
|
|
@ -461,6 +469,9 @@ private:
|
|||
const Function function_;
|
||||
/// The bounding box
|
||||
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
|
||||
FT squared_error_bound_;
|
||||
|
||||
|
|
@ -483,24 +494,40 @@ template<class F, class BGT>
|
|||
Labeled_mesh_domain_3<F,BGT>::Labeled_mesh_domain_3(
|
||||
const F& f,
|
||||
const Sphere_3& bounding_sphere,
|
||||
const FT& error_bound )
|
||||
const FT& error_bound,
|
||||
CGAL::Random* p_rng)
|
||||
: function_(f)
|
||||
, bbox_(iso_cuboid(bounding_sphere.bbox()))
|
||||
, p_rng_(p_rng)
|
||||
, delete_rng_(false)
|
||||
, squared_error_bound_(squared_error_bound(bounding_sphere,error_bound))
|
||||
{
|
||||
// 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>
|
||||
Labeled_mesh_domain_3<F,BGT>::Labeled_mesh_domain_3(
|
||||
const F& f,
|
||||
const Bbox_3& bbox,
|
||||
const FT& error_bound )
|
||||
const FT& error_bound,
|
||||
CGAL::Random* p_rng)
|
||||
: function_(f)
|
||||
, bbox_(iso_cuboid(bbox))
|
||||
, p_rng_(p_rng)
|
||||
, delete_rng_(false)
|
||||
, squared_error_bound_(squared_error_bound(bbox_,error_bound))
|
||||
{
|
||||
// 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));
|
||||
|
||||
Random_points_on_sphere_3 random_point_on_sphere(radius);
|
||||
Random_points_in_sphere_3 random_point_in_sphere(radius);
|
||||
CGAL::Random& rng = *(r_domain_.p_rng_);
|
||||
Random_points_on_sphere_3 random_point_on_sphere(radius, rng);
|
||||
Random_points_in_sphere_3 random_point_in_sphere(radius, rng);
|
||||
|
||||
// Get some functors
|
||||
typename BGT::Construct_segment_3 segment_3 =
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ public:
|
|||
Index index(const Vertex_handle& v) const { return v->index(); }
|
||||
|
||||
/// Outputs the mesh to medit
|
||||
void output_to_medit(std::ofstream& os,
|
||||
void output_to_medit(std::ostream& os,
|
||||
bool rebind = true,
|
||||
bool show_patches = false) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -918,6 +918,9 @@ insert_balls(const Vertex_handle& vp,
|
|||
std::cerr << "Number of to-be-inserted balls is: "
|
||||
<< n << "\n between points ("
|
||||
<< vp->point() << ") and (" << vq->point()
|
||||
<< ") (geodesic distance: "
|
||||
<< domain_.geodesic_distance(vp->point(), vq->point(),
|
||||
curve_index)
|
||||
<< ")\n";
|
||||
#endif
|
||||
const Bare_point new_point =
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#include <CGAL/Timer.h>
|
||||
#include <CGAL/Mesh_3/Null_perturber_visitor.h>
|
||||
#include <CGAL/Mesh_3/sliver_criteria.h>
|
||||
#include <CGAL/Has_timestamp.h>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
#ifdef CGAL_MESH_3_USE_RELAXED_HEAP
|
||||
|
|
@ -61,8 +62,31 @@
|
|||
|
||||
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 {
|
||||
|
||||
|
||||
template < typename C3T3,
|
||||
typename MeshDomain,
|
||||
typename SliverCriterion = Mesh_3::Min_dihedral_angle_criterion
|
||||
|
|
@ -250,14 +274,6 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
struct VHash
|
||||
{
|
||||
std::size_t operator()(Vertex_handle vh) const
|
||||
{
|
||||
return boost::hash_value(&*vh);
|
||||
}
|
||||
};
|
||||
|
||||
// -----------------------------------
|
||||
// Private methods
|
||||
// -----------------------------------
|
||||
|
|
@ -651,7 +667,12 @@ build_priority_queue(const FT& sliver_bound, PQueue& pqueue) const
|
|||
|
||||
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;
|
||||
for ( typename Tr::Finite_cells_iterator cit = tr_.finite_cells_begin();
|
||||
cit != tr_.finite_cells_end() ;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#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/io_signature.h>
|
||||
#include <CGAL/tags.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
|
@ -83,6 +84,7 @@ public:
|
|||
, next_intrusive_()
|
||||
, previous_intrusive_()
|
||||
#endif
|
||||
, time_stamp_(-1)
|
||||
{}
|
||||
|
||||
Mesh_cell_base_3 (Vertex_handle v0,
|
||||
|
|
@ -97,6 +99,7 @@ public:
|
|||
, next_intrusive_()
|
||||
, previous_intrusive_()
|
||||
#endif
|
||||
, time_stamp_(-1)
|
||||
{}
|
||||
|
||||
Mesh_cell_base_3 (Vertex_handle v0,
|
||||
|
|
@ -115,6 +118,7 @@ public:
|
|||
, next_intrusive_()
|
||||
, previous_intrusive_()
|
||||
#endif
|
||||
, time_stamp_(-1)
|
||||
{}
|
||||
|
||||
// Default copy constructor and assignment operator are ok
|
||||
|
|
@ -157,7 +161,19 @@ public:
|
|||
previous_intrusive_ = c;
|
||||
}
|
||||
#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:
|
||||
// The index of the cell of the input complex that contains me
|
||||
Subdomain_index subdomain_index_;
|
||||
|
|
@ -168,11 +184,10 @@ private:
|
|||
#ifdef CGAL_INTRUSIVE_LIST
|
||||
Cell_handle next_intrusive_, previous_intrusive_;
|
||||
#endif
|
||||
std::size_t time_stamp_;
|
||||
|
||||
}; // end class Mesh_cell_base_3
|
||||
|
||||
|
||||
|
||||
template < class GT, class MT, class Cb >
|
||||
std::istream&
|
||||
operator>>(std::istream &is,
|
||||
|
|
|
|||
|
|
@ -54,13 +54,13 @@ class Polyline
|
|||
typedef typename Kernel::FT FT;
|
||||
|
||||
typedef std::vector<Point_3> Data;
|
||||
|
||||
|
||||
public:
|
||||
typedef typename Data::const_iterator const_iterator;
|
||||
|
||||
|
||||
Polyline() {}
|
||||
~Polyline() {}
|
||||
|
||||
|
||||
/// Add a point at the end of the polyline
|
||||
void add_point(const Point_3& p)
|
||||
{
|
||||
|
|
@ -68,33 +68,33 @@ public:
|
|||
points_.push_back(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Returns the starting point of the polyline
|
||||
const Point_3& start_point() const
|
||||
{
|
||||
CGAL_assertion( ! points_.empty() );
|
||||
return points_.front();
|
||||
}
|
||||
|
||||
|
||||
/// Returns the ending point of the polyline
|
||||
const Point_3& end_point() const
|
||||
{
|
||||
CGAL_assertion( ! points_.empty() );
|
||||
return points_.back();
|
||||
return points_.back();
|
||||
}
|
||||
|
||||
|
||||
/// Returns true if the polyline is not degenerated
|
||||
bool is_valid() const
|
||||
{
|
||||
return points_.size() > 1;
|
||||
}
|
||||
|
||||
|
||||
/// Returns true if polyline is a cycle
|
||||
bool is_cycle() const
|
||||
{
|
||||
return start_point() == end_point();
|
||||
}
|
||||
|
||||
|
||||
/// Returns the length of the polyline
|
||||
FT length() const
|
||||
{
|
||||
|
|
@ -102,29 +102,29 @@ public:
|
|||
FT result (0);
|
||||
const_iterator it = points_.begin();
|
||||
const_iterator previous = it++;
|
||||
|
||||
|
||||
for ( const_iterator end = points_.end() ; it != end ; ++it, ++previous )
|
||||
{
|
||||
result += distance(*previous,*it);
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// Returns signed geodesic distance between \c p and \c q
|
||||
FT geodesic_distance(const Point_3& p, const Point_3& q,
|
||||
bool /*treat_cycle*/=true) const
|
||||
{
|
||||
CGAL_precondition(is_valid());
|
||||
|
||||
|
||||
// Locate p & q on polyline
|
||||
const_iterator pit = locate(p);
|
||||
const_iterator qit = locate(q,false);
|
||||
|
||||
|
||||
// Compute geodesic distance
|
||||
FT result = (pit <= qit) ? geodesic_distance(p,q,pit,qit)
|
||||
: -geodesic_distance(q,p,qit,pit);
|
||||
|
||||
|
||||
// Treat cycles: return a positive value
|
||||
if ( is_cycle() && (p==q || result < FT(0)) )
|
||||
{
|
||||
|
|
@ -133,8 +133,8 @@ public:
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// Returns a point at geodesic distance \c distance from p along the
|
||||
/// polyline. The polyline is oriented from starting point to end point.
|
||||
/// The distance could be negative.
|
||||
|
|
@ -142,108 +142,108 @@ public:
|
|||
{
|
||||
// use first point of the polyline instead of p
|
||||
distance += geodesic_distance(start_point(),p,false);
|
||||
|
||||
|
||||
// If polyline is a cycle, ensure that distance is given from start_point()
|
||||
if ( is_cycle() )
|
||||
{
|
||||
if ( distance < FT(0) ) { distance += length(); }
|
||||
else if ( distance > length() ) { distance -= length(); }
|
||||
}
|
||||
|
||||
CGAL_assertion( distance > FT(0) );
|
||||
CGAL_assertion( distance < length() );
|
||||
|
||||
|
||||
CGAL_assertion( distance >= FT(0) );
|
||||
CGAL_assertion( distance <= length() );
|
||||
|
||||
// Initialize iterators
|
||||
const_iterator pit = points_.begin();
|
||||
const_iterator previous = pit++;
|
||||
|
||||
|
||||
// Iterate to find which segment contains the point we want to construct
|
||||
FT segment_length = this->distance(*previous,*pit);
|
||||
while ( distance > segment_length )
|
||||
{
|
||||
distance -= segment_length;
|
||||
|
||||
|
||||
// Increment iterators and update length
|
||||
++previous;
|
||||
++pit;
|
||||
CGAL_assertion(pit != points_.end());
|
||||
|
||||
|
||||
segment_length = this->distance(*previous,*pit);
|
||||
}
|
||||
|
||||
|
||||
// return point at distance from current segment source
|
||||
typedef typename Kernel::Vector_3 Vector_3;
|
||||
Vector_3 v (*previous, *pit);
|
||||
|
||||
|
||||
return (*previous) + (distance / CGAL::sqrt(v.squared_length())) * v;
|
||||
}
|
||||
|
||||
|
||||
bool are_ordered_along(const Point_3& p, const Point_3& q) const
|
||||
{
|
||||
CGAL_precondition(!is_cycle());
|
||||
|
||||
|
||||
// Locate p & q on polyline
|
||||
const_iterator pit = locate(p);
|
||||
const_iterator qit = locate(q,true);
|
||||
|
||||
|
||||
// Points are not located on the same segment
|
||||
if ( pit != qit ) { return (pit <= qit); }
|
||||
|
||||
|
||||
// pit == qit, then we have to sort p&q along (pit,pit+1)
|
||||
return ( compare_distance(*pit,p,q) != CGAL::LARGER );
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
const_iterator first_segment_source() const
|
||||
{
|
||||
CGAL_precondition(is_valid());
|
||||
return points_.begin();
|
||||
}
|
||||
|
||||
|
||||
const_iterator last_segment_source() const
|
||||
{
|
||||
CGAL_precondition(is_valid());
|
||||
return (points_.end() - 2);
|
||||
}
|
||||
|
||||
|
||||
FT geodesic_distance(const Point_3& p, const Point_3& q,
|
||||
const_iterator pit, const_iterator qit) const
|
||||
{
|
||||
CGAL_precondition(std::distance(pit,qit) >= 0);
|
||||
|
||||
|
||||
// If p and q are in the same segment of the polyline
|
||||
if ( pit == qit )
|
||||
{
|
||||
FT result = distance(p,q);
|
||||
|
||||
|
||||
// Find the closest point to *pit
|
||||
if ( compare_distance(*pit,p,q) != CGAL::LARGER )
|
||||
{ return result; }
|
||||
else
|
||||
{ return -result; }
|
||||
}
|
||||
|
||||
|
||||
// p is inside [pit,pit+1], pit+1 != qit, q is inside [qit,qit+1]
|
||||
FT result = distance(p,*(pit+1));
|
||||
result += distance(*qit,q);
|
||||
|
||||
|
||||
// Add segments between pit+1 and qit to result
|
||||
for ( const_iterator it = (pit+1) ; it != qit ; ++it )
|
||||
{
|
||||
result += distance(*it,*(it+1));
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Returns an iterator on the starting point of the segment of the
|
||||
/// Returns an iterator on the starting point of the segment of the
|
||||
/// polyline which contains p
|
||||
/// if end_point_first is true, then --end is returned instead of begin
|
||||
/// if p is the starting point of a cycle.
|
||||
const_iterator locate(const Point_3& p, bool end_point_first=false) const
|
||||
{
|
||||
CGAL_precondition(is_valid());
|
||||
|
||||
|
||||
// First look if p is one of the points of the polyline
|
||||
const_iterator result = std::find(points_.begin(), points_.end(), p);
|
||||
if ( result != points_.end() )
|
||||
|
|
@ -251,7 +251,7 @@ private:
|
|||
if ( result != points_.begin() )
|
||||
{ return --result; }
|
||||
else
|
||||
{
|
||||
{
|
||||
// Treat cycles
|
||||
if ( end_point_first && p == end_point() )
|
||||
{ return last_segment_source(); }
|
||||
|
|
@ -269,7 +269,7 @@ private:
|
|||
const_iterator nearest_vertex = it;
|
||||
result = nearest_vertex;
|
||||
bool nearest_is_a_segment = false;
|
||||
|
||||
|
||||
while ( ++it != points_.end() )
|
||||
{
|
||||
Segment_3 seg (*previous, *it);
|
||||
|
|
@ -311,27 +311,27 @@ private:
|
|||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// FT squared_distance(const Point_3& p, const Point_3& q) const
|
||||
// {
|
||||
// typename Kernel::Compute_squared_distance_3 sq_distance =
|
||||
// Kernel().compute_squared_distance_3_object();
|
||||
// return sq_distance(p,q);
|
||||
// }
|
||||
|
||||
|
||||
FT distance(const Point_3& p, const Point_3& q) const
|
||||
{
|
||||
return CGAL::sqrt(squared_distance(p, q));
|
||||
}
|
||||
|
||||
Angle angle(const Point_3& p,
|
||||
Angle angle(const Point_3& p,
|
||||
const Point_3& angle_vertex_point,
|
||||
const Point_3& q) const
|
||||
const Point_3& q) const
|
||||
{
|
||||
typename Kernel::Angle_3 compute_angle = Kernel().angle_3_object();
|
||||
return compute_angle(p,angle_vertex_point,q);
|
||||
}
|
||||
|
||||
|
||||
template <typename T1, typename T2>
|
||||
CGAL::Sign compare_distance(const Point_3& p,
|
||||
const T1& obj1,
|
||||
|
|
@ -345,7 +345,7 @@ private:
|
|||
public:
|
||||
Data points_;
|
||||
}; // end class Polyline
|
||||
|
||||
|
||||
|
||||
template <typename Gt, typename MapIterator>
|
||||
struct Mesh_domain_segment_of_curve_primitive{
|
||||
|
|
@ -353,7 +353,7 @@ struct Mesh_domain_segment_of_curve_primitive{
|
|||
typedef typename Map_value_type::first_type Curve_id;
|
||||
typedef typename Map_value_type::second_type Polyline;
|
||||
|
||||
typedef std::pair<MapIterator,
|
||||
typedef std::pair<MapIterator,
|
||||
typename Polyline::const_iterator> Id;
|
||||
|
||||
typedef typename std::iterator_traits<
|
||||
|
|
@ -362,7 +362,7 @@ struct Mesh_domain_segment_of_curve_primitive{
|
|||
typedef typename Gt::Segment_3 Datum;
|
||||
|
||||
Id id_;
|
||||
|
||||
|
||||
Mesh_domain_segment_of_curve_primitive(Id id) : id_(id) {}
|
||||
|
||||
const Id& id() const { return id_; }
|
||||
|
|
@ -427,7 +427,7 @@ public:
|
|||
// Index types
|
||||
typedef typename Base::Index Index;
|
||||
|
||||
typedef typename Base::Surface_patch_index
|
||||
typedef typename Base::Surface_patch_index
|
||||
Surface_patch_index;
|
||||
|
||||
typedef int Curve_segment_index;
|
||||
|
|
@ -437,10 +437,10 @@ public:
|
|||
typedef Gt R;
|
||||
typedef typename Base::Point_3 Point_3;
|
||||
typedef typename Gt::FT FT;
|
||||
|
||||
|
||||
typedef CGAL::Tag_true Has_features;
|
||||
|
||||
|
||||
|
||||
#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
|
||||
template <typename ... T>
|
||||
Mesh_domain_with_polyline_features_3(const T& ...t)
|
||||
|
|
@ -472,11 +472,11 @@ public:
|
|||
, curves_aabb_tree_is_built(false) {}
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
Mesh_domain_with_polyline_features_3(const T1& o1, const T2& o2,
|
||||
Mesh_domain_with_polyline_features_3(const T1& o1, const T2& o2,
|
||||
const T3& o3)
|
||||
: Base(o1, o2, o3)
|
||||
, current_corner_index_(1)
|
||||
, current_curve_index_(1)
|
||||
, current_curve_index_(1)
|
||||
, curves_aabb_tree_is_built(false) {}
|
||||
#endif
|
||||
|
||||
|
|
@ -486,13 +486,13 @@ public:
|
|||
/// OutputIterator value type is std::pair<Corner_index, Point_3>
|
||||
template <typename OutputIterator>
|
||||
OutputIterator get_corners(OutputIterator out) const;
|
||||
|
||||
|
||||
/// OutputIterator value type is CGAL::cpp11::tuple<Curve_segment_index,
|
||||
/// std::pair<Point_3,Index>, std::pair<Point_3,Index> >
|
||||
template <typename OutputIterator>
|
||||
OutputIterator get_curve_segments(OutputIterator out) const;
|
||||
|
||||
/// Returns the geodesic distance between points p and q of curve
|
||||
/// Returns the geodesic distance between points p and q of curve
|
||||
/// \c curve_index
|
||||
FT geodesic_distance(const Point_3& p, const Point_3& q,
|
||||
const Curve_segment_index& curve_index) const;
|
||||
|
|
@ -503,17 +503,17 @@ public:
|
|||
construct_point_on_curve_segment(const Point_3& starting_point,
|
||||
const Curve_segment_index& curve_index,
|
||||
FT distance) const;
|
||||
|
||||
|
||||
/// Returns the sign of the orientation of p,q,r along curve segment
|
||||
/// of index \c index
|
||||
CGAL::Sign distance_sign_along_cycle(const Point_3& p,
|
||||
const Point_3& q,
|
||||
const Point_3& r,
|
||||
const Curve_segment_index& index) const;
|
||||
|
||||
|
||||
/// Returns true if curve \c curve_index is a cycle
|
||||
bool is_cycle(const Point_3&, const Curve_segment_index& index) const;
|
||||
|
||||
|
||||
/// Returns an Index from a Curve_segment_index
|
||||
Index index_from_curve_segment_index(const Curve_segment_index& index) const
|
||||
{ return Index(index); }
|
||||
|
|
@ -521,11 +521,11 @@ public:
|
|||
/// Returns an Curve_segment_index from an Index
|
||||
Curve_segment_index curve_segment_index(const Index& index) const
|
||||
{ return boost::get<Curve_segment_index>(index); }
|
||||
|
||||
|
||||
/// Returns an Index from a Corner_index
|
||||
Index index_from_corner_index(const Corner_index& index) const
|
||||
{ return Index(index); }
|
||||
|
||||
|
||||
/// Returns an Corner_index from an Index
|
||||
Corner_index corner_index(const Index& index) const
|
||||
{ return boost::get<Corner_index>(index); }
|
||||
|
|
@ -549,20 +549,20 @@ public:
|
|||
template <typename IndicesOutputIterator>
|
||||
IndicesOutputIterator
|
||||
get_incidences(Curve_segment_index id, IndicesOutputIterator out) const;
|
||||
|
||||
|
||||
template <typename IndicesOutputIterator>
|
||||
IndicesOutputIterator
|
||||
get_corner_incidences(Curve_segment_index id, IndicesOutputIterator out) const;
|
||||
|
||||
typedef std::set<Surface_patch_index> Surface_patch_index_set;
|
||||
|
||||
const Surface_patch_index_set&
|
||||
const Surface_patch_index_set&
|
||||
get_incidences(Curve_segment_index id) const;
|
||||
|
||||
void display_corner_incidences(std::ostream& os, Corner_index id);
|
||||
|
||||
template <typename InputIterator>
|
||||
void
|
||||
void
|
||||
add_features(InputIterator first, InputIterator last)
|
||||
{ add_features(first, last, CGAL::Emptyset_iterator()); }
|
||||
|
||||
|
|
@ -578,8 +578,8 @@ private:
|
|||
/// Returns the sign of the geodesic distance between \c p and \c q
|
||||
/// Precondition: index is not a cycle
|
||||
CGAL::Sign distance_sign(const Point_3& p, const Point_3& q,
|
||||
const Curve_segment_index& index) const;
|
||||
|
||||
const Curve_segment_index& index) const;
|
||||
|
||||
/// Returns Index associated to p (p must be the coordinates of a corner
|
||||
/// point)
|
||||
Index point_corner_index(const Point_3& p) const;
|
||||
|
|
@ -597,7 +597,7 @@ private:
|
|||
Gt,
|
||||
typename Edges::const_iterator> Curves_primitives;
|
||||
|
||||
typedef CGAL::AABB_traits<Gt,
|
||||
typedef CGAL::AABB_traits<Gt,
|
||||
Curves_primitives> AABB_curves_traits;
|
||||
|
||||
Corners corners_;
|
||||
|
|
@ -621,17 +621,17 @@ public:
|
|||
if(!curves_aabb_tree_is_built) build_curves_aabb_tree();
|
||||
return curves_aabb_tree_;
|
||||
}
|
||||
|
||||
|
||||
void build_curves_aabb_tree() const {
|
||||
std::cerr << "Building curves AABB tree...\n";
|
||||
curves_aabb_tree_.clear();
|
||||
for(typename Edges::const_iterator
|
||||
for(typename Edges::const_iterator
|
||||
edges_it = edges_.begin(),
|
||||
edges_end = edges_.end();
|
||||
edges_it != edges_end; ++edges_it)
|
||||
{
|
||||
const Polyline& polyline = edges_it->second;
|
||||
for(typename Polyline::const_iterator
|
||||
for(typename Polyline::const_iterator
|
||||
pit = polyline.points_.begin(),
|
||||
end = polyline.points_.end() - 1;
|
||||
pit != end; ++pit)
|
||||
|
|
@ -664,7 +664,7 @@ get_corners(OutputIterator out) const
|
|||
{
|
||||
*out++ = std::make_pair(cit->second,cit->first);
|
||||
}
|
||||
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
@ -678,10 +678,10 @@ get_curve_segments(OutputIterator out) const
|
|||
eit = edges_.begin(), end = edges_.end() ; eit != end ; ++eit )
|
||||
{
|
||||
CGAL_assertion( eit->second.is_valid() );
|
||||
|
||||
|
||||
const Point_3& p = eit->second.start_point();
|
||||
const Point_3& q = eit->second.end_point();
|
||||
|
||||
|
||||
Index p_index, q_index;
|
||||
if ( ! eit->second.is_cycle() )
|
||||
{
|
||||
|
|
@ -693,15 +693,15 @@ get_curve_segments(OutputIterator out) const
|
|||
p_index = index_from_curve_segment_index(eit->first);
|
||||
q_index = p_index;
|
||||
}
|
||||
|
||||
|
||||
*out++ = CGAL::cpp11::make_tuple(eit->first,
|
||||
std::make_pair(p,p_index),
|
||||
std::make_pair(q,q_index));
|
||||
}
|
||||
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class MD_>
|
||||
typename Mesh_domain_with_polyline_features_3<MD_>::Index
|
||||
|
|
@ -714,7 +714,7 @@ point_corner_index(const Point_3& p) const
|
|||
CGAL_assertion(false);
|
||||
return Index();
|
||||
}
|
||||
|
||||
|
||||
return p_index_it->second;
|
||||
}
|
||||
|
||||
|
|
@ -728,7 +728,7 @@ geodesic_distance(const Point_3& p, const Point_3& q,
|
|||
// Get corresponding polyline
|
||||
typename Edges::const_iterator eit = edges_.find(curve_index);
|
||||
CGAL_assertion(eit != edges_.end());
|
||||
|
||||
|
||||
// Compute geodesic_distance
|
||||
return eit->second.geodesic_distance(p,q);
|
||||
}
|
||||
|
|
@ -744,7 +744,7 @@ construct_point_on_curve_segment(const Point_3& starting_point,
|
|||
// Get corresponding polyline
|
||||
typename Edges::const_iterator eit = edges_.find(curve_index);
|
||||
CGAL_assertion(eit != edges_.end());
|
||||
|
||||
|
||||
// Return point at geodesic_distance distance from starting_point
|
||||
return eit->second.point_at(starting_point,distance);
|
||||
}
|
||||
|
|
@ -778,7 +778,7 @@ add_features_with_context(InputIterator first, InputIterator last,
|
|||
// Insert one edge for each element
|
||||
for( ; first != last ; ++first )
|
||||
{
|
||||
Curve_segment_index curve_id =
|
||||
Curve_segment_index curve_id =
|
||||
insert_edge(first->polyline_content.begin(), first->polyline_content.end());
|
||||
edges_incidences_[curve_id] = first->context.adjacent_patches_ids;
|
||||
*indices_out++ = curve_id;
|
||||
|
|
@ -900,7 +900,7 @@ void
|
|||
Mesh_domain_with_polyline_features_3<MD_>::
|
||||
compute_corners_incidences()
|
||||
{
|
||||
for(typename Corners::iterator
|
||||
for(typename Corners::iterator
|
||||
cit = corners_.begin(), end = corners_.end();
|
||||
cit != end; /* the loop variable is incremented in the body */)
|
||||
{
|
||||
|
|
@ -925,7 +925,7 @@ compute_corners_incidences()
|
|||
|
||||
BOOST_FOREACH(Curve_segment_index curve_index, corner_tmp_incidences)
|
||||
{
|
||||
get_incidences(curve_index,
|
||||
get_incidences(curve_index,
|
||||
std::inserter(incidences,
|
||||
incidences.begin()));
|
||||
}
|
||||
|
|
@ -939,7 +939,7 @@ compute_corners_incidences()
|
|||
}
|
||||
|
||||
template <class MD_>
|
||||
const typename Mesh_domain_with_polyline_features_3<MD_>::Surface_patch_index_set&
|
||||
const typename Mesh_domain_with_polyline_features_3<MD_>::Surface_patch_index_set&
|
||||
Mesh_domain_with_polyline_features_3<MD_>::
|
||||
get_incidences(Curve_segment_index id) const
|
||||
{
|
||||
|
|
@ -952,7 +952,7 @@ void
|
|||
Mesh_domain_with_polyline_features_3<MD_>::
|
||||
register_corner(const Point_3& p, const Curve_segment_index& curve_index)
|
||||
{
|
||||
|
||||
|
||||
typename Corners::iterator cit = corners_.lower_bound(p);
|
||||
|
||||
// If the corner already exists, returns...
|
||||
|
|
@ -977,9 +977,9 @@ Mesh_domain_with_polyline_features_3<MD_>::
|
|||
insert_edge(InputIterator first, InputIterator last)
|
||||
{
|
||||
CGAL_assertion(std::distance(first,last) > 1);
|
||||
|
||||
|
||||
const Curve_segment_index curve_index = current_curve_index_++;
|
||||
|
||||
|
||||
// Fill corners
|
||||
//
|
||||
// For a cycle, the "first" point of the cycle is registered as a
|
||||
|
|
@ -991,11 +991,11 @@ insert_edge(InputIterator first, InputIterator last)
|
|||
{
|
||||
register_corner(*boost::prior(last), curve_index);
|
||||
}
|
||||
|
||||
|
||||
// Create a new polyline
|
||||
std::pair<typename Edges::iterator,bool> insertion =
|
||||
edges_.insert(std::make_pair(curve_index,Polyline()));
|
||||
|
||||
|
||||
// Fill polyline with data
|
||||
while ( first != last )
|
||||
{
|
||||
|
|
@ -1014,7 +1014,7 @@ distance_sign(const Point_3& p, const Point_3& q,
|
|||
typename Edges::const_iterator eit = edges_.find(index);
|
||||
CGAL_assertion(eit != edges_.end());
|
||||
CGAL_precondition( ! eit->second.is_cycle() );
|
||||
|
||||
|
||||
if ( p == q )
|
||||
return CGAL::ZERO;
|
||||
else if ( eit->second.are_ordered_along(p,q) )
|
||||
|
|
@ -1034,17 +1034,17 @@ distance_sign_along_cycle(const Point_3& p,
|
|||
// Find edge
|
||||
typename Edges::const_iterator eit = edges_.find(index);
|
||||
CGAL_assertion(eit != edges_.end());
|
||||
|
||||
|
||||
// If eit is not a cycle, then the orientation corresponds to the sign
|
||||
// of the distance
|
||||
if ( ! eit->second.is_cycle() )
|
||||
{
|
||||
return distance_sign(p,r,index);
|
||||
}
|
||||
|
||||
|
||||
// If p and r are the same point, it correspond to a complete loop on a cycle
|
||||
if ( p == r ) { return CGAL::POSITIVE; }
|
||||
|
||||
|
||||
// We are on a cycle without any clue (p==q). Return the shortest path as
|
||||
// orientation.
|
||||
if ( p == q )
|
||||
|
|
@ -1054,15 +1054,15 @@ distance_sign_along_cycle(const Point_3& p,
|
|||
if ( pr < rp ) { return CGAL::POSITIVE; }
|
||||
else { return CGAL::NEGATIVE; }
|
||||
}
|
||||
|
||||
|
||||
// If pq or pr is negative, edge is not a cycle, thus geodesic_distance
|
||||
// gives the answer.
|
||||
FT pq = eit->second.geodesic_distance(p,q);
|
||||
FT pr = eit->second.geodesic_distance(p,r);
|
||||
CGAL_assertion(pq > FT(0));
|
||||
CGAL_assertion(pr > FT(0));
|
||||
|
||||
// Compare pq and pr
|
||||
|
||||
// Compare pq and pr
|
||||
if ( pq <= pr ) { return CGAL::POSITIVE; }
|
||||
else { return CGAL::NEGATIVE; }
|
||||
}
|
||||
|
|
@ -1075,7 +1075,7 @@ is_cycle(const Point_3&, const Curve_segment_index& index) const
|
|||
// Find edge
|
||||
typename Edges::const_iterator eit = edges_.find(index);
|
||||
CGAL_assertion(eit != edges_.end());
|
||||
|
||||
|
||||
return eit->second.is_cycle();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/Polyhedron_items_3.h>
|
||||
#include <CGAL/Has_timestamp.h>
|
||||
#include <CGAL/tags.h>
|
||||
|
||||
#include <set>
|
||||
|
||||
|
|
@ -44,6 +46,8 @@ private:
|
|||
typedef CGAL::HalfedgeDS_vertex_base<Refs, Tag, Point> Pdv_base;
|
||||
|
||||
Set_of_indices indices;
|
||||
std::size_t time_stamp_;
|
||||
|
||||
public:
|
||||
int nb_of_feature_edges;
|
||||
|
||||
|
|
@ -58,6 +62,18 @@ public:
|
|||
void add_incident_patch(const Patch_id 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&
|
||||
incident_patches_ids_set() const {
|
||||
|
|
@ -74,6 +90,8 @@ public CGAL::HalfedgeDS_halfedge_base<Refs,Tprev,Tvertex,Tface>
|
|||
{
|
||||
private:
|
||||
bool feature_edge;
|
||||
std::size_t time_stamp_;
|
||||
|
||||
public:
|
||||
|
||||
Mesh_polyhedron_halfedge()
|
||||
|
|
@ -87,6 +105,18 @@ public:
|
|||
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>
|
||||
|
|
@ -108,6 +138,8 @@ public CGAL::HalfedgeDS_face_base<Refs,T_,Pln_>
|
|||
{
|
||||
private:
|
||||
Patch_id_ patch_id_;
|
||||
std::size_t time_stamp_;
|
||||
|
||||
public:
|
||||
|
||||
typedef Patch_id_ Patch_id;
|
||||
|
|
@ -122,8 +154,22 @@ public:
|
|||
void set_patch_id(const 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>
|
||||
class Mesh_polyhedron_items : public CGAL::Polyhedron_items_3 {
|
||||
public:
|
||||
|
|
@ -166,7 +212,6 @@ struct Mesh_polyhedron_3
|
|||
typedef type Type;
|
||||
};
|
||||
|
||||
|
||||
} // end namespace CGAL
|
||||
|
||||
#endif // CGAL_MESH_POLYHEDRON_3_H
|
||||
|
|
|
|||
|
|
@ -30,9 +30,10 @@
|
|||
#define CGAL_COMPACT_MESH_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/Mesh_3/io_signature.h>
|
||||
#include <CGAL/Has_timestamp.h>
|
||||
#include <CGAL/tags.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
|
@ -74,6 +75,7 @@ public:
|
|||
, next_intrusive_()
|
||||
, previous_intrusive_()
|
||||
#endif //CGAL_INTRUSIVE_LIST
|
||||
, time_stamp_(-1)
|
||||
{}
|
||||
|
||||
// Default copy constructor and assignment operator are ok
|
||||
|
|
@ -124,6 +126,18 @@ public:
|
|||
}
|
||||
#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 {
|
||||
return cache_validity;
|
||||
}
|
||||
|
|
@ -179,12 +193,9 @@ private:
|
|||
Vertex_handle next_intrusive_;
|
||||
Vertex_handle previous_intrusive_;
|
||||
#endif
|
||||
}; // end class Mesh_vertex_base_3
|
||||
std::size_t time_stamp_;
|
||||
|
||||
namespace internal {
|
||||
namespace Mesh_3 {
|
||||
} // end namespace internal::Mesh_3
|
||||
} // end namespace internal
|
||||
}; // end class Mesh_vertex_base_3
|
||||
|
||||
template<class GT,
|
||||
class MD,
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include <CGAL/AABB_traits.h>
|
||||
#include <sstream>
|
||||
|
||||
#include <CGAL/Random.h>
|
||||
#include <CGAL/point_generators_3.h>
|
||||
#include <CGAL/Mesh_3/Creator_weighted_point_3.h>
|
||||
#include <CGAL/Mesh_3/Profile_counter.h>
|
||||
|
|
@ -63,8 +64,8 @@ max_length(const Bbox_3& b)
|
|||
return (std::max)(b.xmax()-b.xmin(),
|
||||
(std::max)(b.ymax()-b.ymin(),b.zmax()-b.zmin()) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// -----------------------------------
|
||||
// Surface_patch_index_generator
|
||||
// To use patch_id enclosed in AABB_primitives or not
|
||||
|
|
@ -74,12 +75,12 @@ struct Surface_patch_index_generator
|
|||
{
|
||||
typedef std::pair<Subdomain_index,Subdomain_index> Surface_patch_index;
|
||||
typedef Surface_patch_index type;
|
||||
|
||||
|
||||
template < typename Primitive_id >
|
||||
Surface_patch_index operator()(const Primitive_id&)
|
||||
{ return Surface_patch_index(0,1); }
|
||||
};
|
||||
|
||||
|
||||
template < typename Subdomain_index, typename Polyhedron >
|
||||
struct Surface_patch_index_generator<Subdomain_index, Polyhedron, CGAL::Tag_true>
|
||||
{
|
||||
|
|
@ -113,10 +114,10 @@ struct Index_generator<T, T>
|
|||
// -----------------------------------
|
||||
// Geometric traits generator
|
||||
// -----------------------------------
|
||||
template < typename Gt,
|
||||
template < typename Gt,
|
||||
typename Use_exact_intersection_construction_tag >
|
||||
struct IGT_generator {};
|
||||
|
||||
|
||||
template < typename Gt >
|
||||
struct IGT_generator<Gt,CGAL::Tag_true>
|
||||
{
|
||||
|
|
@ -127,14 +128,14 @@ struct IGT_generator<Gt,CGAL::Tag_true>
|
|||
#endif // NOT CGAL_MESH_3_NEW_ROBUST_INTERSECTION_TRAITS
|
||||
typedef type Type;
|
||||
};
|
||||
|
||||
|
||||
template < typename Gt >
|
||||
struct IGT_generator<Gt,CGAL::Tag_false>
|
||||
{
|
||||
typedef Gt type;
|
||||
typedef type Type;
|
||||
};
|
||||
|
||||
|
||||
} // end namespace details
|
||||
|
||||
} // end namespace Mesh_3
|
||||
|
|
@ -154,7 +155,7 @@ class Polyhedral_mesh_domain_3
|
|||
{
|
||||
typedef typename Mesh_3::details::IGT_generator<
|
||||
IGT_,Use_exact_intersection_construction_tag>::type IGT;
|
||||
|
||||
|
||||
public:
|
||||
/// Geometric object types
|
||||
typedef typename IGT::Point_3 Point_3;
|
||||
|
|
@ -196,46 +197,67 @@ private:
|
|||
typedef typename AABB_tree_::Primitive_id AABB_primitive_id;
|
||||
typedef typename AABB_tree_::Primitive Primitive;
|
||||
typedef typename AABB_traits::Bounding_box Bounding_box;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/// Default constructor
|
||||
Polyhedral_mesh_domain_3()
|
||||
: tree_()
|
||||
, bounding_tree_(&tree_)
|
||||
, has_cache(false) {}
|
||||
|
||||
, bounding_tree_(&tree_)
|
||||
, has_cache(false)
|
||||
, p_rng_(NULL)
|
||||
, delete_rng_(true)
|
||||
{
|
||||
p_rng_ = new CGAL::Random(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructor. Contruction from a 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),
|
||||
TriangleAccessor().triangles_end(p)),
|
||||
bounding_tree_(&tree_) // the bounding tree is tree_
|
||||
, has_cache(false)
|
||||
{
|
||||
, p_rng_(p_rng)
|
||||
, delete_rng_(false)
|
||||
{
|
||||
if(!p.is_pure_triangle()) {
|
||||
std::cerr << "Your input polyhedron must be triangulated!\n";
|
||||
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,
|
||||
const Polyhedron& bounding_polyhedron)
|
||||
const Polyhedron& bounding_polyhedron,
|
||||
CGAL::Random* p_rng = NULL)
|
||||
: tree_(TriangleAccessor().triangles_begin(p),
|
||||
TriangleAccessor().triangles_end(p))
|
||||
, bounding_tree_(new AABB_tree_(TriangleAccessor().triangles_begin(bounding_polyhedron),
|
||||
TriangleAccessor().triangles_end(bounding_polyhedron)))
|
||||
, has_cache(false)
|
||||
{
|
||||
, p_rng_(p_rng)
|
||||
, delete_rng_(false)
|
||||
{
|
||||
tree_.insert(TriangleAccessor().triangles_begin(bounding_polyhedron),
|
||||
TriangleAccessor().triangles_end(bounding_polyhedron));
|
||||
tree_.build();
|
||||
bounding_tree_->build();
|
||||
if(!p_rng_)
|
||||
{
|
||||
p_rng_ = new CGAL::Random(0);
|
||||
delete_rng_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Constructor from a sequence of polyhedral surfaces, and a bounding
|
||||
|
|
@ -249,10 +271,13 @@ public:
|
|||
template <typename InputPolyhedraPtrIterator>
|
||||
Polyhedral_mesh_domain_3(InputPolyhedraPtrIterator begin,
|
||||
InputPolyhedraPtrIterator end,
|
||||
const Polyhedron& bounding_polyhedron)
|
||||
: has_cache(false)
|
||||
const Polyhedron& bounding_polyhedron,
|
||||
CGAL::Random* p_rng = NULL)
|
||||
: has_cache(false)
|
||||
, p_rng_(p_rng)
|
||||
, delete_rng_(false)
|
||||
{
|
||||
if(begin != end) {
|
||||
if(begin != end) {
|
||||
for(; begin != end; ++begin) {
|
||||
tree_.insert(TriangleAccessor().triangles_begin(**begin),
|
||||
TriangleAccessor().triangles_end(**begin));
|
||||
|
|
@ -260,7 +285,7 @@ public:
|
|||
tree_.insert(TriangleAccessor().triangles_begin(bounding_polyhedron),
|
||||
TriangleAccessor().triangles_end(bounding_polyhedron));
|
||||
tree_.build();
|
||||
bounding_tree_ =
|
||||
bounding_tree_ =
|
||||
new AABB_tree_(TriangleAccessor().triangles_begin(bounding_polyhedron),
|
||||
TriangleAccessor().triangles_end(bounding_polyhedron));
|
||||
bounding_tree_->build();
|
||||
|
|
@ -270,9 +295,14 @@ public:
|
|||
TriangleAccessor().triangles_end(bounding_polyhedron));
|
||||
bounding_tree_ = &tree_;
|
||||
}
|
||||
if(!p_rng_)
|
||||
{
|
||||
p_rng_ = new CGAL::Random(0);
|
||||
delete_rng_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Constructor from a sequence of polyhedral surfaces, without bounding
|
||||
|
|
@ -284,8 +314,11 @@ public:
|
|||
*/
|
||||
template <typename InputPolyhedraPtrIterator>
|
||||
Polyhedral_mesh_domain_3(InputPolyhedraPtrIterator begin,
|
||||
InputPolyhedraPtrIterator end)
|
||||
: has_cache(false)
|
||||
InputPolyhedraPtrIterator end,
|
||||
CGAL::Random* p_rng = NULL)
|
||||
: has_cache(false)
|
||||
, p_rng_(p_rng)
|
||||
, delete_rng_(false)
|
||||
{
|
||||
if(begin != end) {
|
||||
for(; begin != end; ++begin) {
|
||||
|
|
@ -295,13 +328,20 @@ public:
|
|||
tree_.build();
|
||||
}
|
||||
bounding_tree_ = 0;
|
||||
if(!p_rng_)
|
||||
{
|
||||
p_rng_ = new CGAL::Random(0);
|
||||
delete_rng_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
~Polyhedral_mesh_domain_3() {
|
||||
~Polyhedral_mesh_domain_3() {
|
||||
if(bounding_tree_ != 0 && bounding_tree_ != &tree_) {
|
||||
delete bounding_tree_;
|
||||
delete bounding_tree_;
|
||||
}
|
||||
if(delete_rng_)
|
||||
delete p_rng_;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -348,7 +388,7 @@ public:
|
|||
{
|
||||
return tree_.closest_point(p);
|
||||
}
|
||||
|
||||
|
||||
/// Allowed query types
|
||||
typedef boost::mpl::vector<Segment_3, Ray_3, Line_3> Allowed_query_types;
|
||||
|
||||
|
|
@ -376,10 +416,10 @@ public:
|
|||
|
||||
boost::optional<AABB_primitive_id> primitive_id = r_domain_.tree_.any_intersected_primitive(q);
|
||||
if ( primitive_id )
|
||||
{
|
||||
{
|
||||
r_domain_.cache_primitive(q, *primitive_id);
|
||||
return Surface_patch(r_domain_.make_surface_index(*primitive_id));
|
||||
} else {
|
||||
} else {
|
||||
return Surface_patch();
|
||||
}
|
||||
}
|
||||
|
|
@ -430,7 +470,7 @@ public:
|
|||
intersection = o ?
|
||||
Intersection_and_primitive_id(*o, primitive_id) :
|
||||
AABB_intersection();
|
||||
} else
|
||||
} else
|
||||
#endif // not CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3
|
||||
{
|
||||
#ifndef CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3
|
||||
|
|
@ -443,7 +483,7 @@ public:
|
|||
{
|
||||
// Get primitive
|
||||
AABB_primitive_id primitive_id = intersection->second;
|
||||
|
||||
|
||||
// intersection may be either a point or a segment
|
||||
#if CGAL_INTERSECTION_VERSION > 1
|
||||
if ( const Bare_point* p_intersect_pt =
|
||||
|
|
@ -478,10 +518,10 @@ public:
|
|||
std::stringstream stream;
|
||||
stream.precision(17);
|
||||
set_pretty_mode(stream);
|
||||
stream <<
|
||||
stream <<
|
||||
"Mesh_3 error : AABB_tree any_intersection result is "
|
||||
"not a point nor a segment\n";
|
||||
if(intersection->first.empty()) {
|
||||
if(intersection->first.empty()) {
|
||||
stream << "The intersection is empty!";
|
||||
} else {
|
||||
stream << "The intersection typeinfo name is ";
|
||||
|
|
@ -492,7 +532,7 @@ public:
|
|||
stream << "The intersecting primitive in the AABB tree was: "
|
||||
<< AABB_primitive(intersection->second).datum() << std::endl;
|
||||
CGAL_error_msg(stream.str().c_str());
|
||||
#endif // not CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3
|
||||
#endif // not CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -509,8 +549,8 @@ public:
|
|||
{
|
||||
return Construct_intersection(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the index to be stored in a vertex lying on the surface identified
|
||||
* by \c index.
|
||||
|
|
@ -538,16 +578,16 @@ public:
|
|||
*/
|
||||
Subdomain_index subdomain_index(const Index& index) const
|
||||
{ return boost::get<Subdomain_index>(index); }
|
||||
|
||||
|
||||
// -----------------------------------
|
||||
// Backward Compatibility
|
||||
// -----------------------------------
|
||||
#ifndef CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX
|
||||
typedef Surface_patch_index Surface_index;
|
||||
|
||||
|
||||
Index index_from_surface_index(const Surface_index& index) const
|
||||
{ return index_from_surface_patch_index(index); }
|
||||
|
||||
|
||||
Surface_index surface_index(const Index& index) const
|
||||
{ return surface_patch_index(index); }
|
||||
#endif // CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX
|
||||
|
|
@ -579,10 +619,10 @@ protected:
|
|||
{
|
||||
tree_.insert(TriangleAccessor().triangles_begin(p),
|
||||
TriangleAccessor().triangles_end(p));
|
||||
|
||||
|
||||
tree_.build();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
/// The AABB tree: intersection detection and more
|
||||
AABB_tree_ tree_;
|
||||
|
|
@ -595,10 +635,14 @@ private:
|
|||
mutable Cached_query cached_query;
|
||||
mutable AABB_primitive_id cached_primitive_id;
|
||||
|
||||
//random number generator for Construct_initial_points
|
||||
CGAL::Random* p_rng_;
|
||||
bool delete_rng_;
|
||||
|
||||
public:
|
||||
|
||||
template <typename Query>
|
||||
void cache_primitive(const Query& q,
|
||||
void cache_primitive(const Query& q,
|
||||
const AABB_primitive_id id) const
|
||||
{
|
||||
cached_query = Cached_query(q);
|
||||
|
|
@ -611,6 +655,20 @@ public:
|
|||
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:
|
||||
// Disabled copy constructor & assignment operator
|
||||
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>
|
||||
OutputIterator
|
||||
Polyhedral_mesh_domain_3<P_,IGT_,TA,Tag,E_tag_>::
|
||||
|
|
@ -632,13 +691,14 @@ Construct_initial_points::operator()(OutputIterator pts,
|
|||
{
|
||||
typename IGT::Construct_ray_3 ray = IGT().construct_ray_3_object();
|
||||
typename IGT::Construct_vector_3 vector = IGT().construct_vector_3_object();
|
||||
|
||||
|
||||
const Bounding_box bbox = r_domain_.tree_.bbox();
|
||||
const Point_3 center( FT( (bbox.xmin() + bbox.xmax()) / 2),
|
||||
FT( (bbox.ymin() + bbox.ymax()) / 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;
|
||||
#ifdef CGAL_MESH_3_VERBOSE
|
||||
|
|
@ -658,9 +718,9 @@ Construct_initial_points::operator()(OutputIterator pts,
|
|||
#endif
|
||||
*pts++ = std::make_pair(CGAL::cpp0x::get<0>(intersection),
|
||||
CGAL::cpp0x::get<1>(intersection));
|
||||
|
||||
|
||||
--i;
|
||||
|
||||
|
||||
#ifdef CGAL_MESH_3_VERBOSE
|
||||
std::cerr << boost::format("\r \r"
|
||||
"%1%/%2% initial point(s) found...")
|
||||
|
|
@ -670,7 +730,7 @@ Construct_initial_points::operator()(OutputIterator pts,
|
|||
}
|
||||
++random_point;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CGAL_MESH_3_VERBOSE
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
|
@ -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
|
||||
Polyhedral_mesh_domain_3<P_,IGT_,TA,Tag,E_tag_>::
|
||||
Is_in_domain::operator()(const Point_3& p) const
|
||||
|
|
|
|||
|
|
@ -28,11 +28,11 @@
|
|||
|
||||
#include <CGAL/Mesh_3/config.h>
|
||||
|
||||
#include <CGAL/Random.h>
|
||||
#include <CGAL/Polyhedral_mesh_domain_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_3/Detect_polylines_in_polyhedra.h>
|
||||
#include <CGAL/Mesh_3/Polyline_with_context.h>
|
||||
#include <CGAL/Mesh_3/Detect_features_in_polyhedra.h>
|
||||
|
|
@ -94,11 +94,10 @@ public:
|
|||
typedef CGAL::Tag_true Has_features;
|
||||
|
||||
/// Constructors
|
||||
Polyhedral_mesh_domain_with_features_3(const Polyhedron& p);
|
||||
Polyhedral_mesh_domain_with_features_3(const std::string& filename);
|
||||
|
||||
template <typename T1, typename T2>
|
||||
Polyhedral_mesh_domain_with_features_3(const T1& a, const T2& b) : Base(a, b) {}
|
||||
Polyhedral_mesh_domain_with_features_3(const Polyhedron& p,
|
||||
CGAL::Random* p_rng = NULL);
|
||||
Polyhedral_mesh_domain_with_features_3(const std::string& filename,
|
||||
CGAL::Random* p_rng = NULL);
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
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() {}
|
||||
|
||||
/// Detect features
|
||||
void initialize_ts(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_); }
|
||||
|
||||
|
|
@ -126,17 +127,20 @@ private:
|
|||
template < typename GT_, typename P_, typename TA_,
|
||||
typename Tag_, typename 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()
|
||||
, polyhedron_(p)
|
||||
{
|
||||
this->add_primitives(polyhedron_);
|
||||
this->set_random_generator(p_rng);
|
||||
}
|
||||
|
||||
template < typename GT_, typename P_, typename TA_,
|
||||
typename Tag_, typename 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()
|
||||
, polyhedron_()
|
||||
{
|
||||
|
|
@ -144,6 +148,32 @@ Polyhedral_mesh_domain_with_features_3(const std::string& filename)
|
|||
std::ifstream input(filename.c_str());
|
||||
input >> 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_>::
|
||||
detect_features(FT angle_in_degree, Polyhedron& p)
|
||||
{
|
||||
initialize_ts(p);
|
||||
// Get sharp features
|
||||
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_unit_tetrahedron.cpp" )
|
||||
create_single_source_cgal_program( "test_robust_weighted_circumcenter.cpp" )
|
||||
create_single_source_cgal_program( "test_meshing_determinism.cpp" )
|
||||
|
||||
else()
|
||||
|
||||
|
|
|
|||
|
|
@ -240,11 +240,8 @@ struct Test_c3t3_io {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
#ifdef WIN32
|
||||
# ifdef _MSC_VER
|
||||
# pragma message("Note: The Triangulation_3 facets iterator is not deterministic")
|
||||
# endif
|
||||
#else // not WIN32
|
||||
#if 0
|
||||
// Note: The Triangulation_3 facets iterator order changes after a reload
|
||||
for(typename Tr::Finite_facets_iterator
|
||||
fit1 = t1.finite_facets_begin(),
|
||||
fit2 = t2.finite_facets_begin(),
|
||||
|
|
@ -329,6 +326,10 @@ struct Test_c3t3_io {
|
|||
<< c3t3_bis
|
||||
<< "\n******end******" << std::endl;
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
// Author(s) : Stephane Tayeb
|
||||
//
|
||||
//******************************************************************************
|
||||
// File Description :
|
||||
// File Description :
|
||||
//******************************************************************************
|
||||
|
||||
#include "test_meshing_utilities.h"
|
||||
|
|
@ -35,33 +35,36 @@ public:
|
|||
{
|
||||
typedef CGAL::Image_3 Image;
|
||||
typedef CGAL::Labeled_image_mesh_domain_3<Image, K> Mesh_domain;
|
||||
|
||||
|
||||
typedef typename CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
||||
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
||||
|
||||
|
||||
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
|
||||
typedef typename Mesh_criteria::Facet_criteria Facet_criteria;
|
||||
typedef typename Mesh_criteria::Cell_criteria Cell_criteria;
|
||||
|
||||
|
||||
CGAL_USE_TYPE(typename Mesh_domain::Surface_patch_index);
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Data generation
|
||||
//-------------------------------------------------------
|
||||
Image image;
|
||||
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
|
||||
Facet_criteria facet_criteria(25, 20*image.vx(), 5*image.vx());
|
||||
Cell_criteria cell_criteria(4, 25*image.vx());
|
||||
Mesh_criteria criteria(facet_criteria, cell_criteria);
|
||||
|
||||
|
||||
// Mesh generation
|
||||
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria,
|
||||
CGAL::parameters::no_exude(),
|
||||
CGAL::parameters::no_perturb());
|
||||
|
||||
|
||||
// Verify
|
||||
this->verify_c3t3_volume(c3t3, 1772330*0.95, 1772330*1.05);
|
||||
this->verify(c3t3,domain,criteria, Bissection_tag());
|
||||
|
|
@ -76,6 +79,6 @@ int main()
|
|||
Image_tester<K_e_i> test_epic;
|
||||
std::cerr << "Mesh generation from a 3D image:\n";
|
||||
test_epic.image();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
//-------------------------------------------------------
|
||||
std::cout << "\tSeed is\t"
|
||||
<< CGAL::default_random.get_seed() << std::endl;
|
||||
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
|
||||
Facet_criteria facet_criteria(0, 0, 0.3);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
// Author(s) : Stephane Tayeb
|
||||
//
|
||||
//******************************************************************************
|
||||
// File Description :
|
||||
// File Description :
|
||||
//******************************************************************************
|
||||
|
||||
#include "test_meshing_utilities.h"
|
||||
|
|
@ -34,16 +34,16 @@ struct Polyhedron_tester : public Tester<K>
|
|||
typedef K Gt;
|
||||
typedef CGAL::Polyhedron_3<Gt> Polyhedron;
|
||||
typedef CGAL::Polyhedral_mesh_domain_3<Polyhedron, Gt> Mesh_domain;
|
||||
|
||||
|
||||
typedef typename CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
||||
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
||||
|
||||
|
||||
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
|
||||
typedef typename Mesh_criteria::Facet_criteria Facet_criteria;
|
||||
typedef typename Mesh_criteria::Cell_criteria Cell_criteria;
|
||||
|
||||
|
||||
typedef typename Mesh_domain::Surface_patch_index Surface_patch_index;
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Data generation
|
||||
//-------------------------------------------------------
|
||||
|
|
@ -51,28 +51,30 @@ struct Polyhedron_tester : public Tester<K>
|
|||
std::ifstream input("data/sphere.off");
|
||||
input >> polyhedron;
|
||||
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
|
||||
Facet_criteria facet_criteria(30, 0.2, 0.02);
|
||||
Cell_criteria cell_criteria(2, 0.2);
|
||||
Mesh_criteria criteria(facet_criteria, cell_criteria);
|
||||
|
||||
|
||||
// Mesh generation
|
||||
C3t3 c3t3;
|
||||
typename Polyhedron::Point_iterator end = polyhedron.points_begin();
|
||||
int i=0;
|
||||
while ( i++ < 4 ) { ++end; }
|
||||
|
||||
|
||||
c3t3.insert_surface_points(polyhedron.points_begin(),
|
||||
end,
|
||||
domain.index_from_surface_patch_index(Surface_patch_index(0,1)));
|
||||
|
||||
|
||||
CGAL::refine_mesh_3(c3t3, domain, criteria,
|
||||
CGAL::parameters::no_exude(),
|
||||
CGAL::parameters::no_perturb());
|
||||
|
||||
|
||||
// Verify
|
||||
double vol = 0.479171765761454;
|
||||
this->verify_c3t3_volume(c3t3, vol*0.95, vol*1.05);
|
||||
|
|
@ -85,6 +87,6 @@ int main()
|
|||
Polyhedron_tester<K_e_i> test_epic;
|
||||
std::cerr << "Mesh generation from a polyhedron:\n";
|
||||
test_epic.polyhedron();
|
||||
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
// Author(s) : Stephane Tayeb
|
||||
//
|
||||
//******************************************************************************
|
||||
// File Description :
|
||||
// File Description :
|
||||
//******************************************************************************
|
||||
|
||||
#include "test_meshing_utilities.h"
|
||||
|
|
@ -36,24 +36,26 @@ struct Polyhedron_with_features_tester : public Tester<K>
|
|||
{
|
||||
typedef CGAL::Mesh_3::Robust_intersection_traits_3<K> Gt;
|
||||
typedef CGAL::Polyhedral_mesh_domain_with_features_3<Gt> Mesh_domain;
|
||||
|
||||
|
||||
typedef typename CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
||||
typedef CGAL::Mesh_complex_3_in_triangulation_3 <
|
||||
Tr,
|
||||
typename Mesh_domain::Corner_index,
|
||||
typename Mesh_domain::Curve_segment_index > C3t3;
|
||||
|
||||
|
||||
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
|
||||
typedef typename Mesh_criteria::Edge_criteria Edge_criteria;
|
||||
typedef typename Mesh_criteria::Facet_criteria Facet_criteria;
|
||||
typedef typename Mesh_criteria::Cell_criteria Cell_criteria;
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// 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();
|
||||
|
||||
|
||||
// Set mesh criteria
|
||||
Edge_criteria edge_criteria(0.2);
|
||||
Facet_criteria facet_criteria(30, 0.2, 0.02);
|
||||
|
|
@ -64,7 +66,7 @@ struct Polyhedron_with_features_tester : public Tester<K>
|
|||
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria,
|
||||
CGAL::parameters::no_exude(),
|
||||
CGAL::parameters::no_perturb());
|
||||
|
||||
|
||||
// Verify
|
||||
this->verify(c3t3,domain,criteria,
|
||||
Polyhedral_tag()); //, 1099, 1099, 1158, 1158, 4902, 4902);
|
||||
|
|
@ -81,7 +83,7 @@ struct Polyhedron_with_features_tester : public Tester<K>
|
|||
std::ios_base::in|std::ios_base::binary);
|
||||
CGAL::Mesh_3::load_binary_file(in_binary, c3t3_bis);
|
||||
assert(c3t3_bis.triangulation() == c3t3.triangulation());
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,9 @@ int main(int argc, char** argv)
|
|||
Point(0, 1, 0),
|
||||
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<Polyline> Polylines;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
// surface mesh
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/Polyhedron_items_3.h>
|
||||
#include <CGAL/Has_timestamp.h>
|
||||
#include <CGAL/tags.h>
|
||||
|
||||
#include <set>
|
||||
|
||||
|
|
@ -23,6 +25,8 @@ private:
|
|||
|
||||
Set_of_indices indices;
|
||||
std::size_t mID;
|
||||
std::size_t time_stamp_;
|
||||
|
||||
public:
|
||||
int nb_of_feature_edges;
|
||||
|
||||
|
|
@ -38,6 +42,18 @@ public:
|
|||
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&
|
||||
incident_patches_ids_set() const {
|
||||
return indices;
|
||||
|
|
@ -57,6 +73,8 @@ class Polyhedron_demo_halfedge :
|
|||
private:
|
||||
bool feature_edge;
|
||||
std::size_t mID;
|
||||
std::size_t time_stamp_;
|
||||
|
||||
public:
|
||||
|
||||
Polyhedron_demo_halfedge()
|
||||
|
|
@ -74,6 +92,17 @@ public:
|
|||
std::size_t& id() { 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_>
|
||||
|
|
@ -83,6 +112,8 @@ class Polyhedron_demo_face :
|
|||
private:
|
||||
Patch_id_ patch_id_;
|
||||
std::size_t mID;
|
||||
std::size_t time_stamp_;
|
||||
|
||||
public:
|
||||
typedef Patch_id_ Patch_id;
|
||||
|
||||
|
|
@ -100,6 +131,17 @@ public:
|
|||
std::size_t& id() { 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>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
// Copyright (c) 2003,2004,2007-2010 INRIA Sophia-Antipolis (France).
|
||||
// Copyright (c) 2014 GeometryFactory Sarl (France)
|
||||
// All rights reserved.
|
||||
//
|
||||
// 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/iterator.h>
|
||||
#include <CGAL/Time_stamper.h>
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
// An STL like container with the following properties :
|
||||
// - to achieve compactness, it requires access to a pointer stored in T,
|
||||
|
|
@ -163,17 +164,27 @@ namespace internal {
|
|||
class CC_iterator;
|
||||
}
|
||||
|
||||
template < class T, class Allocator_ = Default, class Increment_policy
|
||||
=Addition_size_policy<CGAL_INIT_COMPACT_CONTAINER_BLOCK_SIZE,
|
||||
CGAL_INCREMENT_COMPACT_CONTAINER_BLOCK_SIZE> >
|
||||
template < class T,
|
||||
class Allocator_ = Default,
|
||||
class Increment_policy_ = Default,
|
||||
class TimeStamper_ = Default >
|
||||
class Compact_container
|
||||
{
|
||||
typedef Allocator_ Al;
|
||||
typedef Increment_policy Incr_policy;
|
||||
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;
|
||||
public:
|
||||
typedef typename Default::Get< TimeStamper_,
|
||||
CGAL::Time_stamper_impl<T> >::type
|
||||
Time_stamper_impl;
|
||||
|
||||
typedef T value_type;
|
||||
typedef Allocator allocator_type;
|
||||
typedef typename Allocator::reference reference;
|
||||
|
|
@ -196,6 +207,7 @@ public:
|
|||
|
||||
explicit Compact_container(const Allocator &a = Allocator())
|
||||
: alloc(a)
|
||||
, time_stamper(new Time_stamper_impl())
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
|
@ -204,6 +216,7 @@ public:
|
|||
Compact_container(InputIterator first, InputIterator last,
|
||||
const Allocator & a = Allocator())
|
||||
: alloc(a)
|
||||
, time_stamper(new Time_stamper_impl())
|
||||
{
|
||||
init();
|
||||
std::copy(first, last, CGAL::inserter(*this));
|
||||
|
|
@ -212,9 +225,11 @@ public:
|
|||
// The copy constructor and assignment operator preserve the iterator order
|
||||
Compact_container(const Compact_container &c)
|
||||
: alloc(c.get_allocator())
|
||||
, time_stamper(new Time_stamper_impl())
|
||||
{
|
||||
init();
|
||||
block_size = c.block_size;
|
||||
*time_stamper = *c.time_stamper;
|
||||
std::copy(c.begin(), c.end(), CGAL::inserter(*this));
|
||||
}
|
||||
|
||||
|
|
@ -230,6 +245,7 @@ public:
|
|||
~Compact_container()
|
||||
{
|
||||
clear();
|
||||
delete time_stamper;
|
||||
}
|
||||
|
||||
bool is_used(size_type i) const
|
||||
|
|
@ -274,6 +290,7 @@ public:
|
|||
std::swap(last_item, c.last_item);
|
||||
std::swap(free_list, c.free_list);
|
||||
all_items.swap(c.all_items);
|
||||
std::swap(time_stamper, c.time_stamper);
|
||||
}
|
||||
|
||||
iterator begin() { return iterator(first_item, 0, 0); }
|
||||
|
|
@ -319,6 +336,7 @@ public:
|
|||
new (ret) value_type(args...);
|
||||
CGAL_assertion(type(ret) == USED);
|
||||
++size_;
|
||||
time_stamper->set_time_stamp(ret);
|
||||
return iterator(ret, 0);
|
||||
}
|
||||
#else
|
||||
|
|
@ -333,6 +351,7 @@ public:
|
|||
new (ret) value_type();
|
||||
CGAL_assertion(type(ret) == USED);
|
||||
++size_;
|
||||
time_stamper->set_time_stamp(ret);
|
||||
return iterator(ret, 0);
|
||||
}
|
||||
|
||||
|
|
@ -348,6 +367,7 @@ public:
|
|||
new (ret) value_type(t1);
|
||||
CGAL_assertion(type(ret) == USED);
|
||||
++size_;
|
||||
time_stamper->set_time_stamp(ret);
|
||||
return iterator(ret, 0);
|
||||
}
|
||||
|
||||
|
|
@ -363,6 +383,7 @@ public:
|
|||
new (ret) value_type(t1, t2);
|
||||
CGAL_assertion(type(ret) == USED);
|
||||
++size_;
|
||||
time_stamper->set_time_stamp(ret);
|
||||
return iterator(ret, 0);
|
||||
}
|
||||
|
||||
|
|
@ -378,6 +399,7 @@ public:
|
|||
new (ret) value_type(t1, t2, t3);
|
||||
CGAL_assertion(type(ret) == USED);
|
||||
++size_;
|
||||
time_stamper->set_time_stamp(ret);
|
||||
return iterator(ret, 0);
|
||||
}
|
||||
|
||||
|
|
@ -393,6 +415,7 @@ public:
|
|||
new (ret) value_type(t1, t2, t3, t4);
|
||||
CGAL_assertion(type(ret) == USED);
|
||||
++size_;
|
||||
time_stamper->set_time_stamp(ret);
|
||||
return iterator(ret, 0);
|
||||
}
|
||||
|
||||
|
|
@ -409,6 +432,7 @@ public:
|
|||
new (ret) value_type(t1, t2, t3, t4, t5);
|
||||
CGAL_assertion(type(ret) == USED);
|
||||
++size_;
|
||||
time_stamper->set_time_stamp(ret);
|
||||
return iterator(ret, 0);
|
||||
}
|
||||
|
||||
|
|
@ -426,6 +450,7 @@ public:
|
|||
new (ret) value_type(t1, t2, t3, t4, t5, t6);
|
||||
CGAL_assertion(type(ret) == USED);
|
||||
++size_;
|
||||
time_stamper->set_time_stamp(ret);
|
||||
return iterator(ret, 0);
|
||||
}
|
||||
|
||||
|
|
@ -443,6 +468,7 @@ public:
|
|||
new (ret) value_type(t1, t2, t3, t4, t5, t6, t7);
|
||||
CGAL_assertion(type(ret) == USED);
|
||||
++size_;
|
||||
time_stamper->set_time_stamp(ret);
|
||||
return iterator(ret, 0);
|
||||
}
|
||||
|
||||
|
|
@ -460,6 +486,7 @@ public:
|
|||
new (ret) value_type(t1, t2, t3, t4, t5, t6, t7, t8);
|
||||
CGAL_assertion(type(ret) == USED);
|
||||
++size_;
|
||||
time_stamper->set_time_stamp(ret);
|
||||
return iterator(ret, 0);
|
||||
}
|
||||
#endif // CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
|
||||
|
|
@ -474,6 +501,7 @@ public:
|
|||
alloc.construct(ret, t);
|
||||
CGAL_assertion(type(ret) == USED);
|
||||
++size_;
|
||||
time_stamper->set_time_stamp(ret);
|
||||
return iterator(ret, 0);
|
||||
}
|
||||
|
||||
|
|
@ -581,7 +609,7 @@ public:
|
|||
|
||||
/** Reserve method to ensure that the capacity of the Compact_container be
|
||||
* greater or equal than a given value n.
|
||||
*/
|
||||
*/
|
||||
void reserve(size_type n)
|
||||
{
|
||||
if ( capacity_>=n ) return;
|
||||
|
|
@ -626,7 +654,7 @@ public:
|
|||
}
|
||||
while ( curblock>lastblock );
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void allocate_new_block();
|
||||
|
|
@ -678,7 +706,7 @@ private:
|
|||
{
|
||||
// This out of range compare is always true and causes lots of
|
||||
// unnecessary warnings.
|
||||
// CGAL_precondition(0 <= t && t < 4);
|
||||
// CGAL_precondition(0 <= t && t < 4);
|
||||
Traits::pointer(*ptr) = (void *) ((clean_pointer((char *) p)) + (int) t);
|
||||
}
|
||||
|
||||
|
|
@ -693,13 +721,14 @@ private:
|
|||
|
||||
void init()
|
||||
{
|
||||
block_size = Incr_policy::first_block_size;
|
||||
block_size = Increment_policy::first_block_size;
|
||||
capacity_ = 0;
|
||||
size_ = 0;
|
||||
free_list = NULL;
|
||||
first_item = NULL;
|
||||
last_item = NULL;
|
||||
all_items = All_items();
|
||||
time_stamper->reset();
|
||||
}
|
||||
|
||||
allocator_type alloc;
|
||||
|
|
@ -710,10 +739,14 @@ private:
|
|||
pointer first_item;
|
||||
pointer last_item;
|
||||
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 >
|
||||
void Compact_container<T, Allocator, Increment_policy>::merge(Self &d)
|
||||
template < class T, class Allocator, class Increment_policy, class TimeStamper >
|
||||
void Compact_container<T, Allocator, Increment_policy, TimeStamper>::merge(Self &d)
|
||||
{
|
||||
CGAL_precondition(&d != this);
|
||||
|
||||
|
|
@ -749,8 +782,8 @@ void Compact_container<T, Allocator, Increment_policy>::merge(Self &d)
|
|||
d.init();
|
||||
}
|
||||
|
||||
template < class T, class Allocator, class Increment_policy >
|
||||
void Compact_container<T, Allocator, Increment_policy>::clear()
|
||||
template < class T, class Allocator, class Increment_policy, class TimeStamper >
|
||||
void Compact_container<T, Allocator, Increment_policy, TimeStamper>::clear()
|
||||
{
|
||||
for (typename All_items::iterator it = all_items.begin(), itend = all_items.end();
|
||||
it != itend; ++it) {
|
||||
|
|
@ -765,8 +798,8 @@ void Compact_container<T, Allocator, Increment_policy>::clear()
|
|||
init();
|
||||
}
|
||||
|
||||
template < class T, class Allocator, class Increment_policy >
|
||||
void Compact_container<T, Allocator, Increment_policy>::allocate_new_block()
|
||||
template < class T, class Allocator, class Increment_policy, class TimeStamper >
|
||||
void Compact_container<T, Allocator, Increment_policy, TimeStamper>::allocate_new_block()
|
||||
{
|
||||
pointer new_block = alloc.allocate(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);
|
||||
}
|
||||
|
||||
template < class T, class Allocator, class Increment_policy >
|
||||
template < class T, class Allocator, class Increment_policy, class TimeStamper >
|
||||
inline
|
||||
bool operator==(const Compact_container<T, Allocator, Increment_policy> &lhs,
|
||||
const Compact_container<T, Allocator, Increment_policy> &rhs)
|
||||
bool operator==(const Compact_container<T, Allocator, Increment_policy, TimeStamper> &lhs,
|
||||
const Compact_container<T, Allocator, Increment_policy, TimeStamper> &rhs)
|
||||
{
|
||||
return lhs.size() == rhs.size() &&
|
||||
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
|
||||
bool operator!=(const Compact_container<T, Allocator, Increment_policy> &lhs,
|
||||
const Compact_container<T, Allocator, Increment_policy> &rhs)
|
||||
bool operator!=(const Compact_container<T, Allocator, Increment_policy, TimeStamper> &lhs,
|
||||
const Compact_container<T, Allocator, Increment_policy, TimeStamper> &rhs)
|
||||
{
|
||||
return ! (lhs == rhs);
|
||||
}
|
||||
|
||||
template < class T, class Allocator, class Increment_policy >
|
||||
template < class T, class Allocator, class Increment_policy, class TimeStamper >
|
||||
inline
|
||||
bool operator< (const Compact_container<T, Allocator, Increment_policy> &lhs,
|
||||
const Compact_container<T, Allocator, Increment_policy> &rhs)
|
||||
bool operator< (const Compact_container<T, Allocator, Increment_policy, TimeStamper> &lhs,
|
||||
const Compact_container<T, Allocator, Increment_policy, TimeStamper> &rhs)
|
||||
{
|
||||
return std::lexicographical_compare(lhs.begin(), lhs.end(),
|
||||
rhs.begin(), rhs.end());
|
||||
}
|
||||
|
||||
template < class T, class Allocator, class Increment_policy >
|
||||
template < class T, class Allocator, class Increment_policy, class TimeStamper >
|
||||
inline
|
||||
bool operator> (const Compact_container<T, Allocator, Increment_policy> &lhs,
|
||||
const Compact_container<T, Allocator, Increment_policy> &rhs)
|
||||
bool operator> (const Compact_container<T, Allocator, Increment_policy, TimeStamper> &lhs,
|
||||
const Compact_container<T, Allocator, Increment_policy, TimeStamper> &rhs)
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
template < class T, class Allocator, class Increment_policy >
|
||||
template < class T, class Allocator, class Increment_policy, class TimeStamper >
|
||||
inline
|
||||
bool operator<=(const Compact_container<T, Allocator, Increment_policy> &lhs,
|
||||
const Compact_container<T, Allocator, Increment_policy> &rhs)
|
||||
bool operator<=(const Compact_container<T, Allocator, Increment_policy, TimeStamper> &lhs,
|
||||
const Compact_container<T, Allocator, Increment_policy, TimeStamper> &rhs)
|
||||
{
|
||||
return ! (lhs > rhs);
|
||||
}
|
||||
|
||||
template < class T, class Allocator, class Increment_policy >
|
||||
template < class T, class Allocator, class Increment_policy, class TimeStamper >
|
||||
inline
|
||||
bool operator>=(const Compact_container<T, Allocator, Increment_policy> &lhs,
|
||||
const Compact_container<T, Allocator, Increment_policy> &rhs)
|
||||
bool operator>=(const Compact_container<T, Allocator, Increment_policy, TimeStamper> &lhs,
|
||||
const Compact_container<T, Allocator, Increment_policy, TimeStamper> &rhs)
|
||||
{
|
||||
return ! (lhs < rhs);
|
||||
}
|
||||
|
|
@ -890,14 +923,19 @@ namespace internal {
|
|||
|
||||
private:
|
||||
|
||||
typedef typename DSC::Time_stamper_impl Time_stamper_impl;
|
||||
|
||||
union {
|
||||
pointer p;
|
||||
void *vp;
|
||||
} m_ptr;
|
||||
|
||||
// Only Compact_container should access these constructors.
|
||||
friend class Compact_container<value_type, typename DSC::Al,
|
||||
typename DSC::Incr_policy>;
|
||||
friend class Compact_container<value_type,
|
||||
typename DSC::Al,
|
||||
typename DSC::Ip,
|
||||
typename DSC::Ts>;
|
||||
|
||||
|
||||
// For begin()
|
||||
CC_iterator(pointer ptr, int, int)
|
||||
|
|
@ -991,22 +1029,24 @@ namespace internal {
|
|||
// For std::less...
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -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 <algorithm>
|
||||
#include <CGAL/memory.h>
|
||||
#include <CGAL/Time_stamper.h>
|
||||
|
||||
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 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 Get_time_stamper<T>::type::less(node, x.node) || 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 Get_time_stamper<T>::type::less(x.node, node) || node==x.node; }
|
||||
T& operator*() const { return *node; }
|
||||
T* operator->() const { return node; }
|
||||
Self& operator++() {
|
||||
|
|
@ -138,12 +139,12 @@ namespace internal {
|
|||
In_place_list_const_iterator( Iterator i) : node(&*i) {}
|
||||
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 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 Get_time_stamper<T>::type::less(node, x.node) || 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 Get_time_stamper<T>::type::less(x.node, node) || node==x.node; }
|
||||
const T& operator*() const { return *node; }
|
||||
const T* operator->() const { return node; }
|
||||
Self& operator++() {
|
||||
|
|
@ -233,6 +234,7 @@ protected:
|
|||
pointer node;
|
||||
size_type length;
|
||||
|
||||
Time_stamper_impl<T>* time_stamper_ptr;
|
||||
// These are the only places where the allocator gets called.
|
||||
pointer get_node() {
|
||||
pointer p = allocator.allocate(1);
|
||||
|
|
@ -265,8 +267,10 @@ public:
|
|||
// CREATION
|
||||
//
|
||||
// New creation variable is: `l'
|
||||
|
||||
explicit In_place_list() : length(0) {
|
||||
explicit In_place_list()
|
||||
: length(0)
|
||||
, time_stamper_ptr(new Time_stamper_impl<T>())
|
||||
{
|
||||
// introduces an empty list.
|
||||
node = get_node();
|
||||
(*node).next_link = node;
|
||||
|
|
@ -314,6 +318,7 @@ public:
|
|||
(*((*position.node).prev_link)).next_link = &x;
|
||||
(*position.node).prev_link = &x;
|
||||
++length;
|
||||
time_stamper_ptr->set_time_stamp(&x);
|
||||
return &x;
|
||||
}
|
||||
iterator insert(T* pos, T& x) {
|
||||
|
|
@ -385,11 +390,17 @@ public:
|
|||
erase( iterator(first), iterator(last));
|
||||
}
|
||||
|
||||
void clear() { erase( begin(), end()); }
|
||||
void clear() {
|
||||
erase( begin(), end());
|
||||
time_stamper_ptr->reset();
|
||||
}
|
||||
|
||||
// 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
|
||||
// value.
|
||||
node = get_node();
|
||||
|
|
@ -399,7 +410,10 @@ public:
|
|||
}
|
||||
|
||||
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').
|
||||
node = get_node();
|
||||
(*node).next_link = node;
|
||||
|
|
@ -407,14 +421,21 @@ public:
|
|||
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').
|
||||
node = get_node();
|
||||
(*node).next_link = node;
|
||||
(*node).prev_link = node;
|
||||
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.
|
||||
node = get_node();
|
||||
(*node).next_link = node;
|
||||
|
|
@ -424,6 +445,7 @@ public:
|
|||
~In_place_list() {
|
||||
erase(begin(), end());
|
||||
put_node(node);
|
||||
delete time_stamper_ptr;
|
||||
}
|
||||
|
||||
Self& operator=(const Self& x);
|
||||
|
|
@ -486,6 +508,8 @@ protected:
|
|||
|
||||
public:
|
||||
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.
|
||||
// It takes constant time. Precondition: `&l != &x'.
|
||||
if (!x.empty()) {
|
||||
|
|
@ -498,6 +522,8 @@ public:
|
|||
splice( iterator(position), x);
|
||||
}
|
||||
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
|
||||
// `pos' and removes the element from x. It takes constant time. i
|
||||
// is a valid dereferenceable iterator of x. The result is
|
||||
|
|
@ -512,6 +538,8 @@ public:
|
|||
splice( iterator(position), x, iterator(i));
|
||||
}
|
||||
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
|
||||
// `pos' and removes the elements from x. It takes constant time
|
||||
// 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/Testsuite/use.h>
|
||||
|
||||
#include <CGAL/tags.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
|
||||
: public CGAL::Compact_container_base
|
||||
{
|
||||
bool operator==(const Node_1 &) const { return true; }
|
||||
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
|
||||
|
|
@ -241,19 +258,62 @@ void test_index(const Cont &C)
|
|||
}
|
||||
}
|
||||
|
||||
struct Incomplete_struct;
|
||||
|
||||
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;
|
||||
CGAL::Compact_container<Node_2, CGAL::Default, CGAL::Addition_size_policy<14,16> > C4;
|
||||
typedef Node_1<CGAL::Tag_true > T1;
|
||||
typedef CGAL::Compact_container<T1> C1; // with timestamps
|
||||
|
||||
test_index(C3);
|
||||
test_index(C4);
|
||||
typedef Node_1<CGAL::Tag_false> T2;
|
||||
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;
|
||||
}
|
||||
// EOF //
|
||||
|
|
|
|||
|
|
@ -3300,11 +3300,11 @@ void
|
|||
Triangulation_3<Gt,Tds>::
|
||||
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) {
|
||||
i = (&*(t.first) < &*(t.third))? 0 : 2;
|
||||
i = (t.first < t.third) ? 0 : 2;
|
||||
} else {
|
||||
i = (&*(t.second) < &*(t.third))? 1 : 2;
|
||||
i = (t.second < t.third) ? 1 : 2;
|
||||
}
|
||||
Vertex_handle tmp;
|
||||
switch(i){
|
||||
|
|
|
|||
Loading…
Reference in New Issue