code and doc for is_valid, for vertex, full_cell and tds

This commit is contained in:
Samuel Hornus 2012-07-09 16:06:37 +00:00
parent 284142f645
commit e96a8301eb
8 changed files with 108 additions and 69 deletions

View File

@ -175,10 +175,15 @@ a neighbor of \ccVar\ if the full cell \ccc{n} is a neighbor of the full cell
\begin{ccDebug} \begin{ccDebug}
\ccHeading{Validity check} \ccHeading{Validity check}
\ccMethod{bool is_valid(bool verbose=false) const;}{Performs any \ccMethod{bool is_valid(bool verbose=false) const;}{
desired test on a full cell. \emph{E.g.}, checks that for each Performs some validity checks on the full cell \ccVar.
existing neighbor \ccc{n}, \ccVar\ and \ccc{n} share relevant vertices
and \ccVar\ is the relevant neighbor of \ccc{n}. It must \emph{at least} check that for each \emph{existing} neighbor \ccc{n},
\ccVar\ is also a neighbor of \ccc{n}.
Returns \ccc{true} if all the tests pass, \ccc{false} if any test fails. See
the documentation for the models of this concept to see the additionnal (if
any) validity checks that they implement.%
} }
\end{ccDebug} \end{ccDebug}

View File

@ -54,10 +54,15 @@ incident full cell. \ccPrecond \ccc{c} must not be the default-constructed
\begin{ccDebug} \begin{ccDebug}
\ccHeading{Validity check} \ccHeading{Validity check}
\ccMethod{bool is_valid(bool verbose=false) const;}{Performs any \ccMethod{bool is_valid(bool verbose=false) const;}{%
desired test on a vertex. For example, it could check that the incident full Performs some validity checks on the vertex \ccVar.
cell exists and contains \ccVar. See the documentation for the models
of this concept to see the validity checks that they implement.% It must \emph{at least} check that \ccVar\ has an incident full cell, which in
turn must contain \ccVar\ as one of its vertices.
Returns \ccc{true} if all the tests pass, \ccc{false} if any test fails. See
the documentation for the models of this concept to see the additionnal (if
any) validity checks that they implement.%
} }
\end{ccDebug} \end{ccDebug}

View File

@ -559,20 +559,22 @@ and \ccc{current_dimension()!=2}.
\begin{ccDebug} \begin{ccDebug}
\ccHeading{Validity check} % - - - - - - - - - - - - - - - - - - - - VALIDITY \ccHeading{Validity check} % - - - - - - - - - - - - - - - - - - - - VALIDITY
\ccMethod{bool is_valid(bool verbose = true) const;} \ccMethod{bool is_valid(bool verbose=false) const;}{%
{Partially checks whether \ccVar\ is a triangulation. This function Partially checks whether \ccVar\ is indeed a triangulation.
returns \ccc{true} if each vertex is a vertex of the full cell of which it
claims to be a vertex, if the vertices of every full cell are pairwise distinct, It must \emph{at least}\begin{itemize}
if the adjacency (neighbor) relationship is symmetric, and if adjacent full cells share \item check the validity of the vertices and full cells of \ccVar\ by calling
exactly \ccVar.\ccc{current_dimension()} vertices and the induced their respective \ccc{is_valid} method.
orientation of these two full cells are compatible. \item check that each full cell has no duplicate vertices and has as many
It prints an error message neighbors as its number of facets (\ccc{current_dimension()+1}).
if one of these conditions is violated and the \ccc{verbose} parameter is \item check that each full cell share exactly \ccVar.\ccc{current_dimension()}
\ccc{true}. Passing these tests does not guaranty that we have a vertices with each of its neighbor.
triangulation (abstract pure \end{itemize}
complex). In particular, for example, it is not
checked whether full cells that share \ccVar.\ccc{current_dimension()} vertices Returns \ccc{true} if all the tests pass, \ccc{false} if any test fails. See
are neighbors in the data structure.} the documentation for the models of this concept to see the additionnal (if
any) validity checks that they implement.%
}
\end{ccDebug} \end{ccDebug}

View File

@ -48,6 +48,23 @@ In addition, the class \ccRefName\ provides the following types and methods:
{The copy constructor. Creates a copy of the \ccRefName\ \ccc{t2} passed as {The copy constructor. Creates a copy of the \ccRefName\ \ccc{t2} passed as
argument. All vertices and full cells are duplicated.} argument. All vertices and full cells are duplicated.}
\begin{ccDebug}
\ccHeading{Validity check} % - - - - - - - - - - - - - - - - - - - - VALIDITY
The \ccc{is_valid} method is only minimally defined in the
\ccc{TriangulationDataStructure} concept, so that we document it more precisely
here, for the model \ccRefName:
\ccMethod{bool is_valid(bool verbose = true) const;}{%
Implements the validity checks required by the concept
\ccc{TriangulationDataStructure}.%
Note that passing all these tests does not guaranty that we have a
triangulation (abstract pure simplicial complex).%
}
\end{ccDebug}
\begin{ccAdvanced} \begin{ccAdvanced}
\ccTypes \ccTypes

View File

@ -51,9 +51,26 @@ See the user manual for how to choose the second option.
\ccc{TriangulationDSFullCell} \ccc{TriangulationDSFullCell}
\ccCreationVariable{c}
\begin{ccDebug}
\ccHeading{Validity check}
The \ccc{is_valid} method is only minimally defined in the
\ccc{TriangulationDSFullCell} concept, so that we document it more precisely
here, for the model \ccRefName:
\ccMethod{bool is_valid(bool verbose=false) const;}{
Implements the validity checks required by the concept
\ccc{TriangulationDSFullCell}. In addition, it is checked that there is no
\ccc{NULL} handle to vertices in the middle of non-\ccc{NULL} ones, that is,
that the internal memory layout is not corrupted.%
}
\end{ccDebug}
\begin{ccAdvanced} \begin{ccAdvanced}
\ccHeading{Rebind mechanism} \ccHeading{Rebind mechanism}
In case oif derivation from that class, the nested class In case of derivation from that class, the nested class
\ccc{Rebind_TDS} need to be provided in the derived class. \ccc{Rebind_TDS} need to be provided in the derived class.
\end{ccAdvanced} \end{ccAdvanced}

View File

@ -33,13 +33,14 @@ The template parameter \ccc{TriangulationDataStructure} must be a model of the
\begin{ccDebug} \begin{ccDebug}
\ccHeading{Validity check} \ccHeading{Validity check}
The \ccc{is_valid} method is only loosely defined in the The \ccc{is_valid} method is only minimally defined in the
\ccc{TriangulationDSVertex} concept, so that we document it more precisely \ccc{TriangulationDSVertex} concept, so that we document it more precisely
here, for the model \ccRefName: here, for the model \ccRefName:
\ccMethod{bool is_valid(bool verbose=false) const;}{Returns \ccc{true} \ccMethod{bool is_valid(bool verbose=false) const;}{%
if the full cell incident to \ccVar\ actually exists and contains Implements the validity checks required by the concept
\ccVar\ as one of its vertices. Returns \ccc{false} otherwise.} \ccc{TriangulationDSVertex}. Does not implement additional checks.%
}
\end{ccDebug} \end{ccDebug}
\begin{ccAdvanced} \begin{ccAdvanced}

View File

@ -476,15 +476,6 @@ public:
// SANITY CHECKS // SANITY CHECKS
bool is_valid(bool = true, int = 0) const; /* Concept */ bool is_valid(bool = true, int = 0) const; /* Concept */
/* op Partially checks whether |\Mvar| is an abstract simplicial
complex. This function terminates without error if each vertex is a
vertex of the full_cell of which it claims to be a vertex, if the
vertices of all full_cells are pairwise distinct, if the neighbor
relationship is symmetric, and if neighboring full_cells share exactly
|dcur_| vertices. It returns an error message if one of these
conditions is violated. Note that it is not checked whether full_cells
that share |dcur_| vertices are neighbors in the data structure.
*/
// NOT DOCUMENTED // NOT DOCUMENTED
template< class OutStream> void write_graph(OutStream &); template< class OutStream> void write_graph(OutStream &);
@ -1179,7 +1170,7 @@ bool Triangulation_data_structure<Dimen, Vb, Fcb>
Vertex_const_handle v; Vertex_const_handle v;
int i, j, k; int i, j, k;
if( dcur_ == -2 ) if( current_dimension() == -2 )
{ {
if( ! vertices_.empty() || ! full_cells_.empty() ) if( ! vertices_.empty() || ! full_cells_.empty() )
{ {
@ -1188,7 +1179,7 @@ bool Triangulation_data_structure<Dimen, Vb, Fcb>
} }
} }
if( dcur_ == -1 ) if( current_dimension() == -1 )
{ {
if ( (number_of_vertices() != 1) || (number_of_full_cells() != 1) ) if ( (number_of_vertices() != 1) || (number_of_full_cells() != 1) )
{ {
@ -1197,39 +1188,25 @@ bool Triangulation_data_structure<Dimen, Vb, Fcb>
} }
} }
int fake_dcur = (dcur_ > 0) ? dcur_ : 0;
for( v = vertices_begin(); v != vertices_end(); ++v ) for( v = vertices_begin(); v != vertices_end(); ++v )
{ {
if( ! v->is_valid(verbose) ) if( ! v->is_valid(verbose) )
return false; return false;
bool ok(false);
// check that |v|'s full_cell actually contains |v|
for( i = 0; i <= fake_dcur; ++i )
{
if( v->full_cell()->vertex(i) == v )
{
ok = true;
break;
}
}
if( ! ok )
{
if( verbose ) CGAL_warning_msg(false, "the full_cell incident to some vertex does not contain that vertex.");
return false;
}
} }
// FUTURE: for each vertex v, gather incident full_cells. then, check that // FUTURE: for each vertex v, gather incident full_cells. then, check that
// any full_cell containing v is among those gathered full_cells... // any full_cell containing v is among those gathered full_cells...
if( dcur_ < 0 ) if( current_dimension() < 0 )
return true; return true;
for( s = full_cells_begin(); s != full_cells_end(); ++s ) for( s = full_cells_begin(); s != full_cells_end(); ++s )
{ {
if( ! s->is_valid(verbose) ) if( ! s->is_valid(verbose) )
return false; return false;
for( i = 0; i <= dcur_; ++i ) // check that the full cell has no duplicate vertices
for( j = i + 1; j <= dcur_; ++j ) for( i = 0; i <= current_dimension(); ++i )
for( j = i + 1; j <= current_dimension(); ++j )
if( vertex(s,i) == vertex(s,j) ) if( vertex(s,i) == vertex(s,j) )
{ {
CGAL_warning_msg(false, "a full_cell has two equal vertices"); CGAL_warning_msg(false, "a full_cell has two equal vertices");
@ -1239,7 +1216,7 @@ bool Triangulation_data_structure<Dimen, Vb, Fcb>
for( s = full_cells_begin(); s != full_cells_end(); ++s ) for( s = full_cells_begin(); s != full_cells_end(); ++s )
{ {
for( i = 0; i <= dcur_; ++i ) for( i = 0; i <= current_dimension(); ++i )
if( (t = neighbor(s,i)) != Full_cell_const_handle() ) if( (t = neighbor(s,i)) != Full_cell_const_handle() )
{ {
int l = mirror_index(s,i); int l = mirror_index(s,i);
@ -1248,13 +1225,13 @@ bool Triangulation_data_structure<Dimen, Vb, Fcb>
if( verbose ) CGAL_warning_msg(false, "neighbor relation is not symmetric"); if( verbose ) CGAL_warning_msg(false, "neighbor relation is not symmetric");
return false; return false;
} }
for( j = 0; j <= dcur_; ++j ) for( j = 0; j <= current_dimension(); ++j )
if( j != i ) if( j != i )
{ {
// j must also occur as a vertex of t // j must also occur as a vertex of t
for( k = 0; k <= dcur_ && ( vertex(s,j) != vertex(t,k) || k == l); ++k ) for( k = 0; k <= current_dimension() && ( vertex(s,j) != vertex(t,k) || k == l); ++k )
; ;
if( k > dcur_ ) if( k > current_dimension() )
{ {
if( verbose ) CGAL_warning_msg(false, "too few shared vertices between neighbors full_cells."); if( verbose ) CGAL_warning_msg(false, "too few shared vertices between neighbors full_cells.");
return false; return false;

View File

@ -208,21 +208,36 @@ public:
void* for_compact_container() const { return combinatorics_.for_compact_container(); } void* for_compact_container() const { return combinatorics_.for_compact_container(); }
void* & for_compact_container() { return combinatorics_.for_compact_container(); } void* & for_compact_container() { return combinatorics_.for_compact_container(); }
bool is_valid(bool verbose = true, int /* level */ = 0) const /* Concept */ bool is_valid(bool verbose = false, int level = 0) const /* Concept */
{ {
const int d = maximal_dimension(); const int d = maximal_dimension();
for( int i = 0; i <= d; ++i ) int i(0);
// test that the non-null Vertex_handles come first, before all null ones
while( i <= d && vertex(i) != Vertex_handle() ) ++i;
while( i <= d && vertex(i) == Vertex_handle() ) ++i;
if( i <= d )
{ {
if( Vertex_handle() != vertex(i) ) if( verbose ) CGAL_warning_msg(false, "full cell has garbage handles to vertices.");
return false;
}
for( i = 0; i <= d; ++i )
{
if( Vertex_handle() == vertex(i) )
break; // there are no more vertices
Full_cell_handle n(neighbor(i));
if( Full_cell_handle() != n )
{ {
if( Full_cell_handle() == neighbor(i) ) int mirror_idx(mirror_index(i));
if( n->neighbor(mirror_idx) == Full_cell_handle() )
{ {
if( verbose ) CGAL_warning_msg(false, "vertex has no opposite full cell."); if( verbose ) CGAL_warning_msg(false, "neighbor has no back-neighbor.");
return false;
}
if( &(*(n->neighbor(mirror_idx))) != this )
{
if( verbose ) CGAL_warning_msg(false, "neighbor does not point back to correct full cell.");
return false; return false;
} }
// Here, we can't check if neighbor(i) counts *this as a neighbor
// because we can't construct a Full_cell_handle to *this...
// So we have to do this check in the `parent' class (TDS)
} }
} }
return true; return true;