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

@ -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.

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

@ -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

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;
}