Ok for group/degroup and operations.

* clarify all the tests of group/ungroup cases for non void attributes
* create specialized functors allowing to consider all the different cases
  (group two edges along their two extremities, only the first or the second...)
* make many cleanup to move functors in different files, and to comment them
* add namespace before global functions

Still to do: sewable for dim>3 (build the isomorphism); try to improve onsplit
  test by testing only one out of two modified darts; add a parameter to
  operations to do not test group/ungroup; do a functor which updates the
  attributes of all the map (avoid do make many small tests, and do only one
  big test once).
This commit is contained in:
Guillaume Damiand 2013-02-14 16:27:51 +01:00
parent 6035180c7a
commit 450a07786b
12 changed files with 1863 additions and 1871 deletions

View File

@ -114,6 +114,11 @@ namespace CGAL {
/// Set the dart associated with the cell. /// Set the dart associated with the cell.
void set_dart(Dart_handle) {} void set_dart(Dart_handle) {}
/// Test if the cell is valid.
/// For cell without dart, return always true.
bool is_valid() const
{ return true; }
protected: protected:
/// Contructor without parameter. /// Contructor without parameter.
Cell_attribute_without_info(): mrefcounting(0) Cell_attribute_without_info(): mrefcounting(0)
@ -124,11 +129,6 @@ namespace CGAL {
mrefcounting(0) mrefcounting(0)
{} {}
/// Test if the cell is valid.
/// For cell without dart, return always true.
bool is_valid() const
{ return true; }
/// Increment the reference counting. /// Increment the reference counting.
void inc_nb_refs() void inc_nb_refs()
{ ++mrefcounting; } { ++mrefcounting; }
@ -216,6 +216,11 @@ namespace CGAL {
/// Set the dart associated with the cell. /// Set the dart associated with the cell.
void set_dart(Dart_handle adart) { mdart = adart; } void set_dart(Dart_handle adart) { mdart = adart; }
/// Test if the cell is valid.
/// A cell is valid if its dart is not NULL.
bool is_valid() const
{ return mdart!=NULL; }
protected: protected:
/// Contructor without parameter. /// Contructor without parameter.
Cell_attribute_without_info() : mdart(NULL), Cell_attribute_without_info() : mdart(NULL),
@ -228,11 +233,6 @@ namespace CGAL {
mrefcounting(0) mrefcounting(0)
{} {}
/// Test if the cell is valid.
/// A cell is valid if its dart is not NULL.
bool is_valid() const
{ return mdart!=NULL; }
/// Increment the reference counting. /// Increment the reference counting.
void inc_nb_refs() void inc_nb_refs()
{ ++mrefcounting; } { ++mrefcounting; }
@ -244,11 +244,11 @@ namespace CGAL {
--mrefcounting; --mrefcounting;
} }
public:
/// Get the reference counting. /// Get the reference counting.
unsigned int get_nb_refs() const unsigned int get_nb_refs() const
{ return mrefcounting; } { return mrefcounting; }
public:
void * for_compact_container() const void * for_compact_container() const
{ return mdart.for_compact_container(); } { return mdart.for_compact_container(); }
void * & for_compact_container() void * & for_compact_container()

File diff suppressed because it is too large Load Diff

View File

@ -22,8 +22,8 @@
#include <boost/type_traits/is_same.hpp> #include <boost/type_traits/is_same.hpp>
namespace CGAL { namespace CGAL
{
/** @file Combinatorial_map_basic_operations.h /** @file Combinatorial_map_basic_operations.h
* Basic operations on a combinatorial map. * Basic operations on a combinatorial map.
*/ */
@ -41,7 +41,7 @@ namespace CGAL {
{ {
CGAL_static_assertion( (boost::is_same<typename Iterator::Basic_iterator, CGAL_static_assertion( (boost::is_same<typename Iterator::Basic_iterator,
Tag_false>::value) ); Tag_false>::value) );
bool found = false; bool found=false;
for (Iterator it(amap, adart1); !found && it.cont(); ++it) for (Iterator it(amap, adart1); !found && it.cont(); ++it)
{ {
@ -64,7 +64,7 @@ namespace CGAL {
{ {
CGAL_static_assertion( (boost::is_same<typename Iterator::Basic_iterator, CGAL_static_assertion( (boost::is_same<typename Iterator::Basic_iterator,
Tag_false>::value) ); Tag_false>::value) );
bool res = true; bool res=true;
for ( Iterator it(amap, adart); res && it.cont(); ++it ) for ( Iterator it(amap, adart); res && it.cont(); ++it )
{ {
@ -86,7 +86,7 @@ namespace CGAL {
int amark) int amark)
{ {
amap.negate_mark(amark); amap.negate_mark(amark);
bool res = is_whole_orbit_marked<Map,Iterator>(amap, adart, amark); bool res=CGAL::is_whole_orbit_marked<Map,Iterator>(amap, adart, amark);
amap.negate_mark(amark); amap.negate_mark(amark);
return res; return res;
} }
@ -108,7 +108,7 @@ namespace CGAL {
CGAL_assertion( (is_whole_orbit_unmarked<Map, CGAL_assertion( (is_whole_orbit_unmarked<Map,
CMap_non_basic_iterator<Map,Iterator> > CMap_non_basic_iterator<Map,Iterator> >
(amap, adart, amark)) ); (amap, adart, amark)) );
typename Map::size_type res = 0; typename Map::size_type res=0;
for (Iterator it(amap, adart, amark); it.cont(); ++it) for (Iterator it(amap, adart, amark); it.cont(); ++it)
{ {
@ -132,7 +132,8 @@ namespace CGAL {
int amark) int amark)
{ {
amap.negate_mark(amark); amap.negate_mark(amark);
typename Map::size_type res = mark_orbit<Map, Iterator>(amap, adart, amark); typename Map::size_type
res=CGAL::mark_orbit<Map, Iterator>(amap, adart, amark);
amap.negate_mark(amark); amap.negate_mark(amark);
return res; return res;
} }
@ -148,9 +149,8 @@ namespace CGAL {
typename Map::Dart_const_handle adart1, typename Map::Dart_const_handle adart1,
typename Map::Dart_const_handle adart2) typename Map::Dart_const_handle adart2)
{ {
return belong_to_same_orbit<Map, return CGAL::belong_to_same_orbit<Map,
typename Map::template typename Map::template Dart_of_cell_range<i,d>::const_iterator>
Dart_of_cell_range<i,d>::const_iterator>
(amap, adart1, adart2); (amap, adart1, adart2);
} }
@ -159,7 +159,7 @@ namespace CGAL {
typename Map::Dart_const_handle adart1, typename Map::Dart_const_handle adart1,
typename Map::Dart_const_handle adart2) typename Map::Dart_const_handle adart2)
{ {
return belong_to_same_cell<Map,i,Map::dimension>(amap,adart1,adart2); return CGAL::belong_to_same_cell<Map,i,Map::dimension>(amap,adart1,adart2);
} }
@ -174,9 +174,8 @@ namespace CGAL {
typename Map::Dart_const_handle adart, typename Map::Dart_const_handle adart,
unsigned int amark) unsigned int amark)
{ {
return is_whole_orbit_marked<Map, return CGAL::is_whole_orbit_marked<Map,
typename Map::template typename Map::template Dart_of_cell_range<i,d>::const_iterator>
Dart_of_cell_range<i,d>::const_iterator>
(amap, adart, amark); (amap, adart, amark);
} }
@ -185,7 +184,7 @@ namespace CGAL {
typename Map::Dart_const_handle adart, typename Map::Dart_const_handle adart,
unsigned int amark) unsigned int amark)
{ {
return is_whole_cell_marked<Map,i,Map::dimension>(amap,adart,amark); return CGAL::is_whole_cell_marked<Map,i,Map::dimension>(amap,adart,amark);
} }
/** Test if all the darts of a given cell are unmarked. /** Test if all the darts of a given cell are unmarked.
@ -199,9 +198,8 @@ namespace CGAL {
typename Map::Dart_const_handle adart, typename Map::Dart_const_handle adart,
unsigned int amark) unsigned int amark)
{ {
return is_whole_orbit_unmarked<Map, return CGAL::is_whole_orbit_unmarked<Map,
typename Map::template typename Map::template Dart_of_cell_range<i,d>::iterator>
Dart_of_cell_range<i,d>::iterator>
(amap, adart, amark); (amap, adart, amark);
} }
@ -210,7 +208,8 @@ namespace CGAL {
typename Map::Dart_const_handle adart, typename Map::Dart_const_handle adart,
unsigned int amark) unsigned int amark)
{ {
return is_whole_cell_unmarked<Map,i,Map::dimension>(amap,adart,amark); return CGAL::is_whole_cell_unmarked<Map,i,Map::dimension>
(amap,adart,amark);
} }
/** Mark a given cell with a given mark. /** Mark a given cell with a given mark.
@ -224,16 +223,15 @@ namespace CGAL {
typename Map::size_type mark_cell(const Map & amap, typename Map::size_type mark_cell(const Map & amap,
typename Map::Dart_const_handle adart, typename Map::Dart_const_handle adart,
int amark) int amark)
{ return mark_orbit<Map, { return CGAL::mark_orbit<Map,
typename Map::template typename Map::template Dart_of_cell_basic_range<i,d>::const_iterator>
Dart_of_cell_basic_range<i,d>::const_iterator>
(amap, adart, amark); } (amap, adart, amark); }
template < class Map, unsigned int i> template < class Map, unsigned int i>
typename Map::size_type mark_cell(const Map & amap, typename Map::size_type mark_cell(const Map & amap,
typename Map::Dart_const_handle adart, typename Map::Dart_const_handle adart,
int amark) int amark)
{ return mark_cell<Map,i,Map::dimension>(amap, adart, amark);} { return CGAL::mark_cell<Map,i,Map::dimension>(amap, adart, amark);}
/** Unmark a given orbit with a given mark. /** Unmark a given orbit with a given mark.
* @param amap a combinatorial map. * @param amap a combinatorial map.
@ -246,16 +244,15 @@ namespace CGAL {
typename Map::size_type unmark_cell(const Map & amap, typename Map::size_type unmark_cell(const Map & amap,
typename Map::Dart_handle adart, typename Map::Dart_handle adart,
int amark) int amark)
{ return unmark_orbit<Map, { return CGAL::unmark_orbit<Map,
typename Map::template typename Map::template Dart_of_cell_basic_range<i,d>::const_iterator>
Dart_of_cell_basic_range<i,d>::const_iterator>
(amap, adart, amark);} (amap, adart, amark);}
template < class Map, unsigned int i > template < class Map, unsigned int i >
typename Map::size_type unmark_cell(const Map & amap, typename Map::size_type unmark_cell(const Map & amap,
typename Map::Dart_handle adart, typename Map::Dart_handle adart,
int amark) int amark)
{ return unmark_cell<Map,i,Map::dimension>(amap, adart, amark);} { return CGAL::unmark_cell<Map,i,Map::dimension>(amap, adart, amark); }
/** Compute the degree of a given i-cell c. /** Compute the degree of a given i-cell c.
* The degree is the number of distinct i+1 cells incident to c. * The degree is the number of distinct i+1 cells incident to c.
@ -280,7 +277,7 @@ namespace CGAL {
if (!amap.is_marked(*it, treated)) if (!amap.is_marked(*it, treated))
{ {
++nbIncident; ++nbIncident;
mark_cell<Map,i+1>(amap, *it, treated); CGAL::mark_cell<Map,i+1>(amap, *it, treated);
} }
amap.mark(*it,mark); amap.mark(*it,mark);
} }
@ -289,7 +286,7 @@ namespace CGAL {
for (it.rewind(); it.cont(); ++it) for (it.rewind(); it.cont(); ++it)
{ {
if (amap.is_marked(*it, treated)) if (amap.is_marked(*it, treated))
unmark_cell<Map,i+1>(amap, *it, treated); CGAL::unmark_cell<Map,i+1>(amap, *it, treated);
amap.mark(*it,mark); amap.mark(*it,mark);
} }
@ -327,7 +324,7 @@ namespace CGAL {
if (!amap.is_marked(*it, treated)) if (!amap.is_marked(*it, treated))
{ {
++nbIncident; ++nbIncident;
mark_cell<Map,i-1>(amap, *it, treated); CGAL::mark_cell<Map,i-1>(amap, *it, treated);
} }
amap.mark(*it,mark); amap.mark(*it,mark);
} }
@ -336,7 +333,7 @@ namespace CGAL {
for (it.rewind(); it.cont(); ++it) for (it.rewind(); it.cont(); ++it)
{ {
if (amap.is_marked(*it, treated)) if (amap.is_marked(*it, treated))
unmark_cell<Map,i-1>(amap, *it, treated); CGAL::unmark_cell<Map,i-1>(amap, *it, treated);
amap.mark(*it,mark); amap.mark(*it,mark);
} }

View File

@ -21,8 +21,8 @@
#define CGAL_COMBINATORIAL_MAP_FUNCTORS_H #define CGAL_COMBINATORIAL_MAP_FUNCTORS_H
#include <CGAL/Dart_const_iterators.h> #include <CGAL/Dart_const_iterators.h>
#include <CGAL/Cell_const_iterators.h>
#include <CGAL/Combinatorial_map_basic_operations.h> #include <CGAL/Combinatorial_map_basic_operations.h>
#include <CGAL/internal/Combinatorial_map_internal_functors.h>
#include <vector> #include <vector>
/* Definition of functors used to manage attributes (we need functors as /* Definition of functors used to manage attributes (we need functors as
@ -30,60 +30,40 @@
* compiling time). Some of these functors are used with * compiling time). Some of these functors are used with
* Foreach_enabled_attributes to iterate through all the non void attribs. * Foreach_enabled_attributes to iterate through all the non void attribs.
* Functors allowing to group/ungroup attributes are defined in * Functors allowing to group/ungroup attributes are defined in
* Combinatorial_map_group_functors.h (included at the end of this file) * Combinatorial_map_group_functors.h. Some internal functors are defined
* in internal/Combinatorial_map_internal_functors.h.
* *
* Reserve_mark_functor<CMap> to reserve one mark for each non void attribute. * Reserve_mark_functor<CMap> to reserve one mark, used with
* Foreach_enabled_attributes to reserve a mark for each non void attribute.
*
* Display_attribute_functor<CMap> to display the address of the i-attribute
* of a given dart (can be used with Foreach_enabled_attributes)
* *
* Set_i_attribute_functor<CMap, i> to set the i-attribute of a given * Set_i_attribute_functor<CMap, i> to set the i-attribute of a given
* i-cell. * i-cell.
*
* internal::Call_split_functor<CMap,i> to call the OnSplit functors on two
* given i-attributes.
*
* internal::Call_merge_functor<CMap,i> to call the OnMerge functors on two
* given i-attributes.
*
* internal::Test_is_valid_attribute_functor<CMap> to test if a given i-cell is
* valid (all its darts are linked to the same attribute, no other dart is
* linked with this attribute).
*
* internal::Count_cell_functor<CMap> to count the nuber of i-cells.
*
* internal::Count_bytes_one_attribute_functor<CMap> to count the memory
* occupied by i-attributes.
*
* internal::Decrease_attribute_functor<CMap> to decrease by one the ref
* counting of a given i-attribute.
*
* internal::Beta_functor<Dart, i...> to call several beta on the given dart.
* Indices are given as parameter of the run function.
*
* internal::Beta_functor_static<Dart, i...> to call several beta on the given
* dart. Indices are given as template arguments.
*
* internal::Set_i_attribute_of_dart_functor<CMap, i> to set the i-attribute
* of a given dart.
*/ */
namespace CGAL namespace CGAL
{ {
/** @file Combinatorial_map_functors.h /** @file Combinatorial_map_functors.h
* Definition of functors used for dD Combinatorial map. * Definition of functors used for dD Combinatorial map.
*/ */
// ************************************************************************** // ****************************************************************************
/// Functor used to reserve one mark for each enabled attribute. /// Functor used to reserve one mark, used with Foreach_enabled_attributes
template<typename CMap> /// to reserve a mark for each enabled attribute.
struct Reserve_mark_functor template<typename CMap>
{ struct Reserve_mark_functor
{
template <unsigned int i> template <unsigned int i>
static void run(const CMap* amap, std::vector<int>* marks) static void run(const CMap* amap, std::vector<int>* marks)
{ (*marks)[i] = amap->get_new_mark(); } { (*marks)[i] = amap->get_new_mark(); }
}; };
// ************************************************************************** // ****************************************************************************
/// Functor used to display the address of the i-cell attribute /// Functor used to display the address of the i-cell attribute. Can be used
template<typename CMap> /// with Foreach_enabled_attributes.
struct Display_attribute_functor template<typename CMap>
{ struct Display_attribute_functor
{
template <unsigned int i> template <unsigned int i>
static void run(const CMap* amap, static void run(const CMap* amap,
typename CMap::Dart_const_handle adart) typename CMap::Dart_const_handle adart)
@ -93,313 +73,45 @@ namespace CGAL
else else
std::cout<<&*(adart->template attribute<i>()); std::cout<<&*(adart->template attribute<i>());
} }
}; };
// ************************************************************************** // ****************************************************************************
namespace internal /// Functor used to test if a cell is valid
{ template<typename CMap>
// Functor which call Functor::operator() on the two given cell_attributes struct Test_is_valid_attribute_functor
template<typename Cell_attribute, typename Functor> {
struct Apply_cell_functor
{
static void run(Cell_attribute& acell1, Cell_attribute& acell2)
{
Functor() (acell1,acell2);
}
};
//...except for Null_functor.
template<typename Cell_attribute>
struct Apply_cell_functor<Cell_attribute,Null_functor>
{
static void run(Cell_attribute&, Cell_attribute&)
{}
};
// **************************************************************************
// Functor used to call the On_split functor between the two given darts.
template<typename CMap, unsigned int i,
typename Enabled=typename CMap::Helper::
#ifndef CGAL_CFG_TEMPLATE_IN_DEFAULT_PARAMETER_BUG
template
#endif
Attribute_type<i>::type>
struct Call_split_functor
{
static void run(typename CMap::Dart_handle adart1,
typename CMap::Dart_handle adart2)
{
Apply_cell_functor
<typename CMap::Helper::template Attribute_type<i>::type,
typename CMap::Helper::
template Attribute_type<i>::type::On_split>::
run(*(adart1->template attribute<i>()),
*(adart2->template attribute<i>()));
}
static void
run(typename CMap::Helper::template Attribute_handle<i>::type a1,
typename CMap::Helper::template Attribute_handle<i>::type a2)
{
Apply_cell_functor
<typename CMap::Helper::template Attribute_type<i>::type,
typename CMap::Helper::
template Attribute_type<i>::type::On_split>::
run(*a1, *a2);
}
};
// Specialization for disabled attributes.
template<typename CMap,unsigned int i>
struct Call_split_functor<CMap,i,CGAL::Void>
{
static void run(typename CMap::Dart_handle,
typename CMap::Dart_handle)
{}
};
// **************************************************************************
// Functor used to call the On_merge functor between the two given darts.
template<typename CMap,unsigned int i,
typename Enabled=typename CMap::Helper::
#ifndef CGAL_CFG_TEMPLATE_IN_DEFAULT_PARAMETER_BUG
template
#endif
Attribute_type<i>::type>
struct Call_merge_functor
{
static void run(typename CMap::Dart_handle adart1,
typename CMap::Dart_handle adart2)
{
Apply_cell_functor
<typename CMap::Helper::template Attribute_type<i>::type,
typename CMap::Helper::template Attribute_type<i>::type::On_merge>::
run(*(adart1->template attribute<i>()),
*(adart2->template attribute<i>()));
}
static void
run(typename CMap::Helper::template Attribute_handle<i>::type a1,
typename CMap::Helper::template Attribute_handle<i>::type a2)
{
Apply_cell_functor
<typename CMap::Helper::template Attribute_type<i>::type,
typename CMap::Helper::template Attribute_type<i>::type::On_merge>::
run(*a1, *a2);
}
};
// Specialization for disabled attributes.
template<typename CMap,unsigned int i>
struct Call_merge_functor<CMap,i,CGAL::Void>
{
static void run(typename CMap::Dart_handle,
typename CMap::Dart_handle)
{}
};
// **************************************************************************
/// Functor used to test if a cell is valid
template<typename CMap>
struct Test_is_valid_attribute_functor
{
template <unsigned int i> template <unsigned int i>
static void run(const CMap* amap, static bool run(const CMap* amap,
typename CMap::Dart_const_handle adart, typename CMap::Dart_const_handle adart)
std::vector<int>* marks, bool *ares)
{ {
if (!amap->template is_valid_attribute<i>(adart,(*marks)[i]) ) int mark=amap->get_new_mark();
{ bool res = true;
(*ares)=false; CGAL::internal::Test_is_valid_attribute_functor<CMap>::
std::cerr << "CMap not valid: a "<<i<<"-cell is not correctly " run<i>(amap, adart, mark, &res);
"associated with an attribute for " << &(*adart)<< std::endl;
}
}
};
// **************************************************************************
/// Functor for counting i-cell
template<typename CMap>
struct Count_cell_functor
{
template <unsigned int i>
static void run( const CMap* amap,
typename CMap::Dart_const_handle adart,
std::vector<int>* amarks,
std::vector<unsigned int>* ares )
{
if ( (*amarks)[i]!=-1 && !amap->is_marked(adart, (*amarks)[i]) )
{
++ (*ares)[i];
mark_cell<CMap,i>(*amap, adart, (*amarks)[i]);
}
}
};
// **************************************************************************
/// Functor for counting the memory occupation of attributes
/// Be careful not reentrant !!! TODO a Foreach_enabled_attributes
/// taking an instance of a functor as argument allowing to compute
/// and return values.
template<typename CMap>
struct Count_bytes_one_attribute_functor
{
template <unsigned int i>
static void run( const CMap* amap )
{
res += amap->template attributes<i>().capacity()*
sizeof(typename CMap::template Attribute_type<i>::type);
}
static typename CMap::size_type res; amap->negate_mark(mark);
}; if ( !amap->is_whole_map_marked(mark) )
template<typename CMap> {
typename CMap::size_type Count_bytes_one_attribute_functor<CMap>::res = 0; for ( CGAL::CMap_dart_const_iterator_basic_of_cell<CMap,i>
it(*amap, adart, mark); it.cont(); ++it )
amap->unmark(it, mark);
}
CGAL_assertion ( amap->is_whole_map_marked(mark) );
amap->free_mark(mark);
template<typename CMap> return res;
struct Count_bytes_all_attributes_functor
{
static typename CMap::size_type run( const CMap& amap )
{
Count_bytes_one_attribute_functor<CMap>::res = 0;
CMap::Helper::template Foreach_enabled_attributes
<Count_bytes_one_attribute_functor<CMap> >::run(&amap);
return Count_bytes_one_attribute_functor<CMap>::res;
} }
}; };
// ************************************************************************** // ****************************************************************************
/// Decrease the cell attribute reference counting of the given dart. /// Functor used to set the i-attribute of a given i-cell.
/// The attribute is removed if there is no more darts linked with it. /// We can use any range as Range type, by default we use
template<typename CMap, unsigned int i, typename T= /// Dart_of_cell_range<i>
typename CMap::Helper::template Attribute_type<i>::type> template<typename CMap, unsigned int i,
struct Decrease_attribute_functor_run
{
static void run(CMap* amap, typename CMap::Dart_handle adart)
{
if ( adart->template attribute<i>()!=NULL )
{
adart->template attribute<i>()->dec_nb_refs();
if ( adart->template attribute<i>()->get_nb_refs()==0 )
amap->template erase_attribute<i>(adart->template attribute<i>());
}
}
};
/// Specialization for void attributes.
template<typename CMap, unsigned int i>
struct Decrease_attribute_functor_run<CMap,i,CGAL::Void>
{
static void run(CMap*, typename CMap::Dart_handle)
{}
};
// **************************************************************************
/// Functor used to call decrease_attribute_ref_counting<i>
/// on each i-cell attribute enabled
template<typename CMap>
struct Decrease_attribute_functor
{
template <unsigned int i>
static void run(CMap* amap, typename CMap::Dart_handle adart)
{ Decrease_attribute_functor_run<CMap,i>::run(amap, adart); }
};
// **************************************************************************
/// Functor used to set the i-attribute of a given dart.
template<typename CMap, unsigned int i, typename T=
typename CMap::Helper::template Attribute_type<i>::type>
struct Set_i_attribute_of_dart_functor
{
static void run( CMap* amap, typename CMap::Dart_handle dh,
typename CMap::Helper::template Attribute_handle<i>::type
ah )
{
CGAL_static_assertion(i<=CMap::dimension);
CGAL_assertion( dh!=NULL && dh!=CMap::null_dart_handle );
if ( dh->template attribute<i>()==ah ) return;
Decrease_attribute_functor_run<CMap, i>::run(amap, dh);
dh->template set_attribute<i>(ah);
}
};
/// Specialization for void attributes.
template<typename CMap, unsigned int i>
struct Set_i_attribute_of_dart_functor<CMap,i,CGAL::Void>
{
static void run( CMap*, typename CMap::Dart_handle,
typename CMap::Helper::template Attribute_handle<i>::type)
{}
};
// **************************************************************************
// Beta functor, used to combine several beta.
#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
template<typename Dart_handle, typename ... Betas>
struct Beta_functor;
template<typename Dart_handle, typename ... Betas>
struct Beta_functor<Dart_handle, int, Betas...>
{
static Dart_handle run(Dart_handle ADart, int B, Betas... betas)
{ return Beta_functor<Dart_handle, Betas...>::run(ADart->beta(B),
betas...); }
};
template<typename Dart_handle>
struct Beta_functor<Dart_handle, int>
{
static Dart_handle run(Dart_handle ADart, int B)
{
CGAL_assertion( ADart!=NULL );
return ADart->beta(B);
}
};
// **************************************************************************
template<typename Dart_handle, int ... Betas>
struct Beta_functor_static;
template<typename Dart_handle, int B, int ... Betas>
struct Beta_functor_static<Dart_handle, B, Betas...>
{
static Dart_handle run(Dart_handle ADart)
{ return Beta_functor_static<Dart_handle, Betas...>::
run(ADart->template beta<B>()); }
};
template<typename Dart_handle, int B>
struct Beta_functor_static<Dart_handle, B>
{
static Dart_handle run(Dart_handle ADart)
{
CGAL_assertion( ADart!=NULL );
return ADart->template beta<B>();
}
};
#endif //CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
// **************************************************************************
/// Functor used to call update_dart_of_attribute<i>
/// on each i-cell attribute enabled
// TODO REMOVE ?
template<typename CMap>
struct Update_dart_of_attribute_functor
{
template <unsigned int i>
static void run(CMap* amap, typename CMap::Dart_handle ah, int amark)
{ amap->template update_dart_of_attribute<i>(ah,amark); }
};
template<typename CMap, unsigned int i, typename Enabled=
typename CMap::Helper::
#ifndef CGAL_CFG_TEMPLATE_IN_DEFAULT_PARAMETER_BUG
template
#endif
Attribute_type<i>::type>
struct Update_dart_of_one_attribute_functor
{
static void run(CMap* amap, typename CMap::Dart_handle ah, int amark)
{ amap->template update_dart_of_attribute<i>(ah,amark); }
};
template<typename CMap, unsigned int i>
struct Update_dart_of_one_attribute_functor<CMap, i, CGAL::Void>
{
static void run(CMap*, typename CMap::Dart_handle, int)
{}
};
// **************************************************************************
} // namespace internal
// **************************************************************************
/// Functor used to set the i-attribute of a given i-cell.
/// We can use any range as Range type, by default we use
/// Dart_of_cell_range<i>
template<typename CMap, unsigned int i,
typename Range=typename CMap::template Dart_of_cell_range<i>, typename Range=typename CMap::template Dart_of_cell_range<i>,
typename T=typename CMap::Helper::template Attribute_type<i>::type> typename T=typename CMap::template Attribute_type<i>::type>
struct Set_i_attribute_functor struct Set_i_attribute_functor
{ {
static void run( CMap* amap, typename CMap::Dart_handle dh, static void run( CMap* amap, typename CMap::Dart_handle dh,
typename CMap::Helper::template Attribute_handle<i>::type typename CMap::template Attribute_handle<i>::type
ah ) ah )
{ {
CGAL_static_assertion(i<=CMap::dimension); CGAL_static_assertion(i<=CMap::dimension);
@ -415,19 +127,17 @@ namespace CGAL
} }
ah->set_dart(dh); ah->set_dart(dh);
} }
}; };
/// Specialization for void attributes. /// Specialization for void attributes.
template<typename CMap, unsigned int i> template<typename CMap, unsigned int i>
struct Set_i_attribute_functor<CMap,i,CGAL::Void> struct Set_i_attribute_functor<CMap,i,CGAL::Void>
{ {
static void run( CMap*, typename CMap::Dart_handle, static void run( CMap*, typename CMap::Dart_handle,
typename CMap::Helper::template Attribute_handle<i>::type) typename CMap::template Attribute_handle<i>::type)
{} {}
}; };
// ************************************************************************** // ****************************************************************************
} // namespace CGAL } // namespace CGAL
#include <CGAL/internal/Combinatorial_map_group_functors.h>
#endif // CGAL_COMBINATORIAL_MAP_FUNCTORS_H // #endif // CGAL_COMBINATORIAL_MAP_FUNCTORS_H //
// EOF // // EOF //

View File

@ -1,7 +1,27 @@
// Copyright (c) 2010-2011 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_INSERTIONS_H #ifndef CGAL_COMBINATORIAL_MAP_INSERTIONS_H
#define CGAL_COMBINATORIAL_MAP_INSERTIONS_H #define CGAL_COMBINATORIAL_MAP_INSERTIONS_H
namespace CGAL { namespace CGAL
{
/** @file Combinatorial_map_insertions.h /** @file Combinatorial_map_insertions.h
* Insertion operations on combinatorial map. * Insertion operations on combinatorial map.
*/ */
@ -54,10 +74,11 @@ insert_cell_0_in_cell_1( CMap& amap, typename CMap::Dart_handle adart,
// We copy all the attributes except for dim=0 // We copy all the attributes except for dim=0
CMap::Helper::template Foreach_enabled_attributes_except CMap::Helper::template Foreach_enabled_attributes_except
<internal::Group_attribute_functor_of_dart<CMap>, 0>:: <CGAL::internal::Group_attribute_functor_of_dart<CMap>, 0>::
run(&amap,*it,d1); run(&amap,*it,d1);
// We initialise the 0-atttrib to ah // We initialise the 0-atttrib to ah
internal::Set_i_attribute_of_dart_functor<CMap, 0>::run(&amap, d1, ah); CGAL::internal::Set_i_attribute_of_dart_functor<CMap, 0>::
run(&amap, d1, ah);
amap.mark(*it, mark); amap.mark(*it, mark);
} }
@ -73,10 +94,12 @@ insert_cell_0_in_cell_1( CMap& amap, typename CMap::Dart_handle adart,
amap.free_mark(m); amap.free_mark(m);
amap.free_mark(mark); amap.free_mark(mark);
internal::Degroup_attribute_functor_run<CMap, 1>:: CGAL::internal::Degroup_attribute_functor_run<CMap, 1>::
run(&amap, adart, adart->beta(1)); run(&amap, adart, adart->beta(1));
#ifdef CGAL_CMAP_TEST_VALID_INSERTIONS
CGAL_assertion( amap.is_valid() ); CGAL_assertion( amap.is_valid() );
#endif
return adart->beta(1); return adart->beta(1);
} }
@ -90,7 +113,7 @@ insert_cell_0_in_cell_1( CMap& amap, typename CMap::Dart_handle adart,
template < class CMap > template < class CMap >
typename CMap::Dart_handle typename CMap::Dart_handle
insert_cell_0_in_cell_2( CMap& amap, typename CMap::Dart_handle adart, insert_cell_0_in_cell_2( CMap& amap, typename CMap::Dart_handle adart,
typename CMap::Helper::template typename CMap::template
Attribute_handle<0>::type ah=NULL ) Attribute_handle<0>::type ah=NULL )
{ {
CGAL_assertion(adart != NULL && adart!=CMap::null_dart_handle); CGAL_assertion(adart != NULL && adart!=CMap::null_dart_handle);
@ -144,7 +167,8 @@ insert_cell_0_in_cell_2( CMap& amap, typename CMap::Dart_handle adart,
if ( prev!=NULL ) if ( prev!=NULL )
amap.template basic_link_beta_for_involution<2>(prev, n1); amap.template basic_link_beta_for_involution<2>(prev, n1);
internal::Set_i_attribute_of_dart_functor<CMap, 0>::run(&amap, n1, ah); CGAL::internal::Set_i_attribute_of_dart_functor<CMap, 0>::
run(&amap, n1, ah);
} }
for (unsigned int dim=3; dim<=CMap::dimension; ++dim) for (unsigned int dim=3; dim<=CMap::dimension; ++dim)
@ -166,7 +190,7 @@ insert_cell_0_in_cell_2( CMap& amap, typename CMap::Dart_handle adart,
nn2=amap.create_dart(); nn2=amap.create_dart();
amap.link_beta_0(cur->beta(dim), nn2); amap.link_beta_0(cur->beta(dim), nn2);
amap.basic_link_beta_for_involution(n2, nn2, dim); amap.basic_link_beta_for_involution(n2, nn2, dim);
internal::Set_i_attribute_of_dart_functor<CMap, 0>:: CGAL::internal::Set_i_attribute_of_dart_functor<CMap, 0>::
run(&amap, nn2, ah); run(&amap, nn2, ah);
} }
else nn2=NULL; else nn2=NULL;
@ -218,14 +242,16 @@ insert_cell_0_in_cell_2( CMap& amap, typename CMap::Dart_handle adart,
amap.unmark(*itd, treated); amap.unmark(*itd, treated);
if ( *itd!=adart ) if ( *itd!=adart )
internal::Degroup_attribute_functor_run<CMap, 2>:: CGAL::internal::Degroup_attribute_functor_run<CMap, 2>::
run(&amap, adart, *itd); run(&amap, adart, *itd);
} }
CGAL_assertion(amap.is_whole_map_unmarked(treated)); CGAL_assertion(amap.is_whole_map_unmarked(treated));
amap.free_mark(treated); amap.free_mark(treated);
#ifdef CGAL_CMAP_TEST_VALID_INSERTIONS
CGAL_assertion( amap.is_valid() ); CGAL_assertion( amap.is_valid() );
#endif
return n1; return n1;
} }
@ -238,7 +264,7 @@ template<class CMap>
typename CMap::Dart_handle typename CMap::Dart_handle
insert_dangling_cell_1_in_cell_2( CMap& amap, insert_dangling_cell_1_in_cell_2( CMap& amap,
typename CMap::Dart_handle adart1, typename CMap::Dart_handle adart1,
typename CMap::Helper::template typename CMap::template
Attribute_handle<0>::type ah=NULL ) Attribute_handle<0>::type ah=NULL )
{ {
CGAL_assertion(adart1!=NULL && adart1!=CMap::null_dart_handle); CGAL_assertion(adart1!=NULL && adart1!=CMap::null_dart_handle);
@ -303,7 +329,8 @@ insert_dangling_cell_1_in_cell_2( CMap& amap,
(it1->beta(dim)->beta_inv(s1)->beta(2), d2, dim); (it1->beta(dim)->beta_inv(s1)->beta(2), d2, dim);
} }
} }
internal::Set_i_attribute_of_dart_functor<CMap, 0>::run(&amap, d1, ah); CGAL::internal::Set_i_attribute_of_dart_functor<CMap, 0>::
run(&amap, d1, ah);
amap.mark(it1, treated); amap.mark(it1, treated);
} }
@ -321,7 +348,9 @@ insert_dangling_cell_1_in_cell_2( CMap& amap,
CGAL_assertion( amap.is_whole_map_unmarked(mark1) ); CGAL_assertion( amap.is_whole_map_unmarked(mark1) );
amap.free_mark(mark1); amap.free_mark(mark1);
#ifdef CGAL_CMAP_TEST_VALID_INSERTIONS
CGAL_assertion( amap.is_valid() ); CGAL_assertion( amap.is_valid() );
#endif
return adart1->template beta<0>(); return adart1->template beta<0>();
} }
@ -339,7 +368,7 @@ bool is_insertable_cell_1_in_cell_2(const CMap& amap,
{ {
CGAL_assertion(adart1 != NULL && adart2 != NULL); CGAL_assertion(adart1 != NULL && adart2 != NULL);
if ( adart1==adart2 ) return false; if ( adart1==adart2 ) return false;
for ( CMap_dart_const_iterator_of_orbit<CMap,1> it(amap,adart1); for ( CGAL::CMap_dart_const_iterator_of_orbit<CMap,1> it(amap,adart1);
it.cont(); ++it ) it.cont(); ++it )
{ {
if ( it==adart2 ) return true; if ( it==adart2 ) return true;
@ -365,17 +394,15 @@ insert_cell_1_in_cell_2(CMap& amap,
CGAL_assertion(is_insertable_cell_1_in_cell_2<CMap>(amap, adart1, adart2)); CGAL_assertion(is_insertable_cell_1_in_cell_2<CMap>(amap, adart1, adart2));
int m1=amap.get_new_mark(); int m1=amap.get_new_mark();
CMap_dart_iterator_basic_of_involution<CMap,1> CGAL::CMap_dart_iterator_basic_of_involution<CMap,1> it1(amap, adart1, m1);
it1 = CMap_dart_iterator_basic_of_involution<CMap,1>(amap, adart1, m1);
int m2=amap.get_new_mark(); int m2=amap.get_new_mark();
CMap_dart_iterator_basic_of_involution<CMap,1> CGAL::CMap_dart_iterator_basic_of_involution<CMap,1> it2(amap, adart2, m2);
it2 = CMap_dart_iterator_basic_of_involution<CMap,1>(amap, adart2, m2);
int mark1=amap.get_new_mark(); int mark1=amap.get_new_mark();
std::deque<typename CMap::Dart_handle> to_unmark; std::deque<typename CMap::Dart_handle> to_unmark;
{ {
for ( CMap_dart_iterator_basic_of_cell<CMap,0> it(amap,adart1,mark1); for ( CGAL::CMap_dart_iterator_basic_of_cell<CMap,0> it(amap,adart1,mark1);
it.cont(); ++it ) it.cont(); ++it )
{ {
to_unmark.push_back(it); to_unmark.push_back(it);
@ -437,8 +464,7 @@ insert_cell_1_in_cell_2(CMap& amap,
amap.mark(it1,treated); amap.mark(it1,treated);
} }
internal::Degroup_attribute_functor_run<CMap, 2>:: CGAL::internal::Degroup_attribute_functor_run<CMap, 2>::run(&amap, d1, d2);
run(&amap, d1, d2);
amap.negate_mark(m1); amap.negate_mark(m1);
amap.negate_mark(m2); amap.negate_mark(m2);
@ -465,7 +491,9 @@ insert_cell_1_in_cell_2(CMap& amap,
CGAL_assertion( amap.is_whole_map_unmarked(mark1) ); CGAL_assertion( amap.is_whole_map_unmarked(mark1) );
amap.free_mark(mark1); amap.free_mark(mark1);
#ifdef CGAL_CMAP_TEST_VALID_INSERTIONS
CGAL_assertion( amap.is_valid() ); CGAL_assertion( amap.is_valid() );
#endif
return adart1->template beta<0>(); return adart1->template beta<0>();
} }
@ -502,7 +530,7 @@ bool is_insertable_cell_2_in_cell_3(const CMap& amap,
if ( od==CMap::null_dart_handle ) return false; if ( od==CMap::null_dart_handle ) return false;
// of and *it must belong to the same vertex of the same volume // of and *it must belong to the same vertex of the same volume
if ( !belong_to_same_cell<CMap, 0, 2>(amap, od, *it) ) if ( !CGAL::belong_to_same_cell<CMap, 0, 2>(amap, od, *it) )
return false; return false;
} }
prec = *it; prec = *it;
@ -512,7 +540,7 @@ bool is_insertable_cell_2_in_cell_3(const CMap& amap,
od = prec->other_extremity(); od = prec->other_extremity();
if ( od==CMap::null_dart_handle ) return false; if ( od==CMap::null_dart_handle ) return false;
if (!belong_to_same_cell<CMap, 0, 2>(amap, od, *afirst)) if (!CGAL::belong_to_same_cell<CMap, 0, 2>(amap, od, *afirst))
return false; return false;
return true; return true;
@ -581,7 +609,7 @@ insert_cell_2_in_cell_3(CMap& amap, InputIterator afirst, InputIterator alast)
{ {
typename CMap::Dart_handle first2 = NULL; typename CMap::Dart_handle first2 = NULL;
prec = NULL; prec = NULL;
for ( CMap_dart_iterator_of_orbit<CMap,1> it(amap, first); for ( CMap_dart_iterator_basic_of_orbit<CMap, 1> it(amap, first);
it.cont(); ++it ) it.cont(); ++it )
{ {
d = amap.create_dart(); d = amap.create_dart();
@ -643,11 +671,13 @@ insert_cell_2_in_cell_3(CMap& amap, InputIterator afirst, InputIterator alast)
if ( withBeta3 ) if ( withBeta3 )
{ // Here we cannot use Degroup_attribute_functor_run as new darts do not { // Here we cannot use Degroup_attribute_functor_run as new darts do not
// have their 3-attribute // have their 3-attribute
internal::Degroup_attribute_functor_run<CMap, 3>:: CGAL::internal::Degroup_attribute_functor_run<CMap, 3>::
run(&amap, first, first->template beta<3>()); run(&amap, first, first->template beta<3>());
} }
#ifdef CGAL_CMAP_TEST_VALID_INSERTIONS
CGAL_assertion( amap.is_valid() ); CGAL_assertion( amap.is_valid() );
#endif
return first; return first;
} }

View File

@ -25,8 +25,8 @@
#include <deque> #include <deque>
#include <stack> #include <stack>
namespace CGAL { namespace CGAL
{
/** @file Combinatorial_map_operations.h /** @file Combinatorial_map_operations.h
* Some operations to modify a combinatorial map. * Some operations to modify a combinatorial map.
*/ */
@ -48,8 +48,8 @@ namespace CGAL {
// TODO? Optimisation for dim-2, and to not test all the darts of the cell? // TODO? Optimisation for dim-2, and to not test all the darts of the cell?
bool res = true; bool res = true;
for (CMap_dart_const_iterator_of_cell<CMap,i> it(amap, adart); for ( CGAL::CMap_dart_const_iterator_of_cell<CMap,i> it(amap, adart);
res && it.cont(); ++it) res && it.cont(); ++it )
{ {
if (it->template beta<i+2>()->template beta<i+1>()!= if (it->template beta<i+2>()->template beta<i+1>()!=
it->template beta_inv<i+1>()->template beta<i+2>() ) it->template beta_inv<i+1>()->template beta<i+2>() )
@ -85,7 +85,7 @@ namespace CGAL {
const int iinv = CGAL_BETAINV(i); const int iinv = CGAL_BETAINV(i);
// First we store and mark all the darts of the i-cell to remove. // First we store and mark all the darts of the i-cell to remove.
for ( CMap_dart_iterator_basic_of_cell<CMap,i> it(amap,adart,mark); for ( CGAL::CMap_dart_iterator_basic_of_cell<CMap,i> it(amap,adart,mark);
it.cont(); ++it ) it.cont(); ++it )
{ {
to_erase.push_back(it); to_erase.push_back(it);
@ -97,29 +97,25 @@ namespace CGAL {
// We group the two (i+1)-cells incident if they exist. // We group the two (i+1)-cells incident if they exist.
if ( dg1!=NULL ) if ( dg1!=NULL )
internal::Group_attribute_functor_run<CMap, i+1>:: CGAL::internal::Group_attribute_functor_run<CMap, i+1>::
run(&amap, dg1, dg2); run(&amap, dg1, dg2);
// Second we store all the incident cells that can be split by // During the operation, we store in modified_darts the darts modified
// the operation. // to test after the loop the non void attributes that are split.
typename std::deque<typename CMap::Dart_handle>::iterator it =
to_erase.begin();
//TODO remove ? or be sure that this is required
for (; it != to_erase.end(); ++it)
amap.update_dart_of_all_attributes(*it, mark);
std::deque<typename CMap::Dart_handle> modified_darts; std::deque<typename CMap::Dart_handle> modified_darts;
std::deque<typename CMap::Dart_handle> modified_darts2;
// If i==1, we modify beta1, thus in modified_darts we store all // If i==1, we modify beta1, thus in modified_darts we store all
// the darts having beta0 modified, and in modified_darts2 all the // the darts having beta0 modified, and in modified_darts2 all the
// darts having beta1 modified. Otherwise we store all the darts in // darts having beta1 modified. For i>1 all the modified darts are
// modified_darts. // stored in modified_darts.
std::deque<typename CMap::Dart_handle> modified_darts2;
std::deque<typename CMap::Dart_handle> &first_modified_darts= std::deque<typename CMap::Dart_handle> &first_modified_darts=
(i==1?modified_darts2:modified_darts); (i==1?modified_darts2:modified_darts);
// For each dart of the i-cell, we modify i-links of neighbors. // For each dart of the i-cell, we modify i-links of neighbors.
for ( it=to_erase.begin(); it!=to_erase.end(); ++it ) typename std::deque<typename CMap::Dart_handle>::iterator it =
to_erase.begin();
for ( ; it!=to_erase.end(); ++it )
{ {
d1=(*it)->template beta<iinv>(); d1=(*it)->template beta<iinv>();
while ( d1!=CMap::null_dart_handle && amap.is_marked(d1, mark) ) while ( d1!=CMap::null_dart_handle && amap.is_marked(d1, mark) )
@ -199,12 +195,12 @@ namespace CGAL {
// void attributes. // void attributes.
if ( i==1 ) if ( i==1 )
CMap::Helper::template Foreach_enabled_attributes_except CMap::Helper::template Foreach_enabled_attributes_except
<internal::Test_split_attribute_functor<CMap,i>, i>:: <CGAL::internal::Test_split_attribute_functor<CMap,i>, i>::
run(&amap, modified_darts, modified_darts2, run(&amap, modified_darts, modified_darts2,
mark_modified_darts); mark_modified_darts);
else else
CMap::Helper::template Foreach_enabled_attributes_except CMap::Helper::template Foreach_enabled_attributes_except
<internal::Test_split_attribute_functor<CMap,i>, i>:: <CGAL::internal::Test_split_attribute_functor<CMap,i>, i>::
run(&amap, modified_darts, mark_modified_darts); run(&amap, modified_darts, mark_modified_darts);
// We remove all the darts of the i-cell. // We remove all the darts of the i-cell.
@ -214,6 +210,9 @@ namespace CGAL {
CGAL_assertion( amap.is_whole_map_unmarked(mark) ); CGAL_assertion( amap.is_whole_map_unmarked(mark) );
amap.free_mark(mark); amap.free_mark(mark);
// If no attribute is enabled (or if only i-attributes are enabled),
// the darts are not unmark by Foreach_enabled_attributes_except.
// Thus we unmark them now.
if ( !amap.is_whole_map_unmarked(mark_modified_darts) ) if ( !amap.is_whole_map_unmarked(mark_modified_darts) )
{ {
for ( typename std::deque<typename CMap::Dart_handle>:: for ( typename std::deque<typename CMap::Dart_handle>::
@ -233,8 +232,9 @@ namespace CGAL {
CGAL_assertion ( amap.is_whole_map_unmarked(mark_modified_darts) ); CGAL_assertion ( amap.is_whole_map_unmarked(mark_modified_darts) );
amap.free_mark(mark_modified_darts); amap.free_mark(mark_modified_darts);
CGAL_expensive_postcondition( amap.is_valid() ); #ifdef CGAL_CMAP_TEST_VALID_REMOVALS
assert( amap.is_valid() ); // TODO remove CGAL_assertion( amap.is_valid() );
#endif
return res; return res;
} }
@ -258,19 +258,18 @@ namespace CGAL {
std::deque<typename CMap::Dart_handle> modified_darts; std::deque<typename CMap::Dart_handle> modified_darts;
// 1) We mark all the darts of the d-cell. // We mark all the darts of the d-cell.
for (CMap_dart_iterator_basic_of_cell<CMap,CMap::dimension> for ( CGAL::CMap_dart_iterator_basic_of_cell<CMap,CMap::dimension>
it(amap,adart,mark); it.cont(); ++it) it(amap,adart,mark); it.cont(); ++it )
{ {
to_erase.push_back(it); to_erase.push_back(it);
amap.mark(it,mark); amap.mark(it,mark);
++res; ++res;
} }
// We unlink all the darts of the volume for beta-d.
typename std::deque<typename CMap::Dart_handle>::iterator typename std::deque<typename CMap::Dart_handle>::iterator
it = to_erase.begin(); it = to_erase.begin();
// 3) We unlink all the darts of the volume for beta-d.
for ( it = to_erase.begin(); it != to_erase.end(); ++it ) for ( it = to_erase.begin(); it != to_erase.end(); ++it )
{ {
if ( !(*it)->template is_free<CMap::dimension>() && if ( !(*it)->template is_free<CMap::dimension>() &&
@ -281,21 +280,22 @@ namespace CGAL {
} }
} }
// 4) We test the split of all the incident cells for all the non // We test the split of all the incident cells for all the non
// void attributes. // void attributes.
CMap::Helper::template Foreach_enabled_attributes_except CMap::Helper::template Foreach_enabled_attributes_except
<internal::Test_split_attribute_functor<CMap,i>, <CGAL::internal::Test_split_attribute_functor<CMap,i>,
CMap::dimension>::run(&amap, modified_darts); CMap::dimension>::run(&amap, modified_darts);
// 5) We remove all the darts of the d-cell. // We remove all the darts of the d-cell.
for ( it = to_erase.begin(); it != to_erase.end(); ++it ) for ( it = to_erase.begin(); it != to_erase.end(); ++it )
{ amap.erase_dart(*it); } { amap.erase_dart(*it); }
CGAL_assertion( amap.is_whole_map_unmarked(mark) ); CGAL_assertion( amap.is_whole_map_unmarked(mark) );
amap.free_mark(mark); amap.free_mark(mark);
CGAL_expensive_postcondition( amap.is_valid() ); #ifdef CGAL_CMAP_TEST_VALID_REMOVALS
assert( amap.is_valid() ); // TO REMOVE CGAL_assertion( amap.is_valid() );
#endif
return res; return res;
} }
@ -321,13 +321,9 @@ namespace CGAL {
int mark = amap.get_new_mark(); int mark = amap.get_new_mark();
// int mark_modified_darts = amap.get_new_mark(); // int mark_modified_darts = amap.get_new_mark();
std::deque<typename CMap::Dart_handle> to_erase;
std::deque<typename CMap::Dart_handle> modified_darts;
std::deque<typename CMap::Dart_handle> modified_darts2;
// First we store and mark all the darts of the 0-cell to remove. // First we store and mark all the darts of the 0-cell to remove.
for ( CMap_dart_iterator_basic_of_cell<CMap,0> it(amap,adart,mark); std::deque<typename CMap::Dart_handle> to_erase;
for ( CGAL::CMap_dart_iterator_basic_of_cell<CMap,0> it(amap,adart,mark);
it.cont(); ++it ) it.cont(); ++it )
{ {
to_erase.push_back(it); to_erase.push_back(it);
@ -337,20 +333,21 @@ namespace CGAL {
++res; ++res;
} }
// Second we store all the incident cells that can be split by
// the operation.
typename std::deque<typename CMap::Dart_handle>::iterator it =
to_erase.begin();
for (; it != to_erase.end(); ++it)
amap.update_dart_of_all_attributes(*it, mark);
// We group the two edges incident if they exist. // We group the two edges incident if they exist.
if ( dg1!=NULL ) if ( dg1!=NULL )
internal::Group_attribute_functor_run<CMap, 1>:: CGAL::internal::Group_attribute_functor_run<CMap, 1>::
run(&amap, dg1, dg2); run(&amap, dg1, dg2);
// During the operation, we store in modified_darts the darts modified
// by beta0 to test after the loop non void attributes that are split.
std::deque<typename CMap::Dart_handle> modified_darts;
// And we store in modified_darts2 all the darts having beta1 modified.
std::deque<typename CMap::Dart_handle> modified_darts2;
// For each dart of the vertex, we modify 0 and 1-links of neighbors. // For each dart of the vertex, we modify 0 and 1-links of neighbors.
for ( it=to_erase.begin(); it != to_erase.end(); ++it) typename std::deque<typename CMap::Dart_handle>::iterator it =
to_erase.begin();
for ( ; it != to_erase.end(); ++it)
{ {
if ( !(*it)->template is_free<0>() ) if ( !(*it)->template is_free<0>() )
{ {
@ -373,8 +370,6 @@ namespace CGAL {
{ {
if ( !(*it)->is_free(j) ) if ( !(*it)->is_free(j) )
{ {
// TODO push these darts in modified_darts ?
// not sure this is required
amap.basic_link_beta((*it)->template beta<0>(), amap.basic_link_beta((*it)->template beta<0>(),
(*it)->beta(j), j); (*it)->beta(j), j);
//((*it)->beta(0))->basic_link_beta((*it)->beta(j),j); //((*it)->beta(0))->basic_link_beta((*it)->beta(j),j);
@ -392,11 +387,7 @@ namespace CGAL {
for ( unsigned int j=2; j<=CMap::dimension; ++j ) for ( unsigned int j=2; j<=CMap::dimension; ++j )
{ {
if ( !(*it)->is_free(j) ) if ( !(*it)->is_free(j) )
{ { amap.unlink_beta(*it, j); }
// TODO push these darts in modified_darts ?
// not sure this is required
amap.unlink_beta(*it, j);
}
} }
} }
} }
@ -404,19 +395,19 @@ namespace CGAL {
// We test the split of all the incident cells for all the non // We test the split of all the incident cells for all the non
// void attributes. // void attributes.
CMap::Helper::template Foreach_enabled_attributes_except CMap::Helper::template Foreach_enabled_attributes_except
<internal::Test_split_attribute_functor<CMap,0>, 1>:: <CGAL::internal::Test_split_attribute_functor<CMap,0>, 1>::
run(&amap, run(&amap,modified_darts, modified_darts2);
modified_darts, modified_darts2);
// We remove all the darts of the i-cell. // We remove all the darts of the 0-cell.
for ( it=to_erase.begin(); it!=to_erase.end(); ++it ) for ( it=to_erase.begin(); it!=to_erase.end(); ++it )
{ amap.erase_dart(*it); } { amap.erase_dart(*it); }
CGAL_assertion( amap.is_whole_map_unmarked(mark) ); CGAL_assertion( amap.is_whole_map_unmarked(mark) );
amap.free_mark(mark); amap.free_mark(mark);
CGAL_expensive_postcondition( amap.is_valid() ); #ifdef CGAL_CMAP_TEST_VALID_REMOVALS
assert( amap.is_valid() ); // TO REMOVEE CGAL_assertion( amap.is_valid() );
#endif
return res; return res;
} }
@ -429,7 +420,10 @@ namespace CGAL {
*/ */
template < class CMap, unsigned int i > template < class CMap, unsigned int i >
size_t remove_cell(CMap& amap, typename CMap::Dart_handle adart) size_t remove_cell(CMap& amap, typename CMap::Dart_handle adart)
{ return Remove_cell_functor<CMap,i,CMap::dimension-i>::run(amap,adart); } {
return
CGAL::Remove_cell_functor<CMap,i,CMap::dimension-i>::run(amap,adart);
}
/** Test if an i-cell can be contracted. /** Test if an i-cell can be contracted.
* An i-cell can be contracted if i==1 * An i-cell can be contracted if i==1
@ -448,8 +442,8 @@ namespace CGAL {
// TODO ? Optimisation possible to not test all the darts of the cell ? // TODO ? Optimisation possible to not test all the darts of the cell ?
bool res = true; bool res = true;
for (CMap_dart_const_iterator_of_cell<CMap,i> it(amap, adart); for ( CGAL::CMap_dart_const_iterator_of_cell<CMap,i> it(amap, adart);
res && it.cont(); ++it) res && it.cont(); ++it )
{ {
if ( it->template beta<i-2>()->template beta<i-1>()!= if ( it->template beta<i-2>()->template beta<i-1>()!=
it->template beta<i-1>()->template beta_inv<i-2>() ) it->template beta<i-1>()->template beta_inv<i-2>() )
@ -480,12 +474,11 @@ namespace CGAL {
int mark = amap.get_new_mark(); int mark = amap.get_new_mark();
int mark_modified_darts = amap.get_new_mark(); int mark_modified_darts = amap.get_new_mark();
std::deque<typename CMap::Dart_handle> to_erase;
const int imuinv = CGAL_BETAINV(i-1); const int imuinv = CGAL_BETAINV(i-1);
// First we store and mark all the darts of the i-cell to contract. // First we store and mark all the darts of the i-cell to contract.
for ( CMap_dart_iterator_basic_of_cell<CMap,i> it(amap,adart,mark); std::deque<typename CMap::Dart_handle> to_erase;
for ( CGAL::CMap_dart_iterator_basic_of_cell<CMap,i> it(amap,adart,mark);
it.cont(); ++it ) it.cont(); ++it )
{ {
to_erase.push_back(it); to_erase.push_back(it);
@ -497,19 +490,17 @@ namespace CGAL {
// We group the two (i+1)-cells incident if they exist. // We group the two (i+1)-cells incident if they exist.
if ( dg1!=NULL ) if ( dg1!=NULL )
internal::Group_attribute_functor_run<CMap,i-1>:: CGAL::internal::Group_attribute_functor_run<CMap,i-1>::
run(&amap, dg1, dg2); run(&amap, dg1, dg2);
// Second we update the dart of the cell attributes on non marked darts. // During the operation, we store in modified_darts the darts modified
typename std::deque<typename CMap::Dart_handle>::iterator it = // to test after the loop the non void attributes that are split.
to_erase.begin();
for (; it != to_erase.end(); ++it)
amap.update_dart_of_all_attributes(*it, mark);
std::deque<typename CMap::Dart_handle> modified_darts; std::deque<typename CMap::Dart_handle> modified_darts;
// For each dart of the i-cell, we modify i-links of neighbors. // For each dart of the i-cell, we modify i-links of neighbors.
for ( it=to_erase.begin(); it!=to_erase.end(); ++it ) typename std::deque<typename CMap::Dart_handle>::iterator it =
to_erase.begin();
for ( ; it!=to_erase.end(); ++it )
{ {
d1 = (*it)->template beta<i>(); d1 = (*it)->template beta<i>();
while ( d1!=CMap::null_dart_handle && amap.is_marked(d1, mark) ) while ( d1!=CMap::null_dart_handle && amap.is_marked(d1, mark) )
@ -580,7 +571,7 @@ namespace CGAL {
// We test the split of all the incident cells for all the non // We test the split of all the incident cells for all the non
// void attributes. // void attributes.
CMap::Helper::template Foreach_enabled_attributes_except CMap::Helper::template Foreach_enabled_attributes_except
<internal::Test_split_attribute_functor<CMap,i>, i>:: <CGAL::internal::Test_split_attribute_functor<CMap,i>, i>::
run(&amap, modified_darts, mark_modified_darts); run(&amap, modified_darts, mark_modified_darts);
// We remove all the darts of the i-cell. // We remove all the darts of the i-cell.
@ -590,6 +581,9 @@ namespace CGAL {
CGAL_assertion( amap.is_whole_map_unmarked(mark) ); CGAL_assertion( amap.is_whole_map_unmarked(mark) );
amap.free_mark(mark); amap.free_mark(mark);
// If no attribute is enabled (or if only i-attributes are enabled),
// the darts are not unmark by Foreach_enabled_attributes_except.
// Thus we unmark them now.
if ( !amap.is_whole_map_unmarked(mark_modified_darts) ) if ( !amap.is_whole_map_unmarked(mark_modified_darts) )
{ {
for ( typename std::deque<typename CMap::Dart_handle>:: for ( typename std::deque<typename CMap::Dart_handle>::
@ -598,13 +592,12 @@ namespace CGAL {
amap.unmark(*it, mark_modified_darts); amap.unmark(*it, mark_modified_darts);
} }
// amap.display_darts(std::cout);
CGAL_assertion ( amap.is_whole_map_unmarked(mark_modified_darts) ); CGAL_assertion ( amap.is_whole_map_unmarked(mark_modified_darts) );
amap.free_mark(mark_modified_darts); amap.free_mark(mark_modified_darts);
CGAL_expensive_postcondition( amap.is_valid() ); #ifdef CGAL_CMAP_TEST_VALID_CONTRACTIONS
assert( amap.is_valid() ); CGAL_assertion( amap.is_valid() );
#endif
return res; return res;
} }
@ -630,13 +623,9 @@ namespace CGAL {
int mark = amap.get_new_mark(); int mark = amap.get_new_mark();
// int mark_modified_darts = amap.get_new_mark(); // int mark_modified_darts = amap.get_new_mark();
std::deque<typename CMap::Dart_handle> to_erase;
std::deque<typename CMap::Dart_handle> modified_darts;
std::deque<typename CMap::Dart_handle> modified_darts2;
// First we store and mark all the darts of the 1-cell to contract. // First we store and mark all the darts of the 1-cell to contract.
for ( CMap_dart_iterator_basic_of_cell<CMap,1> it(amap,adart,mark); std::deque<typename CMap::Dart_handle> to_erase;
for ( CGAL::CMap_dart_iterator_basic_of_cell<CMap,1> it(amap,adart,mark);
it.cont(); ++it ) it.cont(); ++it )
{ {
to_erase.push_back(it); to_erase.push_back(it);
@ -647,19 +636,21 @@ namespace CGAL {
++res; ++res;
} }
typename std::deque<typename CMap::Dart_handle>::iterator it =
to_erase.begin();
for (; it != to_erase.end(); ++it)
amap.update_dart_of_all_attributes(*it, mark);
// We group the two vertices incident if they exist. // We group the two vertices incident if they exist.
if ( dg1!=NULL ) if ( dg1!=NULL )
internal::Group_attribute_functor_run<CMap, 0, 1>:: CGAL::internal::Group_attribute_functor_run<CMap, 0, 1>::
run(&amap, dg1, dg2); run(&amap, dg1, dg2);
// 4) For each dart of the cell, we modify link of neighbors. // During the operation, we store in modified_darts the darts modified
for ( it=to_erase.begin(); it!=to_erase.end(); ++it ) // by beta0 to test after the loop non void attributes that are split.
std::deque<typename CMap::Dart_handle> modified_darts;
// And we store in modified_darts2 all the darts having beta1 modified.
std::deque<typename CMap::Dart_handle> modified_darts2;
// For each dart of the cell, we modify link of neighbors.
typename std::deque<typename CMap::Dart_handle>::iterator it =
to_erase.begin();
for ( ; it!=to_erase.end(); ++it )
{ {
if ( !(*it)->template is_free<0>() ) if ( !(*it)->template is_free<0>() )
{ {
@ -676,7 +667,6 @@ namespace CGAL {
} }
else else
{ {
// TODO todegroup.push(Dart_pair((*it)->beta(0), *it));
modified_darts2.push_back((*it)->template beta<0>()); modified_darts2.push_back((*it)->template beta<0>());
(*it)->template beta<0>()->template unlink_beta<1>(); (*it)->template beta<0>()->template unlink_beta<1>();
} }
@ -685,28 +675,28 @@ namespace CGAL {
{ {
if ( !(*it)->template is_free<1>() ) if ( !(*it)->template is_free<1>() )
{ {
// TODO todegroup.push(Dart_pair((*it)->beta(1), *it));
modified_darts.push_back((*it)->template beta<1>()); modified_darts.push_back((*it)->template beta<1>());
(*it)->template beta<1>()->template unlink_beta<0>(); (*it)->template beta<1>()->template unlink_beta<0>();
} }
} }
} }
// We test the split of all the incident cells for all the non // We remove all the darts of the cell.
// void attributes. for ( it=to_erase.begin(); it!=to_erase.end(); ++it )
CMap::Helper::template Foreach_enabled_attributes_except
<internal::Test_split_attribute_functor<CMap,1>, 1>::
run(&amap, modified_darts, modified_darts2);
// 6) We remove all the darts of the cell.
for (it = to_erase.begin(); it != to_erase.end(); ++it)
{ amap.erase_dart(*it); } { amap.erase_dart(*it); }
CGAL_assertion( amap.is_whole_map_unmarked(mark) ); CGAL_assertion( amap.is_whole_map_unmarked(mark) );
amap.free_mark(mark); amap.free_mark(mark);
CGAL_expensive_postcondition( amap.is_valid() ); // We test the split of all the incident cells for all the non
assert( amap.is_valid() ); // TO REMOVE // void attributes.
CMap::Helper::template Foreach_enabled_attributes_except
<CGAL::internal::Test_split_attribute_functor<CMap,1>, 1>::
run(&amap, modified_darts, modified_darts2);
#ifdef CGAL_CMAP_TEST_VALID_CONTRACTIONS
CGAL_assertion( amap.is_valid() );
#endif
return res; return res;
} }
@ -719,7 +709,7 @@ namespace CGAL {
*/ */
template < class CMap, unsigned int i > template < class CMap, unsigned int i >
size_t contract_cell(CMap& amap, typename CMap::Dart_handle adart) size_t contract_cell(CMap& amap, typename CMap::Dart_handle adart)
{ return Contract_cell_functor<CMap,i>::run(amap,adart); } { return CGAL::Contract_cell_functor<CMap,i>::run(amap,adart); }
} // namespace CGAL } // namespace CGAL

View File

@ -0,0 +1,390 @@
// Copyright (c) 2010-2011 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_INTERNAL_FUNCTORS_H
#define CGAL_COMBINATORIAL_MAP_INTERNAL_FUNCTORS_H
#include <CGAL/Dart_const_iterators.h>
#include <CGAL/Combinatorial_map_basic_operations.h>
#include <vector>
/* Definition of functors used internally to manage attributes (we need
* functors as attributes are stored in tuple, thus all the access must be
* done at compiling time). Some of these functors are used with
* Foreach_enabled_attributes to iterate through all the non void attribs.
* Functors allowing to group/ungroup attributes are defined in
* internal/Combinatorial_map_group_functors.h. Public functions are defined
* in Combinatorial_map_functors.h.
*
* internal::Call_split_functor<CMap,i> to call the OnSplit functors on two
* given i-attributes.
*
* internal::Call_merge_functor<CMap,i> to call the OnMerge functors on two
* given i-attributes.
*
* internal::Test_is_valid_attribute_functor<CMap> to test if a given i-cell is
* valid (all its darts are linked to the same attribute, no other dart is
* linked with this attribute).
*
* internal::Count_cell_functor<CMap> to count the nuber of i-cells.
*
* internal::Count_bytes_one_attribute_functor<CMap> to count the memory
* occupied by i-attributes.
*
* internal::Decrease_attribute_functor<CMap> to decrease by one the ref
* counting of a given i-attribute.
*
* internal::Beta_functor<Dart, i...> to call several beta on the given dart.
* Indices are given as parameter of the run function.
*
* internal::Beta_functor_static<Dart, i...> to call several beta on the given
* dart. Indices are given as template arguments.
*
* internal::Set_i_attribute_of_dart_functor<CMap, i> to set the i-attribute
* of a given dart.
*/
namespace CGAL
{
// ****************************************************************************
namespace internal
{
// Functor which call Functor::operator() on the two given cell_attributes
template<typename Cell_attribute, typename Functor>
struct Apply_cell_functor
{
static void run(Cell_attribute& acell1, Cell_attribute& acell2)
{
Functor() (acell1,acell2);
}
};
//...except for Null_functor.
template<typename Cell_attribute>
struct Apply_cell_functor<Cell_attribute,Null_functor>
{
static void run(Cell_attribute&, Cell_attribute&)
{}
};
// ****************************************************************************
// Functor used to call the On_split functor between the two given darts.
template<typename CMap, unsigned int i,
typename Enabled=typename CMap::
#ifndef CGAL_CFG_TEMPLATE_IN_DEFAULT_PARAMETER_BUG
template
#endif
Attribute_type<i>::type>
struct Call_split_functor
{
static void run(typename CMap::Dart_handle adart1,
typename CMap::Dart_handle adart2)
{
CGAL::internal::Apply_cell_functor
<typename CMap::template Attribute_type<i>::type,
typename CMap::template Attribute_type<i>::type::On_split>::
run(*(adart1->template attribute<i>()),
*(adart2->template attribute<i>()));
}
static void
run(typename CMap::template Attribute_handle<i>::type a1,
typename CMap::template Attribute_handle<i>::type a2)
{
CGAL::internal::Apply_cell_functor
<typename CMap::template Attribute_type<i>::type,
typename CMap::template Attribute_type<i>::type::On_split>::
run(*a1, *a2);
}
};
// Specialization for disabled attributes.
template<typename CMap,unsigned int i>
struct Call_split_functor<CMap, i, CGAL::Void>
{
static void run(typename CMap::Dart_handle,
typename CMap::Dart_handle)
{}
};
// ****************************************************************************
// Functor used to call the On_merge functor between the two given darts.
template<typename CMap,unsigned int i,
typename Enabled=typename CMap::
#ifndef CGAL_CFG_TEMPLATE_IN_DEFAULT_PARAMETER_BUG
template
#endif
Attribute_type<i>::type>
struct Call_merge_functor
{
static void run(typename CMap::Dart_handle adart1,
typename CMap::Dart_handle adart2)
{
CGAL::internal::Apply_cell_functor
<typename CMap::template Attribute_type<i>::type,
typename CMap::template Attribute_type<i>::type::On_merge>::
run(*(adart1->template attribute<i>()),
*(adart2->template attribute<i>()));
}
static void
run(typename CMap::template Attribute_handle<i>::type a1,
typename CMap::template Attribute_handle<i>::type a2)
{
CGAL::internal::Apply_cell_functor
<typename CMap::template Attribute_type<i>::type,
typename CMap::template Attribute_type<i>::type::On_merge>::
run(*a1, *a2);
}
};
// Specialization for disabled attributes.
template<typename CMap,unsigned int i>
struct Call_merge_functor<CMap, i, CGAL::Void>
{
static void run(typename CMap::Dart_handle,
typename CMap::Dart_handle)
{}
};
// ****************************************************************************
/// Functor used to test if a cell is valid
template<typename CMap>
struct Test_is_valid_attribute_functor
{
/** Test the validity of a i-cell-attribute.
* ie all the darts belonging to a i-cell are linked to the same attribute.
* @param adart a dart.
* @param amark a mark used to mark darts of the i-cell.
* @return true iff all the darts of the i-cell link to the same attribute.
*/
template <unsigned int i>
static void run(const CMap* amap,
typename CMap::Dart_const_handle adart,
std::vector<int>* marks, bool *ares)
{
CGAL_static_assertion_msg(CMap::Helper::template
Dimension_index<i>::value>=0,
"Test_is_valid_attribute_functor<i> but "
" i-attributes are disabled");
int amark = (*marks)[i];
if ( amap->is_marked(adart, amark) ) return; // dart already test.
bool valid = true;
bool found_dart = false;
typename CMap::template Attribute_const_handle<i>::type
a=adart->template attribute<i>();
unsigned int nb = 0;
for ( CGAL::CMap_dart_const_iterator_basic_of_cell<CMap,i>
it(*amap, adart, amark); it.cont(); ++it )
{
if ( it->template attribute<i>() != a )
{
std::cout<<"ERROR: an attribute of the "<<i<<"-cell is different. cur:"
<<&*a<<" != first:"<<&*it->template attribute<i>()
<<" for dart "<<&*it<<std::endl;
valid=false;
}
if ( a!=NULL && it==a->dart() ) found_dart=true;
amap->mark(it, amark);
++nb;
}
if ( a!=NULL )
{
if ( a->get_nb_refs()!=nb )
{
std::cout<<"ERROR: the number of reference of an "<<i
<<"-attribute is not correct. Count: "<<nb
<<" != Store in the attribute: "<<a->get_nb_refs()<<" for dart "
<<&*adart<<std::endl;
valid=false;
}
if ( !a->is_valid() )
{
std::cout<<"ERROR: the dart associated with an "<<i
<<"-attribute is NULL for dart "
<<&*adart<<std::endl;
valid=false;
}
if ( a->dart()!=NULL && !found_dart )
{
std::cout<<"ERROR: the non NULL dart of an "<<i
<<"-attribute does not belong to the cell. a->dart()= "
<<&*a->dart()<<" for dart "<<&*adart<<std::endl;
valid=false;
}
}
if ( !valid ) (*ares)=false;
}
};
// ****************************************************************************
/// Functor for counting i-cell
template<typename CMap>
struct Count_cell_functor
{
template <unsigned int i>
static void run( const CMap* amap,
typename CMap::Dart_const_handle adart,
std::vector<int>* amarks,
std::vector<unsigned int>* ares )
{
if ( (*amarks)[i]!=-1 && !amap->is_marked(adart, (*amarks)[i]) )
{
++ (*ares)[i];
CGAL::mark_cell<CMap,i>(*amap, adart, (*amarks)[i]);
}
}
};
// ****************************************************************************
/// Functor for counting the memory occupation of attributes
/// Be careful not reentrant !!! TODO a Foreach_enabled_attributes
/// taking an instance of a functor as argument allowing to compute
/// and return values.
template<typename CMap>
struct Count_bytes_one_attribute_functor
{
template <unsigned int i>
static void run( const CMap* amap )
{
res += amap->template attributes<i>().capacity()*
sizeof(typename CMap::template Attribute_type<i>::type);
}
static typename CMap::size_type res;
};
template<typename CMap>
typename CMap::size_type Count_bytes_one_attribute_functor<CMap>::res = 0;
template<typename CMap>
struct Count_bytes_all_attributes_functor
{
static typename CMap::size_type run( const CMap& amap )
{
CGAL::internal::Count_bytes_one_attribute_functor<CMap>::res = 0;
CMap::Helper::template Foreach_enabled_attributes
<CGAL::internal::Count_bytes_one_attribute_functor<CMap> >::run(&amap);
return CGAL::internal::Count_bytes_one_attribute_functor<CMap>::res;
}
};
// ****************************************************************************
/// Decrease the cell attribute reference counting of the given dart.
/// The attribute is removed if there is no more darts linked with it.
template<typename CMap, unsigned int i, typename T=
typename CMap::template Attribute_type<i>::type>
struct Decrease_attribute_functor_run
{
static void run(CMap* amap, typename CMap::Dart_handle adart)
{
if ( adart->template attribute<i>()!=NULL )
{
adart->template attribute<i>()->dec_nb_refs();
if ( adart->template attribute<i>()->get_nb_refs()==0 )
amap->template erase_attribute<i>(adart->template attribute<i>());
}
}
};
/// Specialization for void attributes.
template<typename CMap, unsigned int i>
struct Decrease_attribute_functor_run<CMap, i, CGAL::Void>
{
static void run(CMap*, typename CMap::Dart_handle)
{}
};
// ****************************************************************************
/// Functor used to call decrease_attribute_ref_counting<i>
/// on each i-cell attribute enabled
template<typename CMap>
struct Decrease_attribute_functor
{
template <unsigned int i>
static void run(CMap* amap, typename CMap::Dart_handle adart)
{ CGAL::internal::Decrease_attribute_functor_run<CMap,i>::run(amap, adart); }
};
// ****************************************************************************
/// Functor used to set the i-attribute of a given dart.
template<typename CMap, unsigned int i, typename T=
typename CMap::template Attribute_type<i>::type>
struct Set_i_attribute_of_dart_functor
{
static void run( CMap* amap, typename CMap::Dart_handle dh,
typename CMap::template Attribute_handle<i>::type ah )
{
CGAL_static_assertion(i<=CMap::dimension);
CGAL_assertion( dh!=NULL && dh!=CMap::null_dart_handle );
if ( dh->template attribute<i>()==ah ) return;
CGAL::internal::Decrease_attribute_functor_run<CMap, i>::run(amap, dh);
dh->template set_attribute<i>(ah);
if ( ah!=NULL ) ah->set_dart(dh);
}
};
/// Specialization for void attributes.
template<typename CMap, unsigned int i>
struct Set_i_attribute_of_dart_functor<CMap, i, CGAL::Void>
{
static void run( CMap*, typename CMap::Dart_handle,
typename CMap::template Attribute_handle<i>::type)
{}
};
// ****************************************************************************
// Beta functor, used to combine several beta.
#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
template<typename Dart_handle, typename ... Betas>
struct Beta_functor;
template<typename Dart_handle, typename ... Betas>
struct Beta_functor<Dart_handle, int, Betas...>
{
static Dart_handle run(Dart_handle ADart, int B, Betas... betas)
{ return Beta_functor<Dart_handle, Betas...>::run(ADart->beta(B),
betas...); }
};
template<typename Dart_handle>
struct Beta_functor<Dart_handle, int>
{
static Dart_handle run(Dart_handle ADart, int B)
{
CGAL_assertion( ADart!=NULL );
return ADart->beta(B);
}
};
// ****************************************************************************
template<typename Dart_handle, int ... Betas>
struct Beta_functor_static;
template<typename Dart_handle, int B, int ... Betas>
struct Beta_functor_static<Dart_handle, B, Betas...>
{
static Dart_handle run(Dart_handle ADart)
{ return Beta_functor_static<Dart_handle, Betas...>::
run(ADart->template beta<B>()); }
};
template<typename Dart_handle, int B>
struct Beta_functor_static<Dart_handle, B>
{
static Dart_handle run(Dart_handle ADart)
{
CGAL_assertion( ADart!=NULL );
return ADart->template beta<B>();
}
};
#endif //CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
// ****************************************************************************
} // namespace internal
} // namespace CGAL
#endif // CGAL_COMBINATORIAL_MAP_INTERNAL_FUNCTORS_H

View File

@ -49,8 +49,8 @@ struct Is_sewable_functor
// TODO use a map (of hashtable) to build the isomorphism and to test // TODO use a map (of hashtable) to build the isomorphism and to test
// it during the while loop // it during the while loop
CMap_dart_const_iterator_of_involution<CMap,i> I1(*amap, adart1); CGAL::CMap_dart_const_iterator_of_involution<CMap,i> I1(*amap, adart1);
CMap_dart_const_iterator_of_involution_inv<CMap,i> I2(*amap, adart2); CGAL::CMap_dart_const_iterator_of_involution_inv<CMap,i> I2(*amap, adart2);
bool res = true; bool res = true;
while (res && I1.cont() && I2.cont()) while (res && I1.cont() && I2.cont())
{ {
@ -102,8 +102,8 @@ struct Is_sewable_functor<CMap, 0, dim>
// TODO use a map (of hashtable) to build the isomorphism and to test // TODO use a map (of hashtable) to build the isomorphism and to test
// it during the while loop // it during the while loop
CMap_dart_const_iterator_of_involution <CMap,1> I1(*amap, adart1); CGAL::CMap_dart_const_iterator_of_involution <CMap,1> I1(*amap, adart1);
CMap_dart_const_iterator_of_involution_inv<CMap,1> I2(*amap, adart2); CGAL::CMap_dart_const_iterator_of_involution_inv<CMap,1> I2(*amap, adart2);
bool res = true; bool res = true;
while (res && I1.cont() && I2.cont()) while (res && I1.cont() && I2.cont())
{ {
@ -324,8 +324,8 @@ struct Is_sewable_functor<CMap, 3, 3>
!adart2->template is_free<3>() ) !adart2->template is_free<3>() )
return false; return false;
CMap_dart_const_iterator_basic_of_orbit<CMap,1> I1(*amap, adart1); CGAL::CMap_dart_const_iterator_basic_of_orbit<CMap,1> I1(*amap, adart1);
CMap_dart_const_iterator_basic_of_orbit<CMap,0> I2(*amap, adart2); CGAL::CMap_dart_const_iterator_basic_of_orbit<CMap,0> I2(*amap, adart2);
bool res=true; bool res=true;
while (res && I1.cont() && I2.cont()) while (res && I1.cont() && I2.cont())
{ {

View File

@ -11,11 +11,20 @@ else()
cmake_policy(VERSION 2.6) cmake_policy(VERSION 2.6)
endif() endif()
## To add expensive tests
# add_definitions("-DCGAL_CHECK_EXPENSIVE") # add_definitions("-DCGAL_CHECK_EXPENSIVE")
# For profilling with gprof ## For profilling with gprof
add_definitions("-pg") # add_definitions("-pg")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg") # SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg")
## To add an is_valid test after each operation (only in debug mode)
add_definitions("-DCGAL_CMAP_TEST_VALID_REMOVALS")
add_definitions("-DCGAL_CMAP_TEST_VALID_CONTRACTIONS")
#add_definitions("-DCGAL_CMAP_TEST_VALID_INSERTIONS")
# Option allowing to profile each operation of the demo (cout times on stdout).
add_definitions(-DCGAL_PROFILE_LCC_DEMO)
################## ##################
find_package(CGAL COMPONENTS Qt4) find_package(CGAL COMPONENTS Qt4)
@ -42,9 +51,6 @@ include(${QT_USE_FILE})
include_directories(${QGLVIEWER_INCLUDE_DIR}) include_directories(${QGLVIEWER_INCLUDE_DIR})
include_directories(BEFORE . ../../include/) include_directories(BEFORE . ../../include/)
# Option allowing to profile each operation of the demo.
add_definitions(-DCGAL_PROFILE_LCC_DEMO)
# ui file, created wih Qt Designer # ui file, created wih Qt Designer
qt4_wrap_ui(uis MainWindow.ui CreateMesh.ui CreateMenger.ui) qt4_wrap_ui(uis MainWindow.ui CreateMesh.ui CreateMenger.ui)

View File

@ -18,6 +18,7 @@
// Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr> // Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
// Jérémy Girerd-Rey <jeremy.girerd-rey@etu.univ-lyon1.fr> // Jérémy Girerd-Rey <jeremy.girerd-rey@etu.univ-lyon1.fr>
// //
#include "typedefs.h" #include "typedefs.h"
// Smooth a vertex depending on the vertices of its incidents facets. // Smooth a vertex depending on the vertices of its incidents facets.
@ -283,8 +284,7 @@ subdivide_lcc_pqq (LCC & m)
CGAL::remove_cell<LCC, 1>(m, *dit); CGAL::remove_cell<LCC, 1>(m, *dit);
} }
remove.resize(0); remove.resize(0);
CGAL_assertion( m.is_valid() ); // CGAL_assertion( m.is_valid() );
} }
} }

View File

@ -70,16 +70,15 @@ namespace CGAL {
typedef typename Base::Dart_range Dart_range; typedef typename Base::Dart_range Dart_range;
typedef typename Helper::template Attribute_type<0>::type typedef typename Base::template Attribute_type<0>::type Vertex_attribute;
Vertex_attribute; typedef typename Base::template Attribute_handle<0>::type
typedef typename Helper::template Attribute_handle<0>::type
Vertex_attribute_handle; Vertex_attribute_handle;
typedef typename Helper::template Attribute_const_handle<0>::type typedef typename Base::template Attribute_const_handle<0>::type
Vertex_attribute_const_handle; Vertex_attribute_const_handle;
typedef typename Helper::template Attribute_range<0>::type typedef typename Base::template Attribute_range<0>::type
Vertex_attribute_range; Vertex_attribute_range;
typedef typename Helper::template Attribute_const_range<0>::type typedef typename Base::template Attribute_const_range<0>::type
Vertex_attribute_const_range; Vertex_attribute_const_range;
/// To use previous definition of create_dart methods. /// To use previous definition of create_dart methods.
@ -89,7 +88,7 @@ namespace CGAL {
* @return an handle on the new attribute. * @return an handle on the new attribute.
*/ */
#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES #ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
template<typename... Args> template<typename ...Args>
Vertex_attribute_handle create_vertex_attribute(const Args&... args) Vertex_attribute_handle create_vertex_attribute(const Args&... args)
{ return Base::template create_attribute<0>(args...); } { return Base::template create_attribute<0>(args...); }
#else #else
@ -184,7 +183,7 @@ namespace CGAL {
void set_vertex_attribute_of_dart(Dart_handle adart, void set_vertex_attribute_of_dart(Dart_handle adart,
Vertex_attribute_handle ah) Vertex_attribute_handle ah)
{ {
return internal::Set_i_attribute_of_dart_functor<Self, 0>:: return CGAL::internal::Set_i_attribute_of_dart_functor<Self, 0>::
run(this, adart,ah); run(this, adart,ah);
} }
@ -194,7 +193,7 @@ namespace CGAL {
*/ */
void set_vertex_attribute(Dart_handle adart, void set_vertex_attribute(Dart_handle adart,
Vertex_attribute_handle ah) Vertex_attribute_handle ah)
{ return Set_i_attribute_functor<Self, 0>::run(this, adart,ah); } { return CGAL::Set_i_attribute_functor<Self, 0>::run(this, adart,ah); }
/// @return the Vertex_attribute_range for all vertex_attributes. /// @return the Vertex_attribute_range for all vertex_attributes.
Vertex_attribute_range& vertex_attributes() Vertex_attribute_range& vertex_attributes()
@ -614,8 +613,8 @@ namespace CGAL {
unsigned int nb = 1; unsigned int nb = 1;
// TODO: test if we can optimize by using <Self,0,i,i+1> ? // TODO: test if we can optimize by using <Self,0,i,i+1> ?
CMap_one_dart_per_incident_cell_const_iterator<Self,0,i> it(*this, CGAL::CMap_one_dart_per_incident_cell_const_iterator<Self,0,i>
adart); it(*this, adart);
for ( ++it; it.cont(); ++it) for ( ++it; it.cont(); ++it)
{ {
vec = typename Traits::Construct_sum_of_vectors() vec = typename Traits::Construct_sum_of_vectors()
@ -675,7 +674,8 @@ namespace CGAL {
* @param p the coordinates of the new vertex. * @param p the coordinates of the new vertex.
* @return a dart of the new edge, incident to the new vertex. * @return a dart of the new edge, incident to the new vertex.
*/ */
Dart_handle insert_dangling_cell_1_in_cell_2(Dart_handle dh, const Point& p) Dart_handle insert_dangling_cell_1_in_cell_2(Dart_handle dh,
const Point& p)
{ {
return CGAL::insert_dangling_cell_1_in_cell_2 return CGAL::insert_dangling_cell_1_in_cell_2
(*this, dh, create_vertex_attribute(p)); (*this, dh, create_vertex_attribute(p));