mirror of https://github.com/CGAL/cgal
Contraction v2 to start a new proper branch.
This commit is contained in:
parent
e17201c286
commit
54a27a09c9
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -177,9 +177,9 @@ namespace CGAL {
|
|||
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.
|
||||
*/
|
||||
|
|
@ -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
|
||||
|
|
@ -218,41 +218,40 @@ 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;
|
||||
std::deque<typename Map::Dart_handle> to_erase;
|
||||
|
||||
// 2) We mark all the darts of the i-cell.
|
||||
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 );
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
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) )
|
||||
|
|
@ -274,48 +273,73 @@ namespace CGAL {
|
|||
{
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
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.
|
||||
|
|
@ -325,6 +349,18 @@ namespace CGAL {
|
|||
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;
|
||||
|
|
@ -332,9 +368,9 @@ namespace CGAL {
|
|||
};
|
||||
|
||||
/** 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>
|
||||
|
|
@ -382,9 +418,9 @@ namespace CGAL {
|
|||
// 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.
|
||||
|
|
@ -484,9 +520,9 @@ 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.
|
||||
|
|
@ -502,7 +538,7 @@ namespace CGAL {
|
|||
}
|
||||
};
|
||||
|
||||
/** 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.
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -466,6 +466,116 @@ 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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue