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}
\ccHeading{Validity check}
\ccMethod{bool is_valid(bool verbose=false) const;}{Performs any
desired test on a full cell. \emph{E.g.}, checks that for each
existing neighbor \ccc{n}, \ccVar\ and \ccc{n} share relevant vertices
and \ccVar\ is the relevant neighbor of \ccc{n}.
\ccMethod{bool is_valid(bool verbose=false) const;}{
Performs some validity checks on the full cell \ccVar.
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}

View File

@ -54,10 +54,15 @@ incident full cell. \ccPrecond \ccc{c} must not be the default-constructed
\begin{ccDebug}
\ccHeading{Validity check}
\ccMethod{bool is_valid(bool verbose=false) const;}{Performs any
desired test on a vertex. For example, it could check that the incident full
cell exists and contains \ccVar. See the documentation for the models
of this concept to see the validity checks that they implement.%
\ccMethod{bool is_valid(bool verbose=false) const;}{%
Performs some validity checks on the vertex \ccVar.
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}

View File

@ -559,20 +559,22 @@ and \ccc{current_dimension()!=2}.
\begin{ccDebug}
\ccHeading{Validity check} % - - - - - - - - - - - - - - - - - - - - VALIDITY
\ccMethod{bool is_valid(bool verbose = true) const;}
{Partially checks whether \ccVar\ is a triangulation. This function
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,
if the adjacency (neighbor) relationship is symmetric, and if adjacent full cells share
exactly \ccVar.\ccc{current_dimension()} vertices and the induced
orientation of these two full cells are compatible.
It prints an error message
if one of these conditions is violated and the \ccc{verbose} parameter is
\ccc{true}. Passing these tests does not guaranty that we have a
triangulation (abstract pure
complex). In particular, for example, it is not
checked whether full cells that share \ccVar.\ccc{current_dimension()} vertices
are neighbors in the data structure.}
\ccMethod{bool is_valid(bool verbose=false) const;}{%
Partially checks whether \ccVar\ is indeed a triangulation.
It must \emph{at least}\begin{itemize}
\item check the validity of the vertices and full cells of \ccVar\ by calling
their respective \ccc{is_valid} method.
\item check that each full cell has no duplicate vertices and has as many
neighbors as its number of facets (\ccc{current_dimension()+1}).
\item check that each full cell share exactly \ccVar.\ccc{current_dimension()}
vertices with each of its neighbor.
\end{itemize}
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}

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
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}
\ccTypes

View File

@ -51,9 +51,26 @@ See the user manual for how to choose the second option.
\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}
\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.
\end{ccAdvanced}

View File

@ -33,13 +33,14 @@ The template parameter \ccc{TriangulationDataStructure} must be a model of the
\begin{ccDebug}
\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
here, for the model \ccRefName:
\ccMethod{bool is_valid(bool verbose=false) const;}{Returns \ccc{true}
if the full cell incident to \ccVar\ actually exists and contains
\ccVar\ as one of its vertices. Returns \ccc{false} otherwise.}
\ccMethod{bool is_valid(bool verbose=false) const;}{%
Implements the validity checks required by the concept
\ccc{TriangulationDSVertex}. Does not implement additional checks.%
}
\end{ccDebug}
\begin{ccAdvanced}

View File

@ -476,15 +476,6 @@ public:
// SANITY CHECKS
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
template< class OutStream> void write_graph(OutStream &);
@ -1179,7 +1170,7 @@ bool Triangulation_data_structure<Dimen, Vb, Fcb>
Vertex_const_handle v;
int i, j, k;
if( dcur_ == -2 )
if( current_dimension() == -2 )
{
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) )
{
@ -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 )
{
if( ! v->is_valid(verbose) )
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
// any full_cell containing v is among those gathered full_cells...
if( dcur_ < 0 )
if( current_dimension() < 0 )
return true;
for( s = full_cells_begin(); s != full_cells_end(); ++s )
{
if( ! s->is_valid(verbose) )
return false;
for( i = 0; i <= dcur_; ++i )
for( j = i + 1; j <= dcur_; ++j )
// check that the full cell has no duplicate vertices
for( i = 0; i <= current_dimension(); ++i )
for( j = i + 1; j <= current_dimension(); ++j )
if( vertex(s,i) == vertex(s,j) )
{
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( i = 0; i <= dcur_; ++i )
for( i = 0; i <= current_dimension(); ++i )
if( (t = neighbor(s,i)) != Full_cell_const_handle() )
{
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");
return false;
}
for( j = 0; j <= dcur_; ++j )
for( j = 0; j <= current_dimension(); ++j )
if( j != i )
{
// 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.");
return false;

View File

@ -208,21 +208,36 @@ public:
void* for_compact_container() const { 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();
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;
}
// 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;