mirror of https://github.com/CGAL/cgal
2992 lines
118 KiB
C++
2992 lines
118 KiB
C++
// 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_H
|
|
#define CGAL_COMBINATORIAL_MAP_H 1
|
|
|
|
#include <CGAL/Compact_container.h>
|
|
#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_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 <bitset>
|
|
#include <vector>
|
|
#include <deque>
|
|
|
|
#include <boost/type_traits/is_same.hpp>
|
|
|
|
// suppress bogus warning when compiling with gcc 4.3 or 4.4
|
|
#if (__GNUC__ == 4 && (__GNUC_MINOR__ == 3 || __GNUC_MINOR__ == 4))
|
|
#pragma GCC diagnostic ignored "-Warray-bounds"
|
|
#endif
|
|
|
|
namespace CGAL {
|
|
|
|
/** @file Combinatorial_map.h
|
|
* Definition of generic dD Combinatorial map.
|
|
*/
|
|
|
|
/** Generic definition of combinatorial map in dD.
|
|
* The Combinatorial_map class describes an dD combinatorial map. It allows
|
|
* mainly to create darts, to use marks onto these darts, to get and set
|
|
* the beta links, and to manage enabled attributes.
|
|
*/
|
|
template < unsigned int d_, class Refs,
|
|
class Items_=Combinatorial_map_min_items<d_>,
|
|
class Alloc_=CGAL_ALLOCATOR(int) >
|
|
class Combinatorial_map_base
|
|
{
|
|
public:
|
|
/// Types definition
|
|
typedef Combinatorial_map_base<d_, Refs, Items_,Alloc_> Self;
|
|
|
|
typedef Items_ Items;
|
|
typedef Alloc_ Alloc;
|
|
|
|
typedef typename Items::template Dart_wrapper<Refs> Dart_wrapper;
|
|
typedef typename Dart_wrapper::Dart Dart;
|
|
|
|
typedef typename Alloc::template rebind<Dart>::other Dart_allocator;
|
|
typedef Compact_container<Dart,Dart_allocator> Dart_container;
|
|
|
|
typedef typename Dart_container::iterator Dart_handle;
|
|
typedef typename Dart_container::const_iterator Dart_const_handle;
|
|
typedef typename Dart_container::size_type size_type;
|
|
|
|
/// The dimension of the combinatorial map.
|
|
static const unsigned int dimension = d_;
|
|
|
|
/// Number of marks
|
|
static const size_type NB_MARKS = 32;
|
|
|
|
typedef internal::Combinatorial_map_helper<Self> Helper;
|
|
|
|
/// Typedef for Dart_range, a range through all the darts of the map.
|
|
typedef Dart_container Dart_range;
|
|
typedef const Dart_container Dart_const_range;
|
|
|
|
typedef typename Dart_wrapper::Attributes Attributes;
|
|
|
|
/// Typedef for attributes
|
|
template<int i>
|
|
struct Attribute_type: public Helper::template Attribute_type<i>
|
|
{};
|
|
template<int i>
|
|
struct Attribute_handle: public Helper::template Attribute_handle<i>
|
|
{};
|
|
template<int i>
|
|
struct Attribute_const_handle:
|
|
public Helper::template Attribute_const_handle<i>
|
|
{};
|
|
template<int i>
|
|
struct Attribute_range: public Helper::template Attribute_range<i>
|
|
{};
|
|
template<int i>
|
|
struct Attribute_const_range:
|
|
public Helper::template Attribute_const_range<i>
|
|
{};
|
|
|
|
public:
|
|
/** Default Combinatorial_map constructor.
|
|
* The map is empty.
|
|
*/
|
|
Combinatorial_map_base()
|
|
{
|
|
CGAL_static_assertion_msg(Dart::dimension==dimension,
|
|
"Dimension of dart different from dimension of map");
|
|
|
|
CGAL_static_assertion_msg(Helper::nb_attribs<=dimension+1,
|
|
"Too many attributes in the tuple Attributes_enabled");
|
|
|
|
this->mnb_used_marks = 0;
|
|
this->mmask_marks.reset();
|
|
|
|
for ( size_type i = 0; i < NB_MARKS; ++i)
|
|
{
|
|
this->mfree_marks_stack[i] = (int)i;
|
|
this->mindex_marks[i] = i;
|
|
this->mnb_marked_darts[i] = 0;
|
|
this->mnb_times_reserved_marks[i] = 0;
|
|
}
|
|
|
|
// 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( std::bitset<NB_MARKS>() );
|
|
|
|
for ( unsigned int i=0; i<=dimension; ++i)
|
|
{
|
|
null_dart_handle->unlink_beta(i);
|
|
}
|
|
}
|
|
|
|
CGAL_assertion(number_of_darts()==0);
|
|
}
|
|
|
|
/** Clear the combinatorial map. Remove all darts and all attributes.
|
|
* Note that reserved marks are not free.
|
|
*/
|
|
void clear()
|
|
{
|
|
mdarts.clear();
|
|
for ( unsigned int i = 0; i < NB_MARKS; ++i)
|
|
this->mnb_marked_darts[i] = 0;
|
|
|
|
internal::Clear_all::run(mattribute_containers);
|
|
}
|
|
|
|
/** Test if the map is empty.
|
|
* @return true iff the map is empty.
|
|
*/
|
|
bool is_empty() const
|
|
{ return mdarts.empty(); }
|
|
|
|
/** Create a new dart and add it to the map.
|
|
* The marks of the darts are initialised with mmask_marks, i.e. the dart
|
|
* is unmarked for all the marks.
|
|
* @return a Dart_handle on the new dart.
|
|
*/
|
|
#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
|
|
template < typename... Args >
|
|
Dart_handle create_dart(const Args&... args)
|
|
{ return mdarts.emplace(mmask_marks, args...); }
|
|
#else
|
|
Dart_handle create_dart()
|
|
{ return mdarts.emplace(mmask_marks); }
|
|
template < typename T1 >
|
|
Dart_handle create_dart(const T1 &t1)
|
|
{ return mdarts.emplace(mmask_marks, t1); }
|
|
template < typename T1, typename T2 >
|
|
Dart_handle create_dart(const T1 &t1, const T2 &t2)
|
|
{ return mdarts.emplace(mmask_marks, t1, t2); }
|
|
template < typename T1, typename T2, typename T3 >
|
|
Dart_handle create_dart(const T1 &t1, const T2 &t2, const T3 &t3)
|
|
{ return mdarts.emplace(mmask_marks, t1, t2, t3); }
|
|
template < typename T1, typename T2, typename T3, typename T4 >
|
|
Dart_handle create_dart(const T1 &t1, const T2 &t2, const T3 &t3,
|
|
const T4 &t4)
|
|
{ return mdarts.emplace(mmask_marks, t1, t2, t3, t4); }
|
|
template < typename T1, typename T2, typename T3, typename T4, typename T5 >
|
|
Dart_handle create_dart(const T1 &t1, const T2 &t2, const T3 &t3,
|
|
const T4 &t4, const T5 &t5)
|
|
{ return mdarts.emplace(mmask_marks, t1, t2, t3, t4, t5); }
|
|
template < typename T1, typename T2, typename T3, typename T4, typename T5,
|
|
typename T6 >
|
|
Dart_handle create_dart(const T1 &t1, const T2 &t2, const T3 &t3,
|
|
const T4 &t4, const T5 &t5, const T6 &t6)
|
|
{ return mdarts.emplace(mmask_marks, t1, t2, t3, t4, t5, t6); }
|
|
template < typename T1, typename T2, typename T3, typename T4, typename T5,
|
|
typename T6, typename T7 >
|
|
Dart_handle create_dart(const T1 &t1, const T2 &t2, const T3 &t3,
|
|
const T4 &t4, const T5 &t5, const T6 &t6,
|
|
const T7 &t7)
|
|
{ return mdarts.emplace(mmask_marks, t1, t2, t3, t4, t5, t6, t7); }
|
|
template < typename T1, typename T2, typename T3, typename T4, typename T5,
|
|
typename T6, typename T7, typename T8 >
|
|
Dart_handle create_dart(const T1 &t1, const T2 &t2, const T3 &t3,
|
|
const T4 &t4, const T5 &t5, const T6 &t6,
|
|
const T7 &t7, const T8 &t8)
|
|
{ return mdarts.emplace(mmask_marks, t1, t2, t3, t4, t5, t6, t7, t8); }
|
|
template < typename T1, typename T2, typename T3, typename T4, typename T5,
|
|
typename T6, typename T7, typename T8, typename T9 >
|
|
Dart_handle create_dart(const T1 &t1, const T2 &t2, const T3 &t3,
|
|
const T4 &t4, const T5 &t5, const T6 &t6,
|
|
const T7 &t7, const T8 &t8, const T9 &t9)
|
|
{ return mdarts.emplace(mmask_marks, t1, t2, t3, t4, t5, t6, t7, t8, t9); }
|
|
#endif
|
|
|
|
/** Erase a dart from the list of darts.
|
|
* @param adart the dart to erase.
|
|
*/
|
|
void erase_dart(Dart_handle adart)
|
|
{
|
|
// 1) We update the number of marked darts.
|
|
for ( unsigned int i = 0; i < mnb_used_marks; ++i)
|
|
{
|
|
if (is_marked(adart, mused_marks_stack[i]))
|
|
--mnb_marked_darts[mused_marks_stack[i]];
|
|
}
|
|
|
|
// 2) We update the attribute_ref_counting.
|
|
Helper::template Foreach_enabled_attributes
|
|
<internal::Decrease_attribute_functor<Self> >::run(this,adart);
|
|
|
|
// 3) We erase the dart.
|
|
mdarts.erase(adart);
|
|
}
|
|
|
|
/// @return a Dart_range (range through all the darts of the map).
|
|
Dart_range& darts() { return mdarts;}
|
|
Dart_const_range& darts() const { return mdarts; }
|
|
|
|
/** Get the first dart of this map.
|
|
* @return the first dart.
|
|
*/
|
|
Dart_handle first_dart()
|
|
{
|
|
if (darts().begin() == darts().end()) return null_dart_handle;
|
|
return mdarts.begin();
|
|
}
|
|
Dart_const_handle first_dart() const
|
|
{
|
|
if (darts().begin() == darts().end()) return null_dart_handle;
|
|
return mdarts.begin();
|
|
}
|
|
|
|
/// @return the Dart_handle corresponding to the given dart.
|
|
Dart_handle dart_handle(Dart& adart)
|
|
{ return mdarts.iterator_to(adart); }
|
|
Dart_const_handle dart_handle(const Dart& adart) const
|
|
{ return mdarts.iterator_to(adart); }
|
|
|
|
/// @return the betas of ADart (beta are used in the same order than
|
|
/// they are given as parameters)
|
|
#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
|
|
template<typename ...Betas>
|
|
Dart_handle beta(Dart_handle ADart, Betas... betas) const
|
|
{ return CGAL::internal::Beta_functor<Dart_handle, Betas...>::
|
|
run(ADart, betas...); }
|
|
template<typename ...Betas>
|
|
Dart_const_handle beta(Dart_const_handle ADart, Betas... betas) const
|
|
{ return CGAL::internal::Beta_functor<Dart_const_handle, Betas...>::
|
|
run(ADart, betas...); }
|
|
template<int... Betas>
|
|
Dart_handle beta(Dart_handle ADart) const
|
|
{ return CGAL::internal::Beta_functor_static<Dart_handle, Betas...>::
|
|
run(ADart); }
|
|
template<int... Betas>
|
|
Dart_const_handle beta(Dart_const_handle ADart) const
|
|
{ return CGAL::internal::Beta_functor_static<Dart_const_handle, Betas...>::
|
|
run(ADart); }
|
|
#else
|
|
Dart_handle beta(Dart_handle ADart, int B1)
|
|
{ return CGAL::internal::Beta_functor<Dart_handle>::run(ADart, B1); }
|
|
Dart_handle beta(Dart_handle ADart, int B1, int B2)
|
|
{ return CGAL::internal::Beta_functor<Dart_handle>::run(ADart, B1, B2); }
|
|
Dart_handle beta(Dart_handle ADart, int B1, int B2, int B3)
|
|
{ return CGAL::internal::Beta_functor<Dart_handle>::
|
|
run(ADart, B1, B2, B3); }
|
|
Dart_handle beta(Dart_handle ADart, int B1, int B2, int B3, int B4)
|
|
{ return CGAL::internal::Beta_functor<Dart_handle>::
|
|
run(ADart, B1, B2, B3, B4); }
|
|
Dart_handle beta(Dart_handle ADart, int B1, int B2, int B3, int B4, int B5)
|
|
{ return CGAL::internal::Beta_functor<Dart_handle>::
|
|
run(ADart, B1, B2, B3, B4, B5); }
|
|
Dart_handle beta(Dart_handle ADart, int B1, int B2, int B3, int B4, int B5,
|
|
int B6)
|
|
{ return CGAL::internal::Beta_functor<Dart_handle>::
|
|
run(ADart, B1, B2, B3, B4, B5, B6); }
|
|
Dart_handle beta(Dart_handle ADart, int B1, int B2, int B3, int B4, int B5,
|
|
int B6, int B7)
|
|
{ return CGAL::internal::Beta_functor<Dart_handle>::
|
|
run(ADart, B1, B2, B3, B4, B5, B6, B7); }
|
|
Dart_handle beta(Dart_handle ADart, int B1, int B2, int B3, int B4, int B5,
|
|
int B6, int B7, int B8)
|
|
{ return CGAL::internal::Beta_functor<Dart_handle>::
|
|
run(ADart, B1, B2, B3, B4, B5, B6, B7, B8); }
|
|
Dart_handle beta(Dart_handle ADart, int B1, int B2, int B3, int B4, int B5,
|
|
int B6, int B7, int B8, int B9)
|
|
{ return CGAL::internal::Beta_functor<Dart_handle>::
|
|
run(ADart, B1, B2, B3, B4, B5, B6, B7, B8, B9); }
|
|
#endif
|
|
|
|
/** Count the number of used marks.
|
|
* @return the number of used marks.
|
|
*/
|
|
size_type number_of_used_marks() const
|
|
{ return mnb_used_marks; }
|
|
|
|
/** Test if a given mark is reserved.
|
|
* @return true iff the mark is reserved (ie in used).
|
|
*/
|
|
bool is_reserved(int amark) const
|
|
{
|
|
CGAL_assertion(amark>=0 && (size_type)amark<NB_MARKS);
|
|
return (mnb_times_reserved_marks[(size_type)amark]!=0);
|
|
}
|
|
|
|
/** Count the number of marked darts for a given mark.
|
|
* @param amark the mark index.
|
|
* @return the number of marked darts for amark.
|
|
*/
|
|
size_type number_of_marked_darts(int amark) const
|
|
{
|
|
CGAL_assertion( is_reserved(amark) );
|
|
return mnb_marked_darts[(size_type)amark];
|
|
}
|
|
|
|
/** Count the number of unmarked darts for a given mark.
|
|
* @param amark the mark index.
|
|
* @return the number of unmarked darts for amark.
|
|
*/
|
|
size_type number_of_unmarked_darts(int amark) const
|
|
{
|
|
CGAL_assertion( is_reserved(amark) );
|
|
return number_of_darts() - number_of_marked_darts(amark);
|
|
}
|
|
|
|
/** Test if all the darts are unmarked for a given mark.
|
|
* @param amark the mark index.
|
|
* @return true iff all the darts are unmarked for amark.
|
|
*/
|
|
bool is_whole_map_unmarked(int amark) const
|
|
{ return number_of_marked_darts(amark) == 0; }
|
|
|
|
/** Test if all the darts are marked for a given mark.
|
|
* @param amark the mark index.
|
|
* @return true iff all the darts are marked for amark.
|
|
*/
|
|
bool is_whole_map_marked(int amark) const
|
|
{ return number_of_marked_darts(amark) == number_of_darts(); }
|
|
|
|
/** Reserve a new mark.
|
|
* Get a new free mark and return its index.
|
|
* All the darts are unmarked for this mark.
|
|
* @return the index of the new mark.
|
|
* @pre mnb_used_marks < NB_MARKS
|
|
*/
|
|
int get_new_mark() const
|
|
{
|
|
if (mnb_used_marks == NB_MARKS)
|
|
{
|
|
std::cerr << "Not enough Boolean marks: "
|
|
"increase NB_MARKS in item class." << std::endl;
|
|
return -1;
|
|
}
|
|
|
|
int m = mfree_marks_stack[mnb_used_marks];
|
|
mused_marks_stack[mnb_used_marks] = m;
|
|
|
|
mindex_marks[m] = mnb_used_marks;
|
|
mnb_times_reserved_marks[m]=1;
|
|
|
|
++mnb_used_marks;
|
|
CGAL_assertion(is_whole_map_unmarked(m));
|
|
|
|
return m;
|
|
}
|
|
|
|
/** Increase the number of times a mark is reserved.
|
|
* @param amark the mark to share.
|
|
*/
|
|
void share_a_mark(int amark) const
|
|
{
|
|
CGAL_assertion( is_reserved(amark) );
|
|
++mnb_times_reserved_marks[amark];
|
|
}
|
|
|
|
/** @return the number of times a mark is reserved.
|
|
* @param amark the mark to share.
|
|
*/
|
|
size_type get_number_of_times_mark_reserved(int amark) const
|
|
{ return mnb_times_reserved_marks[amark]; }
|
|
|
|
/** Negate the mark of all the darts for a given mark.
|
|
* After this call, all the marked darts become unmarked and all the
|
|
* unmarked darts become marked (in constant time operation).
|
|
* @param amark the mark index
|
|
*/
|
|
void negate_mark(int amark) const
|
|
{
|
|
CGAL_assertion( is_reserved(amark) );
|
|
|
|
mnb_marked_darts[amark] =
|
|
number_of_darts() - mnb_marked_darts[amark];
|
|
|
|
mmask_marks.flip((size_type)amark);
|
|
}
|
|
|
|
/** Test if a given dart is marked for a given mark.
|
|
* @param adart the dart to test.
|
|
* @param amark the given mark.
|
|
* @return true iff adart is marked for the mark amark.
|
|
*/
|
|
bool is_marked(Dart_const_handle adart, int amark) const
|
|
{
|
|
// CGAL_assertion( adart != null_dart_handle );
|
|
CGAL_assertion( is_reserved(amark) );
|
|
|
|
return adart->get_mark(amark)!=mmask_marks[(size_type)amark];
|
|
}
|
|
|
|
/** Set the mark of a given dart to a state (on or off).
|
|
* @param adart the dart.
|
|
* @param amark the given mark.
|
|
* @param astate the state of the mark (on or off).
|
|
*/
|
|
void set_mark_to(Dart_const_handle adart, int amark,
|
|
bool astate) const
|
|
{
|
|
CGAL_assertion( adart != null_dart_handle );
|
|
CGAL_assertion( is_reserved(amark) );
|
|
|
|
if (is_marked(adart, amark) != astate)
|
|
{
|
|
if (astate) ++mnb_marked_darts[(size_type)amark];
|
|
else --mnb_marked_darts[(size_type)amark];
|
|
|
|
adart->set_mark(amark, astate ^ mmask_marks[(size_type)amark]);
|
|
}
|
|
}
|
|
|
|
/** Mark the given dart.
|
|
* @param adart the dart.
|
|
* @param amark the given mark.
|
|
*/
|
|
void mark(Dart_const_handle adart, int amark) const
|
|
{
|
|
CGAL_assertion( adart != null_dart_handle );
|
|
CGAL_assertion( is_reserved(amark) );
|
|
|
|
if (is_marked(adart, amark)) return;
|
|
|
|
++mnb_marked_darts[(size_type)amark];
|
|
adart->set_mark(amark, !mmask_marks[(size_type)amark]);
|
|
}
|
|
|
|
/** Unmark the given dart.
|
|
* @param adart the dart.
|
|
* @param amark the given mark.
|
|
*/
|
|
void unmark(Dart_const_handle adart, int amark) const
|
|
{
|
|
CGAL_assertion( adart != null_dart_handle );
|
|
CGAL_assertion( is_reserved(amark) );
|
|
|
|
if (!is_marked(adart, amark)) return;
|
|
|
|
--mnb_marked_darts[(size_type)amark];
|
|
adart->set_mark(amark, mmask_marks[(size_type)amark]);
|
|
}
|
|
|
|
/** Mark null_dart (used as a sentinel in iterators).
|
|
* As null dart does not belong to the set of darts, it is not counted
|
|
* as number of marked darts.
|
|
* @param amark the given mark.
|
|
*/
|
|
void mark_null_dart(int amark) const
|
|
{
|
|
CGAL_assertion( is_reserved(amark) );
|
|
|
|
null_dart_handle->set_mark(amark, !mmask_marks[(size_type)amark]);
|
|
}
|
|
|
|
/** Unmark null_dart.
|
|
* @param amark the given mark.
|
|
*/
|
|
void unmark_null_dart(int amark) const
|
|
{
|
|
CGAL_assertion( is_reserved(amark) );
|
|
|
|
null_dart_handle->set_mark(amark, mmask_marks[(size_type)amark]);
|
|
}
|
|
|
|
/** Unmark all the darts of the map for a given mark.
|
|
* If all the darts are marked or unmarked, this operation takes O(1)
|
|
* operations, otherwise it traverses all the darts of the map.
|
|
* @param amark the given mark.
|
|
*/
|
|
void unmark_all(int amark) const
|
|
{
|
|
CGAL_assertion( is_reserved(amark) );
|
|
|
|
if ( is_whole_map_marked(amark) )
|
|
{
|
|
negate_mark(amark);
|
|
}
|
|
else if ( !is_whole_map_unmarked(amark) )
|
|
{
|
|
for ( typename Dart_range::const_iterator it(darts().begin()),
|
|
itend(darts().end()); it!=itend; ++it)
|
|
unmark(it, amark);
|
|
}
|
|
CGAL_assertion(is_whole_map_unmarked(amark));
|
|
unmark_null_dart(amark);
|
|
}
|
|
|
|
/** Free a given mark, previously calling unmark_all_darts.
|
|
* @param amark the given mark.
|
|
*/
|
|
void free_mark(int amark) const
|
|
{
|
|
CGAL_assertion( is_reserved(amark) );
|
|
|
|
if ( mnb_times_reserved_marks[amark]>1 )
|
|
{
|
|
--mnb_times_reserved_marks[amark];
|
|
return;
|
|
}
|
|
|
|
unmark_all(amark);
|
|
|
|
// 1) We remove amark from the array mused_marks_stack by
|
|
// replacing it with the last mark in this array.
|
|
mused_marks_stack[mindex_marks[(size_type)amark]] =
|
|
mused_marks_stack[--mnb_used_marks];
|
|
mindex_marks[mused_marks_stack[mnb_used_marks]] =
|
|
mindex_marks[(size_type)amark];
|
|
|
|
// 2) We add amark in the array mfree_marks_stack and update its index.
|
|
mfree_marks_stack[ mnb_used_marks ] = amark;
|
|
mindex_marks[(size_type)amark] = mnb_used_marks;
|
|
|
|
mnb_times_reserved_marks[amark]=0;
|
|
}
|
|
|
|
/** Test if this map is without boundary for a given dimension.
|
|
* @param i the dimension.
|
|
* @return true iff all the darts are not i-free.
|
|
* @pre 1<=i<=n
|
|
*/
|
|
bool is_without_boundary(unsigned int i) const
|
|
{
|
|
CGAL_assertion(1<=i && i<=dimension);
|
|
for ( typename Dart_const_range::const_iterator it(darts().begin()),
|
|
itend(darts().end()); it!=itend; ++it)
|
|
if (it->is_free(i)) return false;
|
|
return true;
|
|
}
|
|
|
|
/** Test if this map is without boundary for all the dimensions.
|
|
* @return true iff all the darts are non free.
|
|
*/
|
|
bool is_without_boundary() const
|
|
{
|
|
for ( typename Dart_const_range::const_iterator it(darts().begin()),
|
|
itend(darts().end()); it!=itend; ++it)
|
|
for ( unsigned int i = 1; i<=dimension; ++i)
|
|
if (it->is_free(i)) return false;
|
|
return true;
|
|
}
|
|
|
|
/** Close the combinatorial map for a given dimension.
|
|
* @param i the dimension to close
|
|
* @return the number of new darts.
|
|
* @pre 2<=i<=n (TODO case i==1)
|
|
* @TODO move into Combinatorial_map_operations ?
|
|
*/
|
|
unsigned int close(unsigned int i)
|
|
{
|
|
CGAL_assertion( 2<=i && i<=dimension );
|
|
unsigned int res = 0;
|
|
Dart_handle d, d2;
|
|
|
|
for ( typename Dart_range::iterator it(darts().begin());
|
|
it!=darts().end(); ++it)
|
|
{
|
|
if ( it->is_free(i) )
|
|
{
|
|
d = create_dart();
|
|
++res;
|
|
|
|
// Here we cannot use link_beta as i is not a constant
|
|
// TODO something to solve this problem ?
|
|
basic_link_beta_for_involution(it, d, i);
|
|
// we copy all the non void attribute
|
|
Helper::template Foreach_enabled_attributes_except
|
|
<CGAL::internal::Group_attribute_functor_of_dart
|
|
<Self, dimension+1>, dimension+1>:: run(this,it,d);
|
|
// we need to remove i-attrib, how to do that ?
|
|
|
|
// Special cases for 0 and 1
|
|
if ( !it->template is_free<1>() &&
|
|
!it->template beta<1>()->is_free(i) )
|
|
link_beta<1>(it->beta(1)->beta(i),d);
|
|
if ( !it->template is_free<0>() &&
|
|
!it->template beta<0>()->is_free(i) )
|
|
link_beta<0>(it->template beta<0>()->beta(i),d);
|
|
// General case for 2...dimension
|
|
for ( unsigned int j=2; j<=dimension; ++j)
|
|
{
|
|
if ( j+1!=i && j!=i && j!=i+1 &&
|
|
!it->is_free(j) && !it->beta(j)->is_free(i) )
|
|
{
|
|
basic_link_beta_for_involution(it->beta(j)->beta(i), d, j);
|
|
}
|
|
}
|
|
|
|
d2 = it;
|
|
while (d2 != null_dart_handle && !d2->is_free(i-1))
|
|
{ d2 = d2->beta(i-1)->beta(i); }
|
|
if (d2 != null_dart_handle)
|
|
{
|
|
if (i==2) basic_link_beta<1>(d2, d);
|
|
else basic_link_beta_for_involution(d2, d, i-1);
|
|
}
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
/** Test if the map is valid.
|
|
* @return true iff the map is valid.
|
|
*/
|
|
bool is_valid() const
|
|
{
|
|
bool valid = true;
|
|
unsigned int i = 0, j = 0;
|
|
std::vector<int> marks(dimension+1);
|
|
for ( i=0; i<=dimension; ++i)
|
|
marks[i] = -1;
|
|
|
|
Helper::template
|
|
Foreach_enabled_attributes<Reserve_mark_functor<Self> >::
|
|
run(this,&marks);
|
|
|
|
for ( typename Dart_range::const_iterator it(darts().begin()),
|
|
itend(darts().end()); it!=itend; ++it)
|
|
{
|
|
if ( !valid )
|
|
{ // We continue the traversal to mark all the darts.
|
|
for ( i=0; i<=dimension; ++i)
|
|
if (marks[i]!=-1) mark(it,marks[i]);
|
|
}
|
|
else
|
|
{
|
|
// beta0 must be the inverse of beta1
|
|
if ((!it->is_free(0) && it->beta(0)->beta(1)!=it) ||
|
|
(!it->is_free(1) && it->beta(1)->beta(0)!=it ))
|
|
{
|
|
std::cerr << "Map not valid: beta(0) "
|
|
"is not the inverse of beta(1) for "
|
|
<<&(*it) << std::endl;
|
|
valid = false;
|
|
}
|
|
|
|
// Each beta(i>=2) must be an involution
|
|
for ( i = 2; i <= dimension; ++i)
|
|
if (!it->is_free(i) && it->beta(i)->beta(i)!=it)
|
|
{
|
|
std::cerr << "Map not valid: beta(" << i
|
|
<< ") is not an involution for "
|
|
<<&(*it) << std::endl;
|
|
valid = false;
|
|
}
|
|
|
|
// beta1 o betai and beta0 o betai (i>=3) must be involutions
|
|
if (!it->is_free(0))
|
|
{
|
|
for ( i = 3; i <= dimension; ++i)
|
|
if ((it->is_free(i) != it->beta(0)->is_free(i)) ||
|
|
(!it->is_free(i) &&
|
|
it->beta(0)->beta(i)!=it->beta(i)->beta(1)))
|
|
{
|
|
std::cerr << "Map not valid: beta(0) o beta(" << i
|
|
<< ") is not an involution for "
|
|
<<&(*it) << std::endl;
|
|
valid = false;
|
|
}
|
|
}
|
|
if (!it->is_free(1))
|
|
{
|
|
for ( i = 3; i <= dimension; ++i)
|
|
if ((it->is_free(i) != it->beta(1)->is_free(i)) ||
|
|
(!it->is_free(i) &&
|
|
it->beta(1)->beta(i)!=it->beta(i)->beta(0)))
|
|
{
|
|
std::cerr << "Map not valid: beta(1) o beta(" << i
|
|
<< ") is not an involution for "
|
|
<<&(*it)<< std::endl;
|
|
valid = false;
|
|
}
|
|
}
|
|
|
|
// beta(i>=2) o beta(j>=i+2) must be an involution
|
|
for ( i = 2; i <= dimension; ++i)
|
|
{
|
|
if (!it->is_free(i))
|
|
{
|
|
for ( j = i + 2; j <= dimension; ++j)
|
|
if ((it->is_free(j)!=it->beta(i)->is_free(j)) ||
|
|
(!it->is_free(j) &&
|
|
it->beta(i)->beta(j)!=it->beta(j)->beta(i)))
|
|
{
|
|
std::cerr << "Map not valid: beta(" << i
|
|
<< ") o beta(" << j
|
|
<< ") is not an involution for "
|
|
<< &(*it)<< std::endl;
|
|
valid = false;
|
|
}
|
|
}
|
|
}
|
|
Helper::template Foreach_enabled_attributes
|
|
<internal::Test_is_valid_attribute_functor<Self> >::
|
|
run(this,it,&marks,&valid);
|
|
}
|
|
}
|
|
for ( i=0; i<=dimension; ++i)
|
|
if ( marks[i]!=-1 )
|
|
{
|
|
CGAL_assertion( is_whole_map_marked(marks[i]) );
|
|
free_mark(marks[i]);
|
|
}
|
|
|
|
return valid;
|
|
}
|
|
|
|
/// @return the number of darts.
|
|
size_type number_of_darts() const
|
|
{ return mdarts.size(); }
|
|
|
|
/// @return an estimation of the bytes used by the combinatorial map.
|
|
size_type bytes() const
|
|
{
|
|
return mdarts.capacity() * sizeof(Dart) +
|
|
internal::Count_bytes_all_attributes_functor<Self>::run(*this);
|
|
}
|
|
|
|
/** Write the content of the map: each dart and each beta links.
|
|
* @param os the ostream.
|
|
* @return the ostream.
|
|
*/
|
|
std::ostream& display_darts(std::ostream & os, bool attribs=false) const
|
|
{
|
|
unsigned int nb = 0;
|
|
for ( typename Dart_range::const_iterator it=darts().begin();
|
|
it!=darts().end(); ++it)
|
|
{
|
|
os << " dart " << &(*it) << "; beta[i]=";
|
|
for ( unsigned int i=0; i<=dimension; ++i)
|
|
{
|
|
os << &(*it->beta(i)) << ",\t";
|
|
if (it->is_free(i)) os << "\t";
|
|
}
|
|
if ( attribs )
|
|
{
|
|
Helper::template Foreach_enabled_attributes
|
|
<Display_attribute_functor<Self> >::run(this, it);
|
|
}
|
|
os << std::endl;
|
|
++nb;
|
|
}
|
|
os << "Number of darts: " << nb <<"(sizeofdarts="
|
|
<<number_of_darts()<<")" << std::endl;
|
|
return os;
|
|
}
|
|
|
|
/** Write the content of each given orbit of the map.
|
|
* @param aos the ostream.
|
|
* @return the ostream.
|
|
*/
|
|
template < class Ite >
|
|
std::ostream& display_orbits(std::ostream & aos) const
|
|
{
|
|
CGAL_static_assertion( (boost::is_same<typename Ite::Basic_iterator,
|
|
Tag_true>::value) );
|
|
unsigned int nb = 0;
|
|
int amark = get_new_mark();
|
|
for ( typename Dart_range::const_iterator it1(darts().begin()),
|
|
itend(darts().end()); it1!=itend; ++it1)
|
|
{
|
|
if ( !is_marked(it1, amark) )
|
|
{
|
|
++nb;
|
|
for ( Ite it2(*this, it1, amark); it2.cont(); ++it2 )
|
|
{
|
|
aos << &(**it2) << " - " << std::flush;
|
|
mark(*it2, amark);
|
|
}
|
|
aos << std::endl;
|
|
}
|
|
}
|
|
CGAL_assertion( is_whole_map_marked(amark) );
|
|
free_mark(amark);
|
|
aos << "Number of orbits: " << nb << std::endl;
|
|
return aos;
|
|
}
|
|
|
|
/** Write the content of each i-cell of the map.
|
|
* @param aos the ostream.
|
|
* @return the ostream.
|
|
*/
|
|
template < unsigned int i >
|
|
std::ostream& display_cells(std::ostream & aos) const
|
|
{
|
|
return display_orbits<CMap_dart_const_iterator_basic_of_cell<Self,i> >
|
|
(aos);
|
|
}
|
|
|
|
/** Write the number of darts and cells of the map into a given ostream.
|
|
* @param os the ostream.
|
|
* @return the ostream.
|
|
*/
|
|
std::ostream& display_characteristics(std::ostream & os) const
|
|
{
|
|
std::vector<unsigned int> cells(dimension+2);
|
|
for ( unsigned int i=0; i<=dimension+1; ++i)
|
|
{ cells[i]=i; }
|
|
|
|
std::vector<unsigned int> res = count_cells(cells);
|
|
|
|
os << "#Darts=" << number_of_darts();
|
|
for ( unsigned int i=0; i<=dimension; ++i)
|
|
os<<", #"<<i<<"-cells="<<res[i];
|
|
os<<", #ccs="<<res[dimension+1];
|
|
|
|
return os;
|
|
}
|
|
|
|
/// Create a new attribute.
|
|
/// @return a handle on the new attribute.
|
|
#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
|
|
template<unsigned int i, typename ...Args>
|
|
typename Attribute_handle<i>::type create_attribute(const Args&... args)
|
|
{
|
|
CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0,
|
|
"create_attribute<i> but i-attributes are disabled");
|
|
return CGAL::cpp11::get<Helper::template Dimension_index<i>::value>
|
|
(mattribute_containers).emplace(args...);
|
|
}
|
|
#else
|
|
template<unsigned int i>
|
|
typename Attribute_handle<i>::type
|
|
create_attribute()
|
|
{
|
|
CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0,
|
|
"create_attribute<i> but i-attributes are disabled");
|
|
return CGAL::cpp11::get<Helper::template Dimension_index<i>::value>
|
|
(mattribute_containers).emplace();
|
|
}
|
|
template<unsigned int i, typename T1>
|
|
typename Attribute_handle<i>::type
|
|
create_attribute(const T1 &t1)
|
|
{
|
|
CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0,
|
|
"create_attribute<i> but i-attributes are disabled");
|
|
return CGAL::cpp11::get<Helper::template Dimension_index<i>::value>
|
|
(mattribute_containers).emplace(t1);
|
|
}
|
|
template<unsigned int i, typename T1, typename T2>
|
|
typename Attribute_handle<i>::type
|
|
create_attribute(const T1 &t1, const T2 &t2)
|
|
{
|
|
CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0,
|
|
"create_attribute<i> but i-attributes are disabled");
|
|
return CGAL::cpp11::get<Helper::template Dimension_index<i>::value>
|
|
(mattribute_containers).emplace(t1, t2);
|
|
}
|
|
template<unsigned int i, typename T1, typename T2, typename T3>
|
|
typename Attribute_handle<i>::type
|
|
create_attribute(const T1 &t1, const T2 &t2, const T3 &t3)
|
|
{
|
|
CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0,
|
|
"create_attribute<i> but i-attributes are disabled");
|
|
return CGAL::cpp11::get<Helper::template Dimension_index<i>::value>
|
|
(mattribute_containers).emplace(t1, t2, t3);
|
|
}
|
|
template<unsigned int i, typename T1, typename T2, typename T3, typename T4>
|
|
typename Attribute_handle<i>::type
|
|
create_attribute(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4)
|
|
{
|
|
CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0,
|
|
"create_attribute<i> but i-attributes are disabled");
|
|
return CGAL::cpp11::get<Helper::template Dimension_index<i>::value>
|
|
(mattribute_containers).emplace(t1, t2, t3, t4);
|
|
}
|
|
template<unsigned int i, typename T1, typename T2, typename T3, typename T4,
|
|
typename T5>
|
|
typename Attribute_handle<i>::type
|
|
create_attribute(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4,
|
|
const T5 &t5)
|
|
{
|
|
CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0,
|
|
"create_attribute<i> but i-attributes are disabled");
|
|
return CGAL::cpp11::get<Helper::template Dimension_index<i>::value>
|
|
(mattribute_containers).emplace(t1, t2, t3, t4, t5);
|
|
}
|
|
template<unsigned int i, typename T1, typename T2, typename T3, typename T4,
|
|
typename T5, typename T6>
|
|
typename Attribute_handle<i>::type
|
|
create_attribute(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4,
|
|
const T5 &t5, const T6 &t6)
|
|
{
|
|
CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0,
|
|
"create_attribute<i> but i-attributes are disabled");
|
|
return CGAL::cpp11::get<Helper::template Dimension_index<i>::value>
|
|
(mattribute_containers).emplace(t1, t2, t3, t4, t5, t6);
|
|
}
|
|
template<unsigned int i, typename T1, typename T2, typename T3, typename T4,
|
|
typename T5, typename T6, typename T7>
|
|
typename Attribute_handle<i>::type
|
|
create_attribute(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4,
|
|
const T5 &t5, const T6 &t6, const T7 &t7)
|
|
{
|
|
CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0,
|
|
"create_attribute<i> but i-attributes are disabled");
|
|
return CGAL::cpp11::get<Helper::template Dimension_index<i>::value>
|
|
(mattribute_containers).emplace(t1, t2, t3, t4, t5, t6, t7);
|
|
}
|
|
template<unsigned int i, typename T1, typename T2, typename T3, typename T4,
|
|
typename T5, typename T6, typename T7, typename T8>
|
|
typename Attribute_handle<i>::type
|
|
create_attribute(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4,
|
|
const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8)
|
|
{
|
|
CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0,
|
|
"create_attribute<i> but i-attributes are disabled");
|
|
return CGAL::cpp11::get<Helper::template Dimension_index<i>::value>
|
|
(mattribute_containers).emplace(t1, t2, t3, t4, t5, t6, t7, t8);
|
|
}
|
|
template<unsigned int i, typename T1, typename T2, typename T3, typename T4,
|
|
typename T5, typename T6, typename T7, typename T8, typename T9>
|
|
typename Attribute_handle<i>::type
|
|
create_attribute(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4,
|
|
const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8,
|
|
const T9 &t9)
|
|
{
|
|
CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0,
|
|
"create_attribute<i> but i-attributes are disabled");
|
|
return CGAL::cpp11::get<Helper::template Dimension_index<i>::value>
|
|
(mattribute_containers).emplace(t1, t2, t3, t4, t5, t6, t7, t8, t9);
|
|
}
|
|
#endif
|
|
|
|
/// Erase an attribute.
|
|
/// @param h a handle to the attribute to erase.
|
|
template<unsigned int i>
|
|
void erase_attribute(typename Attribute_handle<i>::type h)
|
|
{
|
|
CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0,
|
|
"erase_attribute<i> but i-attributes are disabled");
|
|
CGAL::cpp11::get<Helper::template Dimension_index<i>::value>
|
|
(mattribute_containers).erase(h);
|
|
}
|
|
|
|
/// @return the number of attributes.
|
|
template <unsigned int i>
|
|
size_type number_of_attributes() const
|
|
{
|
|
CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0,
|
|
"number_of_attributes<i> but i-attributes are disabled");
|
|
return CGAL::cpp11::get<Helper::template Dimension_index<i>::value>
|
|
(mattribute_containers).size();
|
|
}
|
|
|
|
/// @return a Attributes_range<i> (range through all the
|
|
/// attributes<i> of the map).
|
|
template<unsigned int i>
|
|
typename Attribute_range<i>::type & attributes()
|
|
{
|
|
CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0,
|
|
"attributes<i> but i-attributes are disabled");
|
|
return CGAL::cpp11::get<Helper::template Dimension_index<i>::value>
|
|
(mattribute_containers);
|
|
}
|
|
|
|
template<unsigned int i>
|
|
typename Attribute_const_range<i>::type & attributes() const
|
|
{
|
|
CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0,
|
|
"attributes<i> but i-attributes are disabled");
|
|
return CGAL::cpp11::get<Helper::template Dimension_index<i>::value>
|
|
(mattribute_containers);
|
|
}
|
|
|
|
/** Double link a dart with beta 0 to a second dart.
|
|
* \em adart1 is 0-linked to \em adart2 and \em adart2 is 1-linked
|
|
* with \em adart1. Attributes are not updated, thus we can obtain
|
|
* a non-valid map with darts belonging to a same orbit and having
|
|
* different attributes.
|
|
* @param adart1 a first dart.
|
|
* @param adart2 a second dart.
|
|
*/
|
|
void basic_link_beta_0(Dart_handle adart1, Dart_handle adart2)
|
|
{
|
|
CGAL_assertion(adart1 != NULL && adart2 != NULL);
|
|
CGAL_assertion(adart1 != null_dart_handle && adart2 != null_dart_handle);
|
|
adart1->template basic_link_beta<0>(adart2);
|
|
adart2->template basic_link_beta<1>(adart1);
|
|
}
|
|
|
|
/** Double link a dart with beta 0 to a second dart.
|
|
* \em adart1 is 0-linked to \em adart2 and \em adart2 is 1-linked
|
|
* with \em adart1. Attributes are not updated, thus we can obtain
|
|
* a non-valid map with darts belonging to a same orbit and having
|
|
* different attributes.
|
|
* @param adart1 a first dart.
|
|
* @param adart2 a second dart.
|
|
*/
|
|
void basic_link_beta_1(Dart_handle adart1, Dart_handle adart2)
|
|
{
|
|
CGAL_assertion(adart1 != NULL && adart2 != NULL);
|
|
CGAL_assertion(adart1 != null_dart_handle && adart2 != null_dart_handle);
|
|
adart1->template basic_link_beta<1>(adart2);
|
|
adart2->template basic_link_beta<0>(adart1);
|
|
}
|
|
|
|
/** Double link a dart with beta i to a second dart, when i>=2.
|
|
* \em adart1 is i-linked to \em adart2 and \em adart2 is i-linked
|
|
* with \em adart1. Attributes are not updated, thus we can obtain
|
|
* a non-valid map with darts belonging to a same orbit and having
|
|
* different attributes.
|
|
* @param adart1 a first dart.
|
|
* @param adart2 a second dart.
|
|
* @param i the dimension of the beta.
|
|
*/
|
|
template<unsigned int i>
|
|
void basic_link_beta_for_involution(Dart_handle adart1, Dart_handle adart2)
|
|
{
|
|
CGAL_assertion( i>=2 && i<=dimension );
|
|
CGAL_assertion(adart1 != NULL && adart2 != NULL && adart1!=adart2);
|
|
CGAL_assertion(adart1 != null_dart_handle && adart2 != null_dart_handle);
|
|
adart1->template basic_link_beta<i>(adart2);
|
|
adart2->template basic_link_beta<i>(adart1);
|
|
}
|
|
void basic_link_beta_for_involution(Dart_handle adart1, Dart_handle adart2,
|
|
unsigned int i)
|
|
{
|
|
CGAL_assertion( i>=2 && i<=dimension );
|
|
CGAL_assertion(adart1 != NULL && adart2 != NULL && adart1!=adart2);
|
|
CGAL_assertion(adart1 != null_dart_handle && adart2 != null_dart_handle);
|
|
adart1->basic_link_beta(adart2, i);
|
|
adart2->basic_link_beta(adart1, i);
|
|
}
|
|
|
|
/** Double link a dart with betai to a second dart.
|
|
* \em adart1 is i-linked to \em adart2 and \em adart2 is i^-1-linked
|
|
* with \em adart1. Attributes are not updated, thus we can obtain
|
|
* a non-valid map with darts belonging to a same orbit and having
|
|
* different attributes.
|
|
* @param adart1 a first dart.
|
|
* @param adart2 a second dart.
|
|
*/
|
|
template<unsigned int i>
|
|
void basic_link_beta(Dart_handle adart1, Dart_handle adart2)
|
|
{
|
|
if ( i==0 ) basic_link_beta_0(adart1, adart2);
|
|
else if ( i==1 ) basic_link_beta_1(adart1, adart2);
|
|
else basic_link_beta_for_involution<i>(adart1, adart2);
|
|
}
|
|
void basic_link_beta(Dart_handle adart1, Dart_handle adart2,
|
|
unsigned int i)
|
|
{
|
|
if ( i==0 ) basic_link_beta_0(adart1, adart2);
|
|
else if ( i==1 ) basic_link_beta_1(adart1, adart2);
|
|
else basic_link_beta_for_involution(adart1, adart2, i);
|
|
}
|
|
|
|
/** Double link two darts, and update the NULL attributes.
|
|
* \em adart1 is 0-linked to \em adart2 and \em adart2 is 1-linked
|
|
* with \em adart1. The NULL attributes of \em adart1 are updated to
|
|
* non NULL attributes associated to \em adart2, and vice-versa.
|
|
* If both darts have an attribute, the attribute of adart1 is
|
|
* associated to adart2.
|
|
* We can obtain a non-valid map with darts belonging to a same cell
|
|
* and having different attributes.
|
|
* @param adart1 a first dart.
|
|
* @param adart2 a second dart.
|
|
*/
|
|
void link_beta_0(Dart_handle adart1, Dart_handle adart2)
|
|
{
|
|
CGAL_assertion(adart1 != NULL && adart2 != NULL);
|
|
CGAL_assertion(adart1 != null_dart_handle && adart2 != null_dart_handle);
|
|
Helper::template Foreach_enabled_attributes_except
|
|
<internal::Group_attribute_functor_of_dart<Self, 0>, 1>::
|
|
run(this,adart1,adart2);
|
|
adart1->basic_link_beta<0>(adart2);
|
|
adart2->basic_link_beta<1>(adart1);
|
|
}
|
|
|
|
/** Double link two darts, and update the NULL attributes.
|
|
* \em adart1 is 1-linked to \em adart2 and \em adart2 is 0-linked
|
|
* with \em adart1. The NULL attributes of \em adart1 are updated to
|
|
* non NULL attributes associated to \em adart2, and vice-versa.
|
|
* If both darts have an attribute, the attribute of adart1 is
|
|
* associated to adart2.
|
|
* We can obtain a non-valid map with darts belonging to a same cell
|
|
* and having different attributes.
|
|
* @param adart1 a first dart.
|
|
* @param adart2 a second dart.
|
|
*/
|
|
void link_beta_1(Dart_handle adart1, Dart_handle adart2)
|
|
{
|
|
CGAL_assertion(adart1 != NULL && adart2 != NULL);
|
|
CGAL_assertion(adart1 != null_dart_handle && adart2 != null_dart_handle);
|
|
Helper::template Foreach_enabled_attributes_except
|
|
<internal::Group_attribute_functor_of_dart<Self, 1>, 1>::
|
|
run(this,adart1,adart2);
|
|
adart1->basic_link_beta<1>(adart2);
|
|
adart2->basic_link_beta<0>(adart1);
|
|
}
|
|
|
|
/** Double link two darts, and update the NULL attributes.
|
|
* \em adart1 is i-linked to \em adart2 and \em adart2 is i^-1-linked
|
|
* with \em adart1. The NULL attributes of \em adart1 are updated to
|
|
* non NULL attributes associated to \em adart2, and vice-versa.
|
|
* If both darts have an attribute, the attribute of adart1 is
|
|
* associated to adart2.
|
|
* We can obtain a non-valid map with darts belonging to a same cell
|
|
* and having different attributes.
|
|
* @param adart1 a first dart.
|
|
* @param adart2 a second dart.
|
|
* @param i the dimension of the beta.
|
|
* @pre 2<=i<=dimension.
|
|
*/
|
|
template<unsigned int i>
|
|
void link_beta_for_involution(Dart_handle adart1, Dart_handle adart2)
|
|
{
|
|
CGAL_assertion(adart1 != NULL && adart2 != NULL && adart1!=adart2 );
|
|
CGAL_assertion(adart1 != null_dart_handle && adart2 != null_dart_handle);
|
|
CGAL_assertion( 2<=i && i<=dimension );
|
|
Helper::template Foreach_enabled_attributes_except
|
|
<internal::Group_attribute_functor_of_dart<Self, i>, i>::
|
|
run(this,adart1,adart2);
|
|
adart1->template basic_link_beta<i>(adart2);
|
|
adart2->template basic_link_beta<i>(adart1);
|
|
}
|
|
|
|
/** Double link two darts, and update the NULL attributes.
|
|
* \em adart1 is i-linked to \em adart2 and \em adart2 is i^-1-linked
|
|
* with \em adart1. The NULL attributes of \em adart1 are updated to
|
|
* non NULL attributes associated to \em adart2, and vice-versa.
|
|
* If both darts have an attribute, the attribute of adart1 is
|
|
* associated to adart2.
|
|
* We can obtain a non-valid map with darts belonging to a same cell
|
|
* and having different attributes.
|
|
* @param adart1 a first dart.
|
|
* @param adart2 a second dart.
|
|
*/
|
|
template<unsigned int i>
|
|
void link_beta(Dart_handle adart1, Dart_handle adart2)
|
|
{
|
|
if ( i==0 ) link_beta_0(adart1, adart2);
|
|
else if ( i==1 ) link_beta_1(adart1, adart2);
|
|
else link_beta_for_involution<i>(adart1, adart2);
|
|
}
|
|
|
|
/** Double link a dart with betai to a second dart.
|
|
* \em adart1 is i-linked to \em adart2 and \em adart2 is i^-1-linked
|
|
* with \em adart1. The NULL attributes of \em adart1 are updated to
|
|
* non NULL attributes associated to \em adart2, and vice-versa,
|
|
* if both darts have an attribute, the attribute of adart1 is
|
|
* associated to adart2 (only if update_attributes==true).
|
|
* @param adart1 a first dart.
|
|
* @param adart2 a second dart.
|
|
* @param update_attributes a boolean to update the enabled attributes.
|
|
*/
|
|
template<unsigned int i>
|
|
void link_beta(Dart_handle adart1, Dart_handle adart2,
|
|
bool update_attributes)
|
|
{
|
|
if ( update_attributes ) link_beta<i>(adart1, adart2);
|
|
else basic_link_beta<i>(adart1, adart2);
|
|
}
|
|
|
|
/** Double unlink a dart with beta 0.
|
|
* beta0(\em adart) is 1-unlinked and \em adart is 0-unlinked.
|
|
* The attributes are not updated, thus we can obtain a non-valid map
|
|
* with darts belonging to different orbits and having the same
|
|
* attributes.
|
|
* @param adart a dart.
|
|
*/
|
|
void unlink_beta_0(Dart_handle adart)
|
|
{
|
|
CGAL_assertion(adart!=NULL && !adart->template is_free<0>());
|
|
adart->template beta<0>()->template unlink_beta<1>();
|
|
adart->template unlink_beta<0>();
|
|
}
|
|
|
|
/** Double unlink a dart with beta 1.
|
|
* beta1(\em adart) is 0-unlinked and \em adart is 1-unlinked.
|
|
* The attributes are not updated, thus we can obtain a non-valid map
|
|
* with darts belonging to different orbits and having the same
|
|
* attributes.
|
|
* @param adart a dart.
|
|
*/
|
|
void unlink_beta_1(Dart_handle adart)
|
|
{
|
|
CGAL_assertion(adart!=NULL && !adart->template is_free<1>());
|
|
adart->template beta<1>()->template unlink_beta<0>();
|
|
adart->template unlink_beta<1>();
|
|
}
|
|
|
|
/** Double unlink a dart with beta i, for i>=2.
|
|
* betai(\em adart) is i-unlinked and \em adart is i-unlinked.
|
|
* The attributes are not updated, thus we can obtain a non-valid map
|
|
* with darts belonging to different orbits and having the same
|
|
* attributes.
|
|
* @param adart a dart.
|
|
* @param i the dimension of the beta.
|
|
*/
|
|
template<unsigned int i>
|
|
void unlink_beta_for_involution(Dart_handle adart)
|
|
{
|
|
CGAL_assertion(adart!=NULL && adart!=null_dart_handle &&
|
|
!adart->template is_free<i>());
|
|
CGAL_assertion(2<=i && i<=dimension);
|
|
adart->template beta<i>()->template unlink_beta<i>();
|
|
adart->template unlink_beta<i>();
|
|
}
|
|
void unlink_beta_for_involution(Dart_handle adart, unsigned int i)
|
|
{
|
|
CGAL_assertion(adart!=NULL && adart!=null_dart_handle &&
|
|
!adart->is_free(i));
|
|
CGAL_assertion(2<=i && i<=dimension);
|
|
adart->beta(i)->unlink_beta(i);
|
|
adart->unlink_beta(i);
|
|
}
|
|
|
|
/** Double unlink a dart with beta i.
|
|
* betai(\em adart) is i-1-unlinked and \em adart is i-unlinked.
|
|
* The attributes are not updated, thus we can obtain a non-valid map
|
|
* with darts belonging to different orbits and having the same
|
|
* attributes.
|
|
* @param adart a dart.
|
|
* @param i the dimension of the beta.
|
|
*/
|
|
template<unsigned int i>
|
|
void unlink_beta(Dart_handle adart)
|
|
{
|
|
if ( i==0 ) unlink_beta_0(adart);
|
|
else if ( i==1 ) unlink_beta_1(adart);
|
|
else unlink_beta_for_involution<i>(adart);
|
|
}
|
|
void unlink_beta(Dart_handle adart, unsigned int i)
|
|
{
|
|
if ( i==0 ) unlink_beta_0(adart);
|
|
else if ( i==1 ) unlink_beta_1(adart);
|
|
else unlink_beta_for_involution(adart, i);
|
|
}
|
|
|
|
/** Test if it is possible to sew by betai the two given darts
|
|
* @param adart1 the first dart.
|
|
* @param adart2 the second dart.
|
|
* @return true iff \em adart1 can be i-sewn with \em adart2.
|
|
*/
|
|
template<unsigned int i>
|
|
bool is_sewable(Dart_const_handle adart1, Dart_const_handle adart2) const
|
|
{
|
|
return CGAL::internal::
|
|
Is_sewable_functor<Self, i>::run(this, adart1, adart2);
|
|
}
|
|
|
|
/** Topological sew by beta1 the two given darts plus all the required darts
|
|
* to satisfy the combinatorial map validity: but do not update attributes
|
|
* thus the map can be non valid.
|
|
* @param adart1 the first dart.
|
|
* @param adart2 the second dart.
|
|
* @pre is_sewable<1>(adart1, adart2).
|
|
*/
|
|
void topo_sew_1(Dart_handle adart1, Dart_handle adart2)
|
|
{
|
|
CGAL_assertion( (is_sewable<1>(adart1,adart2)) );
|
|
|
|
if ( adart1==adart2 )
|
|
{
|
|
for ( CGAL::CMap_dart_iterator_of_involution<Self,1> it(*this, adart1);
|
|
it.cont(); ++it )
|
|
{
|
|
basic_link_beta_1(it, it);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int m = get_new_mark();
|
|
std::deque<Dart_handle> dartv;
|
|
for ( CGAL::CMap_dart_iterator_basic_of_cell<Self,0>
|
|
it(*this, adart1, m); it.cont(); ++it )
|
|
{
|
|
mark(it,m);
|
|
dartv.push_back(it);
|
|
}
|
|
|
|
CGAL::CMap_dart_iterator_of_involution<Self,1> I1(*this, adart1);
|
|
CGAL::CMap_dart_iterator_of_involution_inv<Self,1> I2(*this, adart2);
|
|
for ( ; I1.cont(); ++I1, ++I2 )
|
|
{
|
|
if ( is_marked(I1,m) ) basic_link_beta_1(I1, I2);
|
|
else basic_link_beta_0(I1, I2);
|
|
}
|
|
|
|
for ( typename std::deque<Dart_handle>::iterator it=dartv.begin();
|
|
it!=dartv.end(); ++it)
|
|
{ unmark(*it,m); }
|
|
CGAL_assertion( is_whole_map_unmarked(m) );
|
|
free_mark(m);
|
|
}
|
|
}
|
|
|
|
/** Topological sew by beta0 two given darts plus all the required darts
|
|
* to satisfy the combinatorial map validity: but do not update attributes
|
|
* thus the map can be non valid.
|
|
* @param adart1 the first dart.
|
|
* @param adart2 the second dart.
|
|
* @pre is_sewable<0>(adart1, adart2).
|
|
*/
|
|
void topo_sew_0(Dart_handle adart1, Dart_handle adart2)
|
|
{ topo_sew_1(adart2, adart1); }
|
|
|
|
/** Topological sew by betai two given darts plus all the required darts
|
|
* to satisfy the combinatorial map validity: but do not update attributes
|
|
* thus the map can be non valid.
|
|
* @param adart1 the first dart.
|
|
* @param adart2 the second dart.
|
|
* @pre 2<=i<=dimension.
|
|
* @pre is_sewable<i>(adart1, adart2).
|
|
*/
|
|
template<unsigned int i>
|
|
void topo_sew_for_involution(Dart_handle adart1, Dart_handle adart2)
|
|
{
|
|
CGAL_assertion( 2<=i && i<=Self::dimension );
|
|
CGAL_assertion( (is_sewable<i>(adart1,adart2)) );
|
|
|
|
CGAL::CMap_dart_iterator_of_involution<Self,i> I1(*this, adart1);
|
|
CGAL::CMap_dart_iterator_of_involution_inv<Self,i> I2(*this, adart2);
|
|
for ( ; I1.cont(); ++I1, ++I2 )
|
|
{
|
|
basic_link_beta_for_involution<i>(I1, I2);
|
|
}
|
|
}
|
|
|
|
/** Topological sew by betai two given darts plus all the required darts
|
|
* to satisfy the combinatorial map validity: but do not update attributes
|
|
* thus the map can be non valid.
|
|
* @param adart1 the first dart.
|
|
* @param adart2 the second dart.
|
|
* @pre is_sewable<i>(adart1, adart2).
|
|
*/
|
|
template<unsigned int i>
|
|
void topo_sew(Dart_handle adart1, Dart_handle adart2)
|
|
{
|
|
if ( i==0 ) topo_sew_1(adart2, adart1);
|
|
else if ( i==1 ) topo_sew_1(adart1, adart2);
|
|
else topo_sew_for_involution<i>(adart1, adart2);
|
|
}
|
|
|
|
/** Sew by beta0 the two given darts plus all the required darts
|
|
* to satisfy the combinatorial map validity, and updates enabled
|
|
* attributes when necessary so that the final map is valid.
|
|
* @param adart1 the first dart.
|
|
* @param adart2 the second dart.
|
|
* @pre is_sewable<0>(adart1, adart2).
|
|
* @post is_valid()
|
|
*/
|
|
void sew_0(Dart_handle adart1, Dart_handle adart2)
|
|
{
|
|
CGAL_assertion( (is_sewable<0>(adart1,adart2)) );
|
|
|
|
if ( adart1==adart2 )
|
|
{
|
|
for ( CGAL::CMap_dart_iterator_of_involution<Self,1> it(*this, adart1);
|
|
it.cont(); ++it )
|
|
{
|
|
basic_link_beta_1(it, it);
|
|
}
|
|
return;
|
|
}
|
|
|
|
int m = get_new_mark();
|
|
std::deque<Dart_handle> dartv;
|
|
for ( CGAL::CMap_dart_iterator_basic_of_cell<Self, 0>
|
|
it(*this, adart1, m); it.cont(); ++it )
|
|
{
|
|
mark(it,m);
|
|
dartv.push_back(it);
|
|
}
|
|
|
|
int mark = get_new_mark();
|
|
CGAL_assertion( mark!=-1 );
|
|
|
|
CGAL::CMap_dart_iterator_basic_of_involution<Self, 1>
|
|
I1(*this, adart1, mark);
|
|
CGAL::CMap_dart_iterator_basic_of_involution_inv<Self, 1>
|
|
I2(*this, adart2, mark);
|
|
|
|
// This first loop do not modify the map, but only the attributes
|
|
// (by calling when required the onmerge functors).
|
|
for ( ; I1.cont(); ++I1, ++I2 )
|
|
{
|
|
if ( is_marked(I1,m) )
|
|
Helper::template Foreach_enabled_attributes_except
|
|
<CGAL::internal::Group_attribute_functor<Self, 0>, 1>::
|
|
run(this, I1, I2);
|
|
else
|
|
Helper::template Foreach_enabled_attributes_except
|
|
<CGAL::internal::Group_attribute_functor<Self, 1>, 1>::
|
|
run(this, I1, I2);
|
|
}
|
|
|
|
// Now we update the beta links.
|
|
negate_mark( mark );
|
|
for ( I1.rewind(), I2.rewind(); I1.cont(); ++I1, ++I2 )
|
|
{
|
|
if ( is_marked(I1,m) ) basic_link_beta_0(I1, I2);
|
|
else basic_link_beta_1(I1, I2);
|
|
}
|
|
|
|
for ( typename std::deque<Dart_handle>::iterator it=dartv.begin();
|
|
it!=dartv.end(); ++it )
|
|
{ unmark(*it,m); }
|
|
CGAL_assertion( is_whole_map_unmarked(m) );
|
|
free_mark(m);
|
|
|
|
negate_mark( mark );
|
|
CGAL_assertion( is_whole_map_unmarked(mark) );
|
|
free_mark(mark);
|
|
}
|
|
|
|
/** Sew by beta1 the two given darts plus all the required darts
|
|
* to satisfy the combinatorial map validity, and updates enabled
|
|
* attributes when necessary so that the final map is valid.
|
|
* @param adart1 the first dart.
|
|
* @param adart2 the second dart.
|
|
* @pre is_sewable<1>(adart1, adart2).
|
|
* @post is_valid()
|
|
*/
|
|
void sew_1(Dart_handle adart1, Dart_handle adart2)
|
|
{
|
|
CGAL_assertion( (is_sewable<1>(adart1,adart2)) );
|
|
|
|
if ( adart1==adart2 )
|
|
{
|
|
for ( CGAL::CMap_dart_iterator_of_involution<Self, 1>
|
|
it(*this, adart1); it.cont(); ++it )
|
|
{
|
|
basic_link_beta_1(it, it);
|
|
}
|
|
return;
|
|
}
|
|
|
|
int m = get_new_mark();
|
|
std::deque<Dart_handle> dartv;
|
|
for ( CGAL::CMap_dart_iterator_basic_of_cell<Self, 0>
|
|
it(*this, adart1, m); it.cont(); ++it )
|
|
{
|
|
mark(it,m);
|
|
dartv.push_back(it);
|
|
}
|
|
|
|
int mark = get_new_mark();
|
|
CGAL_assertion( mark!=-1 );
|
|
|
|
CGAL::CMap_dart_iterator_basic_of_involution<Self, 1>
|
|
I1(*this, adart1, mark);
|
|
CGAL::CMap_dart_iterator_basic_of_involution_inv<Self, 1>
|
|
I2(*this, adart2, mark);
|
|
|
|
// This first loop do not modify the map, but only the attributes
|
|
// (by calling when required the onmerge functors).
|
|
for ( ; I1.cont(); ++I1, ++I2 )
|
|
{
|
|
CGAL_assertion( I2.cont() );
|
|
if ( is_marked(I1,m) )
|
|
Helper::template Foreach_enabled_attributes_except
|
|
<internal::Group_attribute_functor<Self, 1>, 1>::
|
|
run(this, I1, I2);
|
|
else
|
|
Helper::template Foreach_enabled_attributes_except
|
|
<internal::Group_attribute_functor<Self, 0>, 1>::
|
|
run(this, I1, I2);
|
|
}
|
|
|
|
// Now we update the beta links.
|
|
negate_mark( mark );
|
|
for ( I1.rewind(), I2.rewind(); I1.cont(); ++I1, ++I2 )
|
|
{
|
|
if ( is_marked(I1,m) ) basic_link_beta_1(I1, I2);
|
|
else basic_link_beta_0(I1, I2);
|
|
}
|
|
|
|
for ( typename std::deque<Dart_handle>::iterator it=dartv.begin();
|
|
it!=dartv.end(); ++it )
|
|
{ unmark(*it,m); }
|
|
CGAL_assertion( is_whole_map_unmarked(m) );
|
|
free_mark(m);
|
|
|
|
negate_mark( mark );
|
|
CGAL_assertion( is_whole_map_unmarked(mark) );
|
|
free_mark(mark);
|
|
}
|
|
|
|
/** Sew by betai the two given darts plus all the required darts
|
|
* to satisfy the combinatorial map validity, and updates enabled
|
|
* attributes when necessary so that the final map is valid.
|
|
* @param adart1 the first dart.
|
|
* @param adart2 the second dart.
|
|
* @pre is_sewable<i>(adart1, adart2).
|
|
* @pre 2<=i<=dimension.
|
|
* @post is_valid()
|
|
*/
|
|
template<unsigned int i>
|
|
void sew_for_involution(Dart_handle adart1, Dart_handle adart2)
|
|
{
|
|
CGAL_assertion( 2<=i && i<=dimension );
|
|
CGAL_assertion( (is_sewable<i>(adart1,adart2)) );
|
|
|
|
int mark=get_new_mark();
|
|
CGAL_assertion( mark!=-1 );
|
|
|
|
CGAL::CMap_dart_iterator_basic_of_involution<Self, i>
|
|
I1(*this, adart1, mark);
|
|
CGAL::CMap_dart_iterator_basic_of_involution_inv<Self, i>
|
|
I2(*this, adart2, mark);
|
|
|
|
// This first loop do not modify the map, but only the attributes
|
|
// (by calling when required the onmerge functors).
|
|
for ( ; I1.cont(); ++I1, ++I2 )
|
|
{
|
|
Helper::template Foreach_enabled_attributes_except
|
|
<CGAL::internal::Group_attribute_functor<Self, i>, i>::
|
|
run(this, I1, I2);
|
|
}
|
|
|
|
// Now we update the beta links.
|
|
negate_mark( mark );
|
|
for ( I1.rewind(), I2.rewind(); I1.cont(); ++I1, ++I2 )
|
|
{
|
|
basic_link_beta_for_involution<i>(I1, I2);
|
|
}
|
|
|
|
negate_mark( mark );
|
|
CGAL_assertion( is_whole_map_unmarked(mark) );
|
|
free_mark(mark);
|
|
}
|
|
|
|
/** Sew by betai the two given darts plus all the required darts
|
|
* to satisfy the combinatorial map validity, and updates enabled
|
|
* attributes when necessary so that the final map is valid.
|
|
* @param adart1 the first dart.
|
|
* @param adart2 the second dart.
|
|
* @pre is_sewable<i>(adart1, adart2).
|
|
* @post is_valid()
|
|
*/
|
|
template<unsigned int i>
|
|
void sew(Dart_handle adart1, Dart_handle adart2)
|
|
{
|
|
if ( i==0 ) sew_0(adart1, adart2);
|
|
else if ( i==1 ) sew_1(adart1, adart2);
|
|
else sew_for_involution<i>(adart1, adart2);
|
|
}
|
|
|
|
/** Sew by betai the two given darts plus all the required darts
|
|
* to satisfy the combinatorial map validity. Enabled attributes
|
|
* are updated only if update_attributes==true.
|
|
* @param adart1 the first dart.
|
|
* @param adart2 the second dart.
|
|
* @param update_attributes a boolean to update the enabled attributes
|
|
* @pre is_sewable<i>(adart1, adart2).
|
|
*/
|
|
template<unsigned int i>
|
|
void sew(Dart_handle adart1, Dart_handle adart2, bool update_attributes)
|
|
{
|
|
if ( update_attributes ) sew<i>(adart1, adart2);
|
|
else topo_sew<i>(adart1, adart2);
|
|
}
|
|
|
|
/** Topological unsew by beta1 the given dart plus all the required darts
|
|
* to satisfy the combinatorial map validity: but do not update attributes
|
|
* thus the map can be non valid
|
|
* @param adart first dart.
|
|
* @pre !adart->is_free(1).
|
|
*/
|
|
void topo_unsew_1(Dart_handle adart)
|
|
{
|
|
CGAL_assertion( adart!=NULL && !adart->template is_free<1>() );
|
|
|
|
int m = get_new_mark();
|
|
std::deque<Dart_handle> dartv;
|
|
for ( CGAL::CMap_dart_iterator_basic_of_cell<Self,0> it(*this, adart, m);
|
|
it.cont(); ++it )
|
|
{
|
|
mark(*it,m);
|
|
dartv.push_back(*it);
|
|
}
|
|
|
|
for ( CGAL::CMap_dart_iterator_of_involution<Self,1> it(*this, adart);
|
|
it.cont(); ++it )
|
|
{
|
|
if ( is_marked(*it,m) ) unlink_beta_1(*it);
|
|
else unlink_beta_0(*it);
|
|
}
|
|
|
|
for ( typename std::deque<Dart_handle>::iterator it=dartv.begin();
|
|
it!=dartv.end(); ++it )
|
|
{ unmark(*it,m); }
|
|
CGAL_assertion( is_whole_map_unmarked(m) );
|
|
free_mark(m);
|
|
}
|
|
|
|
/** Topological unsew by beta0 the given dart plus all the required darts
|
|
* to satisfy the combinatorial map validity: but do not update attributes
|
|
* thus the map can be non valid
|
|
* @param adart first dart.
|
|
* @pre !adart->is_free(0).
|
|
*/
|
|
void topo_unsew_0(Dart_handle adart)
|
|
{
|
|
CGAL_assertion( adart!=NULL && !adart->template is_free<0>() );
|
|
topo_unsew_1( adart->template beta<0>() );
|
|
}
|
|
|
|
/** Topological unsew by betai the given dart plus all the required darts
|
|
* to satisfy the combinatorial map validity: but do not update attributes
|
|
* thus the map can be non valid
|
|
* @param adart first dart.
|
|
* @pre !adart->is_free(i).
|
|
* @pre 2<=i<=dimension.
|
|
*/
|
|
template<unsigned int i>
|
|
void topo_unsew_for_involution(Dart_handle adart)
|
|
{
|
|
CGAL_assertion( adart!=NULL && !adart->template is_free<i>() );
|
|
CGAL_assertion( 2<=i && i<=Self::dimension );
|
|
|
|
for ( CGAL::CMap_dart_iterator_of_involution<Self,i> it(*this, adart);
|
|
it.cont(); ++it )
|
|
{ unlink_beta<i>(*it); }
|
|
}
|
|
|
|
/** Topological unsew by betai the given dart plus all the required darts
|
|
* to satisfy the combinatorial map validity: but do not update attributes
|
|
* thus the map can be non valid
|
|
* @param adart first dart.
|
|
* @pre !adart->is_free(i).
|
|
*/
|
|
template<unsigned int i>
|
|
void topo_unsew(Dart_handle adart)
|
|
{
|
|
if ( i==0 ) topo_unsew_0(adart);
|
|
else if ( i==1 ) topo_unsew_1(adart);
|
|
else topo_unsew_for_involution<i>(adart);
|
|
}
|
|
|
|
/** Unsew by beta0 the given dart plus all the required darts
|
|
* to satisfy the combinatorial map validity, and update enabled
|
|
* attributes when necessary so that the final map is valid.
|
|
* @param adart first dart.
|
|
* @pre !adart->is_free(0).
|
|
* @post is_valid()
|
|
*/
|
|
void unsew_0(Dart_handle adart)
|
|
{
|
|
CGAL_assertion( adart!=NULL && !adart->template is_free<0>() );
|
|
Dart_handle d2=NULL;
|
|
|
|
int m=get_new_mark();
|
|
std::deque<Dart_handle> dartv;
|
|
std::deque<Dart_handle> modified_darts;
|
|
std::deque<Dart_handle> modified_darts2;
|
|
|
|
for ( CGAL::CMap_dart_iterator_basic_of_cell<Self,0> it(*this, adart, m);
|
|
it.cont(); ++it )
|
|
{
|
|
mark(it, m);
|
|
dartv.push_back(it);
|
|
}
|
|
|
|
for ( CGAL::CMap_dart_iterator_of_involution<Self,1> it(*this, adart);
|
|
it.cont(); ++it )
|
|
{
|
|
if ( is_marked(it, m) )
|
|
{
|
|
modified_darts.push_back(it);
|
|
modified_darts2.push_back(it->template beta<0>());
|
|
unlink_beta_0(it);
|
|
}
|
|
else
|
|
{
|
|
modified_darts2.push_back(it);
|
|
modified_darts.push_back(it->template beta<1>());
|
|
unlink_beta_1(it);
|
|
}
|
|
}
|
|
|
|
for ( typename std::deque<Dart_handle>::iterator it=dartv.begin();
|
|
it!=dartv.end(); ++it )
|
|
{ unmark(*it,m); }
|
|
|
|
CGAL_assertion( is_whole_map_unmarked(m) );
|
|
free_mark(m);
|
|
|
|
// We test the split of all the incident cells for all the non
|
|
// void attributes.
|
|
Helper::template Foreach_enabled_attributes_except
|
|
<CGAL::internal::Test_split_attribute_functor<Self,0>, 1>::
|
|
run(this, modified_darts, modified_darts2);
|
|
}
|
|
|
|
/** Unsew by beta1 the given dart plus all the required darts
|
|
* to satisfy the combinatorial map validity, and update enabled
|
|
* attributes when necessary so that the final map is valid.
|
|
* @param adart first dart.
|
|
* @pre !adart->is_free(1).
|
|
* @post is_valid()
|
|
*/
|
|
void unsew_1(Dart_handle adart)
|
|
{
|
|
CGAL_assertion( adart!=NULL && !adart->is_free(1) );
|
|
Dart_handle d2 = NULL;
|
|
|
|
int m = get_new_mark();
|
|
std::deque<Dart_handle> dartv;
|
|
std::deque<Dart_handle> modified_darts;
|
|
std::deque<Dart_handle> modified_darts2;
|
|
|
|
for ( CGAL::CMap_dart_iterator_basic_of_cell<Self,0>
|
|
it(*this, adart, m); it.cont(); ++it)
|
|
{
|
|
mark(it, m);
|
|
dartv.push_back(it);
|
|
}
|
|
|
|
for ( CGAL::CMap_dart_iterator_of_involution<Self, 1> it(*this, adart);
|
|
it.cont(); ++it )
|
|
{
|
|
if ( is_marked(it, m) )
|
|
{
|
|
modified_darts2.push_back(it);
|
|
modified_darts.push_back(it->template beta<1>());
|
|
unlink_beta_1(it);
|
|
}
|
|
else
|
|
{
|
|
modified_darts.push_back(it);
|
|
modified_darts2.push_back(it->template beta<0>());
|
|
unlink_beta_0(it);
|
|
}
|
|
}
|
|
|
|
for ( typename std::deque<Dart_handle>::iterator
|
|
it=dartv.begin(); it!=dartv.end(); ++it)
|
|
{ unmark(*it, m); }
|
|
CGAL_assertion( is_whole_map_unmarked(m) );
|
|
free_mark(m);
|
|
|
|
// We test the split of all the incident cells for all the non
|
|
// void attributes.
|
|
Helper::template Foreach_enabled_attributes_except
|
|
<CGAL::internal::Test_split_attribute_functor<Self,1>, 1>::
|
|
run(this, modified_darts, modified_darts2);
|
|
}
|
|
|
|
/** Unsew by betai the given dart plus all the required darts
|
|
* to satisfy the combinatorial map validity, and update enabled
|
|
* attributes when necessary so that the final map is valid.
|
|
* @param adart first dart.
|
|
* @pre !adart->is_free(i).
|
|
* @post is_valid()
|
|
* @pre 2<=i<=dimension
|
|
*/
|
|
template<unsigned int i>
|
|
void unsew_for_involution(Dart_handle adart)
|
|
{
|
|
CGAL_assertion(2<=i && i<=Self::dimension);
|
|
CGAL_assertion( adart!=NULL && !adart->is_free(i) );
|
|
|
|
std::deque<Dart_handle> modified_darts;
|
|
|
|
for ( CGAL::CMap_dart_iterator_of_involution<Self, i> it(*this, adart);
|
|
it.cont(); ++it )
|
|
{
|
|
modified_darts.push_back(it);
|
|
modified_darts.push_back(it->template beta<i>());
|
|
unlink_beta_for_involution<i>(it);
|
|
}
|
|
|
|
// We test the split of all the incident cells for all the non
|
|
// void attributes.
|
|
Helper::template Foreach_enabled_attributes_except
|
|
<CGAL::internal::Test_split_attribute_functor<Self, i>, i>::
|
|
run(this, modified_darts);
|
|
}
|
|
|
|
/** Unsew by betai the given dart plus all the required darts
|
|
* to satisfy the combinatorial map validity, and update enabled
|
|
* attributes when necessary so that the final map is valid.
|
|
* @param adart first dart.
|
|
* @pre !adart->is_free(i).
|
|
* @post is_valid()
|
|
*/
|
|
template<unsigned int i>
|
|
void unsew(Dart_handle adart)
|
|
{
|
|
if ( i==0 ) unsew_0(adart);
|
|
else if ( i==1 ) unsew_1(adart);
|
|
else unsew_for_involution<i>(adart);
|
|
}
|
|
|
|
/** Unsew by betai the given dart plus all the required darts
|
|
* to satisfy the combinatorial map validity. Enabled attributes
|
|
* are updated only if update_attributes==true.
|
|
* @param adart first dart.
|
|
* @param update_attributes a boolean to update the enabled attributes
|
|
* @pre !adart->is_free(i).
|
|
*/
|
|
template<unsigned int i>
|
|
void unsew(Dart_handle adart, bool update_attributes)
|
|
{
|
|
if ( update_attributes ) unsew<i>(adart);
|
|
else topo_unsew<i>(adart);
|
|
}
|
|
|
|
/** Count the marked cells (at least one marked dart).
|
|
* @param amark the mark to consider.
|
|
* @param avector containing the dimensions of the cells to count.
|
|
* @return a vector containing the number of cells.
|
|
*/
|
|
std::vector<unsigned int>
|
|
count_marked_cells(int amark, const std::vector<unsigned int>& acells) const
|
|
{
|
|
std::vector<unsigned int> res(dimension+2);
|
|
std::vector<int> marks(dimension+2);
|
|
|
|
// Initialization of the result
|
|
for ( unsigned int i=0; i<dimension+2; ++i)
|
|
{
|
|
res[i]=0;
|
|
marks[i]=-1;
|
|
}
|
|
|
|
// Mark reservation
|
|
for ( unsigned int i=0; i<acells.size(); ++i)
|
|
{
|
|
CGAL_assertion(acells[i]<=dimension+1);
|
|
if ( marks[acells[i]]==-1 )
|
|
{
|
|
marks[acells[i]] = get_new_mark();
|
|
}
|
|
}
|
|
|
|
// Counting and marking cells
|
|
for ( typename Dart_range::const_iterator it(darts().begin()),
|
|
itend(darts().end()); it!=itend; ++it)
|
|
{
|
|
if ( is_marked(it, amark) )
|
|
{
|
|
CGAL::internal::Foreach_static
|
|
<CGAL::internal::Count_cell_functor<Self>,dimension+1>::
|
|
run(this, it, &marks, &res);
|
|
}
|
|
}
|
|
|
|
// Unmarking darts
|
|
std::vector<unsigned int> tounmark;
|
|
for ( unsigned int i=0; i<acells.size(); ++i)
|
|
{
|
|
if ( is_whole_map_marked(marks[acells[i]]) ||
|
|
is_whole_map_unmarked(marks[acells[i]]))
|
|
{
|
|
free_mark(marks[acells[i]]);
|
|
}
|
|
else
|
|
{
|
|
tounmark.push_back(marks[acells[i]]);
|
|
}
|
|
}
|
|
|
|
if ( tounmark.size() > 0 )
|
|
{
|
|
for ( typename Dart_range::const_iterator it(darts().begin()),
|
|
itend(darts().end()); it!=itend; ++it)
|
|
{
|
|
for ( unsigned int i=0; i<tounmark.size(); ++i)
|
|
unmark(it, tounmark[i]);
|
|
}
|
|
for ( unsigned int i=0; i<tounmark.size(); ++i)
|
|
{
|
|
CGAL_assertion(is_whole_map_unmarked(tounmark[i]));
|
|
free_mark(tounmark[i]);
|
|
}
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
/** Count the number of given cells
|
|
* @param avector containing the dimensions of the cells to count.
|
|
* @return a vector containing the number of cells.
|
|
*/
|
|
std::vector<unsigned int>
|
|
count_cells(const std::vector<unsigned int>& acells) const
|
|
{
|
|
std::vector<unsigned int> res;
|
|
int m = get_new_mark();
|
|
negate_mark(m); // We mark all the cells.
|
|
|
|
res = count_marked_cells(m, acells);
|
|
|
|
negate_mark(m); // We unmark the cells
|
|
free_mark(m);
|
|
|
|
return res;
|
|
}
|
|
|
|
/** Count the number of cells in each dimension.
|
|
* @return a vector containing the number of cells.
|
|
*/
|
|
std::vector<unsigned int> count_all_cells() const
|
|
{
|
|
std::vector<unsigned int> dim(dimension+2);
|
|
|
|
for ( unsigned int i=0; i<dimension+2; ++i)
|
|
dim[i]=i;
|
|
|
|
return count_cells(dim);
|
|
}
|
|
|
|
protected:
|
|
/** Set simultaneously all the marks of a given dart.
|
|
* @param adart the dart.
|
|
* @param amarks the marks to set.
|
|
*/
|
|
void set_marks(Dart_handle adart,
|
|
const std::bitset<NB_MARKS> & amarks) const
|
|
{
|
|
CGAL_assertion(adart != NULL && adart!=null_dart_handle);
|
|
adart->set_marks(amarks ^ mmask_marks);
|
|
}
|
|
|
|
/** Get simultaneously all the marks of a given dart.
|
|
* @param adart the dart.
|
|
* @return allt the marks of adart.
|
|
*/
|
|
std::bitset<NB_MARKS> get_marks(Dart_handle adart) const
|
|
{
|
|
CGAL_assertion(adart != NULL && adart!=null_dart_handle);
|
|
return adart->get_marks() ^ mmask_marks;
|
|
}
|
|
|
|
/** Get the mask associated to a given mark.
|
|
* @param amark the mark.
|
|
* @return the mask associated to mark amark.
|
|
*/
|
|
bool get_mask_mark(int amark) const
|
|
{
|
|
CGAL_assertion(amark>=0 && (size_type)amark<NB_MARKS);
|
|
return mmask_marks[(size_type)amark];
|
|
}
|
|
|
|
public:
|
|
/** Erase marked darts from the map.
|
|
* Marked darts are unlinked before to be removed, thus surviving darts
|
|
* are correctly linked, but the map is not necessarily valid depending
|
|
* on the configuration of removed darts. User must check carefully marked
|
|
* darts before calling this method.
|
|
* @param amark the mark of darts to erase.
|
|
* @return the number of removed darts.
|
|
*/
|
|
unsigned int erase_marked_darts(int amark)
|
|
{
|
|
unsigned int res = 0, i = 0;
|
|
Dart_handle d;
|
|
for ( typename Dart_range::iterator it(darts().begin()),
|
|
itend(darts().end()); it!=itend; )
|
|
{
|
|
d = it++;
|
|
if (is_marked(d, amark))
|
|
{
|
|
for ( i = 0; i <= dimension; ++i)
|
|
{ if (!d->is_free(i)) unlink_beta(d, i); }
|
|
erase_dart(d); ++res;
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
|
|
//**************************************************************************
|
|
// Dart_of_orbit_basic_range
|
|
template<unsigned int ... Beta>
|
|
struct Dart_of_orbit_basic_range : public CGAL::CMap_range
|
|
<Self, CGAL::CMap_dart_iterator_basic_of_orbit<Self,Beta...>,
|
|
CGAL::CMap_dart_const_iterator_basic_of_orbit<Self,Beta...> >
|
|
{
|
|
typedef CGAL::CMap_range
|
|
<Self, CGAL::CMap_dart_iterator_basic_of_orbit<Self,Beta...>,
|
|
CGAL::CMap_dart_const_iterator_basic_of_orbit<Self,Beta...> > Base;
|
|
|
|
Dart_of_orbit_basic_range(Self &amap, Dart_handle adart, int amark=-1):
|
|
Base(amap, adart, amark)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
// Dart_of_orbit_basic_const_range
|
|
template<unsigned int ... Beta>
|
|
struct Dart_of_orbit_basic_const_range : public CGAL::CMap_const_range
|
|
<Self, CGAL::CMap_dart_const_iterator_basic_of_orbit<Self,Beta...> >
|
|
{
|
|
typedef CGAL::CMap_const_range
|
|
<Self, CGAL::CMap_dart_const_iterator_basic_of_orbit<Self,Beta...> >
|
|
Base;
|
|
|
|
Dart_of_orbit_basic_const_range(const Self &amap, Dart_const_handle
|
|
adart, int amark=-1):
|
|
Base(amap, adart, amark)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
// Dart_of_orbit_range
|
|
template<unsigned int ... Beta>
|
|
struct Dart_of_orbit_range : public CGAL::CMap_range
|
|
<Self, CGAL::CMap_dart_iterator_of_orbit<Self,Beta...>,
|
|
CGAL::CMap_dart_const_iterator_of_orbit<Self,Beta...> >
|
|
{
|
|
typedef CGAL::CMap_range
|
|
<Self, CGAL::CMap_dart_iterator_of_orbit<Self,Beta...>,
|
|
CGAL::CMap_dart_const_iterator_of_orbit<Self,Beta...> > Base;
|
|
|
|
Dart_of_orbit_range(Self &amap, Dart_handle adart) : Base(amap,adart)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
// Dart_of_orbit_const_range
|
|
template<unsigned int ... Beta>
|
|
struct Dart_of_orbit_const_range : public CGAL::CMap_const_range
|
|
<Self, CGAL::CMap_dart_const_iterator_of_orbit<Self,Beta...> >
|
|
{
|
|
typedef CGAL::CMap_const_range
|
|
<Self, CGAL::CMap_dart_const_iterator_of_orbit<Self,Beta...> > Base;
|
|
|
|
Dart_of_orbit_const_range(const Self &amap, Dart_const_handle adart):
|
|
Base(amap,adart)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
/// @return a range on all the darts of the given orbit
|
|
template<unsigned int ... Beta>
|
|
Dart_of_orbit_range<Beta...> darts_of_orbit(Dart_handle adart)
|
|
{ return Dart_of_orbit_range<Beta...>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int ... Beta>
|
|
Dart_of_orbit_const_range<Beta...>
|
|
darts_of_orbit(Dart_const_handle adart) const
|
|
{ return Dart_of_orbit_const_range<Beta...>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int ... Beta>
|
|
Dart_of_orbit_basic_range<Beta...> darts_of_orbit_basic(Dart_handle adart,
|
|
int amark=-1)
|
|
{ return Dart_of_orbit_basic_range<Beta...>(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int ... Beta>
|
|
Dart_of_orbit_basic_const_range<Beta...>
|
|
darts_of_orbit_basic(Dart_const_handle adart, int amark=-1) const
|
|
{ return Dart_of_orbit_basic_const_range<Beta...>(*this,adart,amark); }
|
|
//**************************************************************************
|
|
#else
|
|
//**************************************************************************
|
|
// Dart_of_orbit_basic_range
|
|
template<int B1=-1,int B2=-1,int B3=-1,int B4=-1,int B5=-1,
|
|
int B6=-1,int B7=-1,int B8=-1,int B9=-1>
|
|
struct Dart_of_orbit_basic_range: public CGAL::CMap_range
|
|
<Self, CGAL::CMap_dart_iterator_basic_of_orbit<Self,B1,B2,B3,B4,B5,B6,B7,
|
|
B8,B9>,
|
|
CGAL::CMap_dart_const_iterator_basic_of_orbit<Self,B1,B2,B3,B4,B5,B6,B7,
|
|
B8,B9> >
|
|
{
|
|
typedef CGAL::CMap_range
|
|
<Self, CGAL::CMap_dart_iterator_basic_of_orbit<Self,B1,B2,B3,B4,B5,B6,B7,
|
|
B8,B9>,
|
|
CGAL::CMap_dart_const_iterator_basic_of_orbit<Self,B1,B2,B3,B4,B5,
|
|
B6,B7,B8,B9> > Base;
|
|
|
|
Dart_of_orbit_basic_range(Self &amap, Dart_handle adart,
|
|
int /*amark*/=-1):
|
|
Base(amap, adart)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
// Dart_of_orbit_basic_const_range
|
|
template<int B1=-1,int B2=-1,int B3=-1,int B4=-1,int B5=-1,
|
|
int B6=-1,int B7=-1,int B8=-1,int B9=-1>
|
|
struct Dart_of_orbit_basic_const_range: public CMap_const_range
|
|
<Self,
|
|
CGAL::CMap_dart_const_iterator_basic_of_orbit<Self,B1,B2,B3,B4,B5,B6,B7,
|
|
B8,B9> >
|
|
{
|
|
typedef CMap_const_range
|
|
<Self, CGAL::CMap_dart_const_iterator_basic_of_orbit
|
|
<Self,B1,B2,B3,B4,B5,B6,B7,B8,B9> > Base;
|
|
|
|
Dart_of_orbit_basic_const_range(const Self &amap,
|
|
Dart_const_handle adart, int amark=-1):
|
|
Base(amap, adart, amark)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
// Dart_of_orbit_range
|
|
template<int B1=-1,int B2=-1,int B3=-1,int B4=-1,int B5=-1,
|
|
int B6=-1,int B7=-1,int B8=-1,int B9=-1>
|
|
struct Dart_of_orbit_range: public CGAL::CMap_range
|
|
<Self, CGAL::CMap_dart_iterator_of_orbit<Self,B1,B2,B3,B4,B5,B6,B7,B8,B9>,
|
|
CGAL::CMap_dart_const_iterator_of_orbit<Self,B1,B2,B3,B4,B5,B6,B7,B8,B9> >
|
|
{
|
|
typedef CGAL::CMap_range
|
|
<Self, CGAL::CMap_dart_iterator_of_orbit<Self,B1,B2,B3,B4,B5,B6,B7,
|
|
B8,B9>,
|
|
CGAL::CMap_dart_const_iterator_of_orbit<Self,B1,B2,B3,B4,B5,B6,B7,
|
|
B8,B9> >
|
|
Base;
|
|
|
|
Dart_of_orbit_range(Self &amap, Dart_handle adart):
|
|
Base(amap, adart)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
// Dart_of_orbit_const_range
|
|
template<int B1=-1,int B2=-1,int B3=-1,int B4=-1,int B5=-1,
|
|
int B6=-1,int B7=-1,int B8=-1,int B9=-1>
|
|
struct Dart_of_orbit_const_range: public CMap_const_range
|
|
<Self, CGAL::CMap_dart_const_iterator_of_orbit<Self,B1,B2,B3,B4,B5,B6,B7,
|
|
B8,B9> >
|
|
{
|
|
typedef CMap_const_range
|
|
<Self, CGAL::CMap_dart_const_iterator_of_orbit
|
|
<Self,B1,B2,B3,B4,B5,B6,B7,B8,B9> > Base;
|
|
|
|
Dart_of_orbit_const_range(const Self &amap, Dart_const_handle adart):
|
|
Base(amap, adart)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
/// @return a range on all the darts of the given orbit
|
|
Dart_of_orbit_range<> darts_of_orbit(Dart_handle adart)
|
|
{ return Dart_of_orbit_range<>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1>
|
|
Dart_of_orbit_range<B1> darts_of_orbit(Dart_handle adart)
|
|
{ return Dart_of_orbit_range<B1>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2>
|
|
Dart_of_orbit_range<B1,B2> darts_of_orbit(Dart_handle adart)
|
|
{ return Dart_of_orbit_range<B1,B2>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3>
|
|
Dart_of_orbit_range<B1,B2,B3> darts_of_orbit(Dart_handle adart)
|
|
{ return Dart_of_orbit_range<B1,B2,B3>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4>
|
|
Dart_of_orbit_range<B1,B2,B3,B4> darts_of_orbit(Dart_handle adart)
|
|
{ return Dart_of_orbit_range<B1,B2,B3,B4>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,
|
|
unsigned int B5>
|
|
Dart_of_orbit_range<B1,B2,B3,B4,B5> darts_of_orbit(Dart_handle adart)
|
|
{ return Dart_of_orbit_range<B1,B2,B3,B4,B5>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,
|
|
unsigned int B5,unsigned int B6>
|
|
Dart_of_orbit_range<B1,B2,B3,B4,B5,B6> darts_of_orbit(Dart_handle adart)
|
|
{ return Dart_of_orbit_range<B1,B2,B3,B4,B5,B6>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,
|
|
unsigned int B5,unsigned int B6,unsigned int B7>
|
|
Dart_of_orbit_range<B1,B2,B3,B4,B5,B6,B7> darts_of_orbit(Dart_handle adart)
|
|
{ return Dart_of_orbit_range<B1,B2,B3,B4,B5,B6,B7>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,
|
|
unsigned int B5,unsigned int B6,unsigned int B7,unsigned int B8>
|
|
Dart_of_orbit_range<B1,B2,B3,B4,B5,B6,B7,B8> darts_of_orbit
|
|
(Dart_handle adart)
|
|
{ return Dart_of_orbit_range<B1,B2,B3,B4,B5,B6,B7,B8>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,
|
|
unsigned int B5,unsigned int B6,unsigned int B7,unsigned int B8,
|
|
unsigned int B9>
|
|
Dart_of_orbit_range<B1,B2,B3,B4,B5,B6,B7,B8,B9>
|
|
darts_of_orbit(Dart_handle adart)
|
|
{ return Dart_of_orbit_range<B1,B2,B3,B4,B5,B6,B7,B8,B9>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
// Const versions.
|
|
Dart_of_orbit_const_range<> darts_of_orbit(Dart_const_handle adart) const
|
|
{ return Dart_of_orbit_const_range<>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1>
|
|
Dart_of_orbit_const_range<B1> darts_of_orbit(Dart_const_handle
|
|
adart) const
|
|
{ return Dart_of_orbit_const_range<B1>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2>
|
|
Dart_of_orbit_const_range<B1,B2> darts_of_orbit(Dart_const_handle
|
|
adart) const
|
|
{ return Dart_of_orbit_const_range<B1,B2>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3>
|
|
Dart_of_orbit_const_range<B1,B2,B3> darts_of_orbit
|
|
(Dart_const_handle adart) const
|
|
{ return Dart_of_orbit_const_range<B1,B2,B3>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4>
|
|
Dart_of_orbit_const_range<B1,B2,B3,B4>
|
|
darts_of_orbit(Dart_const_handle adart) const
|
|
{ return Dart_of_orbit_const_range<B1,B2,B3,B4>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,
|
|
unsigned int B5>
|
|
Dart_of_orbit_const_range<B1,B2,B3,B4,B5>
|
|
darts_of_orbit(Dart_const_handle adart) const
|
|
{ return Dart_of_orbit_const_range<B1,B2,B3,B4,B5>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,
|
|
unsigned int B5,unsigned int B6>
|
|
Dart_of_orbit_const_range<B1,B2,B3,B4,B5,B6>
|
|
darts_of_orbit(Dart_const_handle adart) const
|
|
{ return Dart_of_orbit_const_range<B1,B2,B3,B4,B5,B6>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,
|
|
unsigned int B5,unsigned int B6,unsigned int B7>
|
|
Dart_of_orbit_const_range<B1,B2,B3,B4,B5,B6,B7>
|
|
darts_of_orbit(Dart_const_handle adart) const
|
|
{ return Dart_of_orbit_const_range<B1,B2,B3,B4,B5,B6,B7>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,
|
|
unsigned int B5,unsigned int B6,unsigned int B7,unsigned int B8>
|
|
Dart_of_orbit_const_range<B1,B2,B3,B4,B5,B6,B7,B8>
|
|
darts_of_orbit(Dart_const_handle adart) const
|
|
{ return Dart_of_orbit_const_range<B1,B2,B3,B4,B5,B6,B7,B8>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,
|
|
unsigned int B5,unsigned int B6,unsigned int B7,unsigned int B8,
|
|
unsigned int B9>
|
|
Dart_of_orbit_const_range<B1,B2,B3,B4,B5,B6,B7,B8,B9>
|
|
darts_of_orbit(Dart_const_handle adart) const
|
|
{ return Dart_of_orbit_const_range<B1,B2,B3,B4,B5,B6,B7,B8,B9>
|
|
(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
// Basic versions
|
|
Dart_of_orbit_basic_range<> darts_of_orbit_basic(Dart_handle adart,
|
|
int amark=-1)
|
|
{ return Dart_of_orbit_basic_range<>(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
Dart_of_orbit_basic_const_range<> darts_of_orbit_basic
|
|
(Dart_const_handle adart,int amark=-1) const
|
|
{ return Dart_of_orbit_basic_const_range<>(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1>
|
|
Dart_of_orbit_basic_range<B1> darts_of_orbit_basic(Dart_handle adart,
|
|
int amark=-1)
|
|
{ return Dart_of_orbit_basic_range<B1>(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1>
|
|
Dart_of_orbit_basic_const_range<B1> darts_of_orbit_basic
|
|
(Dart_const_handle adart, int amark=-1) const
|
|
{ return Dart_of_orbit_basic_const_range<B1>(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2>
|
|
Dart_of_orbit_basic_range<B1,B2> darts_of_orbit_basic(Dart_handle adart,
|
|
int amark=-1)
|
|
{ return Dart_of_orbit_basic_range<B1,B2>(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2>
|
|
Dart_of_orbit_basic_const_range<B1,B2> darts_of_orbit_basic
|
|
(Dart_const_handle adart, int amark=-1) const
|
|
{ return Dart_of_orbit_basic_const_range<B1,B2>(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3>
|
|
Dart_of_orbit_basic_range<B1,B2,B3> darts_of_orbit_basic(Dart_handle adart,
|
|
int amark=-1)
|
|
{ return Dart_of_orbit_basic_range<B1,B2,B3>(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3>
|
|
Dart_of_orbit_basic_const_range<B1,B2,B3> darts_of_orbit_basic
|
|
(Dart_const_handle adart, int amark=-1) const
|
|
{ return Dart_of_orbit_basic_const_range<B1,B2,B3>(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4>
|
|
Dart_of_orbit_basic_range<B1,B2,B3,B4> darts_of_orbit_basic
|
|
(Dart_handle adart, int amark=-1)
|
|
{ return Dart_of_orbit_basic_range<B1,B2,B3,B4>(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4>
|
|
Dart_of_orbit_basic_const_range<B1,B2,B3,B4>
|
|
darts_of_orbit_basic(Dart_const_handle adart, int amark=-1) const
|
|
{ return Dart_of_orbit_basic_const_range<B1,B2,B3,B4>(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,
|
|
unsigned int B5>
|
|
Dart_of_orbit_basic_range<B1,B2,B3,B4,B5> darts_of_orbit_basic
|
|
(Dart_handle adart, int amark=-1)
|
|
{ return Dart_of_orbit_basic_range<B1,B2,B3,B4,B5>(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,
|
|
unsigned int B5>
|
|
Dart_of_orbit_basic_const_range<B1,B2,B3,B4,B5>
|
|
darts_of_orbit_basic(Dart_const_handle adart, int amark=-1) const
|
|
{ return Dart_of_orbit_basic_const_range<B1,B2,B3,B4,B5>
|
|
(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,
|
|
unsigned int B5,unsigned int B6>
|
|
Dart_of_orbit_basic_range<B1,B2,B3,B4,B5,B6> darts_of_orbit_basic
|
|
(Dart_handle adart, int amark=-1)
|
|
{ return Dart_of_orbit_basic_range<B1,B2,B3,B4,B5,B6>(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,
|
|
unsigned int B5,unsigned int B6>
|
|
Dart_of_orbit_basic_const_range<B1,B2,B3,B4,B5,B6>
|
|
darts_of_orbit_basic(Dart_const_handle adart, int amark=-1) const
|
|
{ return Dart_of_orbit_basic_const_range<B1,B2,B3,B4,B5,B6>
|
|
(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,
|
|
unsigned int B5,unsigned int B6,unsigned int B7>
|
|
Dart_of_orbit_basic_range<B1,B2,B3,B4,B5,B6,B7> darts_of_orbit_basic
|
|
(Dart_handle adart, int amark=-1)
|
|
{ return Dart_of_orbit_basic_range<B1,B2,B3,B4,B5,B6,B7>
|
|
(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,
|
|
unsigned int B5,unsigned int B6,unsigned int B7>
|
|
Dart_of_orbit_basic_const_range<B1,B2,B3,B4,B5,B6,B7>
|
|
darts_of_orbit_basic(Dart_const_handle adart, int amark=-1) const
|
|
{ return Dart_of_orbit_basic_const_range<B1,B2,B3,B4,B5,B6,B7>
|
|
(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,
|
|
unsigned int B5,unsigned int B6,unsigned int B7,unsigned int B8>
|
|
Dart_of_orbit_basic_range<B1,B2,B3,B4,B5,B6,B7,B8> darts_of_orbit
|
|
(Dart_handle adart, int amark=-1)
|
|
{ return Dart_of_orbit_basic_range<B1,B2,B3,B4,B5,B6,B7,B8>
|
|
(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,
|
|
unsigned int B5,unsigned int B6,unsigned int B7,unsigned int B8>
|
|
Dart_of_orbit_basic_const_range<B1,B2,B3,B4,B5,B6,B7,B8>
|
|
darts_of_orbit_basic(Dart_const_handle adart, int amark=-1) const
|
|
{ return Dart_of_orbit_basic_const_range<B1,B2,B3,B4,B5,B6,B7,B8>
|
|
(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,
|
|
unsigned int B5,unsigned int B6,unsigned int B7,unsigned int B8,
|
|
unsigned int B9>
|
|
Dart_of_orbit_basic_range<B1,B2,B3,B4,B5,B6,B7,B8,B9>
|
|
darts_of_orbit_basic(Dart_handle adart, int amark=-1)
|
|
{ return Dart_of_orbit_basic_range<B1,B2,B3,B4,B5,B6,B7,B8,B9>
|
|
(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template <unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,
|
|
unsigned int B5,unsigned int B6,unsigned int B7,unsigned int B8,
|
|
unsigned int B9>
|
|
Dart_of_orbit_basic_const_range<B1,B2,B3,B4,B5,B6,B7,B8,B9>
|
|
darts_of_orbit_basic(Dart_const_handle adart, int amark=-1) const
|
|
{ return Dart_of_orbit_basic_const_range<B1,B2,B3,B4,B5,B6,B7,B8,B9>
|
|
(*this,adart,amark); }
|
|
//**************************************************************************
|
|
#endif //CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
|
|
//**************************************************************************
|
|
// Dart_of_cell_basic_range
|
|
template<unsigned int i,int dim=Self::dimension>
|
|
struct Dart_of_cell_basic_range: public CGAL::CMap_range
|
|
<Self, CGAL::CMap_dart_iterator_basic_of_cell<Self,i,dim>,
|
|
CGAL::CMap_dart_const_iterator_basic_of_cell<Self,i,dim> >
|
|
{
|
|
typedef CGAL::CMap_range
|
|
<Self, CGAL::CMap_dart_iterator_basic_of_cell<Self,i,dim>,
|
|
CGAL::CMap_dart_const_iterator_basic_of_cell<Self,i,dim> > Base;
|
|
|
|
Dart_of_cell_basic_range(Self &amap, Dart_handle adart, int amark=-1) :
|
|
Base(amap, adart, amark)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
// Dart_of_cell_basic_const_range
|
|
template<unsigned int i,int dim=Self::dimension>
|
|
struct Dart_of_cell_basic_const_range: public CMap_const_range
|
|
<Self, CGAL::CMap_dart_const_iterator_basic_of_cell<Self,i,dim> >
|
|
{
|
|
typedef CMap_const_range
|
|
<Self, CGAL::CMap_dart_const_iterator_basic_of_cell<Self,i,dim> > Base;
|
|
|
|
Dart_of_cell_basic_const_range(const Self &amap, Dart_const_handle adart,
|
|
int amark=-1) :
|
|
Base(amap, adart, amark)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
// Dart_of_cell_range
|
|
template<unsigned int i,int dim=Self::dimension>
|
|
struct Dart_of_cell_range: public CGAL::CMap_range
|
|
<Self,CMap_dart_iterator_of_cell<Self,i,dim>,
|
|
CGAL::CMap_dart_const_iterator_of_cell<Self,i,dim> >
|
|
{
|
|
typedef CGAL::CMap_range
|
|
<Self,CMap_dart_iterator_of_cell<Self,i,dim>,
|
|
CGAL::CMap_dart_const_iterator_of_cell<Self,i,dim> > Base;
|
|
|
|
Dart_of_cell_range(Self &amap, Dart_handle adart) :
|
|
Base(amap, adart)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
// Dart_of_cell_const_range
|
|
template<unsigned int i,int dim=Self::dimension>
|
|
struct Dart_of_cell_const_range: public CMap_const_range
|
|
<Self, CGAL::CMap_dart_const_iterator_of_cell<Self,i,dim> >
|
|
{
|
|
typedef CMap_const_range
|
|
<Self, CGAL::CMap_dart_const_iterator_of_cell<Self,i,dim> > Base;
|
|
|
|
Dart_of_cell_const_range(const Self &amap, Dart_const_handle adart) :
|
|
Base(amap, adart)
|
|
{}
|
|
};
|
|
//--------------------------------------------------------------------------
|
|
/// @return a range on all the darts of the given i-cell
|
|
template<unsigned int i, int dim>
|
|
Dart_of_cell_basic_range<i,dim> darts_of_cell_basic(Dart_handle adart,
|
|
int amark=-1)
|
|
{ return Dart_of_cell_basic_range<i,dim>(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i, int dim>
|
|
Dart_of_cell_basic_const_range<i,dim> darts_of_cell_basic
|
|
(Dart_const_handle adart, int amark=-1) const
|
|
{ return Dart_of_cell_basic_const_range<i,dim>(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i>
|
|
Dart_of_cell_basic_range<i,Self::dimension>
|
|
darts_of_cell_basic(Dart_handle adart, int amark=-1)
|
|
{ return darts_of_cell_basic<i,Self::dimension>(adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i>
|
|
Dart_of_cell_basic_const_range<i,Self::dimension>
|
|
darts_of_cell_basic(Dart_const_handle adart, int amark=-1) const
|
|
{ return darts_of_cell_basic<i,Self::dimension>(adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i, int dim>
|
|
Dart_of_cell_range<i,dim> darts_of_cell(Dart_handle adart)
|
|
{ return Dart_of_cell_range<i,dim>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i, int dim>
|
|
Dart_of_cell_const_range<i,dim> darts_of_cell(Dart_const_handle adart) const
|
|
{ return Dart_of_cell_const_range<i,dim>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i>
|
|
Dart_of_cell_range<i,Self::dimension> darts_of_cell(Dart_handle adart)
|
|
{ return darts_of_cell<i,Self::dimension>(adart); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i>
|
|
Dart_of_cell_const_range<i,Self::dimension>
|
|
darts_of_cell(Dart_const_handle adart) const
|
|
{ return darts_of_cell<i,Self::dimension>(adart); }
|
|
//**************************************************************************
|
|
// Dart_of_involution_basic_range
|
|
template<unsigned int i,int dim=Self::dimension>
|
|
struct Dart_of_involution_basic_range: public CGAL::CMap_range
|
|
<Self, CGAL::CMap_dart_iterator_basic_of_involution<Self,i,dim>,
|
|
CGAL::CMap_dart_const_iterator_basic_of_involution<Self,i,dim> >
|
|
{
|
|
typedef CGAL::CMap_range
|
|
<Self, CGAL::CMap_dart_iterator_basic_of_involution<Self,i,dim>,
|
|
CGAL::CMap_dart_const_iterator_basic_of_involution<Self,i,dim> > Base;
|
|
|
|
Dart_of_involution_basic_range(Self &amap, Dart_handle adart,
|
|
int amark=-1):
|
|
Base(amap, adart, amark)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
// Dart_of_involution_basic_const_range
|
|
template<unsigned int i,int dim=Self::dimension>
|
|
struct Dart_of_involution_basic_const_range: public CMap_const_range
|
|
<Self, CGAL::CMap_dart_const_iterator_basic_of_involution<Self,i,dim> >
|
|
{
|
|
typedef CMap_const_range
|
|
<Self, CGAL::CMap_dart_const_iterator_basic_of_involution<Self,i,dim> >
|
|
Base;
|
|
|
|
Dart_of_involution_basic_const_range(const Self &amap,
|
|
Dart_const_handle adart,
|
|
int amark=-1) :
|
|
Base(amap, adart, amark)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
template<unsigned int i,int dim>
|
|
Dart_of_involution_basic_range<i,dim>
|
|
darts_of_involution_basic(Dart_handle adart, int amark=-1)
|
|
{ return Dart_of_involution_basic_range<i,dim>(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i,int dim>
|
|
Dart_of_involution_basic_const_range<i,dim>
|
|
darts_of_involution_basic(Dart_const_handle adart, int amark=-1) const
|
|
{ return Dart_of_involution_basic_const_range<i,dim>(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i>
|
|
Dart_of_involution_basic_range<i,Self::dimension>
|
|
darts_of_involution_basic(Dart_handle adart, int amark=-1)
|
|
{ return Dart_of_involution_basic_range<i,Self::dimension>
|
|
(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i>
|
|
Dart_of_involution_basic_const_range<i,Self::dimension>
|
|
darts_of_involution_basic(Dart_const_handle adart, int amark=-1) const
|
|
{ return Dart_of_involution_basic_const_range<i,Self::dimension>
|
|
(*this,adart,amark); }
|
|
//**************************************************************************
|
|
// Dart_of_involution_inv_basic_range
|
|
template<unsigned int i,int dim=Self::dimension>
|
|
struct Dart_of_involution_inv_basic_range: public CGAL::CMap_range
|
|
<Self, CGAL::CMap_dart_iterator_basic_of_involution_inv<Self,i,dim>,
|
|
CGAL::CMap_dart_const_iterator_basic_of_involution_inv<Self,i,dim> >
|
|
{
|
|
typedef CGAL::CMap_range
|
|
<Self, CGAL::CMap_dart_iterator_basic_of_involution_inv<Self,i,dim>,
|
|
CGAL::CMap_dart_const_iterator_basic_of_involution_inv<Self,i,dim> >
|
|
Base;
|
|
|
|
Dart_of_involution_inv_basic_range(Self &amap, Dart_handle adart,
|
|
int amark=-1):
|
|
Base(amap, adart, amark)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
// Dart_of_involution_inv_basic_const_range
|
|
template<unsigned int i,int dim=Self::dimension>
|
|
struct Dart_of_involution_inv_basic_const_range: public CMap_const_range
|
|
<Self, CGAL::CMap_dart_const_iterator_basic_of_involution_inv<Self,i,dim> >
|
|
{
|
|
typedef CMap_const_range
|
|
<Self, CGAL::CMap_dart_const_iterator_basic_of_involution_inv
|
|
<Self,i,dim> >
|
|
Base;
|
|
|
|
Dart_of_involution_inv_basic_const_range(const Self &amap,
|
|
Dart_const_handle adart,
|
|
int amark=-1) :
|
|
Base(amap, adart, amark)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
template<unsigned int i,int dim>
|
|
Dart_of_involution_inv_basic_range<i,dim>
|
|
darts_of_involution_inv_basic(Dart_handle adart, int amark=-1)
|
|
{ return Dart_of_involution_inv_basic_range<i,dim>(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i,int dim>
|
|
Dart_of_involution_inv_basic_const_range<i,dim>
|
|
darts_of_involution_inv_basic(Dart_const_handle adart, int amark=-1) const
|
|
{ return Dart_of_involution_inv_basic_const_range<i,dim>
|
|
(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i>
|
|
Dart_of_involution_inv_basic_range<i,Self::dimension>
|
|
darts_of_involution_inv_basic(Dart_handle adart, int amark=-1)
|
|
{ return Dart_of_involution_inv_basic_range<i,Self::dimension>
|
|
(*this,adart,amark); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i>
|
|
Dart_of_involution_inv_basic_const_range<i,Self::dimension>
|
|
darts_of_involution_inv_basic(Dart_const_handle adart, int amark=-1) const
|
|
{ return Dart_of_involution_inv_basic_const_range<i,Self::dimension>
|
|
(*this,adart,amark); }
|
|
//**************************************************************************
|
|
// Dart_of_involution_range
|
|
template<unsigned int i,int dim=Self::dimension>
|
|
struct Dart_of_involution_range: public CGAL::CMap_range
|
|
<Self, CGAL::CMap_dart_iterator_of_involution<Self,i,dim>,
|
|
CGAL::CMap_dart_const_iterator_of_involution<Self,i,dim> >
|
|
{
|
|
typedef CGAL::CMap_range
|
|
<Self, CGAL::CMap_dart_iterator_of_involution<Self,i,dim>,
|
|
CGAL::CMap_dart_const_iterator_of_involution<Self,i,dim> > Base;
|
|
|
|
Dart_of_involution_range(Self &amap, Dart_handle adart) :
|
|
Base(amap, adart)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
// Dart_of_involution_const_range
|
|
template<unsigned int i,int dim=Self::dimension>
|
|
struct Dart_of_involution_const_range: public CMap_const_range
|
|
<Self, CGAL::CMap_dart_const_iterator_of_involution<Self,i,dim> >
|
|
{
|
|
typedef CMap_const_range
|
|
<Self, CGAL::CMap_dart_const_iterator_of_involution<Self,i,dim> > Base;
|
|
|
|
Dart_of_involution_const_range(const Self &amap,
|
|
Dart_const_handle adart):
|
|
Base(amap, adart)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
template<unsigned int i,int dim>
|
|
Dart_of_involution_range<i,dim>
|
|
darts_of_involution(Dart_handle adart)
|
|
{ return Dart_of_involution_range<i,dim>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i,int dim>
|
|
Dart_of_involution_const_range<i,dim>
|
|
darts_of_involution(Dart_const_handle adart) const
|
|
{ return Dart_of_involution_const_range<i,dim>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i>
|
|
Dart_of_involution_range<i,Self::dimension>
|
|
darts_of_involution(Dart_handle adart)
|
|
{ return Dart_of_involution_range<i,Self::dimension>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i>
|
|
Dart_of_involution_const_range<i,Self::dimension>
|
|
darts_of_involution(Dart_const_handle adart) const
|
|
{ return Dart_of_involution_const_range<i,Self::dimension>(*this,adart); }
|
|
//**************************************************************************
|
|
// Dart_of_involution_inv_range
|
|
template<unsigned int i,int dim=Self::dimension>
|
|
struct Dart_of_involution_inv_range: public CGAL::CMap_range
|
|
<Self, CGAL::CMap_dart_iterator_of_involution_inv<Self,i,dim>,
|
|
CGAL::CMap_dart_const_iterator_of_involution_inv<Self,i,dim> >
|
|
{
|
|
typedef CGAL::CMap_range
|
|
<Self, CGAL::CMap_dart_iterator_of_involution_inv<Self,i,dim>,
|
|
CGAL::CMap_dart_const_iterator_of_involution_inv<Self,i,dim> > Base;
|
|
|
|
Dart_of_involution_inv_range(Self &amap, Dart_handle adart) :
|
|
Base(amap, adart)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
// Dart_of_involution_inv_const_range
|
|
template<unsigned int i,int dim=Self::dimension>
|
|
struct Dart_of_involution_inv_const_range: public CMap_const_range
|
|
<Self, CGAL::CMap_dart_const_iterator_of_involution_inv<Self,i,dim> >
|
|
{
|
|
typedef CMap_const_range
|
|
<Self, CGAL::CMap_dart_const_iterator_of_involution_inv<Self,i,dim> >
|
|
Base;
|
|
|
|
Dart_of_involution_inv_const_range(const Self &amap,
|
|
Dart_const_handle adart):
|
|
Base(amap, adart)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
template<unsigned int i,int dim>
|
|
Dart_of_involution_inv_range<i,dim>
|
|
darts_of_involution_inv(Dart_handle adart)
|
|
{ return Dart_of_involution_inv_range<i,dim>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i,int dim>
|
|
Dart_of_involution_inv_const_range<i,dim>
|
|
darts_of_involution_inv(Dart_const_handle adart) const
|
|
{ return Dart_of_involution_inv_const_range<i,dim>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i>
|
|
Dart_of_involution_inv_range<i,Self::dimension>
|
|
darts_of_involution_inv(Dart_handle adart)
|
|
{ return Dart_of_involution_inv_range<i,Self::dimension>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i>
|
|
Dart_of_involution_inv_const_range<i,Self::dimension>
|
|
darts_of_involution_inv(Dart_const_handle adart) const
|
|
{ return Dart_of_involution_inv_const_range<i,Self::dimension>
|
|
(*this,adart); }
|
|
//**************************************************************************
|
|
// Dart_basic_range
|
|
struct Dart_basic_range {
|
|
typedef CGAL::CMap_dart_iterator_basic_of_all<Self> iterator;
|
|
typedef CGAL::CMap_dart_const_iterator_basic_of_all<Self> const_iterator;
|
|
Dart_basic_range(Self &amap) : mmap(amap)
|
|
{}
|
|
iterator begin() { return iterator(mmap); }
|
|
iterator end() { return iterator(mmap,NULL); }
|
|
const_iterator begin() const { return const_iterator(mmap); }
|
|
const_iterator end() const { return const_iterator(mmap,NULL); }
|
|
size_type size()
|
|
{ return mmap.number_of_darts(); }
|
|
bool empty() const
|
|
{ return mmap.is_empty(); }
|
|
private:
|
|
Self & mmap;
|
|
};
|
|
//**************************************************************************
|
|
// Dart_basic_const_range
|
|
struct Dart_basic_const_range {
|
|
typedef CGAL::CMap_dart_const_iterator_basic_of_all<Self> const_iterator;
|
|
Dart_basic_const_range(Self &amap) : mmap(amap)
|
|
{}
|
|
const_iterator begin() const { return const_iterator(mmap); }
|
|
const_iterator end() const { return const_iterator(mmap,NULL); }
|
|
size_type size() const
|
|
{ return mmap.number_of_darts(); }
|
|
bool empty() const
|
|
{ return mmap.is_empty(); }
|
|
private:
|
|
const Self & mmap;
|
|
};
|
|
//**************************************************************************
|
|
Dart_basic_range darts_basic()
|
|
{ return Dart_basic_range(*this); }
|
|
//--------------------------------------------------------------------------
|
|
Dart_basic_const_range darts_basic() const
|
|
{ return Dart_basic_const_range(*this); }
|
|
//**************************************************************************
|
|
// One_dart_per_incident_cell_range
|
|
template<unsigned int i,unsigned int j,int dim=Self::dimension>
|
|
struct One_dart_per_incident_cell_range: public CGAL::CMap_range
|
|
<Self, CGAL::CMap_one_dart_per_incident_cell_iterator<Self,i,j,dim>,
|
|
CGAL::CMap_one_dart_per_incident_cell_const_iterator<Self,i,j,dim> >
|
|
{
|
|
typedef CGAL::CMap_range
|
|
<Self, CGAL::CMap_one_dart_per_incident_cell_iterator<Self,i,j,dim>,
|
|
CGAL::CMap_one_dart_per_incident_cell_const_iterator<Self,i,j,dim> >
|
|
Base;
|
|
|
|
One_dart_per_incident_cell_range(Self &amap, Dart_handle adart):
|
|
Base(amap, adart)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
// One_dart_per_incident_cell_const_range
|
|
template<unsigned int i,unsigned int j,int dim=Self::dimension>
|
|
struct One_dart_per_incident_cell_const_range: public CMap_const_range
|
|
<Self, CGAL::CMap_one_dart_per_incident_cell_const_iterator<Self,i,j,dim> >
|
|
{
|
|
typedef CMap_const_range
|
|
<Self, CGAL::CMap_one_dart_per_incident_cell_const_iterator
|
|
<Self,i,j,dim> > Base;
|
|
|
|
One_dart_per_incident_cell_const_range(const Self &amap,
|
|
Dart_const_handle adart) :
|
|
Base(amap, adart)
|
|
{}
|
|
};
|
|
//**************************************************************************
|
|
// One_dart_per_cell_range
|
|
template<unsigned int i,int dim=Self::dimension>
|
|
struct One_dart_per_cell_range {
|
|
typedef CGAL::CMap_one_dart_per_cell_iterator<Self,i,dim> iterator;
|
|
typedef CGAL::CMap_one_dart_per_cell_const_iterator<Self,i,dim>
|
|
const_iterator;
|
|
One_dart_per_cell_range(Self &amap) : mmap(amap), msize(0)
|
|
{}
|
|
iterator begin() { return iterator(mmap); }
|
|
iterator end() { return iterator(mmap,NULL); }
|
|
const_iterator begin() const { return const_iterator(mmap); }
|
|
const_iterator end() const { return const_iterator(mmap,NULL); }
|
|
size_type size()
|
|
{
|
|
if (msize==0)
|
|
for ( const_iterator it=begin(); it!=end(); ++it)
|
|
++msize;
|
|
return msize;
|
|
}
|
|
bool empty() const
|
|
{ return mmap.is_empty(); }
|
|
private:
|
|
Self & mmap;
|
|
size_type msize;
|
|
};
|
|
//**************************************************************************
|
|
// One_dart_per_cell_const_range
|
|
template<unsigned int i,int dim=Self::dimension>
|
|
struct One_dart_per_cell_const_range {
|
|
typedef CGAL::CMap_one_dart_per_cell_const_iterator<Self,i,dim>
|
|
const_iterator;
|
|
One_dart_per_cell_const_range(const Self &amap) : mmap(amap), msize(0)
|
|
{}
|
|
const_iterator begin() const { return const_iterator(mmap); }
|
|
const_iterator end() const { return const_iterator(mmap,NULL); }
|
|
size_type size()
|
|
{
|
|
if (msize==0)
|
|
for ( const_iterator it=begin(); it!=end(); ++it)
|
|
++msize;
|
|
return msize;
|
|
}
|
|
bool empty() const
|
|
{ return mmap.is_empty(); }
|
|
private:
|
|
const Self & mmap;
|
|
size_type msize;
|
|
};
|
|
//**************************************************************************
|
|
/// @return a range on the i-cells incindent to the given j-cell.
|
|
template<unsigned int i, unsigned int j, int dim>
|
|
One_dart_per_incident_cell_range<i,j,dim>
|
|
one_dart_per_incident_cell(Dart_handle adart)
|
|
{ return One_dart_per_incident_cell_range<i,j,dim>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i, unsigned int j, int dim>
|
|
One_dart_per_incident_cell_const_range<i,j,dim>
|
|
one_dart_per_incident_cell(Dart_const_handle adart) const
|
|
{ return One_dart_per_incident_cell_const_range<i,j,dim>(*this,adart); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i, unsigned int j>
|
|
One_dart_per_incident_cell_range<i,j,Self::dimension>
|
|
one_dart_per_incident_cell(Dart_handle adart)
|
|
{ return one_dart_per_incident_cell<i,j,Self::dimension>(adart); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i, unsigned int j>
|
|
One_dart_per_incident_cell_const_range<i,j,Self::dimension>
|
|
one_dart_per_incident_cell(Dart_const_handle adart) const
|
|
{ return one_dart_per_incident_cell<i,j,Self::dimension>(adart); }
|
|
//--------------------------------------------------------------------------
|
|
/// @return a range on all the i-cells
|
|
template<unsigned int i, int dim>
|
|
One_dart_per_cell_range<i,dim> one_dart_per_cell()
|
|
{ return One_dart_per_cell_range<i,dim>(*this); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i, int dim>
|
|
One_dart_per_cell_const_range<i,dim> one_dart_per_cell() const
|
|
{ return One_dart_per_cell_const_range<i,dim>(*this); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i>
|
|
One_dart_per_cell_range<i,Self::dimension> one_dart_per_cell()
|
|
{ return one_dart_per_cell<i,Self::dimension>(); }
|
|
//--------------------------------------------------------------------------
|
|
template<unsigned int i>
|
|
One_dart_per_cell_const_range<i,Self::dimension> one_dart_per_cell() const
|
|
{ return one_dart_per_cell<i,Self::dimension>(); }
|
|
//--------------------------------------------------------------------------
|
|
|
|
public:
|
|
|
|
/** Compute the dual of a Combinatorial_map.
|
|
* @param amap the cmap in which we build the dual of this map.
|
|
* @param adart a dart of the initial map, NULL by default.
|
|
* @return adart of the dual map, the dual of adart if adart!=NULL,
|
|
* any dart otherwise.
|
|
* As soon as we don't modify this map and amap map, we can iterate
|
|
* simultaneously through all the darts of the two maps and we have
|
|
* each time of the iteration two "dual" darts.
|
|
*/
|
|
Dart_handle dual(Self& amap, Dart_handle adart=NULL)
|
|
{
|
|
CGAL_assertion( is_without_boundary(dimension) );
|
|
|
|
CGAL::Unique_hash_map< Dart_handle, Dart_handle > dual;
|
|
Dart_handle d, d2, res = NULL;
|
|
|
|
// We clear amap. TODO return a new amap ? (but we need to make
|
|
// a copy contructor and =operator...)
|
|
amap.clear();
|
|
|
|
// We create a copy of all the dart of the map.
|
|
for ( typename Dart_range::iterator it=darts().begin();
|
|
it!=darts().end(); ++it)
|
|
{
|
|
dual[it] = amap.create_dart();
|
|
if ( it==adart && res==NULL ) res = dual[it];
|
|
}
|
|
|
|
// Then we link the darts by using the dual formula :
|
|
// G(B,b1,b2,...,bn-1,bn) =>
|
|
// dual(G)=(B, b(n-1)obn, b(n-2)obn,...,b1obn, bn)
|
|
// We suppose darts are run in the same order for both maps.
|
|
typename Dart_range::iterator it2=amap.darts().begin();
|
|
for ( typename Dart_range::iterator it=darts().begin();
|
|
it!=darts().end(); ++it, ++it2)
|
|
{
|
|
d = it2; // The supposition on the order allows to avoid d=dual[it];
|
|
CGAL_assertion( it2==dual[it] );
|
|
|
|
// First case outside the loop since we need to use link_beta1
|
|
if ( d->template is_free<1>() && it->template beta<dimension>()->
|
|
template beta<dimension-1>()!=null_dart_handle )
|
|
amap.basic_link_beta_1(d, dual[it->template beta<dimension>()->
|
|
template beta<dimension-1>()]);
|
|
|
|
// and during the loop we use link_beta(d1,d2,i)
|
|
for ( unsigned int i=dimension-2; i>=1; --i)
|
|
{
|
|
if ( d->is_free(dimension-i) &&
|
|
it->template beta<dimension>()->beta(i)!=null_dart_handle )
|
|
amap.basic_link_beta(d, dual[it->template beta<dimension>()->
|
|
beta(i)], dimension-i);
|
|
}
|
|
if ( d->template is_free<dimension>() )
|
|
{
|
|
CGAL_assertion ( !it->template is_free<dimension>() );
|
|
amap.basic_link_beta(d, dual[it->template beta<dimension>()],
|
|
dimension);
|
|
}
|
|
}
|
|
|
|
// CGAL_postcondition(amap2.is_valid());
|
|
|
|
if ( res==NULL ) res = amap.darts().begin();
|
|
return res;
|
|
}
|
|
|
|
/// Void dart. A dart d is i-free if beta_i(d)=null_dart_handle.
|
|
static Dart_handle null_dart_handle;
|
|
|
|
protected:
|
|
/// Dart container.
|
|
Dart_container mdarts;
|
|
|
|
/// Container for the null_dart_handle, static data member.
|
|
static Dart_container mnull_dart_container;
|
|
|
|
/// Number of times each mark is reserved. 0 if the mark is free.
|
|
mutable size_type mnb_times_reserved_marks[NB_MARKS];
|
|
|
|
/// Mask marks to know the value of unmark dart, for each index i.
|
|
mutable std::bitset<NB_MARKS> mmask_marks;
|
|
|
|
/// Number of used marks.
|
|
mutable size_type mnb_used_marks;
|
|
|
|
/// Index of each mark, in mfree_marks_stack or in mfree_marks_stack.
|
|
mutable size_type mindex_marks[NB_MARKS];
|
|
|
|
/// "Stack" of free marks.
|
|
mutable int mfree_marks_stack[NB_MARKS];
|
|
|
|
/// "Stack" of used marks.
|
|
mutable int mused_marks_stack[NB_MARKS];
|
|
|
|
/// Number of marked darts for each used marks.
|
|
mutable size_type mnb_marked_darts[NB_MARKS];
|
|
|
|
/// Tuple of attributes containers
|
|
typename Helper::Attribute_containers mattribute_containers;
|
|
};
|
|
|
|
/// Allocation of static data members
|
|
/// mnull_dart_container
|
|
template < unsigned int d_, class Refs, class Items_, class Alloc_ >
|
|
typename Combinatorial_map_base<d_, Refs, Items_, Alloc_>::Dart_container
|
|
Combinatorial_map_base<d_, Refs, Items_, Alloc_>::mnull_dart_container;
|
|
|
|
/// null_dart_handle
|
|
template < unsigned int d_, class Refs, class Items_, class Alloc_ >
|
|
typename Combinatorial_map_base<d_, Refs, Items_, Alloc_>::Dart_handle
|
|
Combinatorial_map_base<d_, Refs, Items_, Alloc_>::null_dart_handle;
|
|
// = mnull_dart_container.emplace( std::bitset<NB_MARKS>() );
|
|
// Does not work on windows => segfault
|
|
// Thus we initialize null_dart_handle in the Combinatorial_map constructor
|
|
|
|
template < unsigned int d_,
|
|
class Items_=Combinatorial_map_min_items<d_>,
|
|
class Alloc_=CGAL_ALLOCATOR(int) >
|
|
class Combinatorial_map :
|
|
public Combinatorial_map_base<d_,
|
|
Combinatorial_map<d_,Items_,Alloc_>,
|
|
Items_, Alloc_ >
|
|
{
|
|
public:
|
|
typedef Combinatorial_map<d_, Items_,Alloc_> Self;
|
|
typedef Combinatorial_map_base<d_, Self, Items_, Alloc_> Base;
|
|
|
|
typedef typename Base::Dart_handle Dart_handle;
|
|
typedef typename Base::Dart_const_handle Dart_const_handle;
|
|
typedef typename Base::Alloc Alloc;
|
|
};
|
|
|
|
} // namespace CGAL
|
|
|
|
#endif // CGAL_COMBINATORIAL_MAP_H //
|
|
// EOF //
|