Improved the way parallelism is handle in Mesh_3/Triangulation_3

Added a better support for parallelism in Triangulation_3.
Simplified how to enable/disable concurrency in Mesh_3.
Moved the Compact_container stategies to a new file.
This commit is contained in:
Clement Jamin 2013-02-15 18:07:43 +01:00
parent d9f92dc9bb
commit bce43fbb8e
31 changed files with 943 additions and 622 deletions

View File

@ -684,7 +684,7 @@ public:
}
// Useless here
void set_lock_ds(Mesh_3::LockDataStructureType *) {}
void set_lock_ds(Default_lock_data_structure *) {}
void set_worksharing_ds(Mesh_3::WorksharingDataStructureType *) {}
protected:
@ -1379,7 +1379,7 @@ public:
return ! is_algorithm_done();
}
void set_lock_ds(Mesh_3::LockDataStructureType *p)
void set_lock_ds(Default_lock_data_structure *p)
{
m_lock_ds = p;
}
@ -1395,7 +1395,7 @@ protected:
const int FIRST_GRID_LOCK_RADIUS;
const int MESH_3_REFINEMENT_GRAINSIZE;
const int REFINEMENT_BATCH_SIZE;
Mesh_3::LockDataStructureType *m_lock_ds;
Default_lock_data_structure *m_lock_ds;
Mesh_3::WorksharingDataStructureType *m_worksharing_ds;
#ifdef CGAL_MESH_3_WORKSHARING_USES_TASK_SCHEDULER

View File

@ -16,24 +16,7 @@ typedef FT (Function)(const Point&);
typedef CGAL::Implicit_mesh_domain_3<Function,K> Mesh_domain;
// Triangulation
#if defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \
|| defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE)
typedef CGAL::Kernel_traits<Mesh_domain>::Kernel PMDKernel;
typedef CGAL::details::Mesh_geom_traits_generator<PMDKernel>::type Geom_traits;
typedef CGAL::Triangulation_lazy_ds_cell_base_3<> DS_cell_base;
typedef CGAL::Triangulation_cell_base_with_circumcenter_3<
Geom_traits, DS_cell_base> Cell_base_with_cc;
typedef CGAL::Regular_triangulation_cell_base_3<
Geom_traits, Cell_base_with_cc> Regular_cell_base;
typedef CGAL::Mesh_triangulation_3<
Mesh_domain,
K,
Geom_traits,
Regular_cell_base>::type Tr;
#else
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#endif
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
// Criteria

View File

@ -21,24 +21,7 @@ typedef CGAL::Polyhedron_3<K> Polyhedron;
typedef CGAL::Polyhedral_mesh_domain_3<Polyhedron, K> Mesh_domain;
// Triangulation
#if defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \
|| defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE)
typedef CGAL::Kernel_traits<Mesh_domain>::Kernel PMDKernel;
typedef CGAL::details::Mesh_geom_traits_generator<PMDKernel>::type Geom_traits;
typedef CGAL::Triangulation_lazy_ds_cell_base_3<> DS_cell_base;
typedef CGAL::Triangulation_cell_base_with_circumcenter_3<
Geom_traits, DS_cell_base> Cell_base_with_cc;
typedef CGAL::Regular_triangulation_cell_base_3<
Geom_traits, Cell_base_with_cc> Regular_cell_base;
typedef CGAL::Mesh_triangulation_3<
Mesh_domain,
K,
Geom_traits,
Regular_cell_base>::type Tr;
#else
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#endif
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
// Criteria

View File

@ -382,9 +382,9 @@ protected:
typedef typename Tr::Cell_handle Cell_handle;
typedef typename Tr::Facet Facet;
C3T3_helpers_base(LockDataStructureType *) {}
C3T3_helpers_base(Default_lock_data_structure *) {}
LockDataStructureType *get_lock_data_structure() const
Default_lock_data_structure *get_lock_data_structure() const
{
return 0;
}
@ -444,14 +444,14 @@ protected:
typedef typename Tr::Cell_handle Cell_handle;
typedef typename Tr::Facet Facet;
C3T3_helpers_base(LockDataStructureType *p_lock_ds)
C3T3_helpers_base(Default_lock_data_structure *p_lock_ds)
: m_lock_ds(p_lock_ds) {}
public:
// LOCKS (CONCURRENCY)
/*Mesh_3::LockDataStructureType *get_lock_data_structure() const
/*Default_lock_data_structure *get_lock_data_structure() const
{
return m_lock_ds;
}*/
@ -554,7 +554,7 @@ public:
}
protected:
Mesh_3::LockDataStructureType *m_lock_ds;
Default_lock_data_structure *m_lock_ds;
typedef tbb::mutex Mutex_type;
mutable Mutex_type m_mut_outdated_cells;
@ -640,7 +640,7 @@ public:
* Constructor
*/
C3T3_helpers(C3T3& c3t3, const MeshDomain& domain,
LockDataStructureType *p_lock_ds = 0)
Default_lock_data_structure *p_lock_ds = 0)
: Base(p_lock_ds)
, c3t3_(c3t3)
, tr_(c3t3.triangulation())

View File

@ -38,7 +38,6 @@
#include <algorithm>
namespace CGAL {
namespace Mesh_3 {
//******************************************************************************
// class Grid_locking_ds_base_3
@ -572,17 +571,17 @@ protected:
};
//typedef Simple_grid_locking_ds_3 LockDataStructureType;
//typedef Simple_grid_locking_ds_with_mutex_3 LockDataStructureType;
typedef Simple_grid_locking_ds_with_thread_ids_3 LockDataStructureType;
//typedef Simple_grid_locking_ds_3 Default_lock_data_structure;
//typedef Simple_grid_locking_ds_with_mutex_3 Default_lock_data_structure;
typedef Simple_grid_locking_ds_with_thread_ids_3 Default_lock_data_structure;
} } //namespace CGAL::Mesh_3
} //namespace CGAL
#else // !CGAL_LINKED_WITH_TBB
namespace CGAL { namespace Mesh_3 {
typedef void LockDataStructureType;
} } //namespace CGAL::Mesh_3
namespace CGAL {
typedef void Default_lock_data_structure;
}
#endif // CGAL_LINKED_WITH_TBB

View File

@ -100,7 +100,7 @@ protected:
big_moves_.clear();
}
LockDataStructureType *get_lock_data_structure() { return 0; }
Default_lock_data_structure *get_lock_data_structure() { return 0; }
void unlock_all_elements() {}
protected:
@ -170,7 +170,7 @@ protected:
big_moves_.clear();
}
LockDataStructureType *get_lock_data_structure()
Default_lock_data_structure *get_lock_data_structure()
{
return &m_lock_ds;
}
@ -189,7 +189,7 @@ protected:
std::multiset<FT> big_moves_;
/// Lock data structure
LockDataStructureType m_lock_ds;
Default_lock_data_structure m_lock_ds;
};
#endif // CGAL_LINKED_WITH_TBB

View File

@ -39,7 +39,7 @@ namespace Mesh_3
* @class Mesh_sizing_field_base
*/
// Sequential
template <typename Cell_handle, bool used_by_parallel_mesh_3>
template <typename Cell_handle, typename Concurrency_tag>
class Mesh_sizing_field_base
{
protected:
@ -63,7 +63,7 @@ protected:
*/
// Parallel
template <typename Cell_handle>
class Mesh_sizing_field_base<Cell_handle, true>
class Mesh_sizing_field_base<Cell_handle, Parallel_tag>
{
protected:
Cell_handle get_last_cell() const
@ -87,7 +87,7 @@ protected:
template <typename Tr, bool Need_vertex_update = true>
class Mesh_sizing_field
: public Mesh_sizing_field_base<typename Tr::Cell_handle,
Tr::Is_for_parallel_mesh_3>
typename Tr::Concurrency_tag>
{
// Types
typedef typename Tr::Geom_traits Gt;

View File

@ -138,10 +138,10 @@ protected:
*/
template <class GT,
class MT,
class Cb,
typename Concurrency_tag>
class Cb>
class Mesh_surface_cell_base_3
: public Mesh_surface_cell_base_3_base<Concurrency_tag>
: public Mesh_surface_cell_base_3_base<
typename Cb::Triangulation_data_structure::Concurrency_tag>
, public Cb
{
public:
@ -160,7 +160,7 @@ public:
struct Rebind_TDS
{
typedef typename Cb::template Rebind_TDS<TDS3>::Other Cb3;
typedef Mesh_surface_cell_base_3 <GT, MT, Cb3, Concurrency_tag> Other;
typedef Mesh_surface_cell_base_3 <GT, MT, Cb3> Other;
};
/// Constructors
@ -279,12 +279,12 @@ private:
# pragma warning(default:4351)
#endif
template < class GT, class MT, class Cb, typename Ct >
template < class GT, class MT, class Cb >
inline
std::istream&
operator>>(std::istream &is, Mesh_surface_cell_base_3<GT, MT, Cb, Ct> &c)
operator>>(std::istream &is, Mesh_surface_cell_base_3<GT, MT, Cb> &c)
{
typename Mesh_surface_cell_base_3<GT, MT, Cb, Ct>::Surface_patch_index index;
typename Mesh_surface_cell_base_3<GT, MT, Cb>::Surface_patch_index index;
is >> static_cast<Cb&>(c);
for(int i = 0; i < 4; ++i)
{
@ -299,11 +299,11 @@ operator>>(std::istream &is, Mesh_surface_cell_base_3<GT, MT, Cb, Ct> &c)
return is;
}
template < class GT, class MT, class Cb, typename Ct >
template < class GT, class MT, class Cb >
inline
std::ostream&
operator<<(std::ostream &os,
const Mesh_surface_cell_base_3<GT, MT, Cb, Ct> &c)
const Mesh_surface_cell_base_3<GT, MT, Cb> &c)
{
os << static_cast<const Cb&>(c);
for(int i = 0; i < 4; ++i)

View File

@ -77,7 +77,7 @@ class Mesher_3_base
protected:
Mesher_3_base(const Bbox_3 &, int) {}
LockDataStructureType *get_lock_data_structure() { return 0; }
Default_lock_data_structure *get_lock_data_structure() { return 0; }
WorksharingDataStructureType *get_worksharing_data_structure() { return 0; }
void set_bbox(const Bbox_3 &) {}
};
@ -93,7 +93,7 @@ protected:
m_worksharing_ds(bbox)
{}
LockDataStructureType *get_lock_data_structure()
Default_lock_data_structure *get_lock_data_structure()
{
return &m_lock_ds;
}
@ -109,7 +109,7 @@ protected:
}
/// Lock data structure
LockDataStructureType m_lock_ds;
Default_lock_data_structure m_lock_ds;
/// Worksharing data structure
WorksharingDataStructureType m_worksharing_ds;
};

View File

@ -351,7 +351,7 @@ public:
const MeshDomain& oracle,
Previous_& previous,
C3T3& c3t3,
Mesh_3::LockDataStructureType *p_lock_ds,
Default_lock_data_structure *p_lock_ds,
Mesh_3::WorksharingDataStructureType *p_worksharing_ds);
// Destructor
@ -568,7 +568,7 @@ Refine_cells_3(Tr& triangulation,
const MD& oracle,
P_& previous,
C3T3& c3t3,
Mesh_3::LockDataStructureType *p_lock_ds,
Default_lock_data_structure *p_lock_ds,
Mesh_3::WorksharingDataStructureType *p_worksharing_ds)
: Mesher_level<Tr, Self, Cell_handle, P_,
Triangulation_mesher_level_traits_3<Tr>, Ct >(previous, p_lock_ds, p_worksharing_ds)

View File

@ -451,7 +451,7 @@ public:
const MeshDomain& oracle,
Previous_level_& previous,
C3T3& c3t3,
Mesh_3::LockDataStructureType *p_lock_ds,
Default_lock_data_structure *p_lock_ds,
Mesh_3::WorksharingDataStructureType *p_worksharing_ds);
/// Destructor
@ -866,7 +866,7 @@ Refine_facets_3(Tr& triangulation,
const MD& oracle,
P_& previous,
C3T3& c3t3,
Mesh_3::LockDataStructureType *p_lock_ds,
Default_lock_data_structure *p_lock_ds,
Mesh_3::WorksharingDataStructureType *p_worksharing_ds)
: Mesher_level<Tr, Self, Facet, P_,
Triangulation_mesher_level_traits_3<Tr>, Ct>(previous)

View File

@ -333,7 +333,7 @@ protected:
Sliver_perturber_base(const Bbox_3 &, int) {}
LockDataStructureType *get_lock_data_structure() const { return 0; }
Default_lock_data_structure *get_lock_data_structure() const { return 0; }
void unlock_all_elements() const {}
void create_root_task() const {}
bool flush_work_buffers() const { return true; }
@ -362,7 +362,7 @@ protected:
{
}
LockDataStructureType *get_lock_data_structure() const
Default_lock_data_structure *get_lock_data_structure() const
{
return &m_lock_ds;
}
@ -407,7 +407,7 @@ protected:
public:
protected:
mutable LockDataStructureType m_lock_ds;
mutable Default_lock_data_structure m_lock_ds;
mutable Mesh_3::Auto_worksharing_ds m_worksharing_ds;
mutable tbb::task *m_empty_root_task;
};

View File

@ -146,7 +146,7 @@ protected:
Slivers_exuder_base(const Bbox_3 &, int) {}
LockDataStructureType *get_lock_data_structure() const { return 0; }
Default_lock_data_structure *get_lock_data_structure() const { return 0; }
void unlock_all_elements() const {}
void create_root_task() const {}
bool flush_work_buffers() const { return true; }
@ -193,7 +193,7 @@ protected:
{
}
LockDataStructureType *get_lock_data_structure() const
Default_lock_data_structure *get_lock_data_structure() const
{
return &m_lock_ds;
}
@ -252,7 +252,7 @@ protected:
{ cell->increment_erase_counter(); }
};
mutable LockDataStructureType m_lock_ds;
mutable Default_lock_data_structure m_lock_ds;
mutable Mesh_3::Auto_worksharing_ds m_worksharing_ds;
mutable tbb::task *m_empty_root_task;
};
@ -363,7 +363,7 @@ public: // methods
#ifdef CGAL_LINKED_WITH_TBB
//CJTODO TEST
// Warning: this doesn't work for the becnhmark
// Warning: this doesn't work for the benchmark
// (because the benchmark creates the scheduler instance upstream...)
//tbb::task_scheduler_init tsi(1);
#endif

View File

@ -37,16 +37,16 @@ namespace CGAL {
// Adds information to Cb about the cell of the input complex containing it
template< class GT,
class MD,
class Cb,
typename Concurrency_tag = Sequential_tag>
class Cb = CGAL::Regular_triangulation_cell_base_3<
GT, CGAL::Triangulation_cell_base_with_circumcenter_3<GT> > >
class Mesh_cell_base_3
: public Mesh_3::Mesh_surface_cell_base_3<GT, MD, Cb, Concurrency_tag>
: public Mesh_3::Mesh_surface_cell_base_3<GT, MD, Cb>
{
typedef typename GT::FT FT;
public:
// Base
typedef Mesh_3::Mesh_surface_cell_base_3<GT, MD, Cb, Concurrency_tag> Base;
typedef Mesh_3::Mesh_surface_cell_base_3<GT, MD, Cb> Base;
// Index Type
typedef typename MD::Subdomain_index Subdomain_index;
typedef typename MD::Surface_patch_index Surface_patch_index;
@ -66,7 +66,7 @@ public:
struct Rebind_TDS
{
typedef typename Cb::template Rebind_TDS<TDS3>::Other Cb3;
typedef Mesh_cell_base_3 <GT, MD, Cb3, Concurrency_tag> Other;
typedef Mesh_cell_base_3 <GT, MD, Cb3> Other;
};
// Constructors
@ -163,32 +163,32 @@ private:
template < class GT, class MT, class Cb, typename Ct >
template < class GT, class MT, class Cb >
std::istream&
operator>>(std::istream &is,
Mesh_cell_base_3<GT, MT, Cb, Ct> &c)
Mesh_cell_base_3<GT, MT, Cb> &c)
{
typename Mesh_cell_base_3<GT, MT, Cb, Ct>::Subdomain_index index;
typename Mesh_cell_base_3<GT, MT, Cb>::Subdomain_index index;
if(is_ascii(is))
is >> index;
else
read(is, index);
typedef typename Mesh_cell_base_3<GT, MT, Cb, Ct>::Base Cell_base;
typedef typename Mesh_cell_base_3<GT, MT, Cb>::Base Cell_base;
is >> static_cast<Cell_base&>(c);
if(is) c.set_subdomain_index(index);
return is;
}
template < class GT, class MT, class Cb, typename Ct >
template < class GT, class MT, class Cb >
std::ostream&
operator<<(std::ostream &os,
const Mesh_cell_base_3<GT, MT, Cb, Ct> &c)
const Mesh_cell_base_3<GT, MT, Cb> &c)
{
if(is_ascii(os))
os << c.subdomain_index();
else
write(os, c.subdomain_index());
typedef typename Mesh_cell_base_3<GT, MT, Cb, Ct>::Base Cell_base;
typedef typename Mesh_cell_base_3<GT, MT, Cb>::Base Cell_base;
return os << static_cast<const Cell_base&>(c);
}

View File

@ -45,32 +45,11 @@ template <typename Tr,
typename CornerIndex = int,
typename CurveSegmentIndex = int>
class Mesh_complex_3_in_triangulation_3 :
public Mesh_3::Mesh_complex_3_in_triangulation_3_base
<
Tr,
#ifdef CGAL_LINKED_WITH_TBB
typename boost::mpl::if_c
<
Tr::Is_for_parallel_mesh_3,
Parallel_tag,
Sequential_tag
>::type
#else
Sequential_tag
#endif // CGAL_LINKED_WITH_TBB
>
public Mesh_3::Mesh_complex_3_in_triangulation_3_base<
Tr, typename Tr::Concurrency_tag>
{
public:
#ifdef CGAL_LINKED_WITH_TBB
typedef typename boost::mpl::if_c
<
Tr::Is_for_parallel_mesh_3,
Parallel_tag,
Sequential_tag
>::type Concurrency_tag;
#else
typedef Sequential_tag Concurrency_tag;
#endif // CGAL_LINKED_WITH_TBB
typedef typename typename Tr::Concurrency_tag Concurrency_tag;
private:
typedef Mesh_complex_3_in_triangulation_3<

View File

@ -60,29 +60,29 @@ namespace CGAL {
// Struct Mesh_triangulation_3
//
template< class MD,
class K=typename Kernel_traits<MD>::Kernel,
class GT = typename details::Mesh_geom_traits_generator<K>::type,
class Cb = CGAL::Regular_triangulation_cell_base_3
<
GT,
CGAL::Triangulation_cell_base_with_circumcenter_3<GT>
>
>
template<class MD, class K=typename Kernel_traits<MD>::Kernel>
struct Mesh_triangulation_3
{
private:
typedef GT Geom_traits;
typedef typename details::Mesh_geom_traits_generator<K>::type Geom_traits;
#ifdef CGAL_COMPACT_MESH_VERTEX_CELL
typedef Compact_mesh_vertex_base_3<Geom_traits, MD> Vertex_base;
typedef Compact_mesh_cell_base_3<Geom_traits, MD> Cell_base;
#else // NOT CGAL_COMPACT_MESH_VERTEX_CELL
typedef Mesh_vertex_base_3<Geom_traits, MD> Vertex_base;
typedef Mesh_cell_base_3<Geom_traits, MD, Cb> Cell_base;
typedef Mesh_cell_base_3<Geom_traits, MD> Cell_base;
#endif // NOT CGAL_COMPACT_MESH_VERTEX_CELL
#if defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE)\
|| defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE)
typedef Triangulation_data_structure_3<
Vertex_base, Cell_base,
Compact_container_strategy_with_counter,
Compact_container_strategy_with_counter> Tds;
#else
typedef Triangulation_data_structure_3<Vertex_base,Cell_base> Tds;
#endif
typedef Regular_triangulation_3<Geom_traits, Tds> Triangulation;
public:
@ -92,26 +92,11 @@ public:
// Struct Parallel_mesh_triangulation_3
//
template< class MD,
class K=typename Kernel_traits<MD>::Kernel,
class GT = typename details::Mesh_geom_traits_generator<K>::type,
class Cb = CGAL::Regular_triangulation_cell_base_3
<
GT,
CGAL::Triangulation_cell_base_with_circumcenter_3
<
GT
#ifdef CGAL_LINKED_WITH_TBB
// Force lazy-enabled cell
, Triangulation_lazy_ds_cell_base_3<Parallel_tag>
#endif // CGAL_LINKED_WITH_TBB
>
>
>
template<class MD, class K=typename Kernel_traits<MD>::Kernel>
struct Parallel_mesh_triangulation_3
{
private:
typedef GT Geom_traits;
typedef typename details::Mesh_geom_traits_generator<K>::type Geom_traits;
#ifdef CGAL_LINKED_WITH_TBB
@ -120,13 +105,16 @@ private:
typedef Compact_mesh_cell_base_3<Geom_traits,MD,Parallel_tag> Cell_base;
# else // NOT CGAL_COMPACT_MESH_VERTEX_CELL
typedef Mesh_vertex_base_3<Geom_traits, MD> Vertex_base;
typedef Mesh_cell_base_3<Geom_traits, MD, Cb, Parallel_tag> Cell_base;
typedef Mesh_cell_base_3<Geom_traits, MD> Cell_base;
# endif // NOT CGAL_COMPACT_MESH_VERTEX_CELL
typedef Triangulation_data_structure_3<
Vertex_base, Cell_base, true> Tds;
Vertex_base, Cell_base,
Compact_container_strategy_with_counter,
Compact_container_strategy_with_counter,
Parallel_tag> Tds;
typedef Regular_triangulation_3<
Geom_traits, Tds, Mesh_3::LockDataStructureType> Triangulation;
Geom_traits, Tds, Default_lock_data_structure> Triangulation;
#else // !CGAL_LINKED_WITH_TBB
@ -135,7 +123,7 @@ private:
typedef Compact_mesh_cell_base_3<Geom_traits, MD> Cell_base;
# else // NOT CGAL_COMPACT_MESH_VERTEX_CELL
typedef Mesh_vertex_base_3<Geom_traits, MD> Vertex_base;
typedef Mesh_cell_base_3<Geom_traits, MD, Cb> Cell_base;
typedef Mesh_cell_base_3<Geom_traits, MD> Cell_base;
# endif // NOT CGAL_COMPACT_MESH_VERTEX_CELL
typedef Triangulation_data_structure_3<

View File

@ -22,6 +22,7 @@
#include <CGAL/basic.h>
#include <CGAL/Default.h>
#include <CGAL/Compact_container_strategies.h>
#include <iterator>
#include <algorithm>
@ -112,43 +113,11 @@ namespace internal {
class CC_iterator;
}
// A basic "do nothing" CC_strategy_base
// One can inheritate from it for partial specialisation
template <typename Element>
class CC_strategy_base {
public:
// Do nothing
static unsigned int get_erase_counter(const Element &) { return 0; }
static void set_erase_counter(Element &, unsigned int) {}
static void increment_erase_counter(Element &) {}
};
// A CC_strategy managing an internal counter
template <typename Element>
class CC_strategy_with_counter
{
public:
static unsigned int get_erase_counter(const Element &e)
{
return e.get_erase_counter();
}
static void set_erase_counter(Element &e, unsigned int c)
{
e.set_erase_counter(c);
}
static void increment_erase_counter(Element &e)
{
e.increment_erase_counter();
}
};
// Class Compact_container
//
// Strategy_ is a functor which provides several functions
// See CC_strategy_base and CCC_strategy_with_counter above, and/or documentation
// See Compact_container_strategy_base and
// Compact_container_strategy_with_counter, and/or documentation
//
template < class T, class Allocator_ = Default, class Strategy_ = Default >
class Compact_container
@ -156,7 +125,8 @@ class Compact_container
typedef Allocator_ Al;
typedef Strategy_ Strat;
typedef typename Default::Get< Al, CGAL_ALLOCATOR(T) >::type Allocator;
typedef typename Default::Get< Strat, CC_strategy_base<T> >::type Strategy;
typedef typename Default::Get<
Strat, Compact_container_strategy_base >::type Strategy;
typedef Compact_container <T, Al, Strat> Self;
typedef Compact_container_traits <T> Traits;
public:

View File

@ -0,0 +1,68 @@
// Copyright (c) 2012 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL: $
// $Id: $
//
// Author(s) : Clement Jamin
#ifndef CGAL_COMPACT_CONTAINER_STRATEGIES_H
#define CGAL_COMPACT_CONTAINER_STRATEGIES_H
namespace CGAL {
// A basic "do nothing" strategy
// One can inheritate from it for partial specialisation
class Compact_container_strategy_base {
public:
static const bool Uses_erase_counter = false;
// Do nothing
template <typename Element>
static unsigned int get_erase_counter(const Element &) { return 0; }
template <typename Element>
static void set_erase_counter(Element &, unsigned int) {}
template <typename Element>
static void increment_erase_counter(Element &) {}
};
// A strategy managing an internal counter
class Compact_container_strategy_with_counter
{
public:
static const bool Uses_erase_counter = true;
template <typename Element>
static unsigned int get_erase_counter(const Element &e)
{
return e.get_erase_counter();
}
template <typename Element>
static void set_erase_counter(Element &e, unsigned int c)
{
e.set_erase_counter(c);
}
template <typename Element>
static void increment_erase_counter(Element &e)
{
e.increment_erase_counter();
}
};
} //namespace CGAL
#endif // CGAL_COMPACT_CONTAINER_STRATEGIES_H

View File

@ -24,6 +24,7 @@
#include <CGAL/basic.h>
#include <CGAL/Default.h>
#include <CGAL/Compact_container_strategies.h>
#include <iterator>
#include <algorithm>
@ -55,39 +56,6 @@ namespace internal {
class CCC_iterator;
}
// A basic "do nothing" CCC_strategy_base
// One can inheritate from it for partial specialisation
template <typename Element>
class CCC_strategy_base {
public:
// Do nothing
static unsigned int get_erase_counter(const Element &) { return 0; }
static void set_erase_counter(Element &, unsigned int) {}
static void increment_erase_counter(Element &) {}
};
// A CCC_strategy managing an internal counter
template <typename Element>
class CCC_strategy_with_counter
{
public:
static unsigned int get_erase_counter(const Element &e)
{
return e.get_erase_counter();
}
static void set_erase_counter(Element &e, unsigned int c)
{
e.set_erase_counter(c);
}
static void increment_erase_counter(Element &e)
{
e.increment_erase_counter();
}
};
// Free list (head and size)
template< typename pointer, typename size_type >
class Free_list {
@ -111,7 +79,8 @@ protected:
// Safe concurrent "insert" and "erase".
// Do not parse the container while others are modifying it.
// Strategy_ is a functor which provides several functions
// See CCC_strategy_base and CCC_strategy_with_counter above, and/or documentation
// See Compact_container_strategy_base and
// Compact_container_strategy_with_counter, and/or documentation
//
template < class T, class Allocator_ = Default, class Strategy_ = Default >
class Concurrent_compact_container
@ -119,7 +88,8 @@ class Concurrent_compact_container
typedef Allocator_ Al;
typedef Strategy_ Strat;
typedef typename Default::Get<Al, CGAL_ALLOCATOR(T) >::type Allocator;
typedef typename Default::Get<Strat, CCC_strategy_base<T> >::type Strategy;
typedef typename Default::Get<
Strat, Compact_container_strategy_base >::type Strategy;
typedef Concurrent_compact_container <T, Al, Strat> Self;
typedef Concurrent_compact_container_traits <T> Traits;

View File

@ -26,6 +26,29 @@ if(QT4_FOUND)
find_package(QGLViewer)
endif(QT4_FOUND)
# Activate concurrency ? (turned OFF by default)
option(ACTIVATE_CONCURRENT_TRIANGULATION_3
"Activate parallelism in Triangulation_3"
OFF)
# And add -DCONCURRENT_TRIANGULATION_3 if that option is ON
if( ACTIVATE_CONCURRENT_TRIANGULATION_3 )
add_definitions( -DCONCURRENT_TRIANGULATION_3 )
find_package( TBB REQUIRED )
else( ACTIVATE_CONCURRENT_TRIANGULATION_3 )
option( LINK_WITH_TBB
"Link with TBB anyway so we can use TBB timers for profiling"
ON)
if( LINK_WITH_TBB )
find_package( TBB )
endif( LINK_WITH_TBB )
endif()
if( TBB_FOUND )
add_definitions( -DNOMINMAX -DCGAL_LINKED_WITH_TBB )
include_directories ( ${TBB_INCLUDE_DIRS} )
endif()
if ( CGAL_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND )
include(${QT_USE_FILE})
@ -51,7 +74,7 @@ if ( CGAL_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND )
add_to_cached_list( CGAL_EXECUTABLE_TARGETS T3_demo )
target_link_libraries( T3_demo ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES})
target_link_libraries( T3_demo ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} )
target_link_libraries( T3_demo ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} ${TBB_LIBRARIES})
target_link_libraries( T3_demo ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} )
else( CGAL_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND )

View File

@ -36,6 +36,15 @@ void Scene::generatePoints(int num)
/* Insert the points to build a Delaunay triangulation */
/* Note: this function returns the number of inserted points;
it is not guaranteed to insert the points following the order of iteraror. */
#ifdef CONCURRENT_TRIANGULATION_3
CGAL::Default_lock_data_structure locking_ds(
CGAL::Bbox_3(-1.,-1.,-1.,1,1,1), 50);
m_dt.set_lock_data_structure(&locking_ds);
// CJTODO TEMP
# ifdef CGAL_DEBUG_GLOBAL_LOCK_DS
CGAL::Default_lock_data_structure::set_global_lock_ds(&locking_ds);
# endif
#endif
m_dt.insert( pts.begin(), pts.end() );
/* Check the combinatorial validity of the triangulation */
/* Note: when it is set to be true,

View File

@ -7,6 +7,9 @@
// CGAL
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/point_generators_3.h>
#ifdef CONCURRENT_TRIANGULATION_3
# include <CGAL/Mesh_3/Locking_data_structures.h>
#endif
// Added for T3 demo
#include <CGAL/Delaunay_triangulation_3.h>
@ -32,12 +35,15 @@ typedef Kernel::Direction_3 Direction_3;
/*
* The user has several ways to add his own data in the vertex
* and cell base classes used by the TDS. He can either: * 1. use the classes Triangulation vertex base with info
* and cell base classes used by the TDS. He can either:
* 1. use the classes Triangulation vertex base with info
* and Triangulation cell base with info, which allow to
* add one data member of a user provided type, and give access to it. * 2. derive his own classes from the default base classes
* add one data member of a user provided type, and give access to it.
* 2. derive his own classes from the default base classes
* Triangulation ds vertex base, and Triangulation ds cell base
* (or the geometric versions typically used by the geometric layer,
* Triangulation vertex base, and Triangulation cell base). * 3. write his own base classes following the requirements given by the concepts
* Triangulation vertex base, and Triangulation cell base).
* 3. write his own base classes following the requirements given by the concepts
* TriangulationCellBase 3 and TriangulationVertexBase 3
* (described in page 2494 and page 2495).
*/
@ -69,7 +75,6 @@ private:
bool m_isSelected; // whether it is selected
};
typedef CGAL::Triangulation_data_structure_3< Vertex_base<Kernel> > Tds;
/*
* Delaunay_triangulation_3<arg1, arg2, arg3>
* arg1: a model of the DelaunayTriangulationTraits_3 concept
@ -81,7 +86,19 @@ typedef CGAL::Triangulation_data_structure_3< Vertex_base<Kernel> > Tds;
* Compact_location saves memory by avoiding the separate data structure
* and point location is then O(n^(1/3)) time
*/
typedef CGAL::Delaunay_triangulation_3<Kernel, Tds, CGAL::Fast_location> DT3;
#ifdef CONCURRENT_TRIANGULATION_3
typedef CGAL::Triangulation_data_structure_3<
Vertex_base<Kernel>,
CGAL::Triangulation_ds_cell_base_3<>,
CGAL::Compact_container_strategy_base,
CGAL::Compact_container_strategy_base,
CGAL::Parallel_tag > Tds;
typedef CGAL::Delaunay_triangulation_3<Kernel, Tds> DT3;
#else
typedef CGAL::Triangulation_data_structure_3< Vertex_base<Kernel> > Tds;
typedef CGAL::Delaunay_triangulation_3<
Kernel, Tds, CGAL::Fast_location> DT3;
#endif
typedef DT3::Object Object_3;
typedef DT3::Point Point_3;

View File

@ -31,6 +31,7 @@
#include <CGAL/Triangulation_3.h>
#include <CGAL/iterator.h>
#include <CGAL/Location_policy.h>
#include <CGAL/Mesh_3/Profiling_tools.h> // CJTODO TEMP
#ifndef CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
#include <CGAL/Spatial_sort_traits_adapter_3.h>
@ -41,6 +42,11 @@
#include <boost/mpl/and.hpp>
#endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
#ifdef CGAL_LINKED_WITH_TBB
# include <tbb/parallel_for.h>
# include <tbb/enumerable_thread_specific.h>
#endif
#ifdef CGAL_DELAUNAY_3_OLD_REMOVE
# error "The old remove() code has been removed. Please report any issue you may have with the current one."
#endif
@ -51,7 +57,8 @@ namespace CGAL {
// having a default value. There is no definition of that class template.
template < class Gt,
class Tds_ = Default,
class Location_policy = Default >
class Location_policy = Default,
class Lock_data_structure_ = Default >
class Delaunay_triangulation_3;
// There is a specialization Delaunay_triangulation_3<Gt, Tds, Fast_location>
@ -59,12 +66,14 @@ class Delaunay_triangulation_3;
// Here is the specialization Delaunay_triangulation_3<Gt, Tds>, with two
// arguments, that is if Location_policy being the default value 'Default'.
template < class Gt, class Tds_ >
class Delaunay_triangulation_3<Gt, Tds_>
: public Triangulation_3<Gt, Tds_>
template < class Gt, class Tds_,
class Lock_data_structure_ >
class Delaunay_triangulation_3<Gt, Tds_, Default, Lock_data_structure_>
: public Triangulation_3<Gt, Tds_, Lock_data_structure_>
{
typedef Delaunay_triangulation_3<Gt, Tds_> Self;
typedef Triangulation_3<Gt,Tds_> Tr_Base;
typedef Delaunay_triangulation_3<Gt, Tds_, Default,
Lock_data_structure_> Self;
typedef Triangulation_3<Gt,Tds_,Lock_data_structure_> Tr_Base;
public:
@ -240,10 +249,146 @@ public:
std::vector<Point> points (first, last);
spatial_sort (points.begin(), points.end(), geom_traits());
WallClockTimer t; // CJTODO TEMP
// Parallel
#ifdef CGAL_LINKED_WITH_TBB
if (is_parallel())
{
size_t num_points = points.size();
int i = 0;
// Sequential until dim = 3 (or more)
Vertex_handle hint;
size_t num_points_seq = (std::min)(num_points, (size_t)500); // CJTODO: 100, 1000... ?
while (dimension() < 3 || i < num_points_seq)
{
hint = insert(points[i], hint);
++i;
}
tbb::task_scheduler_init init(10); // CJTODO TEMP
//tbb::enumerable_thread_specific<Vertex_handle> tls_hint(
// [&]()
// {
// static tbb::atomic<size_t> i_hints;
// return hints[(++i_hints) - 1];
// });
tbb::enumerable_thread_specific<Vertex_handle> tls_hint(hint);
// CJTODO: lambda functions OK?
tbb::parallel_for(
tbb::blocked_range<size_t>( i, num_points ),
[&] (const tbb::blocked_range<size_t>& r)
{
for( size_t i_point = r.begin() ; i_point != r.end() ; ++i_point)
{
//std::stringstream sstr;
//sstr << i_point << " ";
//std::cerr << sstr.str() << std::endl;
bool success = false;
while(!success)
{
if (try_lock_vertex(tls_hint.local()) && try_lock_point(points[i_point]))
{
bool could_lock_zone;
Vertex_handle new_hint = insert(
points[i_point], tls_hint.local(), &could_lock_zone);
if (could_lock_zone)
{
tls_hint.local() = new_hint;
success = true;
}
}
else
{
//std::this_thread::yield();
//if (i_point != (r.end() - 1))
// std::swap(points[i_point], points[i_point+1]);
}
unlock_all_elements();
}
//std::cerr << i_point << " done." << std::endl;
}
}
);
/*size_t num_points = points.size();
// Sequential until dim = 3 (or more)
Vertex_handle hint;
size_t num_points_seq = 1000;
std::vector<Vertex_handle> hints(num_points_seq);
size_t i = 0;
while (i < num_points_seq)
{
hint = insert(points[i*num_points/num_points_seq], hint);
hints[i] = hint;
++i;
}
tbb::task_scheduler_init init(10); // CJTODO TEMP
// CJTODO: lambda functions OK?
tbb::parallel_for(
tbb::blocked_range<size_t>( 0, num_points_seq, 1 ),
[&] (const tbb::blocked_range<size_t>& r)
{
for( size_t i_range = r.begin() ; i_range != r.end() ; ++i_range)
{
Vertex_handle hint = hints[i_range];
for (size_t i_point = i_range*num_points/num_points_seq + 1 ;
i_point != (i_range+1)*num_points/num_points_seq ;
++i_point)
{
//std::stringstream sstr;
//sstr << i_point << " ";
//std::cerr << sstr.str() << std::endl;
bool success = false;
while(!success)
{
if (try_lock_vertex(hint) && try_lock_point(points[i_point]))
{
bool could_lock_zone;
Vertex_handle new_hint = insert(
points[i_point], hint, &could_lock_zone);
if (could_lock_zone)
{
hint = new_hint;
success = true;
}
}
else
{
//std::this_thread::yield();
//if (i_point != (r.end() - 1))
// std::swap(points[i_point], points[i_point+1]);
}
unlock_all_elements();
}
}
//std::cerr << i_point << " done." << std::endl;
}
}
);*/
}
// Sequential
else
#endif // CGAL_LINKED_WITH_TBB
{
Vertex_handle hint;
for (typename std::vector<Point>::const_iterator p = points.begin(), end = points.end();
p != end; ++p)
hint = insert(*p, hint);
}
std::cerr << "Triangulation computed in " << t.elapsed() << " seconds." << std::endl;
return number_of_vertices() - n;
}
@ -323,15 +468,19 @@ public:
}
#endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
Vertex_handle insert(const Point & p, Vertex_handle hint)
Vertex_handle insert(const Point & p, Vertex_handle hint,
bool *p_could_lock_zone = 0)
{
return insert(p, hint == Vertex_handle() ? this->infinite_cell() : hint->cell());
return insert(p, hint == Vertex_handle() ? this->infinite_cell() : hint->cell(),
p_could_lock_zone);
}
Vertex_handle insert(const Point & p, Cell_handle start = Cell_handle());
Vertex_handle insert(const Point & p, Cell_handle start = Cell_handle(),
bool *p_could_lock_zone = 0);
Vertex_handle insert(const Point & p, Locate_type lt,
Cell_handle c, int li, int);
Cell_handle c, int li, int,
bool *p_could_lock_zone = 0);
public: // internal methods
@ -675,35 +824,51 @@ protected:
Hidden_point_visitor hidden_point_visitor;
};
template < class Gt, class Tds >
typename Delaunay_triangulation_3<Gt,Tds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds>::
insert(const Point & p, Cell_handle start)
template < class Gt, class Tds, class Lds >
typename Delaunay_triangulation_3<Gt,Tds,Default,Lds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
insert(const Point & p, Cell_handle start, bool *p_could_lock_zone)
{
Locate_type lt;
int li, lj;
// Parallel
if (p_could_lock_zone)
{
Cell_handle c = locate(p, lt, li, lj, start, p_could_lock_zone);
if (*p_could_lock_zone)
return insert(p, lt, c, li, lj, p_could_lock_zone);
else
return Vertex_handle();
}
// Sequential
else
{
Cell_handle c = locate(p, lt, li, lj, start);
return insert(p, lt, c, li, lj);
}
template < class Gt, class Tds >
typename Delaunay_triangulation_3<Gt,Tds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds>::
insert(const Point & p, Locate_type lt, Cell_handle c, int li, int lj)
}
template < class Gt, class Tds, class Lds >
typename Delaunay_triangulation_3<Gt,Tds,Default,Lds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
insert(const Point & p, Locate_type lt, Cell_handle c, int li, int lj,
bool *p_could_lock_zone)
{
switch (dimension()) {
case 3:
{
Conflict_tester_3 tester(p, this);
Vertex_handle v = insert_in_conflict(p, lt, c, li, lj,
tester, hidden_point_visitor);
tester, hidden_point_visitor, p_could_lock_zone);
return v;
}// dim 3
case 2:
{
Conflict_tester_2 tester(p, this);
return insert_in_conflict(p, lt, c, li, lj,
tester, hidden_point_visitor);
tester, hidden_point_visitor, p_could_lock_zone);
}//dim 2
default :
// dimension <= 1
@ -712,10 +877,10 @@ insert(const Point & p, Locate_type lt, Cell_handle c, int li, int lj)
}
}
template < class Gt, class Tds >
template < class Gt, class Tds, class Lds >
template <class OutputItCells>
typename Delaunay_triangulation_3<Gt,Tds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds>::
typename Delaunay_triangulation_3<Gt,Tds,Default,Lds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
insert_and_give_new_cells(const Point &p,
OutputItCells fit,
Cell_handle start)
@ -742,10 +907,10 @@ insert_and_give_new_cells(const Point &p,
return v;
}
template < class Gt, class Tds >
template < class Gt, class Tds, class Lds >
template <class OutputItCells>
typename Delaunay_triangulation_3<Gt,Tds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds>::
typename Delaunay_triangulation_3<Gt,Tds,Default,Lds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
insert_and_give_new_cells(const Point& p,
OutputItCells fit,
Vertex_handle hint)
@ -772,10 +937,10 @@ insert_and_give_new_cells(const Point& p,
return v;
}
template < class Gt, class Tds >
template < class Gt, class Tds, class Lds >
template <class OutputItCells>
typename Delaunay_triangulation_3<Gt,Tds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds>::
typename Delaunay_triangulation_3<Gt,Tds,Default,Lds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
insert_and_give_new_cells(const Point& p,
Locate_type lt,
Cell_handle c, int li, int lj,
@ -804,9 +969,9 @@ insert_and_give_new_cells(const Point& p,
}
#ifndef CGAL_NO_DEPRECATED_CODE
template < class Gt, class Tds >
typename Delaunay_triangulation_3<Gt,Tds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds>::
template < class Gt, class Tds, class Lds >
typename Delaunay_triangulation_3<Gt,Tds,Default,Lds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
move_point(Vertex_handle v, const Point & p)
{
CGAL_triangulation_precondition(! is_infinite(v));
@ -828,9 +993,9 @@ move_point(Vertex_handle v, const Point & p)
}
#endif
template <class Gt, class Tds >
template <class Gt, class Tds, class Lds >
template <class DelaunayTriangulation_3>
class Delaunay_triangulation_3<Gt, Tds>::Vertex_remover {
class Delaunay_triangulation_3<Gt,Tds,Default,Lds>::Vertex_remover {
typedef DelaunayTriangulation_3 Delaunay;
public:
typedef Nullptr_t Hidden_points_iterator;
@ -849,9 +1014,9 @@ public:
}
};
template <class Gt, class Tds >
template <class Gt, class Tds, class Lds >
template <class DelaunayTriangulation_3>
class Delaunay_triangulation_3<Gt, Tds>::Vertex_inserter {
class Delaunay_triangulation_3<Gt,Tds,Default,Lds>::Vertex_inserter {
typedef DelaunayTriangulation_3 Delaunay;
public:
typedef Nullptr_t Hidden_points_iterator;
@ -878,9 +1043,9 @@ public:
}
};
template < class Gt, class Tds >
template < class Gt, class Tds, class Lds >
void
Delaunay_triangulation_3<Gt,Tds>::
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
remove(Vertex_handle v)
{
Self tmp;
@ -890,9 +1055,9 @@ remove(Vertex_handle v)
CGAL_triangulation_expensive_postcondition(is_valid());
}
template < class Gt, class Tds >
typename Delaunay_triangulation_3<Gt,Tds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds>::
template < class Gt, class Tds, class Lds >
typename Delaunay_triangulation_3<Gt,Tds,Default,Lds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
move_if_no_collision(Vertex_handle v, const Point &p)
{
Self tmp;
@ -904,9 +1069,9 @@ move_if_no_collision(Vertex_handle v, const Point &p)
return res;
}
template <class Gt, class Tds >
typename Delaunay_triangulation_3<Gt,Tds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds>::
template <class Gt, class Tds, class Lds >
typename Delaunay_triangulation_3<Gt,Tds,Default,Lds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
move(Vertex_handle v, const Point &p) {
CGAL_triangulation_precondition(!is_infinite(v));
if(v->point() == p) return v;
@ -916,10 +1081,10 @@ move(Vertex_handle v, const Point &p) {
return Tr_Base::move(v,p,remover,inserter);
}
template < class Gt, class Tds >
template < class Gt, class Tds, class Lds >
template <class OutputItCells>
void
Delaunay_triangulation_3<Gt,Tds>::
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
remove_and_give_new_cells(Vertex_handle v, OutputItCells fit)
{
Self tmp;
@ -929,10 +1094,10 @@ remove_and_give_new_cells(Vertex_handle v, OutputItCells fit)
CGAL_triangulation_expensive_postcondition(is_valid());
}
template < class Gt, class Tds >
template < class Gt, class Tds, class Lds >
template <class OutputItCells>
typename Delaunay_triangulation_3<Gt,Tds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds>::
typename Delaunay_triangulation_3<Gt,Tds,Default,Lds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
move_if_no_collision_and_give_new_cells(Vertex_handle v, const Point &p,
OutputItCells fit)
{
@ -947,9 +1112,9 @@ move_if_no_collision_and_give_new_cells(Vertex_handle v, const Point &p,
return res;
}
template < class Gt, class Tds >
template < class Gt, class Tds, class Lds >
Oriented_side
Delaunay_triangulation_3<Gt,Tds>::
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
side_of_oriented_sphere(const Point &p0, const Point &p1, const Point &p2,
const Point &p3, const Point &p, bool perturb) const
{
@ -989,9 +1154,9 @@ side_of_oriented_sphere(const Point &p0, const Point &p1, const Point &p2,
return ON_NEGATIVE_SIDE;
}
template < class Gt, class Tds >
template < class Gt, class Tds, class Lds >
Bounded_side
Delaunay_triangulation_3<Gt,Tds>::
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
coplanar_side_of_bounded_circle(const Point &p0, const Point &p1,
const Point &p2, const Point &p, bool perturb) const
{
@ -1042,9 +1207,9 @@ coplanar_side_of_bounded_circle(const Point &p0, const Point &p1,
return Bounded_side(-local); //ON_UNBOUNDED_SIDE;
}
template < class Gt, class Tds >
template < class Gt, class Tds, class Lds >
Bounded_side
Delaunay_triangulation_3<Gt,Tds>::
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
side_of_sphere(Vertex_handle v0, Vertex_handle v1,
Vertex_handle v2, Vertex_handle v3,
const Point &p, bool perturb) const
@ -1082,9 +1247,9 @@ side_of_sphere(Vertex_handle v0, Vertex_handle v1,
return (Bounded_side) side_of_oriented_sphere(v0->point(), v1->point(), v2->point(), v3->point(), p, perturb);
}
template < class Gt, class Tds >
template < class Gt, class Tds, class Lds >
Bounded_side
Delaunay_triangulation_3<Gt,Tds>::
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
side_of_circle(Cell_handle c, int i,
const Point & p, bool perturb) const
// precondition : dimension >=2
@ -1174,9 +1339,9 @@ side_of_circle(Cell_handle c, int i,
lt, i_e );
}
template < class Gt, class Tds >
typename Delaunay_triangulation_3<Gt,Tds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds>::
template < class Gt, class Tds, class Lds >
typename Delaunay_triangulation_3<Gt,Tds,Default,Lds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
nearest_vertex_in_cell(const Point& p, Cell_handle c) const
// Returns the finite vertex of the cell c which is the closest to p.
{
@ -1191,9 +1356,9 @@ nearest_vertex_in_cell(const Point& p, Cell_handle c) const
return nearest;
}
template < class Gt, class Tds >
typename Delaunay_triangulation_3<Gt,Tds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds>::
template < class Gt, class Tds, class Lds >
typename Delaunay_triangulation_3<Gt,Tds,Default,Lds>::Vertex_handle
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
nearest_vertex(const Point& p, Cell_handle start) const
{
if (number_of_vertices() == 0)
@ -1243,9 +1408,9 @@ nearest_vertex(const Point& p, Cell_handle start) const
// Also the visitor in TDS could be more clever.
// The Delaunay triangulation which filters displacements
// will do these optimizations.
template <class Gt, class Tds >
template <class Gt, class Tds, class Lds >
bool
Delaunay_triangulation_3<Gt,Tds>::
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
is_delaunay_after_displacement(Vertex_handle v, const Point &p) const
{
CGAL_triangulation_precondition(!this->is_infinite(v));
@ -1306,17 +1471,17 @@ is_delaunay_after_displacement(Vertex_handle v, const Point &p) const
return true;
}
template < class Gt, class Tds >
template < class Gt, class Tds, class Lds >
bool
Delaunay_triangulation_3<Gt,Tds>::
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
is_Gabriel(const Facet& f) const
{
return is_Gabriel(f.first, f.second);
}
template < class Gt, class Tds >
template < class Gt, class Tds, class Lds >
bool
Delaunay_triangulation_3<Gt,Tds>::
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
is_Gabriel(Cell_handle c, int i) const
{
CGAL_triangulation_precondition(dimension() == 3 && !is_infinite(c,i));
@ -1343,17 +1508,17 @@ is_Gabriel(Cell_handle c, int i) const
return true;
}
template < class Gt, class Tds >
template < class Gt, class Tds, class Lds >
bool
Delaunay_triangulation_3<Gt,Tds>::
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
is_Gabriel(const Edge& e) const
{
return is_Gabriel(e.first, e.second, e.third);
}
template < class Gt, class Tds >
template < class Gt, class Tds, class Lds >
bool
Delaunay_triangulation_3<Gt,Tds>::
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
is_Gabriel(Cell_handle c, int i, int j) const
{
CGAL_triangulation_precondition(dimension() == 3 && !is_infinite(c,i,j));
@ -1379,9 +1544,9 @@ is_Gabriel(Cell_handle c, int i, int j) const
return true;
}
template < class Gt, class Tds >
typename Delaunay_triangulation_3<Gt,Tds>::Point
Delaunay_triangulation_3<Gt,Tds>::
template < class Gt, class Tds, class Lds >
typename Delaunay_triangulation_3<Gt,Tds,Default,Lds>::Point
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
dual(Cell_handle c) const
{
CGAL_triangulation_precondition(dimension()==3);
@ -1390,9 +1555,9 @@ dual(Cell_handle c) const
}
template < class Gt, class Tds >
typename Delaunay_triangulation_3<Gt,Tds>::Object
Delaunay_triangulation_3<Gt,Tds>::
template < class Gt, class Tds, class Lds >
typename Delaunay_triangulation_3<Gt,Tds,Default,Lds>::Object
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
dual(Cell_handle c, int i) const
{
CGAL_triangulation_precondition(dimension()>=2);
@ -1436,9 +1601,9 @@ dual(Cell_handle c, int i) const
template < class Gt, class Tds >
typename Delaunay_triangulation_3<Gt,Tds>::Line
Delaunay_triangulation_3<Gt,Tds>::
template < class Gt, class Tds, class Lds >
typename Delaunay_triangulation_3<Gt,Tds,Default,Lds>::Line
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
dual_support(Cell_handle c, int i) const
{
CGAL_triangulation_precondition(dimension()>=2);
@ -1457,9 +1622,9 @@ dual_support(Cell_handle c, int i) const
}
template < class Gt, class Tds >
template < class Gt, class Tds, class Lds >
bool
Delaunay_triangulation_3<Gt,Tds>::
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
is_valid(bool verbose, int level) const
{
if ( ! tds().is_valid(verbose,level) ) {
@ -1533,9 +1698,9 @@ is_valid(bool verbose, int level) const
return true;
}
template < class Gt, class Tds >
template < class Gt, class Tds, class Lds >
bool
Delaunay_triangulation_3<Gt,Tds>::
Delaunay_triangulation_3<Gt,Tds,Default,Lds>::
is_valid(Cell_handle c, bool verbose, int level) const
{
if ( ! Tr_Base::is_valid(c,verbose,level) ) {

View File

@ -33,7 +33,6 @@
#include <CGAL/Triangulation_3.h>
#include <CGAL/Regular_triangulation_cell_base_3.h>
#include <boost/bind.hpp>
#include <boost/type_traits/is_base_of.hpp>
#ifndef CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
#include <CGAL/Spatial_sort_traits_adapter_3.h>
@ -57,31 +56,30 @@ namespace CGAL {
*
************************************************/
template < class Gt, class Tds_ = Default, class Locking_data_structure = void >
template < class Gt, class Tds_ = Default, class Lock_data_structure_ = Default >
class Regular_triangulation_3
: public Triangulation_3<
Gt,
typename Default::Get<Tds_, Triangulation_data_structure_3 <
Triangulation_vertex_base_3<Gt>,
Regular_triangulation_cell_base_3<Gt> > >::type,
Locking_data_structure>
Lock_data_structure_>
{
typedef Regular_triangulation_3<Gt, Tds_, Locking_data_structure> Self;
typedef Regular_triangulation_3<Gt, Tds_, Lock_data_structure_> Self;
typedef typename Default::Get<Tds_, Triangulation_data_structure_3 <
Triangulation_vertex_base_3<Gt>,
Regular_triangulation_cell_base_3<Gt> > >::type Tds;
typedef Triangulation_3<Gt,Tds,Locking_data_structure> Tr_Base;
typedef Triangulation_3<Gt,Tds,Lock_data_structure_> Tr_Base;
public:
static const bool Is_for_parallel_mesh_3 =
!boost::is_same<Locking_data_structure, void>::value; // CJTODO: remove this Mesh_3 thing
typedef Tds Triangulation_data_structure;
typedef Gt Geom_traits;
typedef typename Tr_Base::Concurrency_tag Concurrency_tag;
typedef typename Tr_Base::Vertex_handle Vertex_handle;
typedef typename Tr_Base::Cell_handle Cell_handle;
typedef typename Tr_Base::Vertex Vertex;
@ -845,7 +843,7 @@ namespace CGAL {
// Sequential version
// "dummy" is here to allow the specialization (see below)
// See http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/285ab1eec49e1cb6
template<bool used_by_parallel_mesh_3_, typename dummy = void>
template<typename Concurrency_tag_, typename dummy = void>
class Hidden_point_visitor
{
Self *t;
@ -907,9 +905,9 @@ namespace CGAL {
#ifdef CGAL_LINKED_WITH_TBB
// Parallel version specialization
template<typename dummy>
class Hidden_point_visitor<true, dummy>
class Hidden_point_visitor<Parallel_tag, dummy>
{
typedef Hidden_point_visitor<true> HPV;
typedef Hidden_point_visitor<Parallel_tag> HPV;
Self *t;
mutable tbb::enumerable_thread_specific<std::vector<Vertex_handle> > vertices;
@ -968,7 +966,7 @@ namespace CGAL {
};
#endif // CGAL_LINKED_WITH_TBB
Hidden_point_visitor<Is_for_parallel_mesh_3> &get_hidden_point_visitor() // CJTODO: remove this Mesh_3 thing
Hidden_point_visitor<Concurrency_tag> &get_hidden_point_visitor()
{
return hidden_point_visitor;
}
@ -979,7 +977,7 @@ namespace CGAL {
template < class RegularTriangulation_3 >
class Vertex_inserter;
Hidden_point_visitor<Is_for_parallel_mesh_3> hidden_point_visitor; // CJTODO: remove this Mesh_3 thing
Hidden_point_visitor<Concurrency_tag> hidden_point_visitor;
};
@ -1478,7 +1476,7 @@ namespace CGAL {
int li, lj;
// Sequential
if (boost::is_same<Lds, void>::value)
if (!is_parallel())
{
Cell_handle c = locate(p, lt, li, lj, start);
return insert(p, lt, c, li, lj);

View File

@ -46,6 +46,8 @@
#include <CGAL/Unique_hash_map.h>
#include <CGAL/Default.h>
#include <CGAL/Mesh_3/Locking_data_structures.h>
#include <boost/bind.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/uniform_smallint.hpp>
@ -60,7 +62,7 @@
namespace CGAL {
template < class GT, class Tds = Default,
class Locking_data_structure = void >
class Lock_data_structure = Default >
class Triangulation_3;
template < class GT, class Tds, class Lds > std::istream& operator>>
@ -90,27 +92,98 @@ struct Structural_filtering_selector_3<true> {
/************************************************
// Class Triangulation_3_base
// Two versions: with locking / without locking
// Two versions: Sequential (no locking) / Parallel (with locking)
************************************************/
// With locking
template <class Locking_data_structure>
// Sequential (without locking)
template <typename Concurrency_tag, typename Lock_data_structure_>
class Triangulation_3_base
{
protected:
Triangulation_3_base() {}
Triangulation_3_base(Lock_data_structure_ *) {}
void swap(Triangulation_3_base<Concurrency_tag,Lock_data_structure_> &tr){}
public:
bool is_parallel()
{
return false;
}
// LOCKS (no-op functions)
template <typename Vertex_handle>
bool try_lock_vertex(const Vertex_handle &, int = 0) const
{ return true; }
template <typename Cell_handle>
bool try_lock_cell(const Cell_handle &, int = 0) const
{ return true; }
template <typename Facet>
bool try_lock_facet(const Facet &, int = 0) const
{ return true; }
template <typename P3>
bool is_point_locked_by_this_thread(const P3 &) const
{ return false; }
template <typename Cell_handle>
bool is_cell_locked_by_this_thread(const Cell_handle &) const
{ return false; }
void *get_lock_data_structure() const
{
return 0;
}
void set_lock_data_structure(void *) const
{
}
void unlock_all_elements() {}
template <typename P3> void unlock_all_elements_but_one_point(const P3 &) {}
};
// Parallel (with locking)
template <typename Lock_data_structure_>
class Triangulation_3_base<Parallel_tag, Lock_data_structure_>
{
// If Lock_data_structure_ = Default => use Default_lock_data_structure
typedef typename Default::Get<
Lock_data_structure_, Default_lock_data_structure>::type Lock_data_structure;
protected:
Triangulation_3_base()
: m_lock_ds(0) {}
Triangulation_3_base(Locking_data_structure *p_lock_ds)
Triangulation_3_base(Lock_data_structure *p_lock_ds)
: m_lock_ds(p_lock_ds) {}
void swap(Triangulation_3_base<Locking_data_structure> &tr)
void swap(Triangulation_3_base<Parallel_tag, Lock_data_structure_> &tr)
{
std::swap(tr.m_lock_ds, m_lock_ds);
}
public:
bool is_parallel()
{
return m_lock_ds != 0;
}
// LOCKS
template <typename Point_3>
bool try_lock_point(const Point_3 &p, int lock_radius = 0) const
{
bool locked = true;
if (m_lock_ds)
{
locked = m_lock_ds->try_lock(p, lock_radius).first;
}
return locked;
}
template <typename Vertex_handle>
bool try_lock_vertex(const Vertex_handle &vh, int lock_radius = 0) const
{
@ -175,12 +248,12 @@ public:
return locked;
}
Locking_data_structure *get_lock_data_structure() const
Lock_data_structure *get_lock_data_structure() const
{
return m_lock_ds;
}
void set_lock_data_structure(Locking_data_structure *p_lock_ds)
void set_lock_data_structure(Lock_data_structure *p_lock_ds)
{
m_lock_ds = p_lock_ds;
}
@ -188,57 +261,18 @@ public:
void unlock_all_elements()
{
if (m_lock_ds)
{
m_lock_ds->unlock_all_tls_locked_cells();
}
}
protected:
Locking_data_structure *m_lock_ds;
};
// Without locking
template <>
class Triangulation_3_base<void>
{
protected:
Triangulation_3_base() {}
Triangulation_3_base(void *) {}
void swap(Triangulation_3_base<void> &tr) {}
public:
// LOCKS (no-op functions)
template <typename Vertex_handle>
bool try_lock_vertex(const Vertex_handle &, int = 0) const
{ return true; }
template <typename Cell_handle>
bool try_lock_cell(const Cell_handle &, int = 0) const
{ return true; }
template <typename Facet>
bool try_lock_facet(const Facet &, int = 0) const
{ return true; }
template <typename P3>
bool is_point_locked_by_this_thread(const P3 &) const
{ return false; }
template <typename Cell_handle>
bool is_cell_locked_by_this_thread(const Cell_handle &) const
{ return false; }
void *get_lock_data_structure() const
void unlock_all_elements_but_one_point(const P3 &point)
{
return 0;
if (m_lock_ds)
m_lock_ds->unlock_all_tls_locked_cells_but_one_point(point);
}
void set_lock_data_structure(void *) const
{
}
void unlock_all_elements() {}
protected:
Lock_data_structure *m_lock_ds;
};
/************************************************
@ -247,45 +281,30 @@ public:
*
************************************************/
template < class GT, class Tds_, class Locking_data_structure >
template < class GT, class Tds_, class Lock_data_structure_ >
class Triangulation_3
: public Triangulation_3_base<Locking_data_structure>
: public Triangulation_3_base<
// Get Concurrency_tag from TDS
typename Default::Get< Tds_,
Triangulation_data_structure_3
<
Triangulation_vertex_base_3<GT>,
Triangulation_cell_base_3<GT>
>
>::type::Concurrency_tag,
Lock_data_structure_>
, public Triangulation_utils_3
{
friend std::istream& operator>> <>
(std::istream& is, Triangulation_3<GT,Tds_,Locking_data_structure> &tr);
typedef Triangulation_3<GT, Tds_, Locking_data_structure> Self;
typedef Triangulation_3_base<Locking_data_structure> Base;
(std::istream& is, Triangulation_3<GT,Tds_,Lock_data_structure_> &tr);
typedef typename Default::Get<Tds_, Triangulation_data_structure_3 <
Triangulation_vertex_base_3<GT>,
Triangulation_cell_base_3<GT> > >::type Tds;
/*
// Useless: the user is responsible for providing a good TDS
typedef typename Default::Get
<
Tds_,
Triangulation_data_structure_3
<
Triangulation_vertex_base_3<GT>,
Triangulation_cell_base_3
<
GT
// Force lazy cells if used by parallel Mesh_3
#if defined(CGAL_LINKED_WITH_TBB) \
&& !defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \
&& !defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE)
,typename boost::mpl::if_c
<
boost::is_same<Locking_data_structure, void>,
Triangulation_ds_cell_base_3<>,
Triangulation_lazy_ds_cell_base_3<>
>::type
#endif
>
>
>::type Tds;*/
typedef Triangulation_3<GT, Tds_, Lock_data_structure_> Self;
typedef Triangulation_3_base<
typename Tds::Concurrency_tag, Lock_data_structure_> Base;
public:
@ -297,6 +316,8 @@ public:
typedef typename GT::Triangle_3 Triangle;
typedef typename GT::Tetrahedron_3 Tetrahedron;
typedef typename Tds::Concurrency_tag Concurrency_tag;
typedef typename Tds::Vertex Vertex;
typedef typename Tds::Cell Cell;
typedef typename Tds::Facet Facet;
@ -948,7 +969,8 @@ public:
Locate_type lt,
Cell_handle c, int li, int lj,
const Conflict_tester &tester,
Hidden_points_visitor &hider);
Hidden_points_visitor &hider,
bool *p_could_lock_zone = 0);
template < class InputIterator >
std::ptrdiff_t insert(InputIterator first, InputIterator last)
@ -1068,7 +1090,6 @@ protected:
) const
{
CGAL_triangulation_precondition( dimension()>=2 );
CGAL_triangulation_precondition( tester(d) );
if (p_the_facet_is_not_in_its_cz)
*p_the_facet_is_not_in_its_cz = true;
@ -1085,6 +1106,8 @@ protected:
}
}
CGAL_triangulation_precondition( tester(d) );
// To store the boundary cells, in case we need to rollback
std::stack<Cell_handle> cell_stack;
cell_stack.push(d);
@ -1103,6 +1126,7 @@ protected:
// "test" is either in the conflict zone,
// either facet-adjacent to the CZ
// IF WE WANT TO LOCK ADJACENT CELLS
// CJTODO: remove this #ifdef?
#ifdef CGAL_MESH_3_CONCURRENT_REFINEMENT_LOCK_ADJ_CELLS
if (p_could_lock_zone)
{
@ -1134,6 +1158,7 @@ protected:
// "test" is in the conflict zone
// IF WE DO NOT WANT TO LOCK ADJACENT CELLS
// CJTODO: remove this #ifdef?
#if !defined(CGAL_MESH_3_CONCURRENT_REFINEMENT_LOCK_ADJ_CELLS)
if (p_could_lock_zone)
{
@ -2222,7 +2247,6 @@ exact_locate(const Point & p, Locate_type & lt, int & li, int & lj,
Cell_handle previous = Cell_handle();
Cell_handle c = start;
#ifdef CGAL_MESH_3_LOCKING_STRATEGY_SIMPLE_GRID_LOCKING
if (p_could_lock_zone)
{
if (!try_lock_cell(c))
@ -2231,7 +2255,6 @@ exact_locate(const Point & p, Locate_type & lt, int & li, int & lj,
return Cell_handle();
}
}
#endif
// Stores the results of the 4 orientation tests. It will be used
// at the end to decide if p lies on a face/edge/vertex/interior.
@ -2290,19 +2313,16 @@ exact_locate(const Point & p, Locate_type & lt, int & li, int & lj,
}
previous = c;
c = next;
#ifdef CGAL_MESH_3_LOCKING_STRATEGY_SIMPLE_GRID_LOCKING
if (p_could_lock_zone)
{
//previous->unlock(); // DON'T do that, "c" may be in
// the same locking cell as "previous"
//c->lock(); // WARNING: not atomic! => DEADLOCKS?
if (!try_lock_cell(c))
{
*p_could_lock_zone = false;
return Cell_handle();
}
}
#endif
try_next_cell = true;
}
}
@ -2531,6 +2551,16 @@ inexact_locate(const Point & t, Cell_handle start,
if ( start == Cell_handle() )
start = infinite_cell();
// CTODO: useless?
if (p_could_lock_zone)
{
if (!try_lock_cell(start))
{
*p_could_lock_zone = false;
return Cell_handle();
}
}
int ind_inf;
if( start->has_vertex(infinite, ind_inf) )
start = start->neighbor(ind_inf);
@ -2545,7 +2575,6 @@ inexact_locate(const Point & t, Cell_handle start,
Cell_handle previous = Cell_handle();
Cell_handle c = start;
#ifdef CGAL_MESH_3_LOCKING_STRATEGY_SIMPLE_GRID_LOCKING
if (p_could_lock_zone)
{
if (!try_lock_cell(c))
@ -2554,7 +2583,6 @@ inexact_locate(const Point & t, Cell_handle start,
return Cell_handle();
}
}
#endif
// Now treat the cell c.
try_next_cell:
@ -2588,19 +2616,16 @@ inexact_locate(const Point & t, Cell_handle start,
}
previous = c;
c = next;
#ifdef CGAL_MESH_3_LOCKING_STRATEGY_SIMPLE_GRID_LOCKING
if (p_could_lock_zone)
{
//previous->unlock(); // DON'T do that, "c" may be in
// the same locking cell as "previous"
//c->lock(); // WARNING: not atomic! => DEADLOCKS?
if (!try_lock_cell(c))
{
*p_could_lock_zone = false;
return Cell_handle();
}
}
#endif
if(n_of_turns) goto try_next_cell;
}
@ -3250,8 +3275,12 @@ Triangulation_3<GT,Tds,Lds>::
insert_in_conflict(const Point & p,
Locate_type lt, Cell_handle c, int li, int /*lj*/,
const Conflict_tester &tester,
Hidden_points_visitor &hider)
Hidden_points_visitor &hider,
bool *p_could_lock_zone)
{
if (p_could_lock_zone)
*p_could_lock_zone = true;
switch (dimension()) {
case 3:
{
@ -3271,10 +3300,53 @@ insert_in_conflict(const Point & p,
Facet facet;
cells.reserve(32);
find_conflicts
(c, tester, make_triple(Oneset_iterator<Facet>(facet),
// Parallel
if (p_could_lock_zone)
{
std::vector<Facet> facets;
facets.reserve(32);
find_conflicts(
c,
tester,
make_triple(
std::back_inserter(facets),
std::back_inserter(cells),
Emptyset_iterator()),
p_could_lock_zone);
if (*p_could_lock_zone == false)
{
BOOST_FOREACH(Cell_handle& ch,
std::make_pair(cells.begin(), cells.end()))
{
ch->tds_data().clear();
}
BOOST_FOREACH(Facet& f,
std::make_pair(facets.begin(), facets.end()))
{
f.first->neighbor(f.second)->tds_data().clear();
}
return Vertex_handle();
}
facet = facets.back();
}
// Sequential
else
{
cells.reserve(32);
find_conflicts(
c,
tester,
make_triple(
Oneset_iterator<Facet>(facet),
std::back_inserter(cells),
Emptyset_iterator()));
}
// Remember the points that are hidden by the conflicting cells,
// as they will be deleted during the insertion.

View File

@ -29,12 +29,7 @@
namespace CGAL {
#if defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \
|| defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE)
template < typename GT, typename Cb = Triangulation_lazy_ds_cell_base_3<> >
#else
template < typename GT, typename Cb = Triangulation_ds_cell_base_3<> >
#endif
class Triangulation_cell_base_3
: public Cb
{

View File

@ -31,12 +31,7 @@
namespace CGAL {
#if defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \
|| defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE)
template < typename GT, typename Cb = Triangulation_lazy_ds_cell_base_3<> >
#else
template < typename GT, typename Cb = Triangulation_ds_cell_base_3<> >
#endif
class Triangulation_cell_base_with_circumcenter_3
: public Cb
{

View File

@ -59,38 +59,44 @@
# endif
#endif
#include <boost/foreach.hpp>
namespace CGAL {
// TODO : noms : Vb != Vertex_base : clarifier.
template < class Vb = Triangulation_ds_vertex_base_3<>,
#if defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \
|| defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE)
class Cb = Triangulation_lazy_ds_cell_base_3<>,
#else
class Cb = Triangulation_ds_cell_base_3<>,
#endif
bool used_by_parallel_mesh_3 = false
class Vertex_container_strategy_ = Compact_container_strategy_base,
class Cell_container_strategy_ = Compact_container_strategy_base,
class Concurrency_tag_ = Sequential_tag
>
class Triangulation_data_structure_3
: public Triangulation_utils_3
{
typedef Triangulation_data_structure_3<Vb,Cb,used_by_parallel_mesh_3> Tds;
typedef Triangulation_data_structure_3<
Vb, Cb, Vertex_container_strategy_, Cell_container_strategy_,
Concurrency_tag_> Tds;
public:
static const bool Is_for_parallel_mesh_3 = used_by_parallel_mesh_3;
typedef Vertex_container_strategy_ Vertex_container_strategy;
typedef Cell_container_strategy_ Cell_container_strategy;
typedef Concurrency_tag_ Concurrency_tag;
// Tools to change the Vertex and Cell types of the TDS.
template < typename Vb2 >
struct Rebind_vertex {
typedef Triangulation_data_structure_3<Vb2, Cb, used_by_parallel_mesh_3> Other;
typedef Triangulation_data_structure_3<
Vb2, Cb, Vertex_container_strategy,
Cell_container_strategy, Concurrency_tag> Other;
};
template < typename Cb2 >
struct Rebind_cell {
typedef Triangulation_data_structure_3<Vb, Cb2, used_by_parallel_mesh_3> Other;
typedef Triangulation_data_structure_3<
Vb, Cb2, Vertex_container_strategy,
Cell_container_strategy, Concurrency_tag> Other;
};
// Put this TDS inside the Vertex and Cell types.
@ -123,47 +129,40 @@ private:
public:
#ifdef CGAL_LINKED_WITH_TBB
// Cells
// N.B.: Concurrent_compact_container requires TBB
#ifdef CGAL_LINKED_WITH_TBB
typedef typename boost::mpl::if_c
<
used_by_parallel_mesh_3,
// Parallel
boost::is_base_of<Parallel_tag, Concurrency_tag>::value,
Concurrent_compact_container<
Cell, Default, CCC_strategy_with_counter<Cell> >,
// Sequential
# if defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \
|| defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE)
Cell, Default, Cell_container_strategy>,
Compact_container<
Cell, Default, CC_strategy_with_counter<Cell> >
# else
Compact_container<Cell>
# endif
Cell, Default, Cell_container_strategy>
>::type Cell_range;
// Vertices
typedef typename boost::mpl::if_c
<
used_by_parallel_mesh_3,
Concurrent_compact_container<Vertex, Default, CCC_strategy_with_counter<Vertex> >,
Compact_container<Vertex>
>::type Vertex_range;
#else // !CGAL_LINKED_WITH_TBB
// Cells
# if defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \
|| defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE)
typedef Compact_container<
Cell, Default, CC_strategy_with_counter<Cell> > Cell_range;
# else
typedef Compact_container<Cell> Cell_range;
typedef Compact_container<
Cell, Default, Cell_container_strategy> Cell_range;
#endif
// Vertices
typedef Compact_container<Vertex> Vertex_range;
// N.B.: Concurrent_compact_container requires TBB
#ifdef CGAL_LINKED_WITH_TBB
typedef typename boost::mpl::if_c
<
boost::is_base_of<Parallel_tag, Concurrency_tag>::value,
Concurrent_compact_container<
Vertex, Default, Vertex_container_strategy>,
Compact_container<
Vertex, Default, Vertex_container_strategy>
>::type Vertex_range;
# else
typedef Compact_container<
Vertex, Default, Vertex_container_strategy> Vertex_range;
#endif
#endif // CGAL_LINKED_WITH_TBB
typedef typename Cell_range::size_type size_type;
typedef typename Cell_range::difference_type difference_type;
@ -501,6 +500,27 @@ private:
public:
#ifdef CGAL_LINKED_WITH_TBB
// CJTODO TEMP
#ifdef CGAL_DEBUG_GLOBAL_LOCK_DS
template <typename Cell_handle>
bool is_cell_locked_by_this_thread(const Cell_handle &cell_handle) const
{
CGAL::Default_lock_data_structure *p_lock_ds = CGAL::Default_lock_data_structure::get_global_lock_ds();
bool locked = true;
if (p_lock_ds)
{
for (int iVertex = 0 ; locked && iVertex < 4 ; ++iVertex)
{
locked = p_lock_ds->is_locked_by_this_thread(
cell_handle->vertex(iVertex)->point());
}
}
return locked;
}
#endif
#endif
// Internal function : assumes the conflict cells are marked.
template <class CellIt>
Vertex_handle _insert_in_hole(CellIt cell_begin, CellIt cell_end,
@ -1240,9 +1260,9 @@ private:
};
#ifdef CGAL_TDS_USE_RECURSIVE_CREATE_STAR_3
template <class Vb, class Cb, bool Upm>
typename Triangulation_data_structure_3<Vb,Cb,Upm>::Cell_handle
Triangulation_data_structure_3<Vb,Cb,Upm>::
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
typename Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::Cell_handle
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
create_star_3(Vertex_handle v, Cell_handle c, int li, int prev_ind2)
{
CGAL_triangulation_precondition( dimension() == 3);
@ -1297,9 +1317,9 @@ create_star_3(Vertex_handle v, Cell_handle c, int li, int prev_ind2)
return cnew;
}
#else
template <class Vb, class Cb, bool Upm>
typename Triangulation_data_structure_3<Vb,Cb,Upm>::Cell_handle
Triangulation_data_structure_3<Vb,Cb,Upm>::
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
typename Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::Cell_handle
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
recursive_create_star_3(Vertex_handle v, Cell_handle c, int li,
int prev_ind2, int depth)
{
@ -1358,9 +1378,9 @@ recursive_create_star_3(Vertex_handle v, Cell_handle c, int li,
//We use the class iAdjacency_info instead of a tuple because
//at the moment we made the change it was faster like this.
template <class Vb, class Cb, bool Upm>
typename Triangulation_data_structure_3<Vb,Cb,Upm>::Cell_handle
Triangulation_data_structure_3<Vb,Cb,Upm>::
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
typename Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::Cell_handle
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
non_recursive_create_star_3(Vertex_handle v, Cell_handle c, int li, int prev_ind2)
{
CGAL_triangulation_precondition( dimension() == 3);
@ -1436,9 +1456,9 @@ non_recursive_create_star_3(Vertex_handle v, Cell_handle c, int li, int prev_ind
}
#endif
template <class Vb, class Cb, bool Upm>
typename Triangulation_data_structure_3<Vb,Cb,Upm>::Cell_handle
Triangulation_data_structure_3<Vb,Cb,Upm>::
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
typename Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::Cell_handle
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
create_star_2(Vertex_handle v, Cell_handle c, int li )
{
CGAL_triangulation_assertion( dimension() == 2 );
@ -1486,9 +1506,9 @@ create_star_2(Vertex_handle v, Cell_handle c, int li )
return cnew;
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
std::istream&
operator>>(std::istream& is, Triangulation_data_structure_3<Vb,Cb,Upm>& tds)
operator>>(std::istream& is, Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>& tds)
// reads :
// the dimension
// the number of vertices
@ -1497,7 +1517,7 @@ operator>>(std::istream& is, Triangulation_data_structure_3<Vb,Cb,Upm>& tds)
// the neighbors of each cell by their index in the preceding list of cells
// when dimension < 3 : the same with faces of maximal dimension
{
typedef Triangulation_data_structure_3<Vb,Cb,Upm> Tds;
typedef Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct> Tds;
typedef typename Tds::Vertex_handle Vertex_handle;
typedef typename Tds::Cell_handle Cell_handle;
@ -1534,9 +1554,9 @@ operator>>(std::istream& is, Triangulation_data_structure_3<Vb,Cb,Upm>& tds)
return is;
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
std::ostream&
operator<<(std::ostream& os, const Triangulation_data_structure_3<Vb,Cb,Upm> &tds)
operator<<(std::ostream& os, const Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct> &tds)
// writes :
// the dimension
// the number of vertices
@ -1545,7 +1565,7 @@ operator<<(std::ostream& os, const Triangulation_data_structure_3<Vb,Cb,Upm> &td
// the neighbors of each cell by their index in the preceding list of cells
// when dimension < 3 : the same with faces of maximal dimension
{
typedef Triangulation_data_structure_3<Vb,Cb,Upm> Tds;
typedef Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct> Tds;
typedef typename Tds::size_type size_type;
typedef typename Tds::Vertex_handle Vertex_handle;
typedef typename Tds::Vertex_iterator Vertex_iterator;
@ -1579,9 +1599,9 @@ operator<<(std::ostream& os, const Triangulation_data_structure_3<Vb,Cb,Upm> &td
return os;
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
is_simplex( Cell_handle c ) const
{
switch(dimension()) {
@ -1594,17 +1614,17 @@ is_simplex( Cell_handle c ) const
return false;
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
is_vertex(Vertex_handle v) const
{
return vertices().owns_dereferencable(v);
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
is_edge(Vertex_handle u, Vertex_handle v,
Cell_handle &c, int &i, int &j) const
// returns false when dimension <1 or when indices wrong
@ -1628,9 +1648,9 @@ is_edge(Vertex_handle u, Vertex_handle v,
return false;
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
is_edge(Vertex_handle u, Vertex_handle v) const
{
Cell_handle c;
@ -1638,9 +1658,9 @@ is_edge(Vertex_handle u, Vertex_handle v) const
return is_edge(u, v, c, i, j);
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
is_edge(Cell_handle c, int i, int j) const
{
if (dimension() < 1)
@ -1655,9 +1675,9 @@ is_edge(Cell_handle c, int i, int j) const
return cells().owns_dereferencable(c);
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
is_facet(Vertex_handle u, Vertex_handle v,
Vertex_handle w,
Cell_handle & c, int & i, int & j, int & k) const
@ -1686,9 +1706,9 @@ is_facet(Vertex_handle u, Vertex_handle v,
return false;
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
is_facet(Cell_handle c, int i) const
{
CGAL_triangulation_precondition(i>=0 && i<4);
@ -1702,9 +1722,9 @@ is_facet(Cell_handle c, int i) const
return cells().owns_dereferencable(c);
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
is_cell( Cell_handle c ) const
// returns false when dimension <3
{
@ -1714,9 +1734,9 @@ is_cell( Cell_handle c ) const
return cells().owns_dereferencable(c);
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
is_cell(Vertex_handle u, Vertex_handle v,
Vertex_handle w, Vertex_handle t,
Cell_handle & c, int & i, int & j, int & k, int & l) const
@ -1745,9 +1765,9 @@ is_cell(Vertex_handle u, Vertex_handle v,
return false;
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
is_cell(Vertex_handle u, Vertex_handle v,
Vertex_handle w, Vertex_handle t)
const
@ -1758,10 +1778,10 @@ is_cell(Vertex_handle u, Vertex_handle v,
return is_cell(u, v, w, t, c, i, j, k, l);
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
inline
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
has_vertex(Cell_handle c, int i, Vertex_handle v, int & j) const
// computes the index j of the vertex in the cell c giving the query
// facet (c,i)
@ -1771,10 +1791,10 @@ has_vertex(Cell_handle c, int i, Vertex_handle v, int & j) const
return ( c->has_vertex(v,j) && (j != i) );
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
inline
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
has_vertex(Cell_handle c, int i, Vertex_handle v) const
// checks whether the query facet (c,i) has vertex v
{
@ -1783,27 +1803,27 @@ has_vertex(Cell_handle c, int i, Vertex_handle v) const
return ( c->has_vertex(v,j) && (j != i) );
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
inline
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
has_vertex(const Facet & f, Vertex_handle v, int & j) const
{
return has_vertex(f.first, f.second, v, j);
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
inline
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
has_vertex(const Facet & f, Vertex_handle v) const
{
return has_vertex(f.first, f.second, v);
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
are_equal(Cell_handle c, int i, Cell_handle n, int j) const
// tests whether facets c,i and n,j, have the same 3 vertices
// the triangulation is supposed to be valid, the orientation of the
@ -1825,25 +1845,25 @@ are_equal(Cell_handle c, int i, Cell_handle n, int j) const
( j1+j2+j3+j == 6 ) );
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
are_equal(const Facet & f, const Facet & g) const
{
return are_equal(f.first, f.second, g.first, g.second);
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
are_equal(const Facet & f, Cell_handle n, int j) const
{
return are_equal(f.first, f.second, n, j);
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
flip( Cell_handle c, int i )
// returns false if the facet is not flippable
// true other wise and
@ -1866,9 +1886,9 @@ flip( Cell_handle c, int i )
return true;
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
void
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
flip_flippable(Cell_handle c, int i )
// flips facet i of cell c
// c will be replaced by one of the new cells
@ -1887,10 +1907,10 @@ flip_flippable(Cell_handle c, int i )
flip_really(c,i,n,in);
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
inline
void
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
flip_really( Cell_handle c, int i, Cell_handle n, int in )
// private - used by flip and flip_flippable
{
@ -1927,9 +1947,9 @@ flip_really( Cell_handle c, int i, Cell_handle n, int in )
// CGAL_triangulation_precondition( (0<=i) && (i<3) );
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
flip( Cell_handle c, int i, int j )
// returns false if the edge is not flippable
// true otherwise and
@ -1979,9 +1999,9 @@ flip( Cell_handle c, int i, int j )
return true;
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
void
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
flip_flippable( Cell_handle c, int i, int j )
// flips edge i,j of cell c
// c will be deleted
@ -2028,10 +2048,10 @@ flip_flippable( Cell_handle c, int i, int j )
flip_really(c,i,j,c1,v1,i1,j1,next1,c2,v2,i2,j2,next2,v3);
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
inline
void
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
flip_really( Cell_handle c, int i, int j,
Cell_handle c1, Vertex_handle v1,
int i1, int j1, int next1,
@ -2060,9 +2080,9 @@ flip_really( Cell_handle c, int i, int j,
delete_cell( c );
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
void
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
read_cells(std::istream& is, std::map< std::size_t, Vertex_handle > &V,
std::size_t & m, std::map< std::size_t, Cell_handle > &C)
{
@ -2131,9 +2151,9 @@ read_cells(std::istream& is, std::map< std::size_t, Vertex_handle > &V,
}
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
void
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
print_cells(std::ostream& os, const Unique_hash_map<Vertex_handle, std::size_t> &V ) const
{
std::map<Cell_handle, std::size_t > C;
@ -2272,9 +2292,9 @@ print_cells(std::ostream& os, const Unique_hash_map<Vertex_handle, std::size_t>
}
}
template <class Vb, class Cb, bool Upm>
typename Triangulation_data_structure_3<Vb,Cb,Upm>::Vertex_handle
Triangulation_data_structure_3<Vb,Cb,Upm>::
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
typename Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::Vertex_handle
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
insert_in_cell(Cell_handle c)
{
CGAL_triangulation_precondition( dimension() == 3 );
@ -2317,9 +2337,9 @@ insert_in_cell(Cell_handle c)
return v;
}
template <class Vb, class Cb, bool Upm>
typename Triangulation_data_structure_3<Vb,Cb,Upm>::Vertex_handle
Triangulation_data_structure_3<Vb,Cb,Upm>::
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
typename Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::Vertex_handle
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
insert_in_facet(Cell_handle c, int i)
{ // inserts v in the facet opposite to vertex i of cell c
@ -2426,9 +2446,9 @@ insert_in_facet(Cell_handle c, int i)
return v;
}
template <class Vb, class Cb, bool Upm>
typename Triangulation_data_structure_3<Vb,Cb,Upm>::Vertex_handle
Triangulation_data_structure_3<Vb,Cb,Upm>::
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
typename Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::Vertex_handle
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
insert_in_edge(Cell_handle c, int i, int j)
// inserts a vertex in the edge of cell c with vertices i and j
{
@ -2508,9 +2528,9 @@ insert_in_edge(Cell_handle c, int i, int j)
}
}
template <class Vb, class Cb, bool Upm>
typename Triangulation_data_structure_3<Vb,Cb,Upm>::Vertex_handle
Triangulation_data_structure_3<Vb,Cb,Upm>::
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
typename Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::Vertex_handle
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
insert_increase_dimension(Vertex_handle star)
// star = vertex from which we triangulate the facet of the
// incremented dimension
@ -2681,9 +2701,9 @@ insert_increase_dimension(Vertex_handle star)
return v;
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
void
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
remove_decrease_dimension(Vertex_handle v, Vertex_handle w)
{
CGAL_triangulation_expensive_precondition( is_valid() );
@ -2736,9 +2756,9 @@ remove_decrease_dimension(Vertex_handle v, Vertex_handle w)
CGAL_triangulation_postcondition(is_valid());
}
template <class Vb, class Cb, bool Upm>
typename Triangulation_data_structure_3<Vb,Cb,Upm>::Cell_handle
Triangulation_data_structure_3<Vb,Cb,Upm>::
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
typename Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::Cell_handle
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
remove_from_maximal_dimension_simplex(Vertex_handle v)
{
CGAL_triangulation_precondition(dimension() >= 1);
@ -2760,9 +2780,9 @@ remove_from_maximal_dimension_simplex(Vertex_handle v)
return remove_degree_2(v);
}
template <class Vb, class Cb, bool Upm>
typename Triangulation_data_structure_3<Vb,Cb,Upm>::Cell_handle
Triangulation_data_structure_3<Vb,Cb,Upm>::
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
typename Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::Cell_handle
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
remove_degree_2(Vertex_handle v)
{
CGAL_triangulation_precondition(dimension() == 1);
@ -2799,9 +2819,9 @@ remove_degree_2(Vertex_handle v)
return newc;
}
template <class Vb, class Cb, bool Upm>
typename Triangulation_data_structure_3<Vb,Cb,Upm>::Cell_handle
Triangulation_data_structure_3<Vb,Cb,Upm>::
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
typename Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::Cell_handle
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
remove_degree_3(Vertex_handle v)
{
CGAL_triangulation_precondition(dimension() == 2);
@ -2843,9 +2863,9 @@ remove_degree_3(Vertex_handle v)
return newc;
}
template <class Vb, class Cb, bool Upm>
typename Triangulation_data_structure_3<Vb,Cb,Upm>::Cell_handle
Triangulation_data_structure_3<Vb,Cb,Upm>::
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
typename Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::Cell_handle
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
remove_degree_4(Vertex_handle v)
{
CGAL_triangulation_precondition(dimension() == 3);
@ -2893,9 +2913,9 @@ remove_degree_4(Vertex_handle v)
return newc;
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
void
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
decrease_dimension(Cell_handle c, int i)
{
CGAL_triangulation_expensive_precondition( is_valid() );;
@ -3032,9 +3052,9 @@ decrease_dimension(Cell_handle c, int i)
}
template <class Vb, class Cb, bool Upm>
typename Triangulation_data_structure_3<Vb,Cb,Upm>::size_type
Triangulation_data_structure_3<Vb,Cb,Upm>::
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
typename Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::size_type
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
degree(Vertex_handle v) const
{
std::size_t res;
@ -3042,9 +3062,9 @@ degree(Vertex_handle v) const
return res;
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
is_valid(bool verbose, int level ) const
{
switch ( dimension() ) {
@ -3200,9 +3220,9 @@ is_valid(bool verbose, int level ) const
return true;
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
is_valid(Vertex_handle v, bool verbose, int level) const
{
bool result = v->is_valid(verbose,level);
@ -3215,9 +3235,9 @@ is_valid(Vertex_handle v, bool verbose, int level) const
return result;
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
is_valid(Cell_handle c, bool verbose, int level) const
{
if ( ! c->is_valid(verbose, level) )
@ -3526,9 +3546,9 @@ is_valid(Cell_handle c, bool verbose, int level) const
return true;
}
template <class Vb, class Cb, bool Upm>
typename Triangulation_data_structure_3<Vb,Cb,Upm>::Vertex_handle
Triangulation_data_structure_3<Vb,Cb,Upm>::
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
typename Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::Vertex_handle
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
copy_tds(const Tds & tds, Vertex_handle vert )
// returns the new vertex corresponding to vert in the new tds
{
@ -3587,9 +3607,9 @@ copy_tds(const Tds & tds, Vertex_handle vert )
return (vert != Vertex_handle()) ? V[vert] : vert;
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
void
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
swap(Tds & tds)
{
CGAL_triangulation_expensive_precondition(tds.is_valid() && is_valid());
@ -3599,9 +3619,9 @@ swap(Tds & tds)
vertices().swap(tds.vertices());
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
void
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
clear()
{
cells().clear();
@ -3609,9 +3629,9 @@ clear()
set_dimension(-2);
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
count_vertices(size_type & i, bool verbose, int level) const
// counts AND checks the validity
{
@ -3629,9 +3649,9 @@ count_vertices(size_type & i, bool verbose, int level) const
return true;
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
count_facets(size_type & i, bool verbose, int level) const
// counts but does not check
{
@ -3649,9 +3669,9 @@ count_facets(size_type & i, bool verbose, int level) const
return true;
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
count_edges(size_type & i, bool verbose, int level) const
// counts but does not check
{
@ -3669,9 +3689,9 @@ count_edges(size_type & i, bool verbose, int level) const
return true;
}
template <class Vb, class Cb, bool Upm>
template <class Vb, class Cb, class Vcs, class Ccs, class Ct>
bool
Triangulation_data_structure_3<Vb,Cb,Upm>::
Triangulation_data_structure_3<Vb,Cb,Vcs,Ccs,Ct>::
count_cells(size_type & i, bool verbose, int level) const
// counts AND checks the validity
{

View File

@ -27,10 +27,65 @@
#include <CGAL/triangulation_assertions.h>
#include <CGAL/internal/Dummy_tds_3.h>
#ifdef CGAL_LINKED_WITH_TBB
# include <tbb/atomic.h>
#endif
namespace CGAL {
// Without erase counter
template <bool Use_erase_counter, typename Concurrency_tag>
class Triangulation_ds_cell_base_3_base
{
public:
// Dummy
unsigned int get_erase_counter() const { return 0; }
void set_erase_counter(unsigned int) {}
void increment_erase_counter() {}
};
// Specialized version (with erase counter)
template <typename Concurrency_tag>
class Triangulation_ds_cell_base_3_base<true, Concurrency_tag>
{
public:
// Erase counter (cf. Compact_container)
unsigned int get_erase_counter() const
{
return this->m_erase_counter;
}
void set_erase_counter(unsigned int c)
{
this->m_erase_counter = c;
}
void increment_erase_counter()
{
++this->m_erase_counter;
}
protected:
#ifdef CGAL_LINKED_WITH_TBB
typedef typename boost::mpl::if_c<
boost::is_base_of<Parallel_tag, Concurrency_tag>::value,
tbb::atomic<unsigned int>,
unsigned int>::type Erase_counter_type;
#else
typedef unsigned int Erase_counter_type;
#endif
Erase_counter_type m_erase_counter;
};
template < typename TDS = void >
class Triangulation_ds_cell_base_3
: public Triangulation_ds_cell_base_3_base<
TDS::Cell_container_strategy::Uses_erase_counter,
typename TDS::Concurrency_tag>
{
public:
typedef TDS Triangulation_data_structure;
@ -43,14 +98,32 @@ public:
template <typename TDS2>
struct Rebind_TDS { typedef Triangulation_ds_cell_base_3<TDS2> Other; };
Triangulation_ds_cell_base_3() {}
Triangulation_ds_cell_base_3()
{
#ifdef SHOW_REMAINING_BAD_ELEMENT_IN_RED
mark = -1;
mark2 = -1;
#endif
}
Triangulation_ds_cell_base_3(Vertex_handle v0, Vertex_handle v1,
Vertex_handle v2, Vertex_handle v3)
#ifndef CGAL_CFG_ARRAY_MEMBER_INITIALIZATION_BUG
: V((Vertex_handle[4]) {v0, v1, v2, v3} ) {}
: V((Vertex_handle[4]) {v0, v1, v2, v3} )
{
#ifdef SHOW_REMAINING_BAD_ELEMENT_IN_RED
mark = -1;
mark2 = -1;
#endif
}
#else
{ set_vertices(v0, v1, v2, v3); }
{
set_vertices(v0, v1, v2, v3);
#ifdef SHOW_REMAINING_BAD_ELEMENT_IN_RED
mark = -1;
mark2 = -1;
#endif
}
#endif
Triangulation_ds_cell_base_3(Vertex_handle v0, Vertex_handle v1,
@ -63,6 +136,10 @@ public:
{
set_neighbors(n0, n1, n2, n3);
set_vertices(v0, v1, v2, v3);
#ifdef SHOW_REMAINING_BAD_ELEMENT_IN_RED
mark = -1;
mark2 = -1;
#endif
}
#endif
@ -202,6 +279,11 @@ public:
TDS_data& tds_data() { return _tds_data; }
const TDS_data& tds_data() const { return _tds_data; }
#ifdef SHOW_REMAINING_BAD_ELEMENT_IN_RED
int mark;
int mark2;
#endif
private:
Cell_handle N[4];

View File

@ -26,8 +26,8 @@
namespace CGAL {
// Sequential
template <bool used_by_parallel_mesh_3>
// Without erase counter
template <bool Use_erase_counter>
class Triangulation_ds_vertex_base_3_base
{
public:
@ -38,7 +38,7 @@ public:
};
#ifdef CGAL_LINKED_WITH_TBB
// Specialized version (Parallel)
// Specialized version (with erase counter)
template <>
class Triangulation_ds_vertex_base_3_base<true>
{
@ -65,9 +65,12 @@ protected:
};
#endif // CGAL_LINKED_WITH_TBB
template < typename TDS = void >
class Triangulation_ds_vertex_base_3
: public Triangulation_ds_vertex_base_3_base<TDS::Is_for_parallel_mesh_3>
: public Triangulation_ds_vertex_base_3_base<
TDS::Vertex_container_strategy::Uses_erase_counter>
{
public:
typedef TDS Triangulation_data_structure;

View File

@ -25,6 +25,8 @@ namespace CGAL { namespace internal {
// Dummy TDS which provides all types that a vertex_base or cell_base can use.
struct Dummy_tds_3 {
typedef Sequential_tag Concurrency_tag;
struct Vertex {};
struct Cell {};
struct Facet {};