Contraction v2 to start a new proper branch.

This commit is contained in:
Guillaume Damiand 2013-01-25 17:29:34 +01:00
parent e17201c286
commit 54a27a09c9
8 changed files with 752 additions and 267 deletions

View File

@ -56,6 +56,9 @@ namespace CGAL {
template<class Map, unsigned int i, unsigned int nmi>
friend struct Remove_cell_functor;
template<class Map, unsigned int i>
friend struct Contract_cell_functor;
template<class Map>
friend typename Map::Dart_handle
insert_cell_0_in_cell_1(Map& amap, typename Map::Dart_handle adart);

View File

@ -64,6 +64,32 @@ namespace CGAL {
return start;
}
/** Test if a face is a combinatorial polygon of length alg
* (a cycle of alg darts beta1 links together).
* @param amap the used combinatorial map.
* @param adart an intial dart
* @return true iff the face containing adart is a polygon of length alg.
*/
template < class Map >
bool is_face_combinatorial_polygon(const Map& amap,
typename Map::Dart_const_handle adart,
unsigned int alg)
{
CGAL_assertion(alg>0);
CGAL_assertion(adart!=NULL);
unsigned int nb = 0;
typename Map::Dart_const_handle cur = adart;
do
{
++nb;
if ( cur==Map::null_dart_handle ) return false; // Open face
cur = cur->beta(1);
}
while( cur!=adart );
return (nb==alg);
}
/** Create a combinatorial tetrahedron from 4 triangles.
* @param amap the used combinatorial map.
* @param d1 a dart onto a first triangle.
@ -90,6 +116,45 @@ namespace CGAL {
return d1;
}
/** Test if a volume is a combinatorial tetrahedron.
* @param amap the used combinatorial map.
* @param adart an intial dart
* @return true iff the volume containing adart is a combinatorial tetrahedron.
*/
template < class Map >
bool is_volume_combinatorial_tetrahedron(const Map& amap,
typename Map::Dart_const_handle d1)
{
CGAL_assertion(d1!=NULL);
typename Map::Dart_const_handle d2 = d1->beta(2);
typename Map::Dart_const_handle d3 = d2->beta(0)->beta(2);
typename Map::Dart_const_handle d4 = d2->beta(1)->beta(2);
if ( d1==Map::null_dart_handle || d2==Map::null_dart_handle ||
d3==Map::null_dart_handle || d4==Map::null_dart_handle ) return false;
if ( !is_face_combinatorial_polygon(amap, d1, 3) ||
!is_face_combinatorial_polygon(amap, d2, 3) ||
!is_face_combinatorial_polygon(amap, d3, 3) ||
!is_face_combinatorial_polygon(amap, d4, 3) ) return false;
// TODO do better with marks (?).
if ( belong_to_same_cell<Map,2,1>(amap, d1, d2) ||
belong_to_same_cell<Map,2,1>(amap, d1, d3) ||
belong_to_same_cell<Map,2,1>(amap, d1, d4) ||
belong_to_same_cell<Map,2,1>(amap, d2, d3) ||
belong_to_same_cell<Map,2,1>(amap, d2, d4) ||
belong_to_same_cell<Map,2,1>(amap, d3, d4) ) return false;
if ( amap.beta(d1,1,2)!=amap.beta(d3,0) ||
amap.beta(d4,0,2)!=amap.beta(d3,1) ||
amap.beta(d4,1,2)!=amap.beta(d1,0) ) return false;
return true;
}
/** Create a new combinatorial tetrahedron.
* @param amap the used combinatorial map.
* @return a new dart.
@ -156,6 +221,63 @@ namespace CGAL {
return d1;
}
/** Test if a volume is a combinatorial hexahedron.
* @param amap the used combinatorial map.
* @param adart an intial dart
* @return true iff the volume containing adart is a combinatorial hexahedron.
*/
template < class Map >
bool is_volume_combinatorial_hexahedron(const Map& amap,
typename Map::Dart_const_handle d1)
{
CGAL_assertion(d1!=NULL);
typename Map::Dart_const_handle d2 = d1->beta(1)->beta(1)->beta(2);
typename Map::Dart_const_handle d3 = d2->beta(1)->beta(1)->beta(2);
typename Map::Dart_const_handle d4 = d3->beta(1)->beta(1)->beta(2);
typename Map::Dart_const_handle d5 = d1->beta(0)->beta(2);
typename Map::Dart_const_handle d6 = d4->beta(1)->beta(2);
if ( d1==Map::null_dart_handle || d2==Map::null_dart_handle ||
d3==Map::null_dart_handle || d4==Map::null_dart_handle ||
d5==Map::null_dart_handle || d6==Map::null_dart_handle ) return false;
if (!is_face_combinatorial_polygon(amap, d1, 4) ||
!is_face_combinatorial_polygon(amap, d2, 4) ||
!is_face_combinatorial_polygon(amap, d3, 4) ||
!is_face_combinatorial_polygon(amap, d4, 4) ||
!is_face_combinatorial_polygon(amap, d5, 4) ||
!is_face_combinatorial_polygon(amap, d6, 4) ) return false;
// TODO do better with marks.
if ( belong_to_same_cell<Map,2,1>(amap, d1, d2) ||
belong_to_same_cell<Map,2,1>(amap, d1, d3) ||
belong_to_same_cell<Map,2,1>(amap, d1, d4) ||
belong_to_same_cell<Map,2,1>(amap, d1, d5) ||
belong_to_same_cell<Map,2,1>(amap, d1, d6) ||
belong_to_same_cell<Map,2,1>(amap, d2, d3) ||
belong_to_same_cell<Map,2,1>(amap, d2, d4) ||
belong_to_same_cell<Map,2,1>(amap, d2, d5) ||
belong_to_same_cell<Map,2,1>(amap, d2, d6) ||
belong_to_same_cell<Map,2,1>(amap, d3, d4) ||
belong_to_same_cell<Map,2,1>(amap, d3, d5) ||
belong_to_same_cell<Map,2,1>(amap, d3, d6) ||
belong_to_same_cell<Map,2,1>(amap, d4, d5) ||
belong_to_same_cell<Map,2,1>(amap, d4, d6) ||
belong_to_same_cell<Map,2,1>(amap, d5, d6) )
return false;
if ( amap.beta(d1,2) !=amap.beta(d4,1,1) ||
amap.beta(d1,1,2) !=amap.beta(d6,0) ||
amap.beta(d3,1,2) !=amap.beta(d6,1) ||
amap.beta(d3,0,2) !=amap.beta(d5,1,1) ||
amap.beta(d6,1,1,2)!=amap.beta(d2,1) ||
amap.beta(d5,0,2) !=amap.beta(d4,0) ||
amap.beta(d5,1,2) !=amap.beta(d2,0) ) return false;
return true;
}
/** Create a new combinatorial hexahedron.
* @param amap the used combinatorial map.
* @return a new dart.

View File

@ -37,7 +37,7 @@ namespace CGAL {
* @return A dart incident to the new vertex.
*/
template < class Map >
typename Map::Dart_handle
typename Map::Dart_handle
insert_cell_0_in_cell_2(Map& amap, typename Map::Dart_handle adart)
{
CGAL_assertion(adart != NULL && adart!=Map::null_dart_handle);
@ -51,9 +51,9 @@ namespace CGAL {
while (!first->is_free(0) && first->beta(0) != adart)
first = first->beta(0);
// Stack of couple of dart and dimension for which
// Stack of couple of dart and dimension for which
// we must call on_split functor
std::stack<internal::Couple_dart_and_dim<typename Map::Dart_handle> >
std::stack<internal::Couple_dart_and_dim<typename Map::Dart_handle> >
tosplit;
// Mark used to mark darts already treated.
@ -61,7 +61,7 @@ namespace CGAL {
// Stack of marked darts
std::stack<typename Map::Dart_handle> tounmark;
// Now we run through the facet
for (CGAL::CMap_dart_iterator_basic_of_orbit<Map,1> it(amap,first);
it.cont();)
@ -75,7 +75,7 @@ namespace CGAL {
{
if ( amap.template degroup_attribute_of_dart<2,
typename Map::template Dart_of_involution_range<1> >
(first, cur) )
(first, cur) )
tosplit.push(internal::Couple_dart_and_dim
<typename Map::Dart_handle>
(first,cur,2));
@ -83,14 +83,14 @@ namespace CGAL {
if (!cur->is_free(0))
{
n1 = amap.create_dart();
n1 = amap.create_dart();
amap.link_beta_0(cur, n1);
}
else n1 = NULL;
if (!cur->is_free(1))
{
n2 = amap.create_dart();
n2 = amap.create_dart();
amap.link_beta_1(cur, n2);
}
else n2 = NULL;
@ -107,7 +107,7 @@ namespace CGAL {
{
if ( !amap.is_marked(cur->beta(dim), treated) )
{
if (n1!=NULL)
if (n1!=NULL)
{
nn1=amap.create_dart();
amap.link_beta_1(cur->beta(dim), nn1);
@ -125,7 +125,7 @@ namespace CGAL {
if (nn1 != NULL && nn2 != NULL)
amap.basic_link_beta_1(nn1, nn2);
if (nn1 != NULL && prev != NULL)
amap.link_beta_for_involution(nn1, prev->beta(dim), 2);
@ -166,20 +166,20 @@ namespace CGAL {
CGAL_assertion(amap.is_whole_map_unmarked(treated));
amap.free_mark(treated);
while ( !tosplit.empty() )
{
internal::Couple_dart_and_dim<typename Map::Dart_handle> c=tosplit.top();
tosplit.pop();
internal::Call_split_functor<Map, 2>::run(c.d1, c.d2);
}
return n1;
}
/** Test if a i-cell can be removed.
* An i-cell can be removed if i==Map::dimension,
* or if there are at most two (i+1)-cell incident to it.
/** Test if an i-cell can be removed.
* An i-cell can be removed if i==Map::dimension or i==Map::dimension-1,
* or if there are at most two (i+1)-cell incident to it.
* @param adart a dart of the i-cell.
* @return true iff the i-cell can be removed.
*/
@ -193,7 +193,7 @@ namespace CGAL {
if ( i==Map::dimension-1 ) return true;
// TODO ? Optimisation for dim-2, and to not test all
// the darts of the cell ?
// the darts of the cell ?
bool res = true;
for (CMap_dart_const_iterator_of_cell<Map,i> it(amap, adart);
res && it.cont(); ++it)
@ -204,11 +204,11 @@ namespace CGAL {
return res;
}
/** Remove a i-cell, 0<i<dimension, and merge eventually both incident
/** Remove an i-cell, 0<i<dimension, and merge eventually both incident
* (i+1)-cells.
* @param amap the used combinatorial map.
* @param adart a dart of the i-cell to remove.
* @return the number of deleted darts.
* @param amap the used combinatorial map.
* @param adart a dart of the i-cell to remove.
* @return the number of deleted darts.
*/
template<class Map, unsigned int i, unsigned int nmi>
struct Remove_cell_functor
@ -217,42 +217,41 @@ namespace CGAL {
{
CGAL_static_assertion ( 1<=i && i<Map::dimension );
CGAL_assertion( (is_removable<Map,i>(amap, adart)) );
size_t res = 0;
// 1) We group the two (i+1)-cells if they exist.
if (!adart->is_free(i+1))
amap.template group_attribute<i+1>(adart, adart->beta(i+1));
typename Map::Dart_handle d1, d2;
int mark = amap.get_new_mark();
std::vector<typename Map::Dart_handle> to_erase;
// 2) We mark all the darts of the i-cell.
std::deque<typename Map::Dart_handle> to_erase;
const int iinv = CGAL_BETAINV(i);
int mark_for_incident_cells[Map::Helper::nb_attribs];
std::deque<std::deque<typename Map::Dart_handle> >
incident_cells[Map::Helper::nb_attribs];
for (int j=0; j<Map::Helper::nb_attribs; ++j)
{
for ( CMap_dart_iterator_basic_of_cell<Map,i> it(amap,adart,mark);
it.cont(); ++it )
{
to_erase.push_back(it);
amap.mark(it,mark);
++res;
}
mark_for_incident_cells [j] = amap.get_new_mark();
CGAL_assertion( mark_for_incident_cells [j]!=-1 );
}
// Stack of couple of dart for which we must call degroup_all_attributes
size_t res = 0;
for ( CMap_dart_iterator_basic_of_cell<Map,i> it(amap,adart,mark);
it.cont(); ++it )
{
to_erase.push_back(it);
amap.mark(it, mark);
++res;
}
typedef std::pair<typename Map::Dart_handle, typename Map::Dart_handle>
Dart_pair;
std::stack<Dart_pair> todegroup;
std::deque<Dart_pair> tolink;
std::deque<typename Map::Dart_handle> tounlink;
std::deque<typename Map::Dart_handle> tounlinkinv;
// 3) We modify the darts of the cells incident to the removed i-cell
// when they are marked to remove.
typename std::vector<typename Map::Dart_handle>::iterator it =
typename std::deque<typename Map::Dart_handle>::iterator it =
to_erase.begin();
for (; it != to_erase.end(); ++it)
{ amap.update_dart_of_all_attributes(*it, mark); }
// 4) For each dart of the cell, we modify i-link of neighbors.
for ( it=to_erase.begin(); it != to_erase.end(); ++it)
{
d1 = (*it)->beta_inv(i);
while ( d1!=Map::null_dart_handle && amap.is_marked(d1, mark) )
@ -260,81 +259,118 @@ namespace CGAL {
d1 = d1->beta(i+1)->beta_inv(i);
if (d1 == (*it)->beta_inv(i)) d1 = Map::null_dart_handle;
}
d2 = (*it)->beta(i+1)->beta(i);
while ( d2!=Map::null_dart_handle && amap.is_marked(d2, mark) )
{
d2 = d2->beta(i+1)->beta(i);
if ( d2==(*it)->beta(i+1)->beta(i) ) d2=Map::null_dart_handle;
}
// TODO ? We can optimize by using map.basic_link_beta but we
// need to mark the second dart to not process another time...
if (d1 != Map::null_dart_handle)
{
if (d2 != Map::null_dart_handle)
if (d2 != Map::null_dart_handle)
{
d1->basic_link_beta(d2, i);
// Here special case for edge, TODO special method ?
if ( i==1 ) d2->basic_link_beta(d1, 0);
if ( i==1 || d1<d2 )
tolink.push_back(Dart_pair(d1, d2));
amap.update_dart_of_all_attributes(*it, mark);
}
else
else
{
if ( !d1->is_free(i) )
{
if ( !amap.is_marked(d1->beta(i), mark) )
todegroup.push(Dart_pair(d1, d1->beta(i)));
d1->unlink_beta(i);
tounlink.push_back(d1);
Map::Helper::template Foreach_enabled_attributes
<internal::Store_incident_cells<Map,i> >::
run(&amap, d1, mark, &mark_for_incident_cells[0],
&incident_cells[0]);
}
}
}
else if (d2 != Map::null_dart_handle)
else if (d2 != Map::null_dart_handle)
{
if ( !d2->is_free(CGAL_BETAINV(i)) )
if ( !d2->is_free(iinv) )
{
if ( !amap.is_marked(d2->beta_inv(i), mark) )
todegroup.push(Dart_pair(d2, d2->beta_inv(i)));
d2->unlink_beta(CGAL_BETAINV(i));
tounlinkinv.push_back(d2);
Map::Helper::template Foreach_enabled_attributes
<internal::Store_incident_cells<Map,i> >::
run(&amap, d2, mark, &mark_for_incident_cells[0],
&incident_cells[0]);
}
}
if ((*it)->is_free(i+1) && !(*it)->is_free(i))
{
d1 = (*it)->beta(i);
if ( !d1->is_free(CGAL_BETAINV(i)) )
if ( !d1->is_free(iinv) )
{
if ( !amap.is_marked(d1->beta_inv(i), mark))
todegroup.push(Dart_pair(d1, d1->beta_inv(i)));
d1->unlink_beta(CGAL_BETAINV(i));
}
tounlinkinv.push_back(d1);
Map::Helper::template Foreach_enabled_attributes
<internal::Store_incident_cells<Map,i> >::
run(&amap, d1, mark, &mark_for_incident_cells[0],
&incident_cells[0]);
}
}
}
// 5) We degroup all the pair
while ( !todegroup.empty() )
// 2) We group the two (i+1)-cells if they exist.
// TODO assert que dans i+1 il y a 0, 1 ou 2 cells; et appeler group
// que dans le cas ou il y en a 2 et que on a deux brins tq ....
if ( !tolink.empty() )
{
Dart_pair p=todegroup.top();
todegroup.pop();
amap.degroup_all_attributes(p.first,p.second);
Dart_pair & p=tolink.back();
amap.template group_attribute<i+1>(p.first, p.second);
}
// 4) For each dart of the cell, we modify i-link of neighbors.
for ( typename std::deque<typename Map::Dart_handle>::iterator
it=tounlink.begin(); it!=tounlink.end(); ++it )
{
(*it)->unlink_beta(i);
}
for ( typename std::deque<typename Map::Dart_handle>::iterator
it=tounlinkinv.begin(); it!=tounlinkinv.end(); ++it )
{
(*it)->unlink_beta(iinv);
}
for ( typename std::deque<Dart_pair>::iterator
it=tolink.begin(); it!=tolink.end(); ++it )
{
(*it).first->basic_link_beta((*it).second, i);
(*it).second->basic_link_beta((*it).first, iinv);
}
// 6) We remove all the darts of the cell.
for ( it=to_erase.begin(); it!=to_erase.end(); ++it )
{ amap.erase_dart(*it); }
CGAL_assertion( amap.is_whole_map_unmarked(mark) );
amap.free_mark(mark);
Map::Helper::template Foreach_enabled_attributes
<internal::Test_split_with_deque<Map,i> >::
run(&amap, &mark_for_incident_cells[0],
&incident_cells[0]);
for (int j=0; j<Map::Helper::nb_attribs; ++j)
{
CGAL_assertion( amap.is_whole_map_marked
(mark_for_incident_cells [j]) );
amap.free_mark( mark_for_incident_cells [j] );
}
// CGAL_postcondition(amap.is_valid());
return res;
}
};
/** Remove a d-cell, in a d-map (special case).
* @param amap the used combinatorial map.
* @param adart a dart of the volume to remove.
* @return the number of deleted darts.
* @param amap the used combinatorial map.
* @param adart a dart of the volume to remove.
* @return the number of deleted darts.
*/
template<class Map,unsigned int i>
struct Remove_cell_functor<Map,i,0>
@ -342,11 +378,11 @@ namespace CGAL {
static size_t run(Map& amap, typename Map::Dart_handle adart)
{
CGAL_assertion( adart!=NULL );
std::vector<typename Map::Dart_handle> to_erase;
int mark = amap.get_new_mark();
size_t res = 0;
// Stack of couple of dart for which we must call degroup_all_attributes
typedef std::pair<typename Map::Dart_handle, typename Map::Dart_handle>
Dart_pair;
@ -354,7 +390,7 @@ namespace CGAL {
// 1) We mark all the darts of the d-cell.
{
for (CMap_dart_iterator_basic_of_cell<Map,Map::dimension>
for (CMap_dart_iterator_basic_of_cell<Map,Map::dimension>
it(amap,adart,mark); it.cont(); ++it)
{
to_erase.push_back(it);
@ -362,40 +398,40 @@ namespace CGAL {
++res;
}
}
// 2) We update the cells incident to the remove volume.
typename std::vector<typename Map::Dart_handle>::iterator
it = to_erase.begin();
for (; it != to_erase.end(); ++it)
{ amap.update_dart_of_all_attributes(*it, mark); }
// 3) We unlink all the darts of the volume for beta-d.
for ( it = to_erase.begin(); it != to_erase.end(); ++it )
{
{
if ( !(*it)->is_free(Map::dimension) )
{
todegroup.push(Dart_pair(*it, (*it)->beta(Map::dimension)));
amap.unlink_beta_for_involution(*it,Map::dimension);
}
}
}
// 4) We degroup all the pairs
while ( !todegroup.empty() )
{
Dart_pair p=todegroup.top();
todegroup.pop();
Dart_pair & p=todegroup.top();
amap.degroup_all_attributes(p.first,p.second);
todegroup.pop();
}
// 5) last, we remove all the darts of the d-cell.
for ( it = to_erase.begin(); it != to_erase.end(); ++it )
{ amap.erase_dart(*it); }
CGAL_assertion( amap.is_whole_map_unmarked(mark) );
amap.free_mark(mark);
//CGAL_postcondition(amap.is_valid());
return res;
}
};
@ -413,27 +449,27 @@ namespace CGAL {
CGAL_assertion( (is_removable<Map,0>(amap,adart)) );
size_t res = 0;
// Stack of couple of dart for which we must call degroup_all_attributes
typedef std::pair<typename Map::Dart_handle, typename Map::Dart_handle>
Dart_pair;
std::stack<Dart_pair> todegroup;
// 1) We group the two edges if they exist.
if (!adart->is_free(0))
if (!adart->is_free(0))
amap.template group_attribute<1>(adart, adart->beta(0));
typename Map::Dart_handle d1, d2;
int mark = amap.get_new_mark();
std::vector<typename Map::Dart_handle> to_erase;
// 2) We mark all the darts of the vertex.
{
for ( CMap_dart_iterator_basic_of_cell<Map,0> it(amap,adart,mark);
it.cont(); ++it )
{
to_erase.push_back(it);
amap.mark(it,mark);
amap.mark(it,mark);
++res;
}
}
@ -444,7 +480,7 @@ namespace CGAL {
it = to_erase.begin();
for (; it != to_erase.end(); ++it)
{ amap.update_dart_of_all_attributes(*it, mark); }
// 4) For each dart of the cell, we modify link of neighbors.
for ( it=to_erase.begin(); it!=to_erase.end(); ++it )
{
@ -457,7 +493,7 @@ namespace CGAL {
todegroup.push(Dart_pair((*it)->beta(0), *it));
(*it)->beta(0)->unlink_beta(1);
}
for ( unsigned int j=2; j<=Map::dimension; ++j )
{
if ( !(*it)->is_free(j) )
@ -472,7 +508,7 @@ namespace CGAL {
todegroup.push(Dart_pair((*it)->beta(1), *it));
(*it)->beta(1)->unlink_beta(0);
}
for ( unsigned int j=2; j<=Map::dimension; ++j )
{
if ( !(*it)->is_free(j) )
@ -480,29 +516,29 @@ namespace CGAL {
}
}
}
// 5) We degroup all the pairs
while ( !todegroup.empty() )
{
Dart_pair p=todegroup.top();
todegroup.pop();
Dart_pair & p=todegroup.top();
amap.degroup_all_attributes(p.first,p.second);
todegroup.pop();
}
// 6) We remove all the darts of the cell.
for (it = to_erase.begin(); it != to_erase.end(); ++it)
{ amap.erase_dart(*it); }
CGAL_assertion( amap.is_whole_map_unmarked(mark) );
amap.free_mark(mark);
// CGAL_postcondition( amap.is_valid() );
return res;
}
};
/** Remove a i-cell, 0<=i<=dimension.
/** Remove an i-cell, 0<=i<=dimension.
* @param amap the used combinatorial map.
* @param adart a dart of the i-cell to remove.
* @return the number of deleted darts.
@ -524,7 +560,7 @@ namespace CGAL {
{
CGAL_assertion(adart1 != NULL && adart2 != NULL);
if ( adart1==adart2 ) return false;
for ( CMap_dart_const_iterator_of_orbit<Map,1> it(amap,adart1);
for ( CMap_dart_const_iterator_of_orbit<Map,1> it(amap,adart1);
it.cont(); ++it )
{
if ( it==adart2 ) return true;
@ -532,6 +568,152 @@ namespace CGAL {
return false;
}
/** Test if an i-cell can be contracted.
* An i-cell can be contracted if i==1
* or if there are at most two (i-1)-cell incident to it.
* @param adart a dart of the i-cell.
* @return true iff the i-cell can be contracted.
*/
template < class Map, unsigned int i >
bool is_contractible(const Map& amap, typename Map::Dart_const_handle adart)
{
CGAL_assertion(adart != NULL);
CGAL_static_assertion(0<=i && i<=Map::dimension);
if ( i==0 ) return false;
if ( i==1 ) return true;
// TODO ? Optimisation possible to not test all
// the darts of the cell ?
bool res = true;
for (CMap_dart_const_iterator_of_cell<Map,i> it(amap, adart);
res && it.cont(); ++it)
{
if (it->beta(i-2)->beta(i-1) != it->beta_inv(i-2)->beta(i-1) )
res = false;
}
return res;
}
/** Contract an i-cell, 1<i<=dimension, and merge eventually both incident
* (i-1)-cells.
* @param amap the used combinatorial map.
* @param adart a dart of the i-cell to contract.
* @return the number of deleted darts.
*/
template<class Map, unsigned int i>
struct Contract_cell_functor
{
static size_t run(Map& amap, typename Map::Dart_handle adart)
{
CGAL_static_assertion ( 2<=i && i<=Map::dimension );
CGAL_assertion( (is_contractible<Map,i>(amap, adart)) );
size_t res = 0;
return res;
}
};
/** Contract an edge, and merge eventually both incident vertices.
* @param amap the used combinatorial map.
* @param adart a dart of the edge to contract.
* @return the number of deleted darts.
*/
template<class Map>
struct Contract_cell_functor<Map,1>
{
static size_t run(Map& amap, typename Map::Dart_handle adart)
{
CGAL_assertion( (is_contractible<Map,1>(amap,adart)) );
size_t res = 0;
// Stack of couple of dart for which we must call degroup_all_attributes
typedef std::pair<typename Map::Dart_handle, typename Map::Dart_handle>
Dart_pair;
std::stack<Dart_pair> todegroup;
// 1) We group the two vertices if they exist.
typename Map::Dart_handle dh2 = adart->other_extremity();
if (dh2!=NULL)
amap.template group_attribute<0>(adart, dh2);
typename Map::Dart_handle d1, d2;
int mark = amap.get_new_mark();
std::vector<typename Map::Dart_handle> to_erase;
// 2) We mark all the darts of the edge.
{
for ( CMap_dart_iterator_basic_of_cell<Map,1> it(amap,adart,mark);
it.cont(); ++it )
{
to_erase.push_back(it);
amap.mark(it,mark);
++res;
}
}
// 3) We modify the darts of the cells incident to the edge
// when they are marked to remove.
typename std::vector<typename Map::Dart_handle>::iterator
it = to_erase.begin();
for (; it != to_erase.end(); ++it)
{ amap.update_dart_of_all_attributes(*it, mark); }
// 4) For each dart of the cell, we modify link of neighbors.
for ( it=to_erase.begin(); it!=to_erase.end(); ++it )
{
if ( !(*it)->is_free(0) )
{
if ( !(*it)->is_free(1) && (*it)->beta(0)!=(*it) )
amap.template basic_link_beta<1>((*it)->beta(0), (*it)->beta(1));
else
{
// TODO todegroup.push(Dart_pair((*it)->beta(0), *it));
(*it)->beta(0)->unlink_beta(1);
}
}
else
{
if ( !(*it)->is_free(1) )
{
// TODO todegroup.push(Dart_pair((*it)->beta(1), *it));
(*it)->beta(1)->unlink_beta(0);
}
}
}
// 5) We degroup all the pairs
while ( !todegroup.empty() )
{
Dart_pair p=todegroup.top();
todegroup.pop();
amap.degroup_all_attributes(p.first,p.second);
}
// 6) We remove all the darts of the cell.
for (it = to_erase.begin(); it != to_erase.end(); ++it)
{ amap.erase_dart(*it); }
CGAL_assertion( amap.is_whole_map_unmarked(mark) );
amap.free_mark(mark);
// CGAL_postcondition( amap.is_valid() );
return res;
}
};
/** Contract an i-cell, 1<=i<=dimension.
* @param amap the used combinatorial map.
* @param adart a dart of the i-cell to remove.
* @return the number of deleted darts.
*/
template < class Map, unsigned int i >
size_t contract_cell(Map& amap, typename Map::Dart_handle adart)
{ return Contract_cell_functor<Map,i>::run(amap,adart); }
/** Test if a 2-cell can be inserted onto a given 3-cell along
* a path of edges.
* @param amap the used combinatorial map.
@ -540,8 +722,8 @@ namespace CGAL {
* @return true iff a 2-cell can be inserted along the path.
*/
template <class Map, class InputIterator>
bool is_insertable_cell_2_in_cell_3(const Map& amap,
InputIterator afirst,
bool is_insertable_cell_2_in_cell_3(const Map& amap,
InputIterator afirst,
InputIterator alast)
{
CGAL_static_assertion( Map::dimension>= 3 );
@ -586,11 +768,11 @@ namespace CGAL {
* @return a dart of the new vertex.
*/
template<class Map>
typename Map::Dart_handle
typename Map::Dart_handle
insert_cell_0_in_cell_1(Map& amap, typename Map::Dart_handle adart)
{
CGAL_assertion(adart != NULL && adart!=Map::null_dart_handle);
typename Map::Dart_handle d1, d2;
int mark = amap.get_new_mark();
@ -607,7 +789,7 @@ namespace CGAL {
for (; it != vect.end(); ++it)
{
d1 = amap.create_dart();
if (!(*it)->is_free(1))
{ amap.template basic_link_beta<1>(d1, (*it)->beta(1)); }
@ -625,14 +807,14 @@ namespace CGAL {
amap.mark(*it, mark);
}
for (it = vect.begin(); it != vect.end(); ++it)
{ amap.unmark(*it, mark); }
amap.free_mark(mark);
amap.template degroup_attribute<1>(adart, adart->beta(1));
return adart->beta(1);
}
@ -642,7 +824,7 @@ namespace CGAL {
* @return a dart of the new edge, not incident to the vertex of adart1.
*/
template<class Map>
typename Map::Dart_handle
typename Map::Dart_handle
insert_dangling_cell_1_in_cell_2(Map& amap, typename Map::Dart_handle adart1)
{
CGAL_assertion(adart1!=NULL && adart1!=Map::null_dart_handle);
@ -661,7 +843,7 @@ namespace CGAL {
typename Map::Dart_handle d1 = NULL;
typename Map::Dart_handle d2 = NULL;
unsigned int s1 = 0;
int treated = amap.get_new_mark();
CGAL::CMap_dart_iterator_of_involution<Map,1> it1(amap,adart1);
@ -670,8 +852,8 @@ namespace CGAL {
{
d1 = amap.create_dart();
d2 = amap.create_dart();
if ( amap.is_marked(it1, mark1) ) s1 = 0;
if ( amap.is_marked(it1, mark1) ) s1 = 0;
else s1 = 1;
if ( !it1->is_free(s1) )
@ -680,22 +862,22 @@ namespace CGAL {
else amap.template link_beta<0>(it1->beta(1), d2);
}
if (s1==0)
if (s1==0)
{
amap.template link_beta<0>(it1, d1);
amap.template basic_link_beta<0>(d1,d2);
}
else
else
{
amap.template link_beta<1>(it1, d1);
amap.template basic_link_beta<1>(d1,d2);
}
amap.link_beta_for_involution(d1, d2, 2);
for ( unsigned int dim=3; dim<=Map::dimension; ++dim)
{
if ( !it1->is_free(dim) &&
if ( !it1->is_free(dim) &&
amap.is_marked(it1->beta(dim), treated) )
{
amap.basic_link_beta_for_involution(it1->beta(dim)->beta_inv(s1), d1,
@ -723,7 +905,7 @@ namespace CGAL {
for (; it != to_unmark.end(); ++it)
{ amap.unmark(*it, mark1); }
CGAL_assertion( amap.is_whole_map_unmarked(mark1) );
amap.free_mark(mark1);
amap.free_mark(mark1);
// CGAL_postcondition(amap.is_valid());
return adart1->beta(0);
@ -733,11 +915,11 @@ namespace CGAL {
* @param amap the used combinatorial map.
* @param adart1 a first dart of the facet (!=NULL && !=null_dart_handle).
* @param adart2 a second dart of the facet. If NULL insert a dangling edge.
* @return a dart of the new edge, and not incident to the
* @return a dart of the new edge, and not incident to the
* same vertex than adart1.
*/
template<class CMap>
typename CMap::Dart_handle
typename CMap::Dart_handle
insert_cell_1_in_cell_2(CMap& amap,
typename CMap::Dart_handle adart1,
typename CMap::Dart_handle adart2)
@ -747,10 +929,10 @@ namespace CGAL {
CGAL_assertion(is_insertable_cell_1_in_cell_2<CMap>(amap, adart1, adart2));
int m1 = amap.get_new_mark();
CMap_dart_iterator_basic_of_involution<CMap,1>
CMap_dart_iterator_basic_of_involution<CMap,1>
it1 = CMap_dart_iterator_basic_of_involution<CMap,1>(amap, adart1, m1);
int m2 = amap.get_new_mark();
CMap_dart_iterator_basic_of_involution<CMap,1>
CMap_dart_iterator_basic_of_involution<CMap,1>
it2 = CMap_dart_iterator_basic_of_involution<CMap,1>(amap, adart2, m2);
int mark1 = amap.get_new_mark();
@ -767,7 +949,7 @@ namespace CGAL {
typename CMap::Dart_handle d1 = NULL;
typename CMap::Dart_handle d2 = NULL;
unsigned int s1 = 0;
int treated = amap.get_new_mark();
for ( ; it1.cont(); ++it1, ++it2)
@ -775,8 +957,8 @@ namespace CGAL {
CGAL_assertion (it2.cont() );
d1 = amap.create_dart();
d2 = amap.create_dart();
if ( amap.is_marked(it1, mark1) ) s1 = 0;
if ( amap.is_marked(it1, mark1) ) s1 = 0;
else s1 = 1;
if ( !it1->is_free(s1) )
@ -805,7 +987,7 @@ namespace CGAL {
for ( unsigned int dim=3; dim<=CMap::dimension; ++dim)
{
if ( !it1->is_free(dim) &&
if ( !it1->is_free(dim) &&
amap.is_marked(it1->beta(dim), treated) )
{
amap.basic_link_beta_for_involution
@ -826,9 +1008,9 @@ namespace CGAL {
it1.rewind(); it2.rewind();
for ( ; it1.cont(); ++it1, ++it2)
{
amap.mark(it1,m1);
amap.unmark(it1,treated);
amap.mark(it2,m2);
amap.mark(it1,m1);
amap.unmark(it1,treated);
amap.mark(it2,m2);
}
amap.negate_mark(m1);
amap.negate_mark(m2);
@ -844,7 +1026,7 @@ namespace CGAL {
for (; it != to_unmark.end(); ++it)
{ amap.unmark(*it, mark1); }
CGAL_assertion( amap.is_whole_map_unmarked(mark1) );
amap.free_mark(mark1);
amap.free_mark(mark1);
// CGAL_postcondition(amap.is_valid());
return adart1->beta(0);
@ -874,32 +1056,32 @@ namespace CGAL {
{
for (InputIterator it(afirst); it!=alast; ++it)
{
{
d = amap.create_dart();
if (withBeta3)
{
dd = amap.create_dart();
amap.basic_link_beta_for_involution(d, dd, 3);
}
if (prec != NULL)
{
amap.template link_beta<0>(prec, d);
if (withBeta3) amap.template link_beta<1>(prec->beta(3), dd);
}
else first = d;
if (!(*it)->is_free(2))
amap.link_beta_for_involution((*it)->beta(2), dd, 2);
amap.link_beta_for_involution(*it, d, 2);
prec = d;
}
}
amap.template link_beta<0>(prec, first);
if (withBeta3)
if (withBeta3)
{
amap.template link_beta<1>(prec->beta(3), first->beta(3));
}
@ -911,14 +1093,14 @@ namespace CGAL {
{
typename Map::Dart_handle first2 = NULL;
prec = NULL;
for ( CMap_dart_iterator_of_orbit<Map,1> it(amap, first);
for ( CMap_dart_iterator_of_orbit<Map,1> it(amap, first);
it.cont(); ++it )
{
d = amap.create_dart();
amap.link_beta_for_involution(it->beta(2),d,dim);
if ( withBeta3 )
{
dd = amap.create_dart();
dd = amap.create_dart();
amap.link_beta_for_involution(it->beta(2)->beta(3),dd,dim);
amap.basic_link_beta_for_involution(d, dd, 3);
}
@ -936,11 +1118,11 @@ namespace CGAL {
{
if ( dim2+1!=dim && dim2!=dim && dim2!=dim+1 )
{
if ( !it->is_free(dim2) &&
if ( !it->is_free(dim2) &&
it->beta(dim2)->is_free(dim) )
amap.basic_link_beta_for_involution(it->beta(dim2)->beta(dim),
d, dim2);
if ( withBeta3 && !it->beta(3)->is_free(dim2) &&
if ( withBeta3 && !it->beta(3)->is_free(dim2) &&
it->beta(3)->beta(dim2)->is_free(dim) )
amap.basic_link_beta_for_involution
(it->beta(3)->beta(dim2)->beta(dim), dd, dim2);
@ -949,7 +1131,7 @@ namespace CGAL {
prec = d;
}
amap.template link_beta<0>( prec, first2 );
if ( withBeta3 )
if ( withBeta3 )
{
amap.template link_beta<1>( prec->beta(3), first2->beta(3) );
}

View File

@ -67,6 +67,9 @@ namespace CGAL {
template<class Map, unsigned int i, unsigned int nmi>
friend struct Remove_cell_functor;
template<class Map, unsigned int i>
friend struct Contract_cell_functor;
template <typename Map,unsigned int i>
friend struct internal::link_beta_functor;

View File

@ -36,7 +36,7 @@ namespace CGAL {
* - CMap_dart_iterator_of_involution<Map,i,d>
* - CMap_dart_iterator_of_involution_inv<Map,i,d>
* but many specializations to optimize specific cases.
*
*
*/
//****************************************************************************
//**********************BASIC ITERATORS***************************************
@ -133,12 +133,12 @@ namespace CGAL {
-1,-1,-1,-1,-1,-1,-1,-1,-1>
{
typedef CMap_dart_iterator_basic_of_orbit_generic<Map,Const> type;
};
};
#endif //CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
//****************************************************************************
// Case when Beta... is empty: iterator of self
template <typename Map_,bool Const>
class CMap_dart_iterator_basic_of_orbit_generic<Map_,Const>:
class CMap_dart_iterator_basic_of_orbit_generic<Map_,Const>:
public CMap_dart_iterator<Map_,Const>
{
public:
@ -149,13 +149,13 @@ namespace CGAL {
typedef typename Base::Map Map;
typedef Tag_false Use_mark;
public:
/// Main constructor.
CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart):
Base(amap, adart)
{}
/// Main constructor.
CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart,
int /*amark*/):
@ -181,7 +181,7 @@ namespace CGAL {
* necessary in the second direction by using beta1.
*/
template <typename Map_,bool Const>
class CMap_dart_iterator_basic_of_orbit_generic<Map_,Const,0>:
class CMap_dart_iterator_basic_of_orbit_generic<Map_,Const,0>:
public CMap_dart_iterator<Map_,Const>
{
public:
@ -199,7 +199,7 @@ namespace CGAL {
Base(amap, adart),
mfirst_dir(true)
{}
/// Main constructor.
CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart,
int /*amark*/):
@ -229,7 +229,7 @@ namespace CGAL {
Self& operator++()
{
CGAL_assertion(this->cont());
if (mfirst_dir && (*this)->is_free(0))
{
this->set_current_dart(this->mfirst_dart);
@ -240,12 +240,12 @@ namespace CGAL {
{
this->mprev_op = OP_BETAI;
}
if (mfirst_dir)
{
CGAL_assertion(!(*this)->is_free(0));
this->set_current_dart((*this)->beta(0));
if ((*this)==this->mfirst_dart)
{
this->set_current_dart(NULL);
@ -267,7 +267,7 @@ namespace CGAL {
}
return *this;
}
/// Postfix ++ operator.
Self operator++(int)
{ Self res=*this; operator ++(); return res; }
@ -282,7 +282,7 @@ namespace CGAL {
* necessary in the second direction by using beta0.
*/
template <typename Map_,bool Const>
class CMap_dart_iterator_basic_of_orbit_generic<Map_,Const,1>:
class CMap_dart_iterator_basic_of_orbit_generic<Map_,Const,1>:
public CMap_dart_iterator<Map_,Const>
{
public:
@ -319,7 +319,7 @@ namespace CGAL {
Self& operator++()
{
CGAL_assertion(this->cont());
if (mfirst_dir && (*this)->is_free(1))
{
this->set_current_dart(this->mfirst_dart);
@ -330,12 +330,12 @@ namespace CGAL {
{
this->mprev_op = OP_BETAI;
}
if (mfirst_dir)
{
CGAL_assertion(!(*this)->is_free(1));
this->set_current_dart((*this)->beta(1));
if ((*this)==this->mfirst_dart)
{
this->set_current_dart(NULL);
@ -372,7 +372,7 @@ namespace CGAL {
* (not for beta0 and beta1 which are special cases).
*/
template <typename Map_,bool Const,int Bi>
class CMap_dart_iterator_basic_of_orbit_generic<Map_,Const,Bi>:
class CMap_dart_iterator_basic_of_orbit_generic<Map_,Const,Bi>:
public CMap_dart_iterator<Map_,Const>
{
public:
@ -389,7 +389,7 @@ namespace CGAL {
CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart):
Base(amap, adart)
{ CGAL_static_assertion( Bi>=2 && Bi<=Map::dimension ); }
/// Main constructor.
CMap_dart_iterator_basic_of_orbit_generic(Map& amap, Dart_handle adart,
int /*amark*/):
@ -439,7 +439,7 @@ namespace CGAL {
typedef Tag_false Use_mark;
CGAL_static_assertion( Bi>1 && delta>1 && Bi+delta<=Map::dimension );
public:
/// Main constructor.
CMap_dart_iterator_basic_of_two_beta(Map& amap, Dart_handle adart):
@ -448,7 +448,7 @@ namespace CGAL {
{}
/// Main constructor.
CMap_dart_iterator_basic_of_two_beta(Map& amap, Dart_handle adart,
CMap_dart_iterator_basic_of_two_beta(Map& amap, Dart_handle adart,
int /*amark*/):
Base(amap, adart),
mcurdart(0)
@ -516,7 +516,7 @@ namespace CGAL {
this->mprev_op = OP_END;
this->set_current_dart(NULL);
}
return *this;
}
@ -552,10 +552,10 @@ namespace CGAL {
typedef Tag_true Use_mark;
CGAL_static_assertion( 2<=Map::dimension );
public:
/// Main constructor.
CMap_dart_iterator_basic_of_two_beta(Map& amap, Dart_handle adart,
CMap_dart_iterator_basic_of_two_beta(Map& amap, Dart_handle adart,
int amark):
Base(amap, adart, amark)
{}

View File

@ -31,7 +31,7 @@ namespace CGAL {
/** @file Combinatorial_map_functors.h
* Definition of functors used for dD Combinatorial map.
*/
template<typename Dart_handle>
struct Couple_dart_and_dim
{
@ -49,7 +49,7 @@ namespace CGAL {
static void run(CMap* amap,
typename CMap::Dart_handle adart1,
typename CMap::Dart_handle adart2)
{
{
CGAL_assertion(amap!=NULL);
amap->template group_enabled_attribute<i, Type_attr>(adart1,adart2);
}
@ -64,7 +64,7 @@ namespace CGAL {
typename CMap::Dart_handle)
{}
};
// Functor used to degroup one attribute of two given darts
template <typename CMap, unsigned int i, typename Type_attr>
struct Degroup_one_attribute_functor
@ -72,13 +72,13 @@ namespace CGAL {
static bool run(CMap* amap,
typename CMap::Dart_handle adart1,
typename CMap::Dart_handle adart2)
{
{
CGAL_assertion(amap!=NULL);
return amap->template degroup_enabled_attribute<i, Type_attr>
(adart1,adart2);
}
};
// Specialization for i-attributes disabled.
template <typename CMap, unsigned int i>
struct Degroup_one_attribute_functor<CMap,i,CGAL::Void>
@ -96,13 +96,13 @@ namespace CGAL {
static bool run(CMap* amap,
typename CMap::Dart_handle adart1,
typename CMap::Dart_handle adart2)
{
{
CGAL_assertion(amap!=NULL);
return amap->template degroup_enabled_attribute_of_dart
<i, Type_attr, Range>(adart1,adart2);
}
};
// Specialization for i-attributes disabled.
template <typename CMap, unsigned int i, typename Range>
struct Degroup_one_attribute_of_dart_functor<CMap, i, CGAL::Void, Range>
@ -120,11 +120,11 @@ namespace CGAL {
{
template <unsigned int i>
static void run(Map* amap, typename Map::Dart_handle adart)
{ amap->template
{ amap->template
decrease_attribute_ref_counting<i>(adart/*,Tag_true()*/); }
};
/// Functor used to call update_dart_of_attribute<i>
/// Functor used to call update_dart_of_attribute<i>
/// on each i-cell attribute enabled
template<typename Map>
struct Update_dart_of_attribute_functor
@ -141,17 +141,17 @@ namespace CGAL {
template <unsigned int i>
static void run(const Map* amap, std::vector<int>* marks)
{ (*marks)[i] = amap->get_new_mark(); }
};
};
/// Functor used to test if a cell is valid
template<typename Map>
struct Test_is_valid_attribute_functor
{
template <unsigned int i>
static void run(const Map* amap,
typename Map::Dart_const_handle adart,
static void run(const Map* amap,
typename Map::Dart_const_handle adart,
std::vector<int>* marks, bool *ares)
{
{
if (!amap->template is_valid_attribute<i>(adart,(*marks)[i]) )
{
(*ares)=false;
@ -159,14 +159,14 @@ namespace CGAL {
"associated with an attribute for " << &(*adart)<< std::endl;
}
}
};
};
/// Functor for counting i-cell
template<typename Map>
struct Count_cell_functor
{
template <unsigned int i>
static void run( const Map* amap,
static void run( const Map* amap,
typename Map::Dart_const_handle adart,
std::vector<int>* amarks,
std::vector<unsigned int>* ares )
@ -185,7 +185,7 @@ namespace CGAL {
struct Group_attribute_functor_run
{
static void run(Map* amap,
typename Map::Dart_handle adart1,
typename Map::Dart_handle adart1,
typename Map::Dart_handle adart2, int adim)
{
if ( i!=adim )
@ -193,7 +193,7 @@ namespace CGAL {
amap->template group_enabled_attribute
<i, typename Map::Helper::template Attribute_type<i>::type>
(adart1, adart2);
}
}
}
};
@ -201,7 +201,7 @@ namespace CGAL {
struct Group_attribute_functor_run<CMap,0>
{
static void run(CMap* amap,
typename CMap::Dart_handle adart1,
typename CMap::Dart_handle adart1,
typename CMap::Dart_handle adart2, int adim)
{
typename CMap::Dart_handle od = adart1->other_extremity();
@ -211,7 +211,7 @@ namespace CGAL {
<0, typename CMap::Helper::template Attribute_type<0>::type>
(od, adart2);
}
if ( adim!=1 )
{
od = adart2->other_extremity();
@ -228,10 +228,10 @@ namespace CGAL {
{
template <unsigned int i>
static void run(Map* amap,
typename Map::Dart_handle adart1,
typename Map::Dart_handle adart1,
typename Map::Dart_handle adart2, int adim)
{
CGAL_assertion( adim==-1 ||
CGAL_assertion( adim==-1 ||
(1<=adim && (unsigned int)adim<=Map::dimension) );
Group_attribute_functor_run<Map,i>::run(amap,adart1,adart2,adim);
}
@ -243,10 +243,10 @@ namespace CGAL {
struct Degroup_attribute_functor_run
{
static void run(CMap* amap,
typename CMap::Dart_handle adart1,
typename CMap::Dart_handle adart1,
typename CMap::Dart_handle adart2, int adim)
{
CGAL_assertion( adim==-1 ||
CGAL_assertion( adim==-1 ||
(1<=adim && (unsigned int)adim<=CMap::dimension) );
if (i!=adim )
{
@ -260,17 +260,17 @@ namespace CGAL {
struct Degroup_attribute_functor_run<CMap, 0>
{
static void run(CMap* amap,
typename CMap::Dart_handle adart1,
typename CMap::Dart_handle adart1,
typename CMap::Dart_handle adart2, int adim)
{
CGAL_assertion( adim==-1 ||
CGAL_assertion( adim==-1 ||
(1<=adim && (unsigned int)adim<=CMap::dimension) );
typename CMap::Dart_handle od = adart1->other_extremity();
if ( od!=NULL )
amap->template degroup_enabled_attribute
<0, typename CMap::Helper::template Attribute_type<0>::type >
(od, adart2);
if ( adim!=1 )
{
od = adart2->other_extremity();
@ -287,13 +287,13 @@ namespace CGAL {
struct Degroup_attribute_functor
{
template <unsigned int i>
static void run(Map* amap,typename Map::Dart_handle adart1,
static void run(Map* amap,typename Map::Dart_handle adart1,
typename Map::Dart_handle adart2, int adim)
{
Degroup_attribute_functor_run<Map,i>::run(amap,adart1,adart2,adim);
}
};
// Functor which call operator() on the cell_attribute...
template<typename Cell_attribute, typename Functor>
struct Apply_cell_functor
@ -309,9 +309,9 @@ namespace CGAL {
{
static void run(Cell_attribute&, Cell_attribute&)
{}
};
};
/// Functor used for link_beta to update the attributes of
/// Functor used for link_beta to update the attributes of
/// adart2 on the attributes of this dart, except for adimension-attributes.
template<typename CMap, unsigned int i>
struct Group_attribute_functor_of_dart_run
@ -321,9 +321,9 @@ namespace CGAL {
typename CMap::Dart_handle dh2,
int adim)
{
CGAL_assertion( adim==-1 ||
CGAL_assertion( adim==-1 ||
(0<=adim && (unsigned int)adim<=CMap::dimension) );
if ( adim!=i )
if ( adim!=i )
{
amap->template group_enabled_attribute_of_dart
<i, typename CMap::Helper::template Attribute_type<i>::type>
@ -339,7 +339,7 @@ namespace CGAL {
typename CMap::Dart_handle dh2,
int adim)
{
CGAL_assertion( adim==-1 ||
CGAL_assertion( adim==-1 ||
(0<=adim && (unsigned int)adim<=CMap::dimension) );
// todo ASSERT (1<=adim && ...) ???
if ( adim!=0 )
@ -363,20 +363,20 @@ namespace CGAL {
a2=od->template attribute<0>();
if ( a2!=NULL )
amap->template set_attribute_of_dart<0>(dh1, a2);
}
}
}
}
}
};
template<typename CMap>
struct Group_attribute_functor_of_dart
{
template <unsigned int i>
static void run(CMap* amap,
typename CMap::Dart_handle adart1,
typename CMap::Dart_handle adart1,
typename CMap::Dart_handle adart2, int adim)
{
CGAL_assertion( adim==-1 ||
CGAL_assertion( adim==-1 ||
(0<=adim && (unsigned int)adim<=CMap::dimension) );
Group_attribute_functor_of_dart_run<CMap,i>::
run(amap,adart1,adart2,adim);
@ -393,7 +393,7 @@ namespace CGAL {
Attribute_type<i>::type>
struct Call_split_functor
{
static void run(typename Map::Dart_handle adart1,
static void run(typename Map::Dart_handle adart1,
typename Map::Dart_handle adart2)
{
Apply_cell_functor
@ -408,9 +408,9 @@ namespace CGAL {
template<typename Map,unsigned int i>
struct Call_split_functor<Map,i,CGAL::Void>
{
static void run(typename Map::Dart_handle,
static void run(typename Map::Dart_handle,
typename Map::Dart_handle)
{}
{}
};
/// Functor for counting the memory occupation of attributes
@ -447,14 +447,14 @@ namespace CGAL {
#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
template<typename Dart_handle, typename ... Betas>
struct Beta_functor;
template<typename Dart_handle, typename ... Betas>
struct Beta_functor<Dart_handle, int, Betas...>
{
static Dart_handle run(Dart_handle ADart, int B, Betas... betas)
{ return Beta_functor<Dart_handle, Betas...>::run(ADart->beta(B), betas...); }
};
template<typename Dart_handle>
struct Beta_functor<Dart_handle, int>
{
@ -465,7 +465,117 @@ namespace CGAL {
}
};
#endif //CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
template<typename Map, unsigned int i>
struct Store_incident_cells
{
template <unsigned int j>
static void run( Map* amap, typename Map::Dart_handle adart,
int mark_for_icell,
int* mark_for_incident_cells,
std::deque<std::deque<typename Map::Dart_handle> >
*store )
{
if ( i==j ) return;
const int mark_for_jcells = mark_for_incident_cells
[Map::Helper::template Dimension_index<j>::value];
if ( amap->is_marked(adart, mark_for_jcells) ||
adart->template attribute<j>()==NULL )
return;
std::deque<std::deque<typename Map::Dart_handle> >& jcells =
store[Map::Helper::template Dimension_index<j>::value];
CGAL_assertion( amap!=NULL );
CGAL_assertion( adart!=NULL );
CGAL_assertion( amap->is_reserved(mark_for_icell) );
CGAL_assertion( amap->is_reserved(mark_for_jcells) );
jcells.push_back(std::deque<typename Map::Dart_handle>());
for ( CMap_dart_iterator_basic_of_cell<Map,j>
itj(*amap, adart, mark_for_jcells); itj.cont(); ++itj )
{
if ( !amap->is_marked(itj, mark_for_icell) )
{
jcells.back().push_back(itj);
}
amap->mark(itj, mark_for_jcells);
}
if ( jcells.back().empty() ) jcells.pop_back();
}
};
template<typename Map, unsigned int i>
struct Test_split_with_deque
{
template <unsigned int j>
static void run( Map* amap,
int* mark_for_incident_cells,
std::deque<std::deque<typename Map::Dart_handle> >
*store )
{
if ( i==j ) return;
const int mark_for_jcells = mark_for_incident_cells
[Map::Helper::template Dimension_index<j>::value];
std::deque<std::deque<typename Map::Dart_handle> >& jcells =
store[Map::Helper::template Dimension_index<j>::value];
CGAL_assertion( amap!=NULL );
CGAL_assertion( amap->is_reserved(mark_for_jcells) );
int nbofjcell = 0;
typename Map::Helper::template Attribute_handle<j>::type
a1 = NULL;
typename Map::Helper::template Attribute_handle<j>::type
a2=NULL;
amap->negate_mark( mark_for_jcells );
for ( typename std::deque<std::deque<typename Map::Dart_handle> >::
iterator it=jcells.begin(); it!=jcells.end(); ++it )
{
nbofjcell = 0;
for ( typename std::deque<typename Map::Dart_handle>::iterator
itj=it->begin(); itj!=it->end(); ++itj )
{
if ( !amap->is_marked( *itj, mark_for_jcells) )
{
++nbofjcell;
if ( nbofjcell>1 )
{
a2 = amap->template create_attribute<j>(*a1);
a2->set_dart(*itj);
// We call the on_split functor
Apply_cell_functor
<typename Map::Helper::template Attribute_type<j>::type,
typename Map::Helper::template Attribute_type<j>::type::On_split>::
run(*a1, *a2);
}
else
{
a1=(*itj)->template attribute<j>();
a1->set_dart(*itj);
}
for ( CMap_dart_iterator_basic_of_cell<Map,j>
itj2(*amap, *itj, mark_for_jcells);
itj2.cont(); ++itj2 )
{
if ( nbofjcell>1 )
amap->template set_attribute_of_dart<j>(itj2, a2);
amap->mark(itj2, mark_for_jcells);
}
}
}
}
}
};
} // namespace internal
} // namespace CGAL

View File

@ -28,6 +28,37 @@
using namespace std;
template<typename CMap>
bool check_number_of_cells_3(CMap& cmap, unsigned int nbv, unsigned int nbe,
unsigned int nbf, unsigned int nbvol,
unsigned int nbcc)
{
if ( !cmap.is_valid() )
{
std::cout<<"ERROR: the cmap is not valid."<<std::endl;
assert(false);
return false;
}
std::vector<unsigned int> nbc;
nbc=cmap.count_all_cells();
if (nbv!=nbc[0] || nbe!=nbc[1] || nbf!=nbc[2] || nbvol!=nbc[3] ||
nbcc!=nbc[4])
{
std::cout<<"ERROR: the number of cells is not correct. We must have "
<<" ("<<nbv<<", "<<nbe<<", "<<nbf<<", "<<nbvol
<<", "<<nbcc<<") and we have"
<<" ("<<nbc[0]<<", "<<nbc[1]<<", "<<nbc[2]<<", "<<nbc[3]<<", "
<<nbc[4]<<")."
<<std::endl;
assert(false);
return false;
}
return true;
}
template<class Map>
void drawCell3(Map& amap, typename Map::Dart_handle adart, int aorbit, int mark)
{
@ -286,7 +317,7 @@ private:
};
template<class Map>
void test3D()
bool test3D()
{
typedef typename Map::Dart_handle Dart_handle;
Dart_handle d,dh,dh2,d1,d2,d3,d4;
@ -1016,71 +1047,80 @@ template<class Map>
cout << "***************************** TEST INSERT FACET 3D DONE."
<< endl;
/*
cout << "***************************** TEST EDGE CONTRACTION 3D:"
<< endl;
d1 = map.create_dart();
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
cout << "contract edge1: " << flush; CGAL::contract_cell<Map,1>(map,d1);
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
CGAL::contract_cell<Map,1>(map,d1);
if ( !check_number_of_cells_3(map, 0, 0, 0, 0, 0) )
return false;
d1 = map.create_dart(); map.template sew<1>(d1, d1);
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
cout << "contract edge2: " << flush; CGAL::contract_cell<Map,1>(map,d1);
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
CGAL::contract_cell<Map,1>(map,d1);
if ( !check_number_of_cells_3(map, 0, 0, 0, 0, 0) )
return false;
d1 = make_edge(map,, );
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
cout << "contract edge3: " << flush; CGAL::contract_cell<Map,1>(map,d1);
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
d1 = make_edge(map);
CGAL::contract_cell<Map,1>(map,d1);
if ( !check_number_of_cells_3(map, 0, 0, 0, 0, 0) )
return false;
d1 = make_edge(map,, );
map.template sew<1>(d1, d1); map.template sew<1>(d1->beta(2), d1->beta(2));
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
cout << "contract edge4: " << flush; CGAL::contract_cell<Map,1>(map,d1);
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
d1 = make_edge(map,, );
d1 = make_edge(map);
map.template sew<1>(d1, d1);
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
cout << "contract edge5: " << flush; CGAL::contract_cell<Map,1>(map,d1);
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
CGAL::contract_cell<Map,1>(map,d1);
if ( !check_number_of_cells_3(map, 0, 0, 0, 0, 0) )
return false;
d1 = make_edge(map);
map.template sew<1>(d1, d1); map.template sew<1>(d1->beta(2), d1->beta(2));
CGAL::contract_cell<Map,1>(map,d1);
if ( !check_number_of_cells_3(map, 0, 0, 0, 0, 0) )
return false;
d1 = CGAL::make_combinatorial_polygon(map, 3);
d1 = make_triangle(map,, , );
d2 = d1->beta(0); d3 = d1->beta(1);
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
CGAL::contract_cell<Map,1>(map,d1);
if ( !check_number_of_cells_3(map, 2, 2, 1, 1, 1) ||
!CGAL::is_face_combinatorial_polygon(map, d2, 2) )
return false;
cout << "contract edge6: " << flush; CGAL::contract_cell<Map,1>(map,d1);
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
CGAL::contract_cell<Map,1>(map,d2);
if ( !check_number_of_cells_3(map, 1, 1, 1, 1, 1) ||
!CGAL::is_face_combinatorial_polygon(map, d3, 1) )
return false;
cout << "contract edge7: " << flush; CGAL::contract_cell<Map,1>(map,d2);
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
CGAL::contract_cell<Map,1>(map,d3);
if ( !check_number_of_cells_3(map, 0, 0, 0, 0, 0) )
return false;
cout << "contract edge8: " << flush; CGAL::contract_cell<Map,1>(map,d3);
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
d1 = make_triangle(map,, , );
d2 = make_triangle(map,, , );
d1 = CGAL::make_combinatorial_polygon(map, 3);
d2 = CGAL::make_combinatorial_polygon(map, 3);
map.template sew<3>(d1, d2); d2 = d1->beta(0); d3 = d1->beta(1);
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
cout << "contract edge9: " << flush; CGAL::contract_cell<Map,1>(map,d1);
map.display_characteristics(cout)<<std::flush << ", valid=" << map.is_valid() << endl;
CGAL::contract_cell<Map,1>(map,d1);
if ( !check_number_of_cells_3(map, 2, 2, 1, 2, 1) ||
!CGAL::is_face_combinatorial_polygon(map, d2, 2) )
return false;
cout << "contract edge10: " << flush; CGAL::contract_cell<Map,1>(map,d2);
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
CGAL::contract_cell<Map,1>(map,d2);
if ( !check_number_of_cells_3(map, 1, 1, 1, 2, 1) ||
!CGAL::is_face_combinatorial_polygon(map, d3, 1) )
return false;
cout << "contract edge11: " << flush; CGAL::contract_cell<Map,1>(map,d3);
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
CGAL::contract_cell<Map,1>(map,d3);
if ( !check_number_of_cells_3(map, 0, 0, 0, 0, 0) )
return false;
d1 = make_triangle(map,, , );
d2 = make_triangle(map,, , );
d1 = CGAL::make_combinatorial_polygon(map, 3);
d2 = CGAL::make_combinatorial_polygon(map, 3);
map.template sew<2>(d1, d2);
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
cout << "contract edge12: " << flush; CGAL::contract_cell<Map,1>(map,d1);
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
CGAL::contract_cell<Map,1>(map,d1);
if ( !check_number_of_cells_3(map, 4, 4, 2, 2, 2) )
return false;
/* TODO continue tests
d1 = make_triangle(map,, , );
d2 = make_triangle(map,, , );
map.template sew<2>(d1, d2);
@ -1308,6 +1348,7 @@ template<class Map>
cout << "***************************** TEST VOLUME CONTRACTION 3D DONE."
<< endl;
*/
return true;
}
#endif // CGAL_COMBINATORIAL_MAP_3_TEST

View File

@ -84,22 +84,46 @@ int main()
typedef CGAL::Combinatorial_map<3,
CGAL::Combinatorial_map_min_items<3> > Map4;
test3D<Map4>();
if ( !test3D<Map4>() )
{
std::cout<<"ERROR during Test_LCC_4<LCC4b>."<<std::endl;
return EXIT_FAILURE;
}
typedef CGAL::Combinatorial_map<3, Map_3_dart_max_items_3> Map5;
test3D<Map5>();
if ( !test3D<Map5>() )
{
std::cout<<"ERROR during test3D<Map5>."<<std::endl;
return EXIT_FAILURE;
}
typedef CGAL::Combinatorial_map<3, Map_3_dart_max_items_3> Map6;
test3D<Map6>();
if ( !test3D<Map6>() )
{
std::cout<<"ERROR during test3D<Map6>."<<std::endl;
return EXIT_FAILURE;
}
typedef CGAL::Combinatorial_map<3, Another_map_3_dart_items_3> Map7;
test3D<Map7>();
if ( !test3D<Map7>() )
{
std::cout<<"ERROR during test3D<Map7>."<<std::endl;
return EXIT_FAILURE;
}
typedef CGAL::Combinatorial_map<3, Another_map_3_dart_items_3> Map8;
test3D<Map8>();
if ( !test3D<Map8>() )
{
std::cout<<"ERROR during test3D<Map8>."<<std::endl;
return EXIT_FAILURE;
}
typedef CGAL::Combinatorial_map<4, Map_dart_max_items_4> Map9;
test3D<Map9>();
if ( !test3D<Map9>() )
{
std::cout<<"ERROR during test3D<Map9>."<<std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}