mirror of https://github.com/CGAL/cgal
Merge branch 'Combinatorial_map_copy2-gdamiand'
Approved by the release manager
This commit is contained in:
commit
98a4e30f34
|
|
@ -19,6 +19,13 @@ public:
|
|||
*/
|
||||
CombinatorialMap();
|
||||
|
||||
/*!
|
||||
Construct a new combinatorial map from another one.
|
||||
The new combinatorial map is created by copying the darts and the non void attributes of cmap. CMap must be a model of `CombinatorialMap` concept, which can be defined with a different dimension and/or different attributes than `*this`. In this case, only permutations that are common to `cmap` and `*this`, and only non void i-attributes of `cmap` whose info type is the same to the info of non void i-attributes of `*this`, are copied.
|
||||
*/
|
||||
template<typename CMap>
|
||||
CombinatorialMap cm(const CMap& cmap);
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Types
|
||||
|
|
@ -521,6 +528,18 @@ Deletes all the darts and all the attributes of the combinatorial map.
|
|||
*/
|
||||
void clear();
|
||||
|
||||
/*!
|
||||
Assignment operator.
|
||||
All darts and attributes are duplicated, and the former combinatorial map is deleted.
|
||||
*/
|
||||
CombinatorialMap& operator= (const CombinatorialMap& cmap);
|
||||
|
||||
/*!
|
||||
Swap the current combinatorial map with `cmap`.
|
||||
There is no copy of darts and attributes thus this method runs in constant time.
|
||||
*/
|
||||
void swap(CombinatorialMap& cmap);
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Operations
|
||||
|
|
|
|||
|
|
@ -60,26 +60,26 @@ namespace CGAL {
|
|||
|
||||
/// Cell_attribute_without_info
|
||||
template <class Refs, class Tag=Tag_true,
|
||||
class OnMerge=Null_functor,
|
||||
class OnMerge=Null_functor,
|
||||
class OnSplit=Null_functor>
|
||||
class Cell_attribute_without_info;
|
||||
|
||||
// Cell_attribute_without_info without dart support.
|
||||
template <class Refs, class OnMerge, class OnSplit>
|
||||
class Cell_attribute_without_info<Refs, Tag_false,
|
||||
class Cell_attribute_without_info<Refs, Tag_false,
|
||||
OnMerge, OnSplit>
|
||||
{
|
||||
template < unsigned int d_, class Refs_,
|
||||
class Items_, class Alloc_ >
|
||||
friend class Combinatorial_map_base;
|
||||
|
||||
|
||||
template <int d, typename Refs_>
|
||||
friend struct Dart;
|
||||
|
||||
template < unsigned int d_, class Refs_,
|
||||
class Items_, class Alloc_ >
|
||||
class Items_, class Alloc_ >
|
||||
friend class Generalized_map_base;
|
||||
|
||||
|
||||
template <int d, typename Refs_>
|
||||
friend struct GMap_dart;
|
||||
|
||||
|
|
@ -101,7 +101,7 @@ namespace CGAL {
|
|||
|
||||
/// operator =
|
||||
/// We do nothing since we must not copy mrefcounting.
|
||||
Cell_attribute_without_info&
|
||||
Cell_attribute_without_info&
|
||||
operator=(const Cell_attribute_without_info& /*acell*/)
|
||||
{ return *this; }
|
||||
|
||||
|
|
@ -119,7 +119,13 @@ namespace CGAL {
|
|||
bool is_valid() const
|
||||
{ return true; }
|
||||
|
||||
protected:
|
||||
bool operator==(const Cell_attribute_without_info&) const
|
||||
{ return true; }
|
||||
|
||||
bool operator!=(const Cell_attribute_without_info& other) const
|
||||
{ return !operator==(other); }
|
||||
|
||||
// protected:
|
||||
/// Contructor without parameter.
|
||||
Cell_attribute_without_info(): mrefcounting(0)
|
||||
{}
|
||||
|
|
@ -129,6 +135,7 @@ namespace CGAL {
|
|||
mrefcounting(0)
|
||||
{}
|
||||
|
||||
protected:
|
||||
/// Increment the reference counting.
|
||||
void inc_nb_refs()
|
||||
{ mrefcounting+=4; } // 4 because this is the 3rd bit (ie 1<<2)
|
||||
|
|
@ -145,9 +152,9 @@ namespace CGAL {
|
|||
unsigned int get_nb_refs() const
|
||||
{ return (mrefcounting>>2); } // >>2 to ignore the 2 least significant bits
|
||||
|
||||
void * for_compact_container() const
|
||||
void * for_compact_container() const
|
||||
{ return vp; }
|
||||
void * & for_compact_container()
|
||||
void * & for_compact_container()
|
||||
{ return vp; }
|
||||
|
||||
private:
|
||||
|
|
@ -165,7 +172,7 @@ namespace CGAL {
|
|||
* The refs class must provide the type of Combinatorial_map used.
|
||||
*/
|
||||
template <class Refs, class OnMerge, class OnSplit>
|
||||
class Cell_attribute_without_info<Refs, Tag_true,
|
||||
class Cell_attribute_without_info<Refs, Tag_true,
|
||||
OnMerge, OnSplit>
|
||||
{
|
||||
template < unsigned int d_, class Refs_,
|
||||
|
|
@ -176,7 +183,7 @@ namespace CGAL {
|
|||
friend struct Dart;
|
||||
|
||||
template < unsigned int d_, class Refs_,
|
||||
class Items_, class Alloc_ >
|
||||
class Items_, class Alloc_ >
|
||||
friend class Generalized_map_base;
|
||||
|
||||
template <int d, typename Refs_>
|
||||
|
|
@ -194,17 +201,17 @@ namespace CGAL {
|
|||
typedef typename Refs::Dart_handle Dart_handle;
|
||||
typedef typename Refs::Dart_const_handle Dart_const_handle;
|
||||
typedef typename Refs::Alloc Alloc;
|
||||
|
||||
|
||||
typedef OnMerge On_merge;
|
||||
typedef OnSplit On_split;
|
||||
|
||||
/// operator =
|
||||
/// We must not copy mrefcounting.
|
||||
Cell_attribute_without_info&
|
||||
Cell_attribute_without_info&
|
||||
operator=(const Cell_attribute_without_info& acell)
|
||||
{
|
||||
mdart = acell.mdart;
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Get the dart associated with the cell.
|
||||
|
|
@ -221,7 +228,13 @@ namespace CGAL {
|
|||
bool is_valid() const
|
||||
{ return mdart!=NULL; }
|
||||
|
||||
protected:
|
||||
bool operator==(const Cell_attribute_without_info&) const
|
||||
{ return true; }
|
||||
|
||||
bool operator!=(const Cell_attribute_without_info& other) const
|
||||
{ return !operator==(other); }
|
||||
|
||||
// protected:
|
||||
/// Contructor without parameter.
|
||||
Cell_attribute_without_info() : mdart(NULL),
|
||||
mrefcounting(0)
|
||||
|
|
@ -233,6 +246,7 @@ namespace CGAL {
|
|||
mrefcounting(0)
|
||||
{}
|
||||
|
||||
protected:
|
||||
/// Increment the reference counting.
|
||||
void inc_nb_refs()
|
||||
{ ++mrefcounting; }
|
||||
|
|
@ -241,7 +255,7 @@ namespace CGAL {
|
|||
void dec_nb_refs()
|
||||
{
|
||||
CGAL_assertion( mrefcounting>0 );
|
||||
--mrefcounting;
|
||||
--mrefcounting;
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
@ -251,36 +265,36 @@ namespace CGAL {
|
|||
|
||||
void * for_compact_container() const
|
||||
{ return mdart.for_compact_container(); }
|
||||
void * & for_compact_container()
|
||||
void * & for_compact_container()
|
||||
{ return mdart.for_compact_container(); }
|
||||
|
||||
private:
|
||||
/// The dart handle associated with the cell.
|
||||
Dart_handle mdart;
|
||||
|
||||
|
||||
/// Reference counting: the number of darts linked to this cell.
|
||||
unsigned int mrefcounting;
|
||||
};
|
||||
|
||||
/// Cell associated with an attribute, with or without info depending
|
||||
/// Cell associated with an attribute, with or without info depending
|
||||
/// if Info==void.
|
||||
template <class Refs, class Info_=void, class Tag_=Tag_true,
|
||||
class OnMerge=Null_functor,
|
||||
template <class Refs, class Info_=void, class Tag_=Tag_true,
|
||||
class OnMerge=Null_functor,
|
||||
class OnSplit=Null_functor>
|
||||
class Cell_attribute;
|
||||
|
||||
|
||||
/// Specialization when Info==void.
|
||||
template <class Refs, class Tag_,
|
||||
template <class Refs, class Tag_,
|
||||
class OnMerge, class OnSplit>
|
||||
class Cell_attribute<Refs, void, Tag_,
|
||||
OnSplit, OnMerge> :
|
||||
public Cell_attribute_without_info<Refs, Tag_,
|
||||
class Cell_attribute<Refs, void, Tag_,
|
||||
OnSplit, OnMerge> :
|
||||
public Cell_attribute_without_info<Refs, Tag_,
|
||||
OnSplit, OnMerge>
|
||||
{
|
||||
template < unsigned int d_, class Refs_,
|
||||
class Items_, class Alloc_ >
|
||||
friend class Combinatorial_map_base;
|
||||
|
||||
|
||||
template <class T, class Alloc_>
|
||||
friend class Compact_container;
|
||||
|
||||
|
|
@ -291,8 +305,14 @@ namespace CGAL {
|
|||
typedef typename Refs::Alloc Alloc;
|
||||
typedef OnMerge On_merge;
|
||||
typedef OnSplit On_split;
|
||||
typedef void Info;
|
||||
|
||||
// protected:
|
||||
/// Default contructor.
|
||||
Cell_attribute()
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// Specialization when Info!=void.
|
||||
template <class Refs, class Info_, class Tag_,
|
||||
|
|
@ -305,11 +325,13 @@ namespace CGAL {
|
|||
template < unsigned int d_, class Refs_,
|
||||
class Items_, class Alloc_ >
|
||||
friend class Combinatorial_map_base;
|
||||
|
||||
|
||||
template <class T, class Alloc_>
|
||||
friend class Compact_container;
|
||||
|
||||
public:
|
||||
typedef Cell_attribute<Refs, Info_, Tag_, OnMerge, OnSplit> Self;
|
||||
|
||||
typedef Tag_ Supports_cell_dart;
|
||||
typedef typename Refs::Dart_handle Dart_handle;
|
||||
typedef typename Refs::Dart_const_handle Dart_const_handle;
|
||||
|
|
@ -318,13 +340,21 @@ namespace CGAL {
|
|||
typedef OnSplit On_split;
|
||||
typedef Info_ Info;
|
||||
|
||||
protected:
|
||||
bool operator==(const Self& other) const
|
||||
{ return this->info()==other.info(); }
|
||||
|
||||
bool operator!=(const Self& other) const
|
||||
{ return !operator==(other); }
|
||||
|
||||
|
||||
// protected:
|
||||
/// Default contructor.
|
||||
Cell_attribute()
|
||||
{}
|
||||
|
||||
/// Contructor with an attribute in parameter.
|
||||
Cell_attribute(const Info_& ainfo) : Info_for_cell_attribute<Info_>(ainfo)
|
||||
/// Contructor with an info in parameter.
|
||||
Cell_attribute(const Info_& ainfo) :
|
||||
Info_for_cell_attribute<Info_>(ainfo)
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -24,12 +24,14 @@
|
|||
#include <CGAL/internal/Combinatorial_map_utility.h>
|
||||
#include <CGAL/internal/Combinatorial_map_internal_functors.h>
|
||||
#include <CGAL/internal/Combinatorial_map_group_functors.h>
|
||||
#include <CGAL/internal/Combinatorial_map_copy_functors.h>
|
||||
#include <CGAL/internal/Combinatorial_map_sewable.h>
|
||||
#include <CGAL/Combinatorial_map_functors.h>
|
||||
#include <CGAL/Combinatorial_map_min_items.h>
|
||||
#include <CGAL/Dart_const_iterators.h>
|
||||
#include <CGAL/Cell_const_iterators.h>
|
||||
#include <CGAL/Combinatorial_map_basic_operations.h>
|
||||
#include <CGAL/Unique_hash_map.h>
|
||||
#include <bitset>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
|
|
@ -60,6 +62,9 @@ namespace CGAL {
|
|||
friend struct CGAL::internal::Call_split_functor;
|
||||
|
||||
public:
|
||||
template < unsigned int A, class B, class I, class D >
|
||||
friend class Combinatorial_map_base;
|
||||
|
||||
/// Types definition
|
||||
typedef Combinatorial_map_base<d_, Refs, Items_,Alloc_> Self;
|
||||
|
||||
|
|
@ -148,6 +153,168 @@ namespace CGAL {
|
|||
CGAL_assertion(number_of_darts()==0);
|
||||
}
|
||||
|
||||
/** Copy the given combinatorial map into *this.
|
||||
* Note that both CMap can have different dimensions and/or non void attributes.
|
||||
* @param amap the combinatorial map to copy.
|
||||
* @post *this is valid.
|
||||
*/
|
||||
template <typename CMap2, typename Converters, typename Pointconverter>
|
||||
void copy(const CMap2& amap, const Converters& converters,
|
||||
const Pointconverter& pointconverter)
|
||||
{
|
||||
this->clear();
|
||||
|
||||
this->mnb_used_marks = amap.mnb_used_marks;
|
||||
this->mmask_marks = amap.mmask_marks;
|
||||
|
||||
for (size_type i = 0; i < NB_MARKS; ++i)
|
||||
{
|
||||
this->mfree_marks_stack[i] = amap.mfree_marks_stack[i];
|
||||
this->mindex_marks[i] = amap.mindex_marks[i];
|
||||
this->mnb_marked_darts[i] = amap.mnb_marked_darts[i];
|
||||
this->mnb_times_reserved_marks[i] = amap.mnb_times_reserved_marks[i];
|
||||
}
|
||||
|
||||
// We must do this ony once, but problem because null_dart_handle
|
||||
// is static !
|
||||
if (mnull_dart_container.empty())
|
||||
{
|
||||
null_dart_handle =
|
||||
mnull_dart_container.emplace(amap.null_dart_handle->mmarks);
|
||||
|
||||
for (unsigned int i = 0; i <= dimension; ++i)
|
||||
{
|
||||
null_dart_handle->unlink_beta(i);
|
||||
}
|
||||
}
|
||||
else
|
||||
null_dart_handle->mmarks = amap.null_dart_handle->mmarks;
|
||||
|
||||
// Create an mapping between darts of the two maps (originals->copies).
|
||||
std::map<typename CMap2::Dart_const_handle, Dart_handle> dartmap;
|
||||
|
||||
for (typename CMap2::Dart_const_range::const_iterator
|
||||
it=amap.darts().begin(), itend=amap.darts().end();
|
||||
it!=itend; ++it)
|
||||
{
|
||||
dartmap[it]=mdarts.emplace(it->mmarks);
|
||||
}
|
||||
|
||||
unsigned int min_dim=
|
||||
(dimension<amap.dimension?dimension:amap.dimension);
|
||||
|
||||
typename std::map<typename CMap2::Dart_const_handle,Dart_handle>
|
||||
::iterator dartmap_iter, dartmap_iter_end=dartmap.end();
|
||||
for (dartmap_iter=dartmap.begin(); dartmap_iter!=dartmap_iter_end;
|
||||
++dartmap_iter)
|
||||
{
|
||||
for (unsigned int i=0; i<=min_dim; i++)
|
||||
{
|
||||
if (dartmap_iter->first->beta(i)!=CMap2::null_dart_handle &&
|
||||
(dartmap_iter->first)<(dartmap_iter->first->beta(i)))
|
||||
{
|
||||
basic_link_beta(dartmap_iter->second,
|
||||
dartmap[dartmap_iter->first->beta(i)], i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Copy attributes */
|
||||
for (dartmap_iter=dartmap.begin(); dartmap_iter!=dartmap_iter_end;
|
||||
++dartmap_iter)
|
||||
{
|
||||
Helper::template Foreach_enabled_attributes
|
||||
< internal::Copy_attributes_functor <CMap2, Refs, Converters,
|
||||
Pointconverter> >::
|
||||
run(&amap, static_cast<Refs*>(this),
|
||||
dartmap_iter->first, dartmap_iter->second,
|
||||
converters, pointconverter);
|
||||
}
|
||||
|
||||
CGAL_assertion (is_valid () == 1);
|
||||
}
|
||||
|
||||
template <typename CMap2>
|
||||
void copy(const CMap2& amap)
|
||||
{
|
||||
CGAL::cpp11::tuple<> converters;
|
||||
Default_converter_cmap_0attributes_with_point<CMap2, Refs> pointconverter;
|
||||
return copy< CMap2, CGAL::cpp11::tuple<>,
|
||||
Default_converter_cmap_0attributes_with_point<CMap2, Refs> >
|
||||
(amap, converters, pointconverter);
|
||||
}
|
||||
|
||||
template <typename CMap2, typename Converters>
|
||||
void copy(const CMap2& amap, const Converters& converters)
|
||||
{
|
||||
Default_converter_cmap_0attributes_with_point<CMap2, Refs> pointconverter;
|
||||
return copy< CMap2, Converters,
|
||||
Default_converter_cmap_0attributes_with_point<CMap2, Refs> >
|
||||
(amap, converters, pointconverter);
|
||||
}
|
||||
|
||||
// Copy constructor from a map having exactly the same type.
|
||||
Combinatorial_map_base (const Self & amap)
|
||||
{ copy<Self>(amap); }
|
||||
|
||||
// "Copy constructor" from a map having different type.
|
||||
template <typename CMap2>
|
||||
Combinatorial_map_base(const CMap2& amap)
|
||||
{ copy<CMap2>(amap); }
|
||||
|
||||
// "Copy constructor" from a map having different type.
|
||||
template <typename CMap2, typename Converters>
|
||||
Combinatorial_map_base(const CMap2& amap, Converters& converters)
|
||||
{ copy<CMap2,Converters>(amap, converters); }
|
||||
|
||||
// "Copy constructor" from a map having different type.
|
||||
template <typename CMap2, typename Converters, typename Pointconverter>
|
||||
Combinatorial_map_base(const CMap2& amap, Converters& converters,
|
||||
const Pointconverter& pointconverter)
|
||||
{ copy<CMap2,Converters, Pointconverter>
|
||||
(amap, converters, pointconverter); }
|
||||
|
||||
/** Affectation operation. Copies one map to the other.
|
||||
* @param amap a combinatorial map.
|
||||
* @return A copy of that combinatorial map.
|
||||
*/
|
||||
Self & operator= (const Self & amap)
|
||||
{
|
||||
if (this!=&amap)
|
||||
{
|
||||
Self tmp(amap);
|
||||
this->swap(tmp);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Swap this combinatorial map with amap, a second combinatorial map.
|
||||
* Note that the two maps have exactly the same type.
|
||||
* @param amap a combinatorial map.
|
||||
*/
|
||||
void swap(Self & amap)
|
||||
{
|
||||
if (this!=&amap)
|
||||
{
|
||||
amap.mdarts.swap(mdarts);
|
||||
|
||||
std::swap_ranges(mnb_times_reserved_marks,
|
||||
mnb_times_reserved_marks+NB_MARKS,
|
||||
amap.mnb_times_reserved_marks);
|
||||
std::swap(mmask_marks,amap.mmask_marks);
|
||||
std::swap(mnb_used_marks, amap.mnb_used_marks);
|
||||
std::swap_ranges(mindex_marks,mindex_marks+NB_MARKS,
|
||||
amap.mindex_marks);
|
||||
std::swap_ranges(mfree_marks_stack, mfree_marks_stack+NB_MARKS,
|
||||
amap.mfree_marks_stack);
|
||||
std::swap_ranges(mused_marks_stack,mused_marks_stack+NB_MARKS,
|
||||
amap.mused_marks_stack);
|
||||
std::swap_ranges(mnb_marked_darts,mnb_marked_darts+NB_MARKS,
|
||||
amap.mnb_marked_darts);
|
||||
mattribute_containers.swap(amap.mattribute_containers);
|
||||
}
|
||||
}
|
||||
|
||||
/** Clear the combinatorial map. Remove all darts and all attributes.
|
||||
* Note that reserved marks are not free.
|
||||
*/
|
||||
|
|
@ -3081,6 +3248,212 @@ namespace CGAL {
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
/** Test if the connected component of cmap containing dart dh1 is
|
||||
* isomorphic to the connected component of map2 containing dart dh2,
|
||||
* starting from dh1 and dh2.
|
||||
* @param dh1 initial dart for this map
|
||||
* @param map2 the second combinatorial map
|
||||
* @param dh2 initial dart for map2
|
||||
* @param testAttributes Boolean to test the equality of attributes (true)
|
||||
* or not (false)
|
||||
* @return true iff the cc of map is isomorphic to the cc of map2 starting
|
||||
* from dh1 and dh2; by testing the equality of attributes if
|
||||
* testAttributes is true
|
||||
*/
|
||||
template <unsigned int d2, typename Refs2, typename Items2, class Alloc2>
|
||||
bool are_cc_isomorphic(Dart_const_handle dh1,
|
||||
const Combinatorial_map_base
|
||||
<d2,Refs2,Items2,Alloc2>& map2,
|
||||
typename Combinatorial_map_base
|
||||
<d2,Refs2,Items2,Alloc2>::Dart_const_handle dh2,
|
||||
bool testAttributes=true) const
|
||||
{
|
||||
// CGAL_assertion(dimension==map2.dimension);
|
||||
CGAL_assertion(dh1!=NULL && dh2!=NULL);
|
||||
|
||||
typedef Combinatorial_map_base<d2,Refs2,Items2,Alloc2> Map2;
|
||||
|
||||
bool match = true;
|
||||
|
||||
// Two stacks used to run through the two maps.
|
||||
std::deque< Dart_const_handle > toTreat1;
|
||||
std::deque< typename Map2::Dart_const_handle > toTreat2;
|
||||
|
||||
int m1 = get_new_mark();
|
||||
int m2 = map2.get_new_mark();
|
||||
|
||||
toTreat1.push_back(dh1);
|
||||
toTreat2.push_back(dh2);
|
||||
|
||||
Dart_const_handle current;
|
||||
typename Map2::Dart_const_handle other;
|
||||
|
||||
unsigned int i = 0;
|
||||
CGAL::Unique_hash_map<Dart_const_handle,
|
||||
typename Map2::Dart_const_handle> bijection;
|
||||
|
||||
while (match && !toTreat1.empty())
|
||||
{
|
||||
// Next dart
|
||||
current = toTreat1.front();
|
||||
toTreat1.pop_front();
|
||||
other = toTreat2.front();
|
||||
toTreat2.pop_front();
|
||||
|
||||
if (!is_marked(current, m1))
|
||||
{
|
||||
if (map2.is_marked(other, m2))
|
||||
match=false;
|
||||
else
|
||||
{
|
||||
bijection[current] = other;
|
||||
|
||||
mark(current, m1);
|
||||
map2.mark(other, m2);
|
||||
|
||||
if (testAttributes)
|
||||
{
|
||||
// We need to test in both direction because
|
||||
// Foreach_enabled_attributes only test non void attributes
|
||||
// of Self.
|
||||
Helper::template Foreach_enabled_attributes
|
||||
< internal::Test_is_same_attribute_functor<Self, Map2> >::
|
||||
run(current, other);
|
||||
Map2::Helper::template Foreach_enabled_attributes
|
||||
< internal::Test_is_same_attribute_functor<Map2, Self> >::
|
||||
run(other, current);
|
||||
if ( !internal::Test_is_same_attribute_functor<Self, Map2>::
|
||||
value ||
|
||||
!internal::Test_is_same_attribute_functor<Map2, Self>::
|
||||
value )
|
||||
match=false;
|
||||
}
|
||||
|
||||
// We test if the injection is valid with its neighboors.
|
||||
// We go out as soon as it is not satisfied.
|
||||
for (i = 0; match && i <= dimension; ++i)
|
||||
{
|
||||
if ( i>map2.dimension )
|
||||
{
|
||||
if (!current->is_free(i)) match=false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (current->is_free(i))
|
||||
{
|
||||
if (!other->is_free(i))
|
||||
match = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (other->is_free(i))
|
||||
match = false;
|
||||
else
|
||||
{
|
||||
if (is_marked(current->beta (i), m1) !=
|
||||
map2.is_marked(other->beta(i), m2))
|
||||
match = false;
|
||||
else
|
||||
{
|
||||
if (!is_marked (current->beta(i), m1))
|
||||
{
|
||||
toTreat1.push_back(current->beta (i));
|
||||
toTreat2.push_back(other->beta (i));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bijection[current->beta(i)] !=
|
||||
other->beta(i))
|
||||
match = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Now we test if the second map has more beta links than the first
|
||||
for ( i=dimension+1; match && i<=map2.dimension; ++i )
|
||||
{
|
||||
if (!other->is_free(i)) match=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!map2.is_marked(other, m2))
|
||||
match = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Here we test if both queue are empty
|
||||
if ( !toTreat1.empty() || !toTreat2.empty() ) match = false;
|
||||
|
||||
// Here we unmark all the marked darts.
|
||||
toTreat1.clear();
|
||||
toTreat2.clear();
|
||||
|
||||
toTreat1.push_back(dh1);
|
||||
toTreat2.push_back(dh2);
|
||||
|
||||
while (!toTreat1.empty())
|
||||
{
|
||||
current = toTreat1.front();
|
||||
toTreat1.pop_front();
|
||||
other = toTreat2.front();
|
||||
toTreat2.pop_front();
|
||||
|
||||
unmark(current, m1);
|
||||
map2.unmark(other, m2);
|
||||
|
||||
for (i = 0; match && i <= dimension; ++i)
|
||||
{
|
||||
if (!current->is_free(i) && is_marked(current->beta(i), m1))
|
||||
{
|
||||
CGAL_assertion(!other->is_free(i) &&
|
||||
map2.is_marked(other->beta(i), m2));
|
||||
toTreat1.push_back(current->beta(i));
|
||||
toTreat2.push_back(other->beta(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free_mark(m1);
|
||||
map2.free_mark(m2);
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
/** Test if this cmap is isomorphic to map2.
|
||||
* @pre cmap is connected.
|
||||
* @param map2 the second combinatorial map
|
||||
* @param testAttributes Boolean to test the equality of attributes (true)
|
||||
* or not (false)
|
||||
* @return true iff this map is isomorphic to map2, testing the equality
|
||||
* of attributes if testAttributes is true
|
||||
*/
|
||||
template <unsigned int d2, typename Refs2, typename Items2, class Alloc2>
|
||||
bool is_isomorphic_to(const Combinatorial_map_base
|
||||
<d2,Refs2,Items2,Alloc2>& map2,
|
||||
bool testAttributes=true)
|
||||
{
|
||||
// if ( dimension!=map2.dimension ) return false;
|
||||
|
||||
Dart_const_handle d1=darts().begin();
|
||||
|
||||
for (typename Combinatorial_map_base<d2,Refs2,Items2,Alloc2>::
|
||||
Dart_range::const_iterator it(map2.darts().begin()),
|
||||
itend(map2.darts().end()); it!=itend; ++it)
|
||||
{
|
||||
if (are_cc_isomorphic(d1, map2, it, testAttributes))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Void dart. A dart d is i-free if beta_i(d)=null_dart_handle.
|
||||
static Dart_handle null_dart_handle;
|
||||
|
||||
|
|
@ -3149,6 +3522,27 @@ namespace CGAL {
|
|||
typedef typename Base::Dart_handle Dart_handle;
|
||||
typedef typename Base::Dart_const_handle Dart_const_handle;
|
||||
typedef typename Base::Alloc Alloc;
|
||||
|
||||
Combinatorial_map() : Base()
|
||||
{}
|
||||
|
||||
Combinatorial_map(const Self & amap)
|
||||
{ Base::template copy<Self>(amap); }
|
||||
|
||||
template < class CMap >
|
||||
Combinatorial_map(const CMap & amap)
|
||||
{ Base::template copy<CMap>(amap); }
|
||||
|
||||
template < class CMap, typename Converters >
|
||||
Combinatorial_map(const CMap & amap, const Converters& converters)
|
||||
{ Base::template copy<CMap, Converters>
|
||||
(amap, converters); }
|
||||
|
||||
template < class CMap, typename Converters, typename Pointconverter >
|
||||
Combinatorial_map(const CMap & amap, const Converters& converters,
|
||||
const Pointconverter& pointconverter)
|
||||
{ Base::template copy<CMap, Converters, Pointconverter>
|
||||
(amap, converters, pointconverter); }
|
||||
};
|
||||
|
||||
} // namespace CGAL
|
||||
|
|
|
|||
|
|
@ -0,0 +1,415 @@
|
|||
// Copyright (c) 2010-2013 CNRS and LIRIS' Establishments (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) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
|
||||
//
|
||||
#ifndef CGAL_COMBINATORIAL_MAP_COPY_FUNCTORS_H
|
||||
#define CGAL_COMBINATORIAL_MAP_COPY_FUNCTORS_H
|
||||
|
||||
#include <CGAL/internal/Combinatorial_map_utility.h>
|
||||
#include <CGAL/internal/Combinatorial_map_internal_functors.h>
|
||||
#include <CGAL/Dimension.h>
|
||||
#include <CGAL/Kernel_traits.h>
|
||||
#include <CGAL/Cartesian_converter.h>
|
||||
|
||||
/* Definition of functors used internally to copy combinatorial maps attributes
|
||||
* (we need functors as attributes are stored in tuple, thus all the access
|
||||
* must be done at compiling time).
|
||||
*/
|
||||
namespace CGAL
|
||||
{
|
||||
template< typename Map1, typename Map2, unsigned int i>
|
||||
struct Default_converter_cmap_attributes;
|
||||
template< typename Map1, typename Map2>
|
||||
struct Default_converter_cmap_0attributes_with_point;
|
||||
// ****************************************************************************
|
||||
namespace internal
|
||||
{
|
||||
// ****************************************************************************
|
||||
// Map1 is the existing map, to convert into map2.
|
||||
// Functor called only when both i-attributes have non void info.
|
||||
// General cases when both info are differents.
|
||||
template< typename Map1, typename Map2, unsigned int i,
|
||||
typename Info1=typename Map1::template
|
||||
Attribute_type<i>::type::Info,
|
||||
typename Info2=typename Map2::template
|
||||
Attribute_type<i>::type::Info >
|
||||
struct Create_attribute_if_same_info_cmap
|
||||
{
|
||||
static typename Map2::template Attribute_handle<i>::type
|
||||
run(Map2&, typename Map1::template Attribute_const_handle<i>::type)
|
||||
{ return NULL; }
|
||||
};
|
||||
|
||||
// Special case when both attributes have the same info.
|
||||
template< typename Map1, typename Map2, unsigned int i, typename Info >
|
||||
struct Create_attribute_if_same_info_cmap<Map1, Map2, i, Info, Info>
|
||||
{
|
||||
static typename Map2::template Attribute_handle<i>::type
|
||||
run(Map2& map2, typename Map1::template Attribute_const_handle<i>::type ah)
|
||||
{
|
||||
CGAL_assertion( ah!=NULL );
|
||||
typename Map2::template Attribute_handle<i>::type
|
||||
res = map2.template create_attribute<i>();
|
||||
res->info() = ah->info();
|
||||
return res;
|
||||
}
|
||||
};
|
||||
// ****************************************************************************
|
||||
// Functor allowing to set the value of a point if point exist, have
|
||||
// same dimension. For dim>3, if type of points are the same
|
||||
// (because no converter).
|
||||
template<typename Point1, typename Point2,
|
||||
typename T1=typename Ambient_dimension<Point1>::type,
|
||||
typename T2=typename Ambient_dimension<Point2>::type>
|
||||
struct Set_point_if_possible_cmap
|
||||
{
|
||||
static void run(const Point1&, Point2&)
|
||||
{}
|
||||
};
|
||||
|
||||
template<typename Point1, typename Point2>
|
||||
struct Set_point_if_possible_cmap<Point1, Point2,
|
||||
Dimension_tag<2>, Dimension_tag<2> >
|
||||
{
|
||||
static void run(const Point1& p1, Point2& p2)
|
||||
{
|
||||
p2 = Cartesian_converter<typename Kernel_traits<Point1>::Kernel,
|
||||
typename Kernel_traits<Point2>::Kernel>(p1);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Point1>
|
||||
struct Set_point_if_possible_cmap<Point1, Point1,
|
||||
Dimension_tag<2>, Dimension_tag<2> >
|
||||
{
|
||||
static void run(const Point1& p1, Point1& p2)
|
||||
{
|
||||
p2 = p1;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Point1, typename Point2>
|
||||
struct Set_point_if_possible_cmap<Point1, Point2,
|
||||
Dimension_tag<3>, Dimension_tag<3> >
|
||||
{
|
||||
static void run(const Point1& p1, Point2& p2)
|
||||
{
|
||||
p2 = Cartesian_converter<typename Kernel_traits<Point1>::Kernel,
|
||||
typename Kernel_traits<Point2>::Kernel>()(p1);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Point1>
|
||||
struct Set_point_if_possible_cmap<Point1, Point1,
|
||||
Dimension_tag<3>, Dimension_tag<3> >
|
||||
{
|
||||
static void run(const Point1& p1, Point1& p2)
|
||||
{
|
||||
p2 = p1;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Point1>
|
||||
struct Set_point_if_possible_cmap<Point1, Point1,
|
||||
Dynamic_dimension_tag, Dynamic_dimension_tag >
|
||||
{
|
||||
static void run(const Point1& p1, Point1& p2)
|
||||
{
|
||||
p2 = p1;
|
||||
}
|
||||
};
|
||||
// ****************************************************************************
|
||||
// Get the ith functor of the converters tuple if i<length of the tuple,
|
||||
// otherwise get the default converter.
|
||||
template<typename Map1, typename Map2, unsigned int i, typename Converters,
|
||||
bool t=((int)i>=My_length<Converters>::value)>
|
||||
struct Get_convert_attribute_functor
|
||||
{
|
||||
static typename Map2::template Attribute_handle<i>::type
|
||||
run( const Map1* cmap1, Map2* cmap2, typename Map1::Dart_const_handle dh1,
|
||||
typename Map2::Dart_handle dh2, const Converters& converters)
|
||||
{
|
||||
return
|
||||
CGAL::Default_converter_cmap_attributes<Map1, Map2, i>()
|
||||
(*cmap1, *cmap2, dh1, dh2);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Map1, typename Map2, unsigned int i, typename Converters>
|
||||
struct Get_convert_attribute_functor<Map1,Map2,i,Converters,false>
|
||||
{
|
||||
static typename Map2::template Attribute_handle<i>::type
|
||||
run( const Map1* cmap1, Map2* cmap2, typename Map1::Dart_const_handle dh1,
|
||||
typename Map2::Dart_handle dh2, const Converters& converters)
|
||||
{
|
||||
return CGAL::cpp11::get<i>(converters) (*cmap1, *cmap2, dh1, dh2);
|
||||
}
|
||||
};
|
||||
// ****************************************************************************
|
||||
// Call a given functor if both i-attribute have an non void info
|
||||
template< typename Map1, typename Map2, unsigned int i,
|
||||
typename Converters,
|
||||
bool Withinfo1=CGAL::internal::template
|
||||
Is_attribute_has_non_void_info
|
||||
<typename Map1::template Attribute_type<i>::type>::value,
|
||||
bool Withinfo2=CGAL::internal::template
|
||||
Is_attribute_has_non_void_info
|
||||
<typename Map2::template Attribute_type<i>::type>::value >
|
||||
struct Call_functor_if_both_attributes_have_info
|
||||
{
|
||||
static typename Map2::template Attribute_handle<i>::type
|
||||
run( const Map1*,
|
||||
Map2*,
|
||||
typename Map1::Dart_const_handle,
|
||||
typename Map2::Dart_handle,
|
||||
const Converters&)
|
||||
{ return NULL; }
|
||||
};
|
||||
|
||||
template< typename Map1, typename Map2, unsigned int i, typename Converters >
|
||||
struct Call_functor_if_both_attributes_have_info<Map1, Map2, i,
|
||||
Converters, true, true>
|
||||
{
|
||||
static typename Map2::template Attribute_handle<i>::type
|
||||
run( const Map1* cmap1,
|
||||
Map2* cmap2,
|
||||
typename Map1::Dart_const_handle dh1,
|
||||
typename Map2::Dart_handle dh2,
|
||||
const Converters& converters )
|
||||
{
|
||||
return Get_convert_attribute_functor<Map1,Map2,i,Converters>::
|
||||
run(cmap1, cmap2, dh1, dh2, converters);
|
||||
}
|
||||
};
|
||||
// ****************************************************************************
|
||||
// Call a given functor only if both 0-attribute have a point.
|
||||
// general case i!=0 or one attribute without point.
|
||||
template< typename Map1, typename Map2, unsigned int i,
|
||||
typename Pointconverter,
|
||||
bool Withpoint1=CGAL::internal::template Is_attribute_has_point
|
||||
<typename Map1::template Attribute_type<i>::type>::value,
|
||||
bool Withpoint2=CGAL::internal::template Is_attribute_has_point
|
||||
<typename Map2::template Attribute_type<i>::type>::value >
|
||||
struct Call_functor_if_both_attributes_have_point
|
||||
{
|
||||
static typename Map2::template Attribute_handle<i>::type
|
||||
run( const Map1*,
|
||||
Map2*,
|
||||
typename Map1::Dart_const_handle,
|
||||
typename Map2::Dart_handle,
|
||||
const Pointconverter&)
|
||||
{ return NULL; }
|
||||
};
|
||||
// Specialisation with i==0 and both attributes have points.
|
||||
template< typename Map1, typename Map2, typename Pointconverter >
|
||||
struct Call_functor_if_both_attributes_have_point<Map1, Map2, 0,
|
||||
Pointconverter, true, true>
|
||||
{
|
||||
static typename Map2::template Attribute_handle<0>::type
|
||||
run( const Map1* cmap1,
|
||||
Map2* cmap2,
|
||||
typename Map1::Dart_const_handle dh1,
|
||||
typename Map2::Dart_handle dh2,
|
||||
const Pointconverter& pointconverter )
|
||||
{ return pointconverter(*cmap1, *cmap2, dh1, dh2); }
|
||||
};
|
||||
// ****************************************************************************
|
||||
// Copy attribute when if both i-attributes are non void.
|
||||
// (note Attr2 could not be Void as copy functor is called only for
|
||||
// non void attributes)
|
||||
// General case with both attributes non void.
|
||||
template<typename Map1, typename Map2, typename Converters,
|
||||
typename Pointconverter, unsigned int i,
|
||||
typename Attr1=typename Map1::template Attribute_type<i>::type,
|
||||
typename Attr2=typename Map2::template Attribute_type<i>::type >
|
||||
struct Copy_attribute_functor_if_nonvoid
|
||||
{
|
||||
static void run( const Map1* cmap1,
|
||||
Map2* cmap2,
|
||||
typename Map1::Dart_const_handle dh1,
|
||||
typename Map2::Dart_handle dh2,
|
||||
const Converters& converters,
|
||||
const Pointconverter& pointconverter)
|
||||
{
|
||||
// If dh1 has no i-attribute, nothing to copy.
|
||||
if ( dh1->template attribute<i>()==NULL ) return;
|
||||
|
||||
// If dh2 has already an i-attribute, it was already copied.
|
||||
if ( dh2->template attribute<i>()!=NULL ) return;
|
||||
|
||||
// Otherwise we copy the info if both attribute have non void info.
|
||||
typename Map2::template Attribute_handle<i>::type
|
||||
res=Call_functor_if_both_attributes_have_info
|
||||
<Map1, Map2, i, Converters>::
|
||||
run(cmap1, cmap2, dh1, dh2, converters);
|
||||
|
||||
if ( res!=NULL )
|
||||
cmap2->template set_attribute<i>(dh2, res);
|
||||
|
||||
// And the point if both attributes have points (and only for 0-attributes)
|
||||
res=Call_functor_if_both_attributes_have_point
|
||||
<Map1, Map2, i, Pointconverter>::
|
||||
run(cmap1, cmap2, dh1, dh2, pointconverter);
|
||||
|
||||
if ( res!=NULL && dh2->template attribute<i>()==NULL )
|
||||
cmap2->template set_attribute<i>(dh2, res);
|
||||
}
|
||||
};
|
||||
// Specialisation when attr1 is void, and attr2 is non void i==0. Nothing to
|
||||
// copy, but if 0-attributes has point and i==0, we need to create
|
||||
// vertex attributes.
|
||||
template<typename Map1, typename Map2, typename Converters,
|
||||
typename Pointconverter, typename Attr2>
|
||||
struct Copy_attribute_functor_if_nonvoid<Map1, Map2, Converters,
|
||||
Pointconverter, 0, CGAL::Void, Attr2>
|
||||
{
|
||||
static void run( const Map1*,
|
||||
Map2* cmap2,
|
||||
typename Map1::Dart_const_handle,
|
||||
typename Map2::Dart_handle dh2,
|
||||
const Converters&,
|
||||
const Pointconverter&)
|
||||
{
|
||||
// If dh2 has already an 0-attribute, it was already created.
|
||||
if ( dh2->template attribute<0>()!=NULL ) return;
|
||||
|
||||
// Create the point if 0-attributes has Point.
|
||||
if ( CGAL::internal::template Is_attribute_has_point
|
||||
<typename Map2::template Attribute_type<0>::type>::value )
|
||||
cmap2->template
|
||||
set_attribute<0>(dh2, cmap2->template create_attribute<0>());
|
||||
}
|
||||
};
|
||||
// Specialisation when attr1 is void, and attr2 is non void i!=0.
|
||||
// Nothing to do.
|
||||
template<typename Map1, typename Map2, typename Converters, unsigned int i,
|
||||
typename Pointconverter, typename Attr2>
|
||||
struct Copy_attribute_functor_if_nonvoid<Map1, Map2, Converters,
|
||||
Pointconverter, i, CGAL::Void, Attr2>
|
||||
{
|
||||
static void run( const Map1*,
|
||||
Map2*,
|
||||
typename Map1::Dart_const_handle,
|
||||
typename Map2::Dart_handle,
|
||||
const Converters&,
|
||||
const Pointconverter&)
|
||||
{}
|
||||
};
|
||||
// ****************************************************************************
|
||||
/// Copy enabled attributes from one cmap to other. General case called
|
||||
/// by copy function in Combinatorial_map on all the non void attributes
|
||||
/// of Map2. Map1 is the existing map, to convert into map2.
|
||||
template<typename Map1, typename Map2, typename Converters,
|
||||
typename Pointconverter>
|
||||
struct Copy_attributes_functor
|
||||
{
|
||||
template<unsigned int i>
|
||||
static void run( const Map1* cmap1,
|
||||
Map2* cmap2,
|
||||
typename Map1::Dart_const_handle dh1,
|
||||
typename Map2::Dart_handle dh2,
|
||||
const Converters& converters,
|
||||
const Pointconverter& pointconverter)
|
||||
{ Copy_attribute_functor_if_nonvoid
|
||||
<Map1, Map2, Converters, Pointconverter, i>::
|
||||
run(cmap1, cmap2, dh1, dh2, converters, pointconverter);
|
||||
}
|
||||
};
|
||||
// ****************************************************************************
|
||||
} // namespace internal
|
||||
// ****************************************************************************
|
||||
// "Converters" called during the copy of attributes, to copy Info.
|
||||
// Users can replace them by their own converters.
|
||||
// Info converter are called only if both i-attributes have non void info,
|
||||
// if dh1 has an i-attribute and if dh2 does not already has an i-attribute.
|
||||
// Map1 is the existing map, to convert into map2.
|
||||
// ****************************************************************************
|
||||
// Default converter copy only attributes if they have same info types.
|
||||
template< typename Map1, typename Map2, unsigned int i>
|
||||
struct Default_converter_cmap_attributes
|
||||
{
|
||||
typename Map2::template Attribute_handle<i>::type operator()
|
||||
(const Map1&, Map2& map2, typename Map1::Dart_const_handle dh1,
|
||||
typename Map2::Dart_handle dh2) const
|
||||
{
|
||||
CGAL_assertion( dh1->template attribute<i>()!=NULL );
|
||||
CGAL_assertion( dh2->template attribute<i>()==NULL );
|
||||
return internal::Create_attribute_if_same_info_cmap
|
||||
<Map1,Map2,i>::
|
||||
run(map2, dh1->template attribute<i>());
|
||||
}
|
||||
};
|
||||
// ****************************************************************************
|
||||
// Cast converter always copy attributes, doing a cast. This can work only
|
||||
// if both types are convertible and this is user responsability
|
||||
// to use it only in this case.
|
||||
template< typename Map1, typename Map2, unsigned int i>
|
||||
struct Cast_converter_cmap_attributes
|
||||
{
|
||||
typename Map2::template Attribute_handle<i>::type operator()
|
||||
(const Map1&, Map2& map2, typename Map1::Dart_const_handle dh1,
|
||||
typename Map2::Dart_handle dh2) const
|
||||
{
|
||||
CGAL_assertion( dh1->template attribute<i>()!=NULL );
|
||||
CGAL_assertion( dh2->template attribute<i>()==NULL );
|
||||
typename Map2::template Attribute_handle<i>::type
|
||||
res = map2.template create_attribute<i>();
|
||||
res->info() = (typename Map2::template Attribute_type<i>::type::Info)
|
||||
dh1->template attribute<i>()->info();
|
||||
return res;
|
||||
}
|
||||
};
|
||||
// ****************************************************************************
|
||||
// "Converters" called during the copy of attributes, to copy Point (for
|
||||
// attributes having such type defined).
|
||||
// Users can replace them by their own converters.
|
||||
// Point converter is called after Info converters; thus it is possible that
|
||||
// attribute<0> was already created for dh2.
|
||||
// Point converter is only called if both types of 0-attributes have
|
||||
// Point type defined, and if dh1 has a 0-attribute.
|
||||
// Map1 is the existing map, to convert into map2.
|
||||
// ****************************************************************************
|
||||
// Default converter for points. Point are copied only if they have same
|
||||
// types, or in 2D/3D we use Cartesian_converter.
|
||||
template< typename Map1, typename Map2>
|
||||
struct Default_converter_cmap_0attributes_with_point
|
||||
{
|
||||
typename Map2::template Attribute_handle<0>::type operator()
|
||||
(const Map1&, Map2& map2, typename Map1::Dart_const_handle dh1,
|
||||
typename Map2::Dart_handle dh2) const
|
||||
{
|
||||
CGAL_assertion( dh1->template attribute<0>()!=NULL );
|
||||
|
||||
typename Map2::template Attribute_handle<0>::type
|
||||
res = dh2->template attribute<0>();
|
||||
if ( res==NULL )
|
||||
{
|
||||
res = map2.template create_attribute<0>();
|
||||
}
|
||||
internal::Set_point_if_possible_cmap
|
||||
<typename Map1::template Attribute_type<0>::type::Point,
|
||||
typename Map2::template Attribute_type<0>::type::Point>::
|
||||
run(dh1->template attribute<0>()->point(),
|
||||
res->point());
|
||||
return res;
|
||||
}
|
||||
};
|
||||
// ****************************************************************************
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_COMBINATORIAL_MAP_COPY_FUNCTORS_H
|
||||
|
|
@ -22,7 +22,10 @@
|
|||
|
||||
#include <CGAL/Dart_const_iterators.h>
|
||||
#include <CGAL/Combinatorial_map_basic_operations.h>
|
||||
#include <CGAL/Dimension.h>
|
||||
#include <CGAL/Kernel_traits.h>
|
||||
#include <vector>
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
|
||||
/* Definition of functors used internally to manage attributes (we need
|
||||
* functors as attributes are stored in tuple, thus all the access must be
|
||||
|
|
@ -58,6 +61,15 @@
|
|||
*
|
||||
* internal::Set_i_attribute_of_dart_functor<CMap, i> to set the i-attribute
|
||||
* of a given dart.
|
||||
*
|
||||
* internal::Test_is_same_attribute_functor<Map1, Map2> to test if two
|
||||
* i-attributes of two darts are isomorphic.
|
||||
*
|
||||
* internal::Is_attribute_has_non_void_info<Attr> to test if the attribute
|
||||
* Attr is non Void and has an non void Info as inner type
|
||||
*
|
||||
* internal::Is_attribute_has_point<Attr> to test if the attribute
|
||||
* Attr is non Void and has a Point inner type
|
||||
*/
|
||||
|
||||
namespace CGAL
|
||||
|
|
@ -413,6 +425,254 @@ struct Set_i_attribute_of_dart_functor<CMap, i, CGAL::Void>
|
|||
{}
|
||||
};
|
||||
// ****************************************************************************
|
||||
// Functor allowing to test if two info are the same or not
|
||||
template< typename Attr1, typename Attr2,
|
||||
typename Info1=typename Attr1::Info,
|
||||
typename Info2=typename Attr2::Info >
|
||||
struct Is_same_info
|
||||
{
|
||||
static bool run(const Attr1&, const Attr2&)
|
||||
{ return false; }
|
||||
};
|
||||
|
||||
template< typename Attr1, typename Attr2, typename Info1 >
|
||||
struct Is_same_info<Attr1, Attr2, Info1, void>
|
||||
{
|
||||
static bool run(const Attr1&, const Attr2&)
|
||||
{ return false; }
|
||||
};
|
||||
|
||||
template< typename Attr1, typename Attr2, typename Info2 >
|
||||
struct Is_same_info<Attr1, Attr2, void, Info2>
|
||||
{
|
||||
static bool run(const Attr1&, const Attr2&)
|
||||
{ return false; }
|
||||
};
|
||||
|
||||
template< typename Attr1, typename Attr2 >
|
||||
struct Is_same_info<Attr1, Attr2, void, void>
|
||||
{
|
||||
static bool run(const Attr1&, const Attr2&)
|
||||
{ return true; }
|
||||
};
|
||||
|
||||
template< typename Attr1, typename Attr2, typename Info >
|
||||
struct Is_same_info<Attr1, Attr2, Info, Info>
|
||||
{
|
||||
static bool run(const Attr1&a1, const Attr2&a2)
|
||||
{ return a1.info()==a2.info(); }
|
||||
};
|
||||
|
||||
// Case of two non void type
|
||||
template<typename Map1, typename Map2,
|
||||
typename T1, typename T2, int i>
|
||||
struct Is_same_attribute_info_functor
|
||||
{
|
||||
static bool run(typename Map1::Dart_const_handle dh1,
|
||||
typename Map2::Dart_const_handle dh2)
|
||||
{
|
||||
if (dh1->template attribute<i>()==NULL &&
|
||||
dh2->template attribute<i>()==NULL)
|
||||
return true;
|
||||
|
||||
if (dh1->template attribute<i>()==NULL ||
|
||||
dh2->template attribute<i>()==NULL)
|
||||
return false;
|
||||
|
||||
return
|
||||
Is_same_info<T1,T2>::run(*(dh1->template attribute<i>()),
|
||||
*(dh2->template attribute<i>()));
|
||||
}
|
||||
};
|
||||
|
||||
// Case T1==void
|
||||
template <typename Map1, typename Map2,
|
||||
typename T2, int i>
|
||||
struct Is_same_attribute_info_functor<Map1, Map2, Void, T2, i>
|
||||
{
|
||||
static bool run(typename Map1::Dart_const_handle,
|
||||
typename Map2::Dart_const_handle dh2)
|
||||
{
|
||||
return dh2->template attribute<i>()==NULL ||
|
||||
Is_same_info<int,T2,void,typename T2::Info>::
|
||||
run(0, *(dh2->template attribute<i>()));
|
||||
}
|
||||
};
|
||||
|
||||
// Case T2==void
|
||||
template <typename Map1, typename Map2,
|
||||
typename T1, int i>
|
||||
struct Is_same_attribute_info_functor<Map1, Map2, T1, Void, i>
|
||||
{
|
||||
static bool run(typename Map1::Dart_const_handle dh1,
|
||||
typename Map2::Dart_const_handle)
|
||||
{
|
||||
return dh1->template attribute<i>()==NULL ||
|
||||
Is_same_info<T1, int, typename T1::Info, void>::
|
||||
run(*(dh1->template attribute<i>()), 0);
|
||||
}
|
||||
};
|
||||
|
||||
// Case T1==T2==void
|
||||
template <typename Map1, typename Map2, int i>
|
||||
struct Is_same_attribute_info_functor<Map1, Map2, Void, Void, i>
|
||||
{
|
||||
static bool run(typename Map1::Dart_const_handle,
|
||||
typename Map2::Dart_const_handle)
|
||||
{ return true; }
|
||||
};
|
||||
|
||||
// ****************************************************************************
|
||||
// Functor allowing to test if two points are the same or not.
|
||||
// Here we know both attributes have points.
|
||||
template< typename Attr1, typename Attr2,
|
||||
typename Point1=typename Attr1::Point,
|
||||
typename Point2=typename Attr2::Point,
|
||||
typename T1=typename Ambient_dimension<Point1>::type >
|
||||
struct Is_same_point
|
||||
{
|
||||
static bool run(const Attr1&, const Attr2&)
|
||||
{ return false; }
|
||||
};
|
||||
|
||||
template< typename Attr1, typename Attr2, typename Point>
|
||||
struct Is_same_point<Attr1, Attr2, Point, Point, Dimension_tag<2> >
|
||||
{
|
||||
static bool run(const Attr1& a1, const Attr2& a2)
|
||||
{ return typename Kernel_traits<Point>::Kernel::Equal_2()
|
||||
(a1.point(),a2.point()); }
|
||||
};
|
||||
|
||||
template< typename Attr1, typename Attr2, typename Point>
|
||||
struct Is_same_point<Attr1, Attr2, Point, Point, Dimension_tag<3> >
|
||||
{
|
||||
static bool run(const Attr1& a1, const Attr2& a2)
|
||||
{ return typename Kernel_traits<Point>::Kernel::Equal_3()
|
||||
(a1.point(),a2.point()); }
|
||||
};
|
||||
|
||||
template< typename Attr1, typename Attr2, typename Point>
|
||||
struct Is_same_point<Attr1, Attr2, Point, Point, Dynamic_dimension_tag >
|
||||
{
|
||||
static bool run(const Attr1& a1, const Attr2& a2)
|
||||
{ return typename Kernel_traits<Point>::Kernel::Equal_d()
|
||||
(a1.point(),a2.point()); }
|
||||
};
|
||||
|
||||
// Case of two non void type, with two points
|
||||
template<typename Map1, typename Map2,
|
||||
typename T1, typename T2, bool Withpoint1, bool Withpoint2, int i>
|
||||
struct Is_same_attribute_point_functor
|
||||
{
|
||||
static bool run(typename Map1::Dart_const_handle dh1,
|
||||
typename Map2::Dart_const_handle dh2)
|
||||
{
|
||||
CGAL_static_assertion( Withpoint1==true && Withpoint2==true );
|
||||
if (dh1->template attribute<i>()==NULL &&
|
||||
dh2->template attribute<i>()==NULL)
|
||||
return true;
|
||||
|
||||
if (dh1->template attribute<i>()==NULL ||
|
||||
dh2->template attribute<i>()==NULL)
|
||||
return false;
|
||||
|
||||
return
|
||||
Is_same_point<T1,T2>::run(*(dh1->template attribute<i>()),
|
||||
*(dh2->template attribute<i>()));
|
||||
}
|
||||
};
|
||||
|
||||
// Case of two non void type, first without point
|
||||
template<typename Map1, typename Map2,
|
||||
typename T1, typename T2, int i>
|
||||
struct Is_same_attribute_point_functor<Map1, Map2, T1, T2, false, true, i>
|
||||
{
|
||||
static bool run(typename Map1::Dart_const_handle,
|
||||
typename Map2::Dart_const_handle)
|
||||
{ return false; }
|
||||
};
|
||||
|
||||
// Case of two non void type, second without point
|
||||
template<typename Map1, typename Map2,
|
||||
typename T1, typename T2, int i>
|
||||
struct Is_same_attribute_point_functor<Map1, Map2, T1, T2, true, false, i>
|
||||
{
|
||||
static bool run(typename Map1::Dart_const_handle,
|
||||
typename Map2::Dart_const_handle)
|
||||
{ return false; }
|
||||
};
|
||||
|
||||
// Case of two non void type, both without point
|
||||
template<typename Map1, typename Map2,
|
||||
typename T1, typename T2, int i>
|
||||
struct Is_same_attribute_point_functor<Map1, Map2, T1, T2, false, false, i>
|
||||
{
|
||||
static bool run(typename Map1::Dart_const_handle,
|
||||
typename Map2::Dart_const_handle)
|
||||
{ return true; }
|
||||
};
|
||||
// ****************************************************************************
|
||||
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_point,Point,false)
|
||||
|
||||
template<typename Attr, typename Info=typename Attr::Info>
|
||||
struct Is_nonvoid_attribute_has_non_void_info
|
||||
{
|
||||
static const bool value=true;
|
||||
};
|
||||
template<typename Attr>
|
||||
struct Is_nonvoid_attribute_has_non_void_info<Attr, void>
|
||||
{
|
||||
static const bool value=false;
|
||||
};
|
||||
|
||||
template<typename Attr>
|
||||
struct Is_attribute_has_non_void_info
|
||||
{
|
||||
static const bool value=Is_nonvoid_attribute_has_non_void_info<Attr>::value;
|
||||
};
|
||||
template<>
|
||||
struct Is_attribute_has_non_void_info<CGAL::Void>
|
||||
{
|
||||
static const bool value=false;
|
||||
};
|
||||
// ****************************************************************************
|
||||
template<typename Attr>
|
||||
struct Is_attribute_has_point
|
||||
{ static const bool value=Has_point<Attr>::value; };
|
||||
// ****************************************************************************
|
||||
/// Test if the two darts are associated with the same attribute.
|
||||
template<typename Map1, typename Map2>
|
||||
struct Test_is_same_attribute_functor
|
||||
{
|
||||
template<unsigned int i>
|
||||
static void run(typename Map1::Dart_const_handle dh1,
|
||||
typename Map2::Dart_const_handle dh2 )
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
value = Is_same_attribute_info_functor
|
||||
<Map1, Map2,
|
||||
typename Map1::template Attribute_type<i>::type,
|
||||
typename Map2::template Attribute_type<i>::type,
|
||||
i>::run(dh1, dh2);
|
||||
}
|
||||
if (value)
|
||||
{
|
||||
value = Is_same_attribute_point_functor
|
||||
<Map1, Map2,
|
||||
typename Map1::template Attribute_type<i>::type,
|
||||
typename Map2::template Attribute_type<i>::type,
|
||||
Is_attribute_has_point<typename Map1::template
|
||||
Attribute_type<i>::type>::value,
|
||||
Is_attribute_has_point<typename Map2::template
|
||||
Attribute_type<i>::type>::value, i>::run(dh1, dh2);
|
||||
}
|
||||
}
|
||||
static bool value;
|
||||
};
|
||||
template<typename Map1, typename Map2>
|
||||
bool Test_is_same_attribute_functor<Map1, Map2>::value = true;
|
||||
// ****************************************************************************
|
||||
// Beta functor, used to combine several beta.
|
||||
#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
|
||||
template<typename Dart_handle, typename ... Betas>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,564 @@
|
|||
#include <CGAL/Combinatorial_map.h>
|
||||
#include <CGAL/Cell_attribute.h>
|
||||
#include <CGAL/Combinatorial_map_constructors.h>
|
||||
#include <CGAL/Combinatorial_map_operations.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct f1
|
||||
{
|
||||
template<typename Attr>
|
||||
void operator() (Attr&, Attr&)
|
||||
{}
|
||||
};
|
||||
struct f2
|
||||
{
|
||||
template<typename Attr>
|
||||
void operator() (const Attr&, Attr&)
|
||||
{}
|
||||
};
|
||||
struct f3
|
||||
{
|
||||
template<typename Attr>
|
||||
void operator() (Attr&, const Attr&)
|
||||
{}
|
||||
};
|
||||
struct f4
|
||||
{
|
||||
template<typename Attr>
|
||||
void operator() (const Attr&, const Attr&)
|
||||
{}
|
||||
};
|
||||
struct f5
|
||||
{
|
||||
template<typename Attr>
|
||||
void operator() (const Attr&, const Attr&)
|
||||
{}
|
||||
template<typename Attr>
|
||||
void operator() (Attr&, const Attr&)
|
||||
{}
|
||||
};
|
||||
struct f6
|
||||
{
|
||||
template<typename CMap, typename Attr>
|
||||
void operator() (CMap*, Attr&, Attr&)
|
||||
{}
|
||||
};
|
||||
struct f7
|
||||
{
|
||||
template<typename Attr>
|
||||
void operator() (Attr&, const Attr&)
|
||||
{}
|
||||
template<typename CMap, typename Attr>
|
||||
void operator() (CMap*, Attr&, Attr&)
|
||||
{}
|
||||
};
|
||||
|
||||
struct Map_2_dart_items
|
||||
{
|
||||
/// Dart_wrapper defines the type of darts used.
|
||||
template < class Refs >
|
||||
struct Dart_wrapper
|
||||
{
|
||||
typedef CGAL::Dart< 2, Refs > Dart;
|
||||
|
||||
typedef CGAL::Cell_attribute< Refs, int, CGAL::Tag_true, f1, f2 > Int_attrib;
|
||||
typedef CGAL::Cell_attribute< Refs, double, CGAL::Tag_true, f3, f4 > Double_attrib;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Double_attrib, void, Double_attrib> Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
struct Map_2_dart_max_items_3
|
||||
{
|
||||
/// Dart_wrapper defines the type of darts used.
|
||||
template < class Refs >
|
||||
struct Dart_wrapper
|
||||
{
|
||||
typedef CGAL::Dart< 2, Refs > Dart;
|
||||
|
||||
typedef CGAL::Cell_attribute< Refs, int, CGAL::Tag_true, f1, f2 > Int_attrib;
|
||||
typedef CGAL::Cell_attribute< Refs, double, CGAL::Tag_true, f3, f4 > Double_attrib;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Int_attrib, Int_attrib,
|
||||
Double_attrib> Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
struct Map_3_dart_items_3
|
||||
{
|
||||
/// Dart_wrapper defines the type of darts used.
|
||||
template < class Refs >
|
||||
struct Dart_wrapper
|
||||
{
|
||||
typedef CGAL::Dart< 3, Refs > Dart;
|
||||
|
||||
typedef CGAL::Cell_attribute< Refs, int, CGAL::Tag_true, f5, f6 > Int_attrib;
|
||||
typedef CGAL::Cell_attribute< Refs, double, CGAL::Tag_true, f7 > Double_attrib;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Double_attrib, void,
|
||||
Int_attrib, Double_attrib> Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
struct Map_3_dart_max_items_3
|
||||
{
|
||||
/// Dart_wrapper defines the type of darts used.
|
||||
template < class Refs >
|
||||
struct Dart_wrapper
|
||||
{
|
||||
typedef CGAL::Dart< 3, Refs > Dart;
|
||||
|
||||
typedef CGAL::Cell_attribute< Refs, int, CGAL::Tag_true, f5, f6 > Int_attrib;
|
||||
typedef CGAL::Cell_attribute< Refs, double, CGAL::Tag_true, f7 > Double_attrib;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Int_attrib, Int_attrib,
|
||||
Int_attrib, Double_attrib> Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
class Another_map_3_dart_items_3
|
||||
{
|
||||
public:
|
||||
/// Dart_wrapper defines the type of darts used.
|
||||
template < class Refs >
|
||||
struct Dart_wrapper
|
||||
{
|
||||
typedef CGAL::Dart< 3, Refs > Dart;
|
||||
|
||||
typedef CGAL::Cell_attribute< Refs, int > Int_attrib;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Int_attrib, void, Int_attrib> Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
struct Map_dart_items_4
|
||||
{
|
||||
template < class Refs >
|
||||
struct Dart_wrapper
|
||||
{
|
||||
typedef CGAL::Dart< 4, Refs > Dart;
|
||||
|
||||
typedef CGAL::Cell_attribute< Refs, int > Int_attrib;
|
||||
typedef CGAL::Cell_attribute< Refs, double > Double_attrib;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Int_attrib, void,
|
||||
Int_attrib, void, Int_attrib>
|
||||
Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
struct Map_dart_max_items_4
|
||||
{
|
||||
template < class Refs >
|
||||
struct Dart_wrapper
|
||||
{
|
||||
typedef CGAL::Dart< 4, Refs > Dart;
|
||||
|
||||
typedef CGAL::Cell_attribute< Refs, int > Int_attrib;
|
||||
typedef CGAL::Cell_attribute< Refs, double > Double_attrib;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Int_attrib, Int_attrib,
|
||||
Int_attrib, Int_attrib, Double_attrib>
|
||||
Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
// void, void, void
|
||||
typedef CGAL::Combinatorial_map<2, CGAL::Combinatorial_map_min_items<2> > Map1;
|
||||
|
||||
// double, void, double
|
||||
typedef CGAL::Combinatorial_map<2, Map_2_dart_items > Map2;
|
||||
|
||||
// int, int, double
|
||||
typedef CGAL::Combinatorial_map<2, Map_2_dart_max_items_3> Map3;
|
||||
|
||||
// void, void, void, void
|
||||
typedef CGAL::Combinatorial_map<3, CGAL::Combinatorial_map_min_items<3> > Map4;
|
||||
|
||||
// double, void, int, double
|
||||
typedef CGAL::Combinatorial_map<3, Map_3_dart_items_3> Map5;
|
||||
|
||||
// int, int, int, double
|
||||
typedef CGAL::Combinatorial_map<3, Map_3_dart_max_items_3> Map6;
|
||||
|
||||
// int, void, int, void
|
||||
typedef CGAL::Combinatorial_map<3, Another_map_3_dart_items_3> Map7;
|
||||
|
||||
// int, void, int, void, int
|
||||
typedef CGAL::Combinatorial_map<4, Map_dart_items_4> Map8;
|
||||
|
||||
// int, int, int, int, double
|
||||
typedef CGAL::Combinatorial_map<4, Map_dart_max_items_4> Map9;
|
||||
|
||||
/*
|
||||
template<typename Map>
|
||||
typename Map::Dart_handle getRandomDart(Map& map)
|
||||
{
|
||||
int nb = rand()%map.number_of_darts();
|
||||
typename Map::Dart_range::iterator it=map.darts().begin();
|
||||
for ( int i=0; i<nb; ++i, ++it )
|
||||
{}
|
||||
return it;
|
||||
}
|
||||
*/
|
||||
|
||||
template<typename Map, unsigned int i, typename Attr=typename Map::
|
||||
template Attribute_type<i>::type>
|
||||
struct CreateAttributes
|
||||
{
|
||||
static void run(Map& map)
|
||||
{
|
||||
int nb=0;
|
||||
for(typename Map::Dart_range::iterator it=map.darts().begin(),
|
||||
itend=map.darts().end(); it!=itend; ++it)
|
||||
{
|
||||
if ( it->template attribute<i>()==NULL )
|
||||
map.template set_attribute<i>
|
||||
(it, map.template create_attribute<i>(++nb));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Map, unsigned int i>
|
||||
struct CreateAttributes<Map, i, CGAL::Void>
|
||||
{
|
||||
static void run(Map&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Map, unsigned int i, typename Attr=typename Map::
|
||||
template Attribute_type<i>::type>
|
||||
struct DisplayAttribs
|
||||
{
|
||||
static void run(Map& amap)
|
||||
{
|
||||
std::cout<<i<<"-attributes: ";
|
||||
for ( typename Map::template Attribute_range<i>::type::iterator
|
||||
it=amap.template attributes<i>().begin(),
|
||||
itend=amap.template attributes<i>().end();
|
||||
it!=itend; ++it )
|
||||
{
|
||||
std::cout<<it->info()<<"; ";
|
||||
}
|
||||
std::cout<<std::endl;
|
||||
}
|
||||
};
|
||||
template<typename Map, unsigned int i>
|
||||
struct DisplayAttribs<Map,i,CGAL::Void>
|
||||
{
|
||||
static void run(Map&)
|
||||
{}
|
||||
};
|
||||
|
||||
template<typename Map>
|
||||
void displayAllAttribs2D(Map& amap, const char* c)
|
||||
{
|
||||
std::cout<<c;
|
||||
DisplayAttribs<Map,0>::run(amap);
|
||||
DisplayAttribs<Map,1>::run(amap);
|
||||
DisplayAttribs<Map,2>::run(amap);
|
||||
}
|
||||
|
||||
template<typename Map>
|
||||
void displayAllAttribs3D(Map& amap, const char* c)
|
||||
{
|
||||
std::cout<<c;
|
||||
DisplayAttribs<Map,0>::run(amap);
|
||||
DisplayAttribs<Map,1>::run(amap);
|
||||
DisplayAttribs<Map,2>::run(amap);
|
||||
DisplayAttribs<Map,3>::run(amap);
|
||||
}
|
||||
|
||||
template<typename Map>
|
||||
void displayAllAttribs4D(Map& amap, const char* c)
|
||||
{
|
||||
std::cout<<c;
|
||||
DisplayAttribs<Map,0>::run(amap);
|
||||
DisplayAttribs<Map,1>::run(amap);
|
||||
DisplayAttribs<Map,2>::run(amap);
|
||||
DisplayAttribs<Map,3>::run(amap);
|
||||
DisplayAttribs<Map,4>::run(amap);
|
||||
}
|
||||
|
||||
template<typename Map>
|
||||
void create2Dmap(Map& map)
|
||||
{
|
||||
for ( int i=0; i<15; ++i )
|
||||
CGAL::make_combinatorial_hexahedron(map);
|
||||
CreateAttributes<Map,0>::run(map);
|
||||
CreateAttributes<Map,1>::run(map);
|
||||
CreateAttributes<Map,2>::run(map);
|
||||
}
|
||||
template<typename Map>
|
||||
void create3Dmap(Map& map)
|
||||
{
|
||||
for ( int i=0; i<15; ++i )
|
||||
CGAL::make_combinatorial_hexahedron(map);
|
||||
|
||||
for ( int i=0; i<20; ++i )
|
||||
{
|
||||
typename Map::Dart_handle d1=map.darts().begin();
|
||||
while ( !d1->template is_free<3>() ) ++d1;
|
||||
typename Map::Dart_handle d2=map.darts().begin();
|
||||
while ( !map.template is_sewable<3>(d1, d2) ) ++d2;
|
||||
map.template sew<3>(d1,d2);
|
||||
}
|
||||
CreateAttributes<Map,0>::run(map);
|
||||
CreateAttributes<Map,1>::run(map);
|
||||
CreateAttributes<Map,2>::run(map);
|
||||
CreateAttributes<Map,3>::run(map);
|
||||
}
|
||||
template<typename Map>
|
||||
void create4Dmap(Map& map)
|
||||
{
|
||||
for ( int i=0; i<45; ++i )
|
||||
CGAL::make_combinatorial_hexahedron(map);
|
||||
|
||||
for ( int i=0; i<40; ++i )
|
||||
{
|
||||
typename Map::Dart_handle d1=map.darts().begin();
|
||||
while ( !d1->template is_free<3>() ) ++d1;
|
||||
typename Map::Dart_handle d2=map.darts().begin();
|
||||
while ( !map.template is_sewable<3>(d1, d2) ) ++d2;
|
||||
map.template sew<3>(d1,d2);
|
||||
}
|
||||
|
||||
for ( int i=0; i<20; ++i )
|
||||
{
|
||||
typename Map::Dart_handle d1=map.darts().begin();
|
||||
while ( !d1->template is_free<4>() ) ++d1;
|
||||
typename Map::Dart_handle d2=map.darts().begin();
|
||||
while ( !map.template is_sewable<4>(d1, d2) ) ++d2;
|
||||
map.template sew<4>(d1,d2);
|
||||
}
|
||||
CreateAttributes<Map,0>::run(map);
|
||||
CreateAttributes<Map,1>::run(map);
|
||||
CreateAttributes<Map,2>::run(map);
|
||||
CreateAttributes<Map,3>::run(map);
|
||||
CreateAttributes<Map,4>::run(map);
|
||||
}
|
||||
|
||||
bool testCopy()
|
||||
{
|
||||
Map1 map1; create2Dmap(map1);
|
||||
Map2 map2; create2Dmap(map2);
|
||||
Map3 map3; create2Dmap(map3);
|
||||
|
||||
Map4 map4; create3Dmap(map4);
|
||||
Map5 map5; create3Dmap(map5);
|
||||
Map6 map6; create3Dmap(map6);
|
||||
Map7 map7; create3Dmap(map7);
|
||||
|
||||
Map8 map8; create4Dmap(map8);
|
||||
Map9 map9; create4Dmap(map9);
|
||||
|
||||
// First copy of same types
|
||||
{
|
||||
Map1 map1p(map1);
|
||||
if ( !map1p.is_valid() || !map1.is_isomorphic_to(map1p) )
|
||||
{ assert(false); return false; }
|
||||
Map2 map2p(map2);
|
||||
if ( !map2p.is_valid() || !map2.is_isomorphic_to(map2p) )
|
||||
{ assert(false); return false; }
|
||||
Map3 map3p(map3);
|
||||
if ( !map3p.is_valid() || !map3.is_isomorphic_to(map3p) )
|
||||
{ assert(false); return false; }
|
||||
Map4 map4p(map4);
|
||||
if ( !map4p.is_valid() || !map4.is_isomorphic_to(map4p) )
|
||||
{ assert(false); return false; }
|
||||
Map5 map5p(map5);
|
||||
if ( !map5p.is_valid() || !map5.is_isomorphic_to(map5p) )
|
||||
{ assert(false); return false; }
|
||||
Map6 map6p(map6);
|
||||
if ( !map6p.is_valid() || !map6.is_isomorphic_to(map6p) )
|
||||
{ assert(false); return false; }
|
||||
Map7 map7p(map7);
|
||||
if ( !map7p.is_valid() || !map7.is_isomorphic_to(map7p) )
|
||||
{ assert(false); return false; }
|
||||
Map8 map8p(map8);
|
||||
if ( !map8p.is_valid() || !map8.is_isomorphic_to(map8p) )
|
||||
{ assert(false); return false; }
|
||||
Map9 map9p(map9);
|
||||
if ( !map9p.is_valid() || !map9.is_isomorphic_to(map9p) )
|
||||
{ assert(false); return false; }
|
||||
}
|
||||
|
||||
// Second copy of same dimensions but different attributes
|
||||
// Maps are still isomorphic but no same attributes
|
||||
{
|
||||
// 2D
|
||||
Map2 map1p(map1); assert(map1p.is_valid());
|
||||
if ( !map1.is_isomorphic_to(map1p) ) { assert(false); return false; }
|
||||
|
||||
Map3 map1t(map1); assert(map1t.is_valid());
|
||||
if ( !map1.is_isomorphic_to(map1t) ) { assert(false); return false; }
|
||||
|
||||
if ( !map1p.is_isomorphic_to(map1t) ) { assert(false); return false; }
|
||||
|
||||
Map1 map2p(map2); assert(map2p.is_valid());
|
||||
if ( map2.is_isomorphic_to(map2p) ) { assert(false); return false; }
|
||||
if ( !map2.is_isomorphic_to(map2p, false) ) { assert(false); return false; }
|
||||
|
||||
Map3 map2t(map2); assert(map2t.is_valid());
|
||||
if ( map2.is_isomorphic_to(map2t) ) { assert(false); return false; }
|
||||
if ( !map2.is_isomorphic_to(map2t, false) ) { assert(false); return false; }
|
||||
|
||||
if ( map2p.is_isomorphic_to(map2t) ) { assert(false); return false; }
|
||||
if ( !map2p.is_isomorphic_to(map2t, false) ) { assert(false); return false; }
|
||||
|
||||
Map1 map3p(map3); assert(map3p.is_valid());
|
||||
if ( map3.is_isomorphic_to(map3p) ) { assert(false); return false; }
|
||||
if ( !map3.is_isomorphic_to(map3p, false) ) { assert(false); return false; }
|
||||
|
||||
Map2 map3t(map3); assert(map3t.is_valid());
|
||||
if ( map3.is_isomorphic_to(map3t) ) { assert(false); return false; }
|
||||
if ( !map3.is_isomorphic_to(map3t, false) ) { assert(false); return false; }
|
||||
|
||||
if ( map3p.is_isomorphic_to(map3t) ) { assert(false); return false; }
|
||||
if ( !map3p.is_isomorphic_to(map3t, false) ) { assert(false); return false; }
|
||||
|
||||
assert( map1.is_isomorphic_to(map1p)==map1p.is_isomorphic_to(map1) );
|
||||
assert( map1.is_isomorphic_to(map1t)==map1t.is_isomorphic_to(map1) );
|
||||
assert( map2.is_isomorphic_to(map2p)==map2p.is_isomorphic_to(map2) );
|
||||
assert( map2.is_isomorphic_to(map2t)==map2t.is_isomorphic_to(map2) );
|
||||
assert( map3.is_isomorphic_to(map3p)==map3p.is_isomorphic_to(map3) );
|
||||
assert( map3.is_isomorphic_to(map3t)==map3t.is_isomorphic_to(map3) );
|
||||
|
||||
// 3D
|
||||
Map4 map5a(map5); assert(map5a.is_valid());
|
||||
if ( map5.is_isomorphic_to(map5a) ) { assert(false); return false; }
|
||||
if ( !map5.is_isomorphic_to(map5a, false) ) { assert(false); return false; }
|
||||
|
||||
Map6 map5b(map5); assert(map5b.is_valid());
|
||||
if ( map5.is_isomorphic_to(map5b) ) { assert(false); return false; }
|
||||
if ( !map5.is_isomorphic_to(map5b, false) ) { assert(false); return false; }
|
||||
assert( map5b.number_of_attributes<0>()==0 &&
|
||||
map5b.number_of_attributes<1>()==0 &&
|
||||
map5b.number_of_attributes<2>()==map5.number_of_attributes<2>() &&
|
||||
map5b.number_of_attributes<3>()==map5.number_of_attributes<3>() );
|
||||
|
||||
Map7 map5c(map5); assert(map5c.is_valid());
|
||||
if ( map5.is_isomorphic_to(map5c) ) { assert(false); return false; }
|
||||
if ( !map5.is_isomorphic_to(map5c, false) ) { assert(false); return false; }
|
||||
assert( map5c.number_of_attributes<0>()==0 &&
|
||||
map5c.number_of_attributes<2>()==map5.number_of_attributes<2>() );
|
||||
|
||||
assert( map5.is_isomorphic_to(map5a)==map5a.is_isomorphic_to(map5) );
|
||||
assert( map5.is_isomorphic_to(map5b)==map5b.is_isomorphic_to(map5) );
|
||||
assert( map5.is_isomorphic_to(map5c)==map5c.is_isomorphic_to(map5) );
|
||||
|
||||
// 4D
|
||||
Map8 map9a(map9); assert(map9a.is_valid());
|
||||
if ( map9.is_isomorphic_to(map9a) ) { assert(false); return false; }
|
||||
if ( !map9.is_isomorphic_to(map9a, false) ) { assert(false); return false; }
|
||||
assert( map9a.number_of_attributes<0>()==map9.number_of_attributes<0>() &&
|
||||
map9a.number_of_attributes<2>()==map9.number_of_attributes<2>() &&
|
||||
map9a.number_of_attributes<4>()==0 );
|
||||
assert( map9a.is_isomorphic_to(map9)==map9.is_isomorphic_to(map9a) );
|
||||
|
||||
Map9 map8a(map8); assert(map8a.is_valid());
|
||||
if ( map8.is_isomorphic_to(map8a) ) { assert(false); return false; }
|
||||
if ( !map8.is_isomorphic_to(map8a, false) ) { assert(false); return false; }
|
||||
assert( map8a.number_of_attributes<0>()==map8.number_of_attributes<0>() &&
|
||||
map8a.number_of_attributes<1>()==0 &&
|
||||
map8a.number_of_attributes<2>()==map8.number_of_attributes<2>() &&
|
||||
map8a.number_of_attributes<3>()==0 &&
|
||||
map8a.number_of_attributes<4>()==0 );
|
||||
assert( map8a.is_isomorphic_to(map8)==map8.is_isomorphic_to(map8a) );
|
||||
|
||||
}
|
||||
|
||||
// Third copy of different dimensions and different attributes
|
||||
{
|
||||
Map5 map2a(map2); assert(map2a.is_valid());
|
||||
if ( map2a.is_isomorphic_to(map2) ) { assert(false); return false; }
|
||||
if ( !map2a.is_isomorphic_to(map2, false) ) { assert(false); return false; }
|
||||
assert( map2a.number_of_attributes<0>()==map2.number_of_attributes<0>() &&
|
||||
map2a.number_of_attributes<2>()==0 &&
|
||||
map2a.number_of_attributes<3>()==0 );
|
||||
assert( map2a.is_isomorphic_to(map2)==map2.is_isomorphic_to(map2a) );
|
||||
|
||||
Map2 map5a(map5); assert(map5a.is_valid());
|
||||
if ( map5a.is_isomorphic_to(map5) ) { assert(false); return false; }
|
||||
assert( map5a.number_of_attributes<0>()>=map5.number_of_attributes<0>() &&
|
||||
map5a.number_of_attributes<2>()==0 );
|
||||
|
||||
Map5 map9a(map9); assert(map9a.is_valid());
|
||||
if ( map9a.is_isomorphic_to(map9) ) { assert(false); return false; }
|
||||
assert( map9a.number_of_attributes<0>()==0 &&
|
||||
map9a.number_of_attributes<2>()>=map9.number_of_attributes<2>() &&
|
||||
map9a.number_of_attributes<3>()==0 );
|
||||
assert( map9a.is_isomorphic_to(map9)==map9.is_isomorphic_to(map9a) );
|
||||
|
||||
CGAL::Cast_converter_cmap_attributes<Map9,Map5,0> c0;
|
||||
CGAL::Default_converter_cmap_attributes<Map9,Map5,1> c1;
|
||||
CGAL::Default_converter_cmap_attributes<Map9,Map5,2> c2;
|
||||
CGAL::Cast_converter_cmap_attributes<Map9,Map5,3> c3;
|
||||
|
||||
CGAL::cpp11::tuple<CGAL::Cast_converter_cmap_attributes<Map9,Map5,0>,
|
||||
CGAL::Default_converter_cmap_attributes<Map9,Map5,1>,
|
||||
CGAL::Default_converter_cmap_attributes<Map9,Map5,2>,
|
||||
CGAL::Cast_converter_cmap_attributes<Map9,Map5,3> > myconverters
|
||||
(c0, c1, c2, c3);
|
||||
|
||||
Map5 map9b(map9, myconverters); assert(map9a.is_valid());
|
||||
if ( map9b.is_isomorphic_to(map9) ) { assert(false); return false; }
|
||||
assert( map9b.number_of_attributes<0>()>=map9.number_of_attributes<0>() &&
|
||||
map9b.number_of_attributes<2>()>=map9.number_of_attributes<2>() &&
|
||||
map9b.number_of_attributes<3>()>=map9.number_of_attributes<3>() );
|
||||
assert( map9b.is_isomorphic_to(map9)==map9.is_isomorphic_to(map9b) );
|
||||
|
||||
CGAL::Cast_converter_cmap_attributes<Map5,Map9,0> cb0;
|
||||
CGAL::Default_converter_cmap_attributes<Map5,Map9,1> cb1;
|
||||
CGAL::Default_converter_cmap_attributes<Map5,Map9,2> cb2;
|
||||
CGAL::Cast_converter_cmap_attributes<Map5,Map9,3> cb3;
|
||||
|
||||
CGAL::cpp11::tuple<CGAL::Cast_converter_cmap_attributes<Map5,Map9,0>,
|
||||
CGAL::Default_converter_cmap_attributes<Map5,Map9,1>,
|
||||
CGAL::Default_converter_cmap_attributes<Map5,Map9,2>,
|
||||
CGAL::Cast_converter_cmap_attributes<Map5,Map9,3> > myconverters2
|
||||
(cb0, cb1, cb2, cb3);
|
||||
|
||||
Map9 map5b(map5, myconverters2); assert(map5b.is_valid());
|
||||
if ( map5b.is_isomorphic_to(map5) ) { assert(false); return false; }
|
||||
if ( !map5b.is_isomorphic_to(map5, false) ) { assert(false); return false; }
|
||||
assert( map5b.number_of_attributes<0>()==map5.number_of_attributes<0>() &&
|
||||
map5b.number_of_attributes<2>()==map5.number_of_attributes<2>() &&
|
||||
map5b.number_of_attributes<3>()==map5.number_of_attributes<3>() );
|
||||
assert( map5b.is_isomorphic_to(map5)==map5.is_isomorphic_to(map5b) );
|
||||
}
|
||||
|
||||
/* displayAllAttribs4D(map9, "map9******************\n");
|
||||
displayAllAttribs3D(map9b, "map9b******************\n");*/
|
||||
|
||||
/* std::cout<<map9b.number_of_attributes<0>()<<" "
|
||||
<<map9.number_of_attributes<0>()<<" "
|
||||
<<map9b.number_of_attributes<2>()<<" "
|
||||
<<map9.number_of_attributes<2>()<<" "
|
||||
<<map9b.number_of_attributes<3>()<<" "
|
||||
<<map9.number_of_attributes<3>()<<std::endl;*/
|
||||
|
||||
//map5.display_characteristics(std::cout)<<std::endl;
|
||||
//map5a.display_characteristics(std::cout)<<std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout<<"Combinatorial map copy test (v1)."<<std::flush;
|
||||
|
||||
if ( !testCopy() )
|
||||
{
|
||||
std::cout<<" Failed."<<std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::cout<<" Success."<<std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -53,6 +53,21 @@ struct f7
|
|||
{}
|
||||
};
|
||||
|
||||
struct Map_2_dart_items
|
||||
{
|
||||
/// Dart_wrapper defines the type of darts used.
|
||||
template < class Refs >
|
||||
struct Dart_wrapper
|
||||
{
|
||||
typedef CGAL::Dart< 2, Refs > Dart;
|
||||
|
||||
typedef CGAL::Cell_attribute< Refs, int, CGAL::Tag_true, f1, f2 > Int_attrib;
|
||||
typedef CGAL::Cell_attribute< Refs, double, CGAL::Tag_true, f3, f4 > Double_attrib;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Double_attrib, void, Double_attrib> Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
struct Map_2_dart_max_items_3
|
||||
{
|
||||
/// Dart_wrapper defines the type of darts used.
|
||||
|
|
@ -63,9 +78,25 @@ struct Map_2_dart_max_items_3
|
|||
|
||||
typedef CGAL::Cell_attribute< Refs, int, CGAL::Tag_true, f1, f2 > Int_attrib;
|
||||
typedef CGAL::Cell_attribute< Refs, double, CGAL::Tag_true, f3, f4 > Double_attrib;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Int_attrib, Int_attrib,
|
||||
Double_attrib> Attributes;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Int_attrib, Int_attrib,
|
||||
Double_attrib> Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
struct Map_3_dart_items_3
|
||||
{
|
||||
/// Dart_wrapper defines the type of darts used.
|
||||
template < class Refs >
|
||||
struct Dart_wrapper
|
||||
{
|
||||
typedef CGAL::Dart< 3, Refs > Dart;
|
||||
|
||||
typedef CGAL::Cell_attribute< Refs, int, CGAL::Tag_true, f5, f6 > Int_attrib;
|
||||
typedef CGAL::Cell_attribute< Refs, double, CGAL::Tag_true, f7 > Double_attrib;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Double_attrib, void,
|
||||
Int_attrib, Double_attrib> Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -79,9 +110,9 @@ struct Map_3_dart_max_items_3
|
|||
|
||||
typedef CGAL::Cell_attribute< Refs, int, CGAL::Tag_true, f5, f6 > Int_attrib;
|
||||
typedef CGAL::Cell_attribute< Refs, double, CGAL::Tag_true, f7 > Double_attrib;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Int_attrib, Int_attrib,
|
||||
Int_attrib, Double_attrib> Attributes;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Int_attrib, Int_attrib,
|
||||
Int_attrib, Double_attrib> Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -95,8 +126,23 @@ public:
|
|||
typedef CGAL::Dart< 3, Refs > Dart;
|
||||
|
||||
typedef CGAL::Cell_attribute< Refs, int > Int_attrib;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Int_attrib, void, Int_attrib>
|
||||
|
||||
typedef CGAL::cpp11::tuple<Int_attrib, void, Int_attrib> Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
struct Map_dart_items_4
|
||||
{
|
||||
template < class Refs >
|
||||
struct Dart_wrapper
|
||||
{
|
||||
typedef CGAL::Dart< 4, Refs > Dart;
|
||||
|
||||
typedef CGAL::Cell_attribute< Refs, int > Int_attrib;
|
||||
typedef CGAL::Cell_attribute< Refs, double > Double_attrib;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Int_attrib, void,
|
||||
Int_attrib, void, Int_attrib>
|
||||
Attributes;
|
||||
};
|
||||
};
|
||||
|
|
@ -110,76 +156,81 @@ struct Map_dart_max_items_4
|
|||
|
||||
typedef CGAL::Cell_attribute< Refs, int > Int_attrib;
|
||||
typedef CGAL::Cell_attribute< Refs, double > Double_attrib;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Int_attrib, Int_attrib,
|
||||
Int_attrib, Double_attrib, Double_attrib>
|
||||
|
||||
typedef CGAL::cpp11::tuple<Int_attrib, Int_attrib,
|
||||
Int_attrib, Double_attrib, Double_attrib>
|
||||
Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
typedef CGAL::Combinatorial_map<2, CGAL::Combinatorial_map_min_items<2> > Map1;
|
||||
|
||||
typedef CGAL::Combinatorial_map<2, Map_2_dart_items > Map2;
|
||||
|
||||
typedef CGAL::Combinatorial_map<2, Map_2_dart_max_items_3> Map3;
|
||||
|
||||
typedef CGAL::Combinatorial_map<3, CGAL::Combinatorial_map_min_items<3> > Map4;
|
||||
|
||||
typedef CGAL::Combinatorial_map<3, Map_3_dart_items_3> Map5;
|
||||
|
||||
typedef CGAL::Combinatorial_map<3, Map_3_dart_max_items_3> Map6;
|
||||
|
||||
typedef CGAL::Combinatorial_map<3, Another_map_3_dart_items_3> Map7;
|
||||
|
||||
typedef CGAL::Combinatorial_map<4, Map_dart_items_4> Map8;
|
||||
|
||||
typedef CGAL::Combinatorial_map<4, Map_dart_max_items_4> Map9;
|
||||
|
||||
int main()
|
||||
{
|
||||
typedef CGAL::Combinatorial_map<2,
|
||||
CGAL::Combinatorial_map_min_items<2> > Map1;
|
||||
if ( !test2D<Map1>() )
|
||||
{
|
||||
std::cout<<"ERROR during test2D<Map1>."<<std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
typedef CGAL::Combinatorial_map<2, Map_2_dart_max_items_3 > Map2;
|
||||
if ( !test2D<Map2>() )
|
||||
{
|
||||
std::cout<<"ERROR during test2D<Map2>."<<std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
typedef CGAL::Combinatorial_map<2, Map_2_dart_max_items_3> Map3;
|
||||
if ( !test2D<Map3>() )
|
||||
{
|
||||
std::cout<<"ERROR during test2D<Map3>."<<std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
typedef CGAL::Combinatorial_map<3,
|
||||
CGAL::Combinatorial_map_min_items<3> > Map4;
|
||||
if ( !test3D<Map4>() )
|
||||
{
|
||||
std::cout<<"ERROR during test3D<Map4>."<<std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
typedef CGAL::Combinatorial_map<3, Map_3_dart_max_items_3> Map5;
|
||||
if ( !test3D<Map5>() )
|
||||
{
|
||||
std::cout<<"ERROR during test3D<Map5>."<<std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
typedef CGAL::Combinatorial_map<3, Map_3_dart_max_items_3> Map6;
|
||||
if ( !test3D<Map6>() )
|
||||
{
|
||||
std::cout<<"ERROR during test3D<Map6>."<<std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
typedef CGAL::Combinatorial_map<3, Another_map_3_dart_items_3> Map7;
|
||||
if ( !test3D<Map7>() )
|
||||
{
|
||||
std::cout<<"ERROR during test3D<Map7>."<<std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
typedef CGAL::Combinatorial_map<3, Another_map_3_dart_items_3> Map8;
|
||||
if ( !test3D<Map8>() )
|
||||
{
|
||||
std::cout<<"ERROR during test3D<Map8>."<<std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
typedef CGAL::Combinatorial_map<4, Map_dart_max_items_4> Map9;
|
||||
if ( !test3D<Map9>() )
|
||||
{
|
||||
std::cout<<"ERROR during test3D<Map9>."<<std::endl;
|
||||
|
|
|
|||
|
|
@ -134,6 +134,8 @@ David A. Wheeler's 'SLOCCount'</a>, restricted to the <code>include/CGAL/</code>
|
|||
<h3>Combinatorial Maps</h3>
|
||||
<ul>
|
||||
<li>Two bug fixes: do not use the 2 least significant bits for cell attribute without dart support; add share a mark in CMap_cell_iterator.</li>
|
||||
<li>Add a constructor taking a given combinatorial map as argument, possibly with different dimension and/or different attributes. This allows to transform a combinatorial map. </li>
|
||||
<li>Add operator= and swap method.</li>
|
||||
</ul>
|
||||
|
||||
<h3>2D Apollonius graphs</h3>
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ if ( CGAL_FOUND )
|
|||
|
||||
# If you want to visualize a linear cell complex, there are 2 viewers
|
||||
# based on qt and vtk. Just uncomment the corresponding line
|
||||
# include("CMakeLCCViewerQt.inc")
|
||||
# include("CMakeLCCViewerVtk.inc")
|
||||
# include("CMakeLCCViewerQt.inc")
|
||||
# include("CMakeLCCViewerVtk.inc")
|
||||
|
||||
add_executable(linear_cell_complex_3_triangulation
|
||||
linear_cell_complex_3_triangulation.cpp)
|
||||
|
|
|
|||
|
|
@ -56,27 +56,45 @@ namespace CGAL {
|
|||
|
||||
/// Attribute associated with a point and an info.
|
||||
template < class LCC, class Info_=void, class Tag=Tag_true,
|
||||
class Functor_on_merge_=Null_functor,
|
||||
class Functor_on_merge_=Null_functor,
|
||||
class Functor_on_split_=Null_functor >
|
||||
class Cell_attribute_with_point :
|
||||
public Cell_attribute<LCC, Info_, Tag,
|
||||
public Cell_attribute<LCC, Info_, Tag,
|
||||
Functor_on_merge_, Functor_on_split_>,
|
||||
public Point_for_cell<typename LCC::Point>
|
||||
{
|
||||
template < unsigned int d_, class Refs_,
|
||||
class Items_, class Alloc_ >
|
||||
friend class Combinatorial_map_base;
|
||||
|
||||
template <class T, class Alloc_>
|
||||
friend class Compact_container;
|
||||
|
||||
public:
|
||||
typedef Cell_attribute<LCC, Info_, Tag,
|
||||
typedef Cell_attribute_with_point<LCC, Info_, Tag, Functor_on_merge_,
|
||||
Functor_on_split_> Self;
|
||||
|
||||
typedef Cell_attribute<LCC, Info_, Tag,
|
||||
Functor_on_merge_, Functor_on_split_> Base1;
|
||||
typedef Point_for_cell<typename LCC::Point> Base2;
|
||||
|
||||
|
||||
typedef typename LCC::Point Point;
|
||||
typedef typename LCC::Dart_handle Dart_handle;
|
||||
typedef typename LCC::Dart_const_handle Dart_const_handle;
|
||||
|
||||
|
||||
typedef Info_ Info;
|
||||
typedef Functor_on_merge_ Functor_on_merge;
|
||||
typedef Functor_on_split_ Functor_on_split;
|
||||
|
||||
|
||||
using Base1::info;
|
||||
|
||||
bool operator==(const Self& other) const
|
||||
{ return Base1::operator==(other) && this->point()==other.point(); }
|
||||
|
||||
bool operator!=(const Self& other) const
|
||||
{ return !operator==(other); }
|
||||
|
||||
// protected:
|
||||
/// Default contructor.
|
||||
Cell_attribute_with_point()
|
||||
{}
|
||||
|
|
@ -90,31 +108,47 @@ namespace CGAL {
|
|||
Base1(ainfo),
|
||||
Base2(apoint)
|
||||
{}
|
||||
|
||||
using Base1::info;
|
||||
};
|
||||
|
||||
/// Attribute associated with a point and without info.
|
||||
template < class LCC, class Tag,
|
||||
class Functor_on_merge_,
|
||||
class Functor_on_merge_,
|
||||
class Functor_on_split_ >
|
||||
class Cell_attribute_with_point<LCC, void, Tag,
|
||||
Functor_on_merge_, Functor_on_split_> :
|
||||
public Cell_attribute<LCC, void, Tag, Functor_on_merge_, Functor_on_split_>,
|
||||
public Point_for_cell<typename LCC::Point>
|
||||
{
|
||||
template < unsigned int d_, class Refs_,
|
||||
class Items_, class Alloc_ >
|
||||
friend class Combinatorial_map_base;
|
||||
|
||||
template <class T, class Alloc_>
|
||||
friend class Compact_container;
|
||||
|
||||
public:
|
||||
typedef Cell_attribute<LCC, void, Tag,
|
||||
typedef Cell_attribute<LCC, void, Tag,
|
||||
Functor_on_merge_, Functor_on_split_> Base1;
|
||||
typedef Point_for_cell<typename LCC::Point> Base2;
|
||||
|
||||
typedef typename LCC::Point Point;
|
||||
typedef typename LCC::Dart_handle Dart_handle;
|
||||
typedef typename LCC::Dart_const_handle Dart_const_handle;
|
||||
typedef typename LCC::Dart_const_handle Dart_const_handle;
|
||||
|
||||
typedef Functor_on_merge_ Functor_on_merge;
|
||||
typedef Functor_on_split_ Functor_on_split;
|
||||
|
||||
bool operator==(const Cell_attribute_with_point& other) const
|
||||
{ return Base1::operator==(other) && this->point()==other.point(); }
|
||||
|
||||
bool operator!=(const Cell_attribute_with_point& other) const
|
||||
{ return !operator==(other); }
|
||||
|
||||
template<typename Cellattr>
|
||||
bool operator==(const Cellattr& other) const
|
||||
{ return false; }
|
||||
|
||||
// protected:
|
||||
/// Default contructor.
|
||||
Cell_attribute_with_point()
|
||||
{}
|
||||
|
|
|
|||
|
|
@ -81,9 +81,36 @@ namespace CGAL {
|
|||
typedef typename Base::template Attribute_const_range<0>::type
|
||||
Vertex_attribute_const_range;
|
||||
|
||||
typedef typename Base::size_type size_type;
|
||||
|
||||
/// To use previous definition of create_dart methods.
|
||||
using Base::create_dart;
|
||||
|
||||
Linear_cell_complex() : Base()
|
||||
{}
|
||||
|
||||
/** Copy the given linear cell complex into *this.
|
||||
* Note that both LCC can have different dimensions and/or non void attributes.
|
||||
* @param alcc the linear cell complex to copy.
|
||||
* @post *this is valid.
|
||||
*/
|
||||
Linear_cell_complex(const Self & alcc)
|
||||
{ Base::template copy<Self>(alcc); }
|
||||
|
||||
template < class LCC2 >
|
||||
Linear_cell_complex(const LCC2& alcc)
|
||||
{ Base::template copy<LCC2>(alcc);}
|
||||
|
||||
template < class LCC2, typename Converters >
|
||||
Linear_cell_complex(const LCC2& alcc, Converters& converters)
|
||||
{ Base::template copy<LCC2, Converters>(alcc, converters);}
|
||||
|
||||
template < class LCC2, typename Converters, typename Pointconverter >
|
||||
Linear_cell_complex(const LCC2& alcc, Converters& converters,
|
||||
const Pointconverter& pointconverter)
|
||||
{ Base::template copy<LCC2, Converters, Pointconverter>
|
||||
(alcc, converters, pointconverter);}
|
||||
|
||||
/** Create a vertex attribute.
|
||||
* @return an handle on the new attribute.
|
||||
*/
|
||||
|
|
@ -691,7 +718,7 @@ namespace CGAL {
|
|||
{ return insert_point_in_cell<i>(dh, barycenter<i>(dh)); }
|
||||
|
||||
/** Compute the dual of a Linear_cell_complex.
|
||||
* @param amap the lcc in which we build the dual of this lcc.
|
||||
* @param alcc the lcc in which we build the dual of this lcc.
|
||||
* @param adart a dart of the initial lcc, NULL by default.
|
||||
* @return adart of the dual lcc, the dual of adart if adart!=NULL,
|
||||
* any dart otherwise.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,690 @@
|
|||
#include <CGAL/Linear_cell_complex.h>
|
||||
#include <CGAL/Cell_attribute_with_point.h>
|
||||
#include <CGAL/Linear_cell_complex_constructors.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct Map_2_dart_items
|
||||
{
|
||||
/// Dart_wrapper defines the type of darts used.
|
||||
template < class Refs >
|
||||
struct Dart_wrapper
|
||||
{
|
||||
typedef CGAL::Dart< 2, Refs > Dart;
|
||||
|
||||
typedef CGAL::Cell_attribute< Refs, int > Int_attrib;
|
||||
typedef CGAL::Cell_attribute< Refs, double > Double_attrib;
|
||||
typedef CGAL::Cell_attribute_with_point< Refs, double > Double_attrib_wp;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Double_attrib_wp, void, Double_attrib> Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
struct Map_2_dart_max_items_3
|
||||
{
|
||||
/// Dart_wrapper defines the type of darts used.
|
||||
template < class Refs >
|
||||
struct Dart_wrapper
|
||||
{
|
||||
typedef CGAL::Dart< 2, Refs > Dart;
|
||||
|
||||
typedef CGAL::Cell_attribute_with_point< Refs, int > Int_attrib_wp;
|
||||
typedef CGAL::Cell_attribute< Refs, int > Int_attrib;
|
||||
typedef CGAL::Cell_attribute< Refs, double > Double_attrib;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Int_attrib_wp, Int_attrib,
|
||||
Double_attrib> Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
struct Map_3_dart_items_3
|
||||
{
|
||||
/// Dart_wrapper defines the type of darts used.
|
||||
template < class Refs >
|
||||
struct Dart_wrapper
|
||||
{
|
||||
typedef CGAL::Dart< 3, Refs > Dart;
|
||||
|
||||
typedef CGAL::Cell_attribute< Refs, int > Int_attrib;
|
||||
typedef CGAL::Cell_attribute< Refs, double > Double_attrib;
|
||||
typedef CGAL::Cell_attribute_with_point< Refs, double > Double_attrib_wp;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Double_attrib_wp, void,
|
||||
Int_attrib, Double_attrib> Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
struct Map_3_dart_max_items_3
|
||||
{
|
||||
/// Dart_wrapper defines the type of darts used.
|
||||
template < class Refs >
|
||||
struct Dart_wrapper
|
||||
{
|
||||
typedef CGAL::Dart< 3, Refs > Dart;
|
||||
|
||||
typedef CGAL::Cell_attribute_with_point< Refs, int > Int_attrib_wp;
|
||||
typedef CGAL::Cell_attribute< Refs, int > Int_attrib;
|
||||
typedef CGAL::Cell_attribute< Refs, double > Double_attrib;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Int_attrib_wp, Int_attrib,
|
||||
Int_attrib, Double_attrib> Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
class Another_map_3_dart_items_3
|
||||
{
|
||||
public:
|
||||
/// Dart_wrapper defines the type of darts used.
|
||||
template < class Refs >
|
||||
struct Dart_wrapper
|
||||
{
|
||||
typedef CGAL::Dart< 3, Refs > Dart;
|
||||
|
||||
typedef CGAL::Cell_attribute_with_point< Refs, int > Int_attrib_wp;
|
||||
typedef CGAL::Cell_attribute< Refs, int > Int_attrib;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Int_attrib_wp, void, Int_attrib> Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
struct Map_dart_items_4
|
||||
{
|
||||
template < class Refs >
|
||||
struct Dart_wrapper
|
||||
{
|
||||
typedef CGAL::Dart< 4, Refs > Dart;
|
||||
|
||||
typedef CGAL::Cell_attribute_with_point< Refs, int > Int_attrib_wp;
|
||||
typedef CGAL::Cell_attribute< Refs, int > Int_attrib;
|
||||
typedef CGAL::Cell_attribute< Refs, double > Double_attrib;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Int_attrib_wp, void,
|
||||
Int_attrib, void, Int_attrib>
|
||||
Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
struct Map_dart_max_items_4
|
||||
{
|
||||
template < class Refs >
|
||||
struct Dart_wrapper
|
||||
{
|
||||
typedef CGAL::Dart< 4, Refs > Dart;
|
||||
|
||||
typedef CGAL::Cell_attribute_with_point< Refs, int > Int_attrib_wp;
|
||||
typedef CGAL::Cell_attribute< Refs, int > Int_attrib;
|
||||
typedef CGAL::Cell_attribute< Refs, double > Double_attrib;
|
||||
|
||||
typedef CGAL::cpp11::tuple<Int_attrib_wp, Int_attrib,
|
||||
Int_attrib, Int_attrib, Double_attrib>
|
||||
Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
typedef CGAL::Linear_cell_complex_traits
|
||||
<3, CGAL::Exact_predicates_inexact_constructions_kernel> Traits3_a;
|
||||
|
||||
typedef CGAL::Linear_cell_complex_traits
|
||||
<3, CGAL::Exact_predicates_exact_constructions_kernel> Traits3_b;
|
||||
|
||||
typedef CGAL::Linear_cell_complex_traits<4> Traits4_a;
|
||||
|
||||
// Point_3, void, void
|
||||
typedef CGAL::Linear_cell_complex<2,3, Traits3_a, CGAL::Linear_cell_complex_min_items<2> > Map1;
|
||||
|
||||
// Point_3+double, void, double
|
||||
typedef CGAL::Linear_cell_complex<2,3, Traits3_a, Map_2_dart_items > Map2;
|
||||
|
||||
// Point_3+int, int, double
|
||||
typedef CGAL::Linear_cell_complex<2,3, Traits3_b, Map_2_dart_max_items_3> Map3;
|
||||
|
||||
// Point_3, void, void, void
|
||||
typedef CGAL::Linear_cell_complex<3,3, Traits3_a, CGAL::Linear_cell_complex_min_items<3> > Map4;
|
||||
|
||||
// Point_3+double, void, int, double
|
||||
typedef CGAL::Linear_cell_complex<3,3, Traits3_a, Map_3_dart_items_3> Map5;
|
||||
|
||||
// Point_3+int, int, int, double
|
||||
typedef CGAL::Linear_cell_complex<3,3, Traits3_b, Map_3_dart_max_items_3> Map6;
|
||||
|
||||
// Point_3+int, void, int, void
|
||||
typedef CGAL::Linear_cell_complex<3,3, Traits3_b, Another_map_3_dart_items_3> Map7;
|
||||
|
||||
// Point_4+int, void, int, void, int
|
||||
typedef CGAL::Linear_cell_complex<4,4, Traits4_a, Map_dart_items_4> Map8;
|
||||
|
||||
// Point_4+int, int, int, int, double
|
||||
typedef CGAL::Linear_cell_complex<4,4, Traits4_a, Map_dart_max_items_4> Map9;
|
||||
|
||||
struct Converter_map9_points_into_map5_points
|
||||
{
|
||||
Map5::Attribute_handle<0>::type operator()
|
||||
(const Map9&, Map5& map2, Map9::Dart_const_handle dh1,
|
||||
Map5::Dart_handle dh2) const
|
||||
{
|
||||
CGAL_assertion( dh1->attribute<0>()!=NULL );
|
||||
|
||||
Map5::Attribute_handle<0>::type
|
||||
res = dh2->attribute<0>();
|
||||
if ( res==NULL )
|
||||
{
|
||||
res = map2.create_attribute<0>();
|
||||
}
|
||||
|
||||
const Map9::Point & p = dh1->attribute<0>()->point();
|
||||
res->point() = Map5::Point(p[0],p[1],p[2]);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
template<typename Map>
|
||||
typename Map::Dart_handle getRandomDart(Map& map)
|
||||
{
|
||||
int nb = rand()%map.number_of_darts();
|
||||
typename Map::Dart_range::iterator it=map.darts().begin();
|
||||
for ( int i=0; i<nb; ++i, ++it )
|
||||
{}
|
||||
return it;
|
||||
}
|
||||
*/
|
||||
|
||||
template<typename Attr, typename Info=typename Attr::Info>
|
||||
struct SetInfoIfNonVoid
|
||||
{
|
||||
static void run(Attr&attr, int nb)
|
||||
{
|
||||
attr.info()=nb;
|
||||
}
|
||||
};
|
||||
template<typename Attr>
|
||||
struct SetInfoIfNonVoid<Attr, void>
|
||||
{
|
||||
static void run(Attr&, int)
|
||||
{}
|
||||
};
|
||||
|
||||
template<typename Map, unsigned int i, typename Attr=typename Map::
|
||||
template Attribute_type<i>::type>
|
||||
struct CreateAttributes
|
||||
{
|
||||
static void run(Map& map)
|
||||
{
|
||||
int nb=0;
|
||||
for(typename Map::Dart_range::iterator it=map.darts().begin(),
|
||||
itend=map.darts().end(); it!=itend; ++it)
|
||||
{
|
||||
if ( it->template attribute<i>()==NULL )
|
||||
{
|
||||
map.template set_attribute<i>
|
||||
(it, map.template create_attribute<i>());
|
||||
SetInfoIfNonVoid<Attr>::run(*(it->template attribute<i>()), ++nb);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Map, typename Attr>
|
||||
struct CreateAttributes<Map, 0, Attr>
|
||||
{
|
||||
static void run(Map& amap)
|
||||
{
|
||||
int nb=0;
|
||||
for ( typename Map::template Attribute_range<0>::type::iterator
|
||||
it=amap.template attributes<0>().begin(),
|
||||
itend=amap.template attributes<0>().end();
|
||||
it!=itend; ++it )
|
||||
SetInfoIfNonVoid<Attr>::run(*it, ++nb);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Map, unsigned int i>
|
||||
struct CreateAttributes<Map, i, CGAL::Void>
|
||||
{
|
||||
static void run(Map&)
|
||||
{}
|
||||
};
|
||||
|
||||
template<typename Map>
|
||||
struct CreateAttributes<Map, 0, CGAL::Void>
|
||||
{
|
||||
static void run(Map&)
|
||||
{}
|
||||
};
|
||||
|
||||
template<typename Map, unsigned int i, typename Attr=typename Map::
|
||||
template Attribute_type<i>::type>
|
||||
struct DisplayNumberOfAttribs
|
||||
{
|
||||
static void run(Map& amap)
|
||||
{
|
||||
std::cout<<i<<"-attributes="<<amap.template number_of_attributes<i>()<<" ";
|
||||
}
|
||||
};
|
||||
template<typename Map, unsigned int i>
|
||||
struct DisplayNumberOfAttribs<Map,i,CGAL::Void>
|
||||
{
|
||||
static void run(Map&)
|
||||
{}
|
||||
};
|
||||
|
||||
template<typename Map, unsigned int i, typename Attr=typename Map::
|
||||
template Attribute_type<i>::type>
|
||||
struct DisplayAttribs
|
||||
{
|
||||
static void run(Map& amap)
|
||||
{
|
||||
std::cout<<i<<"-attributes: ";
|
||||
for ( typename Map::template Attribute_range<i>::type::iterator
|
||||
it=amap.template attributes<i>().begin(),
|
||||
itend=amap.template attributes<i>().end();
|
||||
it!=itend; ++it )
|
||||
{
|
||||
std::cout<<it->info()<<"; ";
|
||||
}
|
||||
std::cout<<std::endl;
|
||||
}
|
||||
};
|
||||
template<typename Map, unsigned int i>
|
||||
struct DisplayAttribs<Map,i,CGAL::Void>
|
||||
{
|
||||
static void run(Map&)
|
||||
{}
|
||||
};
|
||||
|
||||
template<typename Map,typename Attr,typename Info=typename Attr::Info>
|
||||
struct DisplayVertexAttrib
|
||||
{
|
||||
static void run(Map& amap)
|
||||
{
|
||||
std::cout<<"0-attributes: ";
|
||||
for ( typename Map::template Attribute_range<0>::type::iterator
|
||||
it=amap.template attributes<0>().begin(),
|
||||
itend=amap.template attributes<0>().end();
|
||||
it!=itend; ++it )
|
||||
{
|
||||
std::cout<<it->info()<<"; ";
|
||||
}
|
||||
std::cout<<std::endl;
|
||||
}
|
||||
};
|
||||
template<typename Map,typename Attr>
|
||||
struct DisplayVertexAttrib<Map,Attr,void>
|
||||
{
|
||||
static void run(Map& amap)
|
||||
{}
|
||||
};
|
||||
|
||||
template<typename Map, typename Attr>
|
||||
struct DisplayAttribs<Map,0,Attr>
|
||||
{
|
||||
static void run(Map& amap)
|
||||
{ DisplayVertexAttrib<Map,Attr>::run(amap); }
|
||||
};
|
||||
|
||||
template<typename Map>
|
||||
void displayAllAttribs2D(Map& amap, const char* c)
|
||||
{
|
||||
std::cout<<c;
|
||||
DisplayAttribs<Map,0>::run(amap);
|
||||
DisplayAttribs<Map,1>::run(amap);
|
||||
DisplayAttribs<Map,2>::run(amap);
|
||||
|
||||
std::cout<<"Points: ";
|
||||
for ( typename Map::template Attribute_range<0>::type::iterator
|
||||
it=amap.template attributes<0>().begin(),
|
||||
itend=amap.template attributes<0>().end();
|
||||
it!=itend; ++it )
|
||||
{
|
||||
std::cout<<it->point()<<"; ";
|
||||
}
|
||||
std::cout<<std::endl;
|
||||
}
|
||||
|
||||
template<typename Map>
|
||||
void displayAllAttribs3D(Map& amap, const char* c)
|
||||
{
|
||||
std::cout<<c;
|
||||
DisplayAttribs<Map,0>::run(amap);
|
||||
DisplayAttribs<Map,1>::run(amap);
|
||||
DisplayAttribs<Map,2>::run(amap);
|
||||
DisplayAttribs<Map,3>::run(amap);
|
||||
|
||||
std::cout<<"Points: ";
|
||||
for ( typename Map::template Attribute_range<0>::type::iterator
|
||||
it=amap.template attributes<0>().begin(),
|
||||
itend=amap.template attributes<0>().end();
|
||||
it!=itend; ++it )
|
||||
{
|
||||
std::cout<<it->point()<<"; ";
|
||||
}
|
||||
std::cout<<std::endl;
|
||||
}
|
||||
|
||||
template<typename Map>
|
||||
void displayAllAttribs4D(Map& amap, const char* c)
|
||||
{
|
||||
std::cout<<c;
|
||||
DisplayAttribs<Map,0>::run(amap);
|
||||
DisplayAttribs<Map,1>::run(amap);
|
||||
DisplayAttribs<Map,2>::run(amap);
|
||||
DisplayAttribs<Map,3>::run(amap);
|
||||
DisplayAttribs<Map,4>::run(amap);
|
||||
|
||||
std::cout<<"Points: ";
|
||||
for ( typename Map::template Attribute_range<0>::type::iterator
|
||||
it=amap.template attributes<0>().begin(),
|
||||
itend=amap.template attributes<0>().end();
|
||||
it!=itend; ++it )
|
||||
{
|
||||
std::cout<<it->point()<<"; ";
|
||||
}
|
||||
std::cout<<std::endl;
|
||||
|
||||
}
|
||||
|
||||
template<typename Map>
|
||||
void create2Dmap(Map& map)
|
||||
{
|
||||
for ( int i=0; i<15; ++i )
|
||||
map.make_tetrahedron(typename Map::Point(i, 0, 0),typename Map::Point(i, 2, 0),
|
||||
typename Map::Point(i+1, 0, 0),typename Map::Point(i+1, 1, 2));
|
||||
CreateAttributes<Map,0>::run(map);
|
||||
CreateAttributes<Map,1>::run(map);
|
||||
CreateAttributes<Map,2>::run(map);
|
||||
}
|
||||
template<typename Map>
|
||||
void create3Dmap(Map& map)
|
||||
{
|
||||
for ( int i=0; i<15; ++i )
|
||||
map.make_tetrahedron(typename Map::Point(i, 0, 0),typename Map::Point(i, 2, 0),
|
||||
typename Map::Point(i+1, 0, 0),typename Map::Point(i+1, 1, 2));
|
||||
|
||||
for ( int i=0; i<20; ++i )
|
||||
{
|
||||
typename Map::Dart_handle d1=map.darts().begin();
|
||||
while ( !d1->template is_free<3>() ) ++d1;
|
||||
typename Map::Dart_handle d2=map.darts().begin();
|
||||
while ( !map.template is_sewable<3>(d1, d2) ) ++d2;
|
||||
map.template sew<3>(d1,d2);
|
||||
}
|
||||
CreateAttributes<Map,0>::run(map);
|
||||
CreateAttributes<Map,1>::run(map);
|
||||
CreateAttributes<Map,2>::run(map);
|
||||
CreateAttributes<Map,3>::run(map);
|
||||
}
|
||||
|
||||
template<typename LCC>
|
||||
typename LCC::Point apoint(typename LCC::FT x, typename LCC::FT y,
|
||||
typename LCC::FT z, typename LCC::FT t)
|
||||
{
|
||||
std::vector<typename LCC::FT> tab;
|
||||
tab.push_back(x); tab.push_back(y);
|
||||
tab.push_back(z); tab.push_back(t);
|
||||
typename LCC::Point p(4,tab.begin(),tab.end());
|
||||
return p;
|
||||
}
|
||||
|
||||
template<typename Map>
|
||||
void create4Dmap(Map& map)
|
||||
{
|
||||
for ( int i=0; i<45; ++i )
|
||||
map.make_tetrahedron(apoint<Map>(i, 0, 0, 0),apoint<Map>(i, 2, 0, 0),
|
||||
apoint<Map>(i+1, 0, 0, 0),apoint<Map>(i+1, 1, 2, 0));
|
||||
|
||||
for ( int i=0; i<40; ++i )
|
||||
{
|
||||
typename Map::Dart_handle d1=map.darts().begin();
|
||||
while ( !d1->template is_free<3>() ) ++d1;
|
||||
typename Map::Dart_handle d2=map.darts().begin();
|
||||
while ( !map.template is_sewable<3>(d1, d2) ) ++d2;
|
||||
map.template sew<3>(d1,d2);
|
||||
}
|
||||
|
||||
for ( int i=0; i<20; ++i )
|
||||
{
|
||||
typename Map::Dart_handle d1=map.darts().begin();
|
||||
while ( !d1->template is_free<4>() ) ++d1;
|
||||
typename Map::Dart_handle d2=map.darts().begin();
|
||||
while ( !map.template is_sewable<4>(d1, d2) ) ++d2;
|
||||
map.template sew<4>(d1,d2);
|
||||
}
|
||||
CreateAttributes<Map,0>::run(map);
|
||||
CreateAttributes<Map,1>::run(map);
|
||||
CreateAttributes<Map,2>::run(map);
|
||||
CreateAttributes<Map,3>::run(map);
|
||||
CreateAttributes<Map,4>::run(map);
|
||||
}
|
||||
|
||||
bool testCopy()
|
||||
{
|
||||
Map1 map1; create2Dmap(map1);
|
||||
Map2 map2; create2Dmap(map2);
|
||||
Map3 map3; create2Dmap(map3);
|
||||
|
||||
Map4 map4; create3Dmap(map4);
|
||||
Map5 map5; create3Dmap(map5);
|
||||
Map6 map6; create3Dmap(map6);
|
||||
Map7 map7; create3Dmap(map7);
|
||||
|
||||
Map8 map8; create4Dmap(map8);
|
||||
Map9 map9; create4Dmap(map9);
|
||||
|
||||
// First copy of same types
|
||||
{
|
||||
Map1 map1p(map1);
|
||||
if ( !map1p.is_valid() || !map1.is_isomorphic_to(map1p) )
|
||||
{ assert(false); return false; }
|
||||
Map2 map2p(map2);
|
||||
if ( !map2p.is_valid() || !map2.is_isomorphic_to(map2p) )
|
||||
{ assert(false); return false; }
|
||||
Map3 map3p(map3);
|
||||
if ( !map3p.is_valid() || !map3.is_isomorphic_to(map3p) )
|
||||
{ assert(false); return false; }
|
||||
Map4 map4p(map4);
|
||||
if ( !map4p.is_valid() || !map4.is_isomorphic_to(map4p) )
|
||||
{ assert(false); return false; }
|
||||
Map5 map5p(map5);
|
||||
if ( !map5p.is_valid() || !map5.is_isomorphic_to(map5p) )
|
||||
{ assert(false); return false; }
|
||||
Map6 map6p(map6);
|
||||
if ( !map6p.is_valid() || !map6.is_isomorphic_to(map6p) )
|
||||
{ assert(false); return false; }
|
||||
Map7 map7p(map7);
|
||||
if ( !map7p.is_valid() || !map7.is_isomorphic_to(map7p) )
|
||||
{ assert(false); return false; }
|
||||
Map8 map8p(map8);
|
||||
if ( !map8p.is_valid() || !map8.is_isomorphic_to(map8p) )
|
||||
{ assert(false); return false; }
|
||||
Map9 map9p(map9);
|
||||
if ( !map9p.is_valid() || !map9.is_isomorphic_to(map9p) )
|
||||
{ assert(false); return false; }
|
||||
}
|
||||
|
||||
// Second copy of same dimensions but different attributes
|
||||
// Maps are still isomorphic but no same attributes
|
||||
{
|
||||
// 2D
|
||||
Map2 map1p(map1); assert(map1p.is_valid());
|
||||
if ( map1.is_isomorphic_to(map1p) ) { assert(false); return false; }
|
||||
if ( !map1.is_isomorphic_to(map1p, false) ) { assert(false); return false; }
|
||||
|
||||
Map3 map1t(map1); assert(map1t.is_valid());
|
||||
if ( map1.is_isomorphic_to(map1t) ) { assert(false); return false; }
|
||||
if ( !map1.is_isomorphic_to(map1t, false) ) { assert(false); return false; }
|
||||
|
||||
if ( map1p.is_isomorphic_to(map1t) ) { assert(false); return false; }
|
||||
if ( !map1p.is_isomorphic_to(map1t, false) ) { assert(false); return false; }
|
||||
|
||||
Map1 map2p(map2); assert(map2p.is_valid());
|
||||
if ( map2.is_isomorphic_to(map2p) ) { assert(false); return false; }
|
||||
if ( !map2.is_isomorphic_to(map2p, false) ) { assert(false); return false; }
|
||||
|
||||
Map3 map2t(map2); assert(map2t.is_valid());
|
||||
if ( map2.is_isomorphic_to(map2t) ) { assert(false); return false; }
|
||||
if ( !map2.is_isomorphic_to(map2t, false) ) { assert(false); return false; }
|
||||
|
||||
if ( map2p.is_isomorphic_to(map2t) ) { assert(false); return false; }
|
||||
if ( !map2p.is_isomorphic_to(map2t, false) ) { assert(false); return false; }
|
||||
|
||||
Map1 map3p(map3); assert(map3p.is_valid());
|
||||
if ( map3.is_isomorphic_to(map3p) ) { assert(false); return false; }
|
||||
if ( !map3.is_isomorphic_to(map3p, false) ) { assert(false); return false; }
|
||||
|
||||
Map2 map3t(map3); assert(map3t.is_valid());
|
||||
if ( map3.is_isomorphic_to(map3t) ) { assert(false); return false; }
|
||||
if ( !map3.is_isomorphic_to(map3t, false) ) { assert(false); return false; }
|
||||
|
||||
if ( map3p.is_isomorphic_to(map3t) ) { assert(false); return false; }
|
||||
if ( !map3p.is_isomorphic_to(map3t, false) ) { assert(false); return false; }
|
||||
|
||||
assert( map1.is_isomorphic_to(map1p)==map1p.is_isomorphic_to(map1) );
|
||||
assert( map1.is_isomorphic_to(map1t)==map1t.is_isomorphic_to(map1) );
|
||||
assert( map2.is_isomorphic_to(map2p)==map2p.is_isomorphic_to(map2) );
|
||||
assert( map2.is_isomorphic_to(map2t)==map2t.is_isomorphic_to(map2) );
|
||||
assert( map3.is_isomorphic_to(map3p)==map3p.is_isomorphic_to(map3) );
|
||||
assert( map3.is_isomorphic_to(map3t)==map3t.is_isomorphic_to(map3) );
|
||||
|
||||
// 3D
|
||||
Map4 map5a(map5); assert(map5a.is_valid());
|
||||
if ( map5.is_isomorphic_to(map5a) ) { assert(false); return false; }
|
||||
if ( !map5.is_isomorphic_to(map5a, false) ) { assert(false); return false; }
|
||||
|
||||
Map6 map5b(map5); assert(map5b.is_valid());
|
||||
if ( map5.is_isomorphic_to(map5b) ) { assert(false); return false; }
|
||||
if ( !map5.is_isomorphic_to(map5b, false) ) { assert(false); return false; }
|
||||
assert( map5b.number_of_attributes<0>()==map5.number_of_attributes<0>() &&
|
||||
map5b.number_of_attributes<1>()==0 &&
|
||||
map5b.number_of_attributes<2>()==map5.number_of_attributes<2>() &&
|
||||
map5b.number_of_attributes<3>()==map5.number_of_attributes<3>() );
|
||||
|
||||
Map7 map5c(map5); assert(map5c.is_valid());
|
||||
if ( map5.is_isomorphic_to(map5c) ) { assert(false); return false; }
|
||||
if ( !map5.is_isomorphic_to(map5c, false) ) { assert(false); return false; }
|
||||
assert( map5c.number_of_attributes<0>()==map5.number_of_attributes<0>() &&
|
||||
map5c.number_of_attributes<2>()==map5.number_of_attributes<2>() );
|
||||
|
||||
assert( map5.is_isomorphic_to(map5a)==map5a.is_isomorphic_to(map5) );
|
||||
assert( map5.is_isomorphic_to(map5b)==map5b.is_isomorphic_to(map5) );
|
||||
assert( map5.is_isomorphic_to(map5c)==map5c.is_isomorphic_to(map5) );
|
||||
|
||||
// 4D
|
||||
Map8 map9a(map9); assert(map9a.is_valid());
|
||||
if ( map9.is_isomorphic_to(map9a) ) { assert(false); return false; }
|
||||
if ( !map9.is_isomorphic_to(map9a, false) ) { assert(false); return false; }
|
||||
assert( map9a.number_of_attributes<0>()==map9.number_of_attributes<0>() &&
|
||||
map9a.number_of_attributes<2>()==map9.number_of_attributes<2>() &&
|
||||
map9a.number_of_attributes<4>()==0 );
|
||||
assert( map9a.is_isomorphic_to(map9)==map9.is_isomorphic_to(map9a) );
|
||||
|
||||
Map9 map8a(map8); assert(map8a.is_valid());
|
||||
if ( map8.is_isomorphic_to(map8a) ) { assert(false); return false; }
|
||||
if ( !map8.is_isomorphic_to(map8a, false) ) { assert(false); return false; }
|
||||
assert( map8a.number_of_attributes<0>()==map8.number_of_attributes<0>() &&
|
||||
map8a.number_of_attributes<1>()==0 &&
|
||||
map8a.number_of_attributes<2>()==map8.number_of_attributes<2>() &&
|
||||
map8a.number_of_attributes<3>()==0 &&
|
||||
map8a.number_of_attributes<4>()==0 );
|
||||
assert( map8a.is_isomorphic_to(map8)==map8.is_isomorphic_to(map8a) );
|
||||
|
||||
}
|
||||
|
||||
// Third copy of different dimensions and different attributes
|
||||
{
|
||||
Map5 map2a(map2); assert(map2a.is_valid());
|
||||
if ( map2a.is_isomorphic_to(map2) ) { assert(false); return false; }
|
||||
if ( !map2a.is_isomorphic_to(map2, false) ) { assert(false); return false; }
|
||||
assert( map2a.number_of_attributes<0>()==map2.number_of_attributes<0>() &&
|
||||
map2a.number_of_attributes<2>()==0 &&
|
||||
map2a.number_of_attributes<3>()==0 );
|
||||
assert( map2a.is_isomorphic_to(map2)==map2.is_isomorphic_to(map2a) );
|
||||
|
||||
Map2 map5a(map5); assert(map5a.is_valid());
|
||||
if ( map5a.is_isomorphic_to(map5) ) { assert(false); return false; }
|
||||
assert( map5a.number_of_attributes<0>()==map2.number_of_attributes<0>() &&
|
||||
map5a.number_of_attributes<2>()==0 );
|
||||
|
||||
Map5 map9a(map9); assert(map9a.is_valid());
|
||||
if ( map9a.is_isomorphic_to(map9) ) { assert(false); return false; }
|
||||
assert( map9a.number_of_attributes<0>()>=map9.number_of_attributes<0>() &&
|
||||
map9a.number_of_attributes<2>()>=map9.number_of_attributes<2>() &&
|
||||
map9a.number_of_attributes<3>()==0 );
|
||||
assert( map9a.is_isomorphic_to(map9)==map9.is_isomorphic_to(map9a) );
|
||||
|
||||
CGAL::Cast_converter_cmap_attributes<Map9,Map5,0> c0;
|
||||
CGAL::Default_converter_cmap_attributes<Map9,Map5,1> c1;
|
||||
CGAL::Default_converter_cmap_attributes<Map9,Map5,2> c2;
|
||||
CGAL::Cast_converter_cmap_attributes<Map9,Map5,3> c3;
|
||||
|
||||
CGAL::cpp11::tuple<CGAL::Cast_converter_cmap_attributes<Map9,Map5,0>,
|
||||
CGAL::Default_converter_cmap_attributes<Map9,Map5,1>,
|
||||
CGAL::Default_converter_cmap_attributes<Map9,Map5,2>,
|
||||
CGAL::Cast_converter_cmap_attributes<Map9,Map5,3> > myconverters
|
||||
(c0, c1, c2, c3);
|
||||
|
||||
Map5 map9b(map9, myconverters); assert(map9a.is_valid());
|
||||
if ( map9b.is_isomorphic_to(map9) ) { assert(false); return false; }
|
||||
assert( map9b.number_of_attributes<0>()>=map9.number_of_attributes<0>() &&
|
||||
map9b.number_of_attributes<2>()>=map9.number_of_attributes<2>() &&
|
||||
map9b.number_of_attributes<3>()>=map9.number_of_attributes<3>() );
|
||||
assert( map9b.is_isomorphic_to(map9)==map9.is_isomorphic_to(map9b) );
|
||||
|
||||
Converter_map9_points_into_map5_points mypointconverter;
|
||||
|
||||
Map5 map9c(map9, myconverters, mypointconverter); assert(map9a.is_valid());
|
||||
if ( map9c.is_isomorphic_to(map9) ) { assert(false); return false; }
|
||||
assert( map9c.number_of_attributes<0>()>=map9.number_of_attributes<0>() &&
|
||||
map9c.number_of_attributes<2>()>=map9.number_of_attributes<2>() &&
|
||||
map9c.number_of_attributes<3>()>=map9.number_of_attributes<3>() );
|
||||
assert( map9c.is_isomorphic_to(map9)==map9.is_isomorphic_to(map9c) );
|
||||
|
||||
CGAL::Cast_converter_cmap_attributes<Map5,Map9,0> cb0;
|
||||
CGAL::Default_converter_cmap_attributes<Map5,Map9,1> cb1;
|
||||
CGAL::Default_converter_cmap_attributes<Map5,Map9,2> cb2;
|
||||
CGAL::Cast_converter_cmap_attributes<Map5,Map9,3> cb3;
|
||||
|
||||
CGAL::cpp11::tuple<CGAL::Cast_converter_cmap_attributes<Map5,Map9,0>,
|
||||
CGAL::Default_converter_cmap_attributes<Map5,Map9,1>,
|
||||
CGAL::Default_converter_cmap_attributes<Map5,Map9,2>,
|
||||
CGAL::Cast_converter_cmap_attributes<Map5,Map9,3> > myconverters2
|
||||
(cb0, cb1, cb2, cb3);
|
||||
|
||||
Map9 map5b(map5, myconverters2); assert(map5b.is_valid());
|
||||
if ( map5b.is_isomorphic_to(map5) ) { assert(false); return false; }
|
||||
if ( !map5b.is_isomorphic_to(map5, false) ) { assert(false); return false; }
|
||||
assert( map5b.number_of_attributes<0>()==map5.number_of_attributes<0>() &&
|
||||
map5b.number_of_attributes<2>()==map5.number_of_attributes<2>() &&
|
||||
map5b.number_of_attributes<3>()==map5.number_of_attributes<3>() );
|
||||
assert( map5b.is_isomorphic_to(map5)==map5.is_isomorphic_to(map5b) );
|
||||
}
|
||||
|
||||
/*map2.display_characteristics(std::cout)<<std::endl;
|
||||
map2a.display_characteristics(std::cout)<<std::endl;
|
||||
displayAllAttribs2D(mapXX, "mapXX******************\n");
|
||||
displayAllAttribs2D(mapYY, "mapYY******************\n");*/
|
||||
/*map5.display_characteristics(std::cout)<<std::endl;
|
||||
map5b.display_characteristics(std::cout)<<std::endl;
|
||||
displayAllAttribs3D(map5, "map5******************\n");
|
||||
displayAllAttribs3D(map5b, "map5b******************\n");*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout<<"Linear cell complex copy test (v1)."<<std::flush;
|
||||
|
||||
if ( !testCopy() )
|
||||
{
|
||||
std::cout<<" Failed."<<std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::cout<<" Success."<<std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Loading…
Reference in New Issue