cgal/Packages/Triangulation_3/include/CGAL/Triangulation_ds_cell_3.h

429 lines
11 KiB
C++

// Copyright (c) 1999-2004 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $Source$
// $Revision$ $Date$
// $Name$
//
// Author(s) : Monique Teillaud <Monique.Teillaud@sophia.inria.fr>
// cell of a combinatorial triangulation of any dimension <=3
// use to store vertices if dimension <=0, edges if dimension 1,
// faces if dimension 2, plain cells if dimension 3
#ifndef CGAL_TRIANGULATION_DS_CELL_3_H
#define CGAL_TRIANGULATION_DS_CELL_3_H
#include <CGAL/basic.h>
#include <CGAL/Triangulation_short_names_3.h>
#include <CGAL/Triangulation_utils_3.h>
CGAL_BEGIN_NAMESPACE
template < class Cb >
class Triangulation_ds_cell_3
: public Cb
{
static int ccw(int i)
{
return Triangulation_utils_3::ccw(i);
}
static int cw(int i)
{
return Triangulation_utils_3::cw(i);
}
typedef typename Cb::Triangulation_data_structure Tds;
public:
typedef typename Tds::Vertex_handle Vertex_handle;
typedef typename Tds::Cell_handle Cell_handle;
typedef typename Tds::Vertex Vertex;
typedef typename Tds::Cell Cell;
using Cb::neighbor;
using Cb::vertex;
Triangulation_ds_cell_3()
: Cb()
{
set_in_conflict_flag(0);
}
Triangulation_ds_cell_3(Vertex_handle v0, Vertex_handle v1,
Vertex_handle v2, Vertex_handle v3)
: Cb(v0, v1, v2, v3)
{
set_in_conflict_flag(0);
}
Triangulation_ds_cell_3(Vertex_handle v0, Vertex_handle v1,
Vertex_handle v2, Vertex_handle v3,
Cell_handle n0, Cell_handle n1,
Cell_handle n2, Cell_handle n3)
: Cb(v0, v1, v2, v3, n0, n1, n2, n3)
{
set_in_conflict_flag(0);
}
int mirror_index(int i) const
{
CGAL_triangulation_precondition ( i>=0 && i<4 );
Cell_handle ni = neighbor(i);
if (&*ni->neighbor(0) == this) return 0;
if (&*ni->neighbor(1) == this) return 1;
if (&*ni->neighbor(2) == this) return 2;
CGAL_triangulation_assertion(&*ni->neighbor(3) == this);
return 3;
}
Vertex_handle mirror_vertex(int i) const
{
return neighbor(i)->vertex(mirror_index(i));
}
void set_in_conflict_flag(unsigned char f)
{
_in_conflict_flag = f;
}
unsigned char get_in_conflict_flag() const
{
return _in_conflict_flag;
}
bool is_valid(int dim = 3, bool verbose = false, int level = 0) const;
private:
unsigned char _in_conflict_flag;
void error_orient(Cell_handle, int i) const
{
std::cerr << " pb orientation with neighbor " << i << std::endl;
}
};
template < class Cb >
bool
Triangulation_ds_cell_3<Cb>::is_valid(int dim, bool verbose, int level) const
{
if ( ! Cb::is_valid(verbose,level) )
return false;
switch (dim) {
case -2:
case -1:
{
if ( vertex(0) == Vertex_handle() ) {
if (verbose)
std::cerr << "vertex 0 NULL" << std::endl;
CGAL_triangulation_assertion(false);
return false;
}
vertex(0)->is_valid(verbose,level);
if ( vertex(1) != Vertex_handle() || vertex(2) != Vertex_handle()) {
if (verbose)
std::cerr << "vertex 1 or 2 != NULL" << std::endl;
CGAL_triangulation_assertion(false);
return false;
}
if ( neighbor(0) != Cell_handle() ||
neighbor(1) != Cell_handle() ||
neighbor(2) != Cell_handle()) {
if (verbose)
std::cerr << "one neighbor != NULL" << std::endl;
CGAL_triangulation_assertion(false);
return false;
}
break;
}
case 0:
{
if ( vertex(0) == Vertex_handle() ) {
if (verbose)
std::cerr << "vertex 0 NULL" << std::endl;
CGAL_triangulation_assertion(false);
return false;
}
vertex(0)->is_valid(verbose,level);
if ( neighbor (0) == Cell_handle() ) {
if (verbose)
std::cerr << "neighbor 0 NULL" << std::endl;
CGAL_triangulation_assertion(false);
return false;
}
if ( vertex(1) != Vertex_handle() || vertex(2) != Vertex_handle() ) {
if (verbose)
std::cerr << "vertex 1 or 2 != NULL" << std::endl;
CGAL_triangulation_assertion(false);
return false;
}
if ( neighbor(1) != Cell_handle() || neighbor(2) != Cell_handle() ) {
if (verbose)
std::cerr << "neighbor 1 or 2 != NULL" << std::endl;
CGAL_triangulation_assertion(false);
return false;
}
if ( ! neighbor(0)->has_vertex(vertex(0)) ) {
if (verbose)
std::cerr << "neighbor 0 does not have vertex 0" << std::endl;
CGAL_triangulation_assertion(false);
return false;
}
break;
}
case 1:
{
Vertex_handle v0 = vertex(0);
Vertex_handle v1 = vertex(1);
Cell_handle n0 = neighbor(0);
Cell_handle n1 = neighbor(1);
if ( v0 == Vertex_handle() || v1 == Vertex_handle() ) {
if (verbose)
std::cerr << "vertex 0 or 1 NULL" << std::endl;
CGAL_triangulation_assertion(false);
return false;
}
vertex(0)->is_valid(verbose,level);
vertex(1)->is_valid(verbose,level);
if ( n0 == Cell_handle() || n1 == Cell_handle() ) {
if (verbose)
std::cerr << "neighbor 0 or 1 NULL" << std::endl;
CGAL_triangulation_assertion(false);
return false;
}
if ( v0 != n1->vertex(1) ) {
if (verbose)
std::cerr << "neighbor 1 does not have vertex 0 as vertex 1"
<< std::endl;
CGAL_triangulation_assertion(false);
return false;
}
if ( v1 != n0->vertex(0) ) {
if (verbose)
std::cerr << "neighbor 0 does not have vertex 1 as vertex 0"
<< std::endl;
CGAL_triangulation_assertion(false);
return false;
}
if ( &*n0->neighbor(1) != this ) {
if (verbose)
std::cerr << "neighbor 0 does not have this as neighbor 1"
<< std::endl;
CGAL_triangulation_assertion(false);
return false;
}
if ( &*n1->neighbor(0) != this ) {
if (verbose)
std::cerr << "neighbor 1 does not have this as neighbor 0"
<< std::endl;
CGAL_triangulation_assertion(false);
return false;
}
break;
}
case 2:
{
if ( vertex(0) == Vertex_handle() ||
vertex(1) == Vertex_handle() ||
vertex(2) == Vertex_handle() ) {
if (verbose)
std::cerr << "vertex 0, 1, or 2 NULL" << std::endl;
CGAL_triangulation_assertion(false);
return false;
}
vertex(0)->is_valid(verbose,level);
vertex(1)->is_valid(verbose,level);
vertex(2)->is_valid(verbose,level);
int in;
Cell_handle n;
for(int i = 0; i < 3; i++) {
n = neighbor(i);
if ( n == Cell_handle() ) {
if (verbose)
std::cerr << "neighbor " << i << " NULL" << std::endl;
CGAL_triangulation_assertion(false);
return false;
}
if ( ! n->has_vertex(vertex(cw(i)),in ) ) {
if (verbose)
std::cerr << "vertex " << cw(i)
<< " not vertex of neighbor " << i << std::endl;
CGAL_triangulation_assertion(false);
return false;
}
in = cw(in);
if ( &*n->neighbor(in) != this ) {
if (verbose)
std::cerr << "neighbor " << i
<< " does not have this as neighbor "
<< in << std::endl;
CGAL_triangulation_assertion(false);
return false;
}
if ( vertex(ccw(i)) != n->vertex(cw(in)) ) {
if (verbose)
std::cerr << "vertex " << ccw(i)
<< " is not vertex " << cw(in)
<< " of neighbor " << i << std::endl;
CGAL_triangulation_assertion(false);
return false;
}
}
break;
}
case 3:
{
int i;
for(i = 0; i < 4; i++) {
if ( vertex(i) == Vertex_handle() ) {
if (verbose)
std::cerr << "vertex " << i << " NULL" << std::endl;
CGAL_triangulation_assertion(false);
return false;
}
vertex(i)->is_valid(verbose,level);
}
for(i = 0; i < 4; i++) {
Cell_handle n = neighbor(i);
if ( n == Cell_handle() ) {
if (verbose)
std::cerr << "neighbor " << i << " NULL" << std::endl;
CGAL_triangulation_assertion(false);
return false;
}
int in = 5;
// if ( ! n->has_neighbor(handle(), in) ) {
if ( &*n->neighbor(0) == this) in = 0;
if ( &*n->neighbor(1) == this) in = 1;
if ( &*n->neighbor(2) == this) in = 2;
if ( &*n->neighbor(3) == this) in = 3;
if (in == 5) {
if (verbose)
std::cerr << "neighbor of c has not c as neighbor" << std::endl;
CGAL_triangulation_assertion(false);
return false;
}
int j1n,j2n,j3n;
if ( ! n->has_vertex(vertex((i+1)&3),j1n) ) {
if (verbose) { std::cerr << "vertex " << ((i+1)&3)
<< " not vertex of neighbor "
<< i << std::endl; }
CGAL_triangulation_assertion(false);
return false;
}
if ( ! n->has_vertex(vertex((i+2)&3),j2n) ) {
if (verbose) { std::cerr << "vertex " << ((i+2)&3)
<< " not vertex of neighbor "
<< i << std::endl; }
CGAL_triangulation_assertion(false);
return false;
}
if ( ! n->has_vertex(vertex((i+3)&3),j3n) ) {
if (verbose) { std::cerr << "vertex " << ((i+3)&3)
<< " not vertex of neighbor "
<< i << std::endl; }
CGAL_triangulation_assertion(false);
return false;
}
if ( in+j1n+j2n+j3n != 6) {
if (verbose) { std::cerr << "sum of the indices != 6 "
<< std::endl; }
CGAL_triangulation_assertion(false);
return false;
}
// tests whether the orientations of this and n are consistent
if ( ((i+in)&1) == 0 ) { // i and in have the same parity
if ( j1n == ((in+1)&3) ) {
if ( ( j2n != ((in+3)&3) ) || ( j3n != ((in+2)&3) ) ) {
if (verbose) {
error_orient(n,i);
}
CGAL_triangulation_assertion(false);
return false;
}
}
if ( j1n == ((in+2)&3) ) {
if ( ( j2n != ((in+1)&3) ) || ( j3n != ((in+3)&3) ) ) {
if (verbose) {
error_orient(n,i);
}
CGAL_triangulation_assertion(false);
return false;
}
}
if ( j1n == ((in+3)&3) ) {
if ( ( j2n != ((in+2)&3) ) || ( j3n != ((in+1)&3) ) ) {
if (verbose) {
error_orient(n,i);
}
CGAL_triangulation_assertion(false);
return false;
}
}
}
else { // i and in do not have the same parity
if ( j1n == ((in+1)&3) ) {
if ( ( j2n != ((in+2)&3) ) || ( j3n != ((in+3)&3) ) ) {
if (verbose) {
error_orient(n,i);
}
CGAL_triangulation_assertion(false);
return false;
}
}
if ( j1n == ((in+2)&3) ) {
if ( ( j2n != ((in+3)&3) ) || ( j3n != ((in+1)&3) ) ) {
if (verbose) {
error_orient(n,i);
}
CGAL_triangulation_assertion(false);
return false;
}
}
if ( j1n == ((in+3)&3) ) {
if ( ( j2n != ((in+1)&3) ) || ( j3n != ((in+2)&3) ) ) {
if (verbose) {
error_orient(n,i);
}
CGAL_triangulation_assertion(false);
return false;
}
}
}
} // end looking at neighbors
}// end case dim 3
} // end switch
return true;
} // end is_valid
CGAL_END_NAMESPACE
#endif // CGAL_TRIANGULATION_DS_CELL_3_H