380 lines
13 KiB
C++
Executable File
380 lines
13 KiB
C++
Executable File
// Copyright (c) 1997-2002 Max-Planck-Institute Saarbruecken (Germany).
|
|
// All rights reserved.
|
|
//
|
|
// This file is part of CGAL (www.cgal.org).
|
|
// You can redistribute it and/or modify it under the terms of the GNU
|
|
// General Public License as published by the Free Software Foundation,
|
|
// either version 3 of the License, or (at your option) any later version.
|
|
//
|
|
// 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.
|
|
//
|
|
// $URL$
|
|
// $Id$
|
|
// SPDX-License-Identifier: GPL-3.0+
|
|
//
|
|
//
|
|
// Author(s) : Michael Seel <seel@mpi-sb.mpg.de>
|
|
// Miguel Granados <granados@mpi-sb.mpg.de>
|
|
// Susan Hert <hert@mpi-sb.mpg.de>
|
|
// Lutz Kettner <kettner@mpi-sb.mpg.de>
|
|
// Peter Hachenberger <hachenberger@mpi-sb.mpg.de>
|
|
#ifndef CGAL_NEF_VERTEX_H
|
|
#define CGAL_NEF_VERTEX_H
|
|
|
|
#include <CGAL/license/Nef_3.h>
|
|
|
|
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <CGAL/IO/io.h>
|
|
#include <CGAL/IO/Verbose_ostream.h>
|
|
#include <CGAL/Nef_3/SNC_iteration.h>
|
|
|
|
#undef CGAL_NEF_DEBUG
|
|
#define CGAL_NEF_DEBUG 83
|
|
#include <CGAL/Nef_2/debug.h>
|
|
|
|
#ifndef CGAL_I_DO_WANT_TO_USE_GENINFO
|
|
#include <boost/any.hpp>
|
|
#endif
|
|
|
|
namespace CGAL {
|
|
|
|
template<class Refs>
|
|
class Vertex_base {
|
|
|
|
#ifdef CGAL_I_DO_WANT_TO_USE_GENINFO
|
|
typedef void* GenPtr;
|
|
#else
|
|
typedef boost::any GenPtr;
|
|
#endif
|
|
typedef typename Refs::Mark Mark;
|
|
typedef typename Refs::Point_3 Point_3;
|
|
|
|
typedef typename Refs::Vertex_handle Vertex_handle;
|
|
typedef typename Refs::SHalfloop_handle SHalfloop_handle;
|
|
|
|
typedef typename Refs::Vertex_iterator Vertex_iterator;
|
|
typedef typename Refs::SVertex_iterator SVertex_iterator;
|
|
typedef typename Refs::SHalfedge_iterator SHalfedge_iterator;
|
|
typedef typename Refs::SHalfloop_iterator SHalfloop_iterator;
|
|
typedef typename Refs::SFace_iterator SFace_iterator;
|
|
|
|
typedef typename Refs::Vertex_const_iterator Vertex_const_iterator;
|
|
typedef typename Refs::SVertex_const_iterator SVertex_const_iterator;
|
|
typedef typename Refs::SHalfedge_const_iterator SHalfedge_const_iterator;
|
|
typedef typename Refs::SFace_const_iterator SFace_const_iterator;
|
|
typedef typename Refs::SHalfloop_const_handle SHalfloop_const_handle;
|
|
|
|
typedef typename Refs::Size_type Size_type;
|
|
|
|
Point_3 point_at_center_;
|
|
Mark mark_;
|
|
// local view (surface graph):
|
|
public:
|
|
Refs* sncp_;
|
|
SVertex_iterator svertices_begin_, svertices_last_;
|
|
SHalfedge_iterator shalfedges_begin_, shalfedges_last_;
|
|
SFace_iterator sfaces_begin_, sfaces_last_;
|
|
SHalfloop_iterator shalfloop_;
|
|
GenPtr info_;
|
|
|
|
public:
|
|
|
|
Vertex_base() : point_at_center_(), mark_(), sncp_(),
|
|
svertices_begin_(), svertices_last_(),
|
|
shalfedges_begin_(), shalfedges_last_(),
|
|
sfaces_begin_(), sfaces_last_(), shalfloop_(),
|
|
info_()
|
|
// , sm_(Vertex_handle((SNC_in_place_list_vertex<Vertex_base>*) this))
|
|
{}
|
|
|
|
Vertex_base(const Point_3& p, Mark m) :
|
|
point_at_center_(p), mark_(m), sncp_(),
|
|
svertices_begin_(), svertices_last_(),
|
|
shalfedges_begin_(), shalfedges_last_(),
|
|
sfaces_begin_(), sfaces_last_(), shalfloop_(),
|
|
info_()
|
|
// , sm_(Vertex_handle((SNC_in_place_list_vertex<Vertex_base>*) this))
|
|
{}
|
|
|
|
Vertex_base(const Vertex_base<Refs>& v)
|
|
// : sm_(Vertex_handle((SNC_in_place_list_vertex<Vertex_base>*)this))
|
|
{
|
|
point_at_center_ = v.point_at_center_;
|
|
mark_ = v.mark_;
|
|
sncp_ = v.sncp_;
|
|
svertices_begin_ = v.svertices_begin_;
|
|
svertices_last_ = v.svertices_last_;
|
|
shalfedges_begin_ = v.shalfedges_begin_;
|
|
shalfedges_last_ = v.shalfedges_last_;
|
|
sfaces_begin_ = v.sfaces_begin_;
|
|
sfaces_last_ = v.sfaces_last_;
|
|
shalfloop_ = v.shalfloop_;
|
|
info_ = 0;
|
|
}
|
|
|
|
Vertex_base<Refs>& operator=(const Vertex_base<Refs>& v)
|
|
{ if (this == &v) return *this;
|
|
point_at_center_ = v.point_at_center_;
|
|
mark_ = v.mark_;
|
|
sncp_ = v.sncp_;
|
|
svertices_begin_ = v.svertices_begin_;
|
|
svertices_last_ = v.svertices_last_;
|
|
shalfedges_begin_ = v.shalfedges_begin_;
|
|
shalfedges_last_ = v.shalfedges_last_;
|
|
sfaces_begin_ = v.sfaces_begin_;
|
|
sfaces_last_ = v.sfaces_last_;
|
|
shalfloop_ = v.shalfloop_;
|
|
return *this;
|
|
}
|
|
|
|
Refs* sncp() const { return sncp_; }
|
|
Refs*& sncp() { return sncp_; }
|
|
|
|
/* all sobjects of the local graph are stored in a global list
|
|
where each vertex has a continous range in each list for its
|
|
sobjects. All objects of the range [sxxx_begin_,sxxx_last_]
|
|
belong to a vertex. This range is empty iff
|
|
sxxx_begin_ == sxxx_last_ == sncp()->sxxx_end()
|
|
( the latter being the standard end iterator of the
|
|
corresponding list )
|
|
for the past the end iterator we have to increment sxxx_last_
|
|
once iff the range is non-empty. */
|
|
|
|
void init_range(SVertex_iterator it)
|
|
{ svertices_begin_ = svertices_last_ = it; }
|
|
void init_range(SHalfedge_iterator it)
|
|
{ shalfedges_begin_ = shalfedges_last_ = it; }
|
|
void init_range(SFace_iterator it)
|
|
{ sfaces_begin_ = sfaces_last_ = it; }
|
|
|
|
SVertex_iterator& svertices_begin()
|
|
{ return svertices_begin_; }
|
|
SVertex_iterator& svertices_last()
|
|
{ return svertices_last_; }
|
|
SVertex_iterator svertices_end()
|
|
{ if ( svertices_last_ == sncp()->svertices_end() )
|
|
return svertices_last_;
|
|
else
|
|
return ++SVertex_iterator(svertices_last_); }
|
|
|
|
SHalfedge_iterator& shalfedges_begin()
|
|
{ return shalfedges_begin_; }
|
|
SHalfedge_iterator& shalfedges_last()
|
|
{ return shalfedges_last_; }
|
|
SHalfedge_iterator shalfedges_end()
|
|
{ if ( shalfedges_last_ == sncp()->shalfedges_end() )
|
|
return shalfedges_last_;
|
|
else
|
|
return ++SHalfedge_iterator(shalfedges_last_); }
|
|
|
|
SFace_iterator& sfaces_begin()
|
|
{ return sfaces_begin_; }
|
|
SFace_iterator& sfaces_last()
|
|
{ return sfaces_last_; }
|
|
SFace_iterator sfaces_end()
|
|
{ if ( sfaces_last_ == sncp()->sfaces_end() )
|
|
return sfaces_last_;
|
|
else
|
|
return ++SFace_iterator(sfaces_last_); }
|
|
|
|
SVertex_const_iterator svertices_begin() const
|
|
{ return svertices_begin_; }
|
|
SVertex_const_iterator svertices_last() const
|
|
{ return svertices_last_; }
|
|
SVertex_const_iterator svertices_end() const
|
|
{ if ( svertices_last_ == sncp()->svertices_end() )
|
|
return svertices_last_;
|
|
else
|
|
return ++SVertex_const_iterator(svertices_last_); }
|
|
|
|
SHalfedge_const_iterator shalfedges_begin() const
|
|
{ return shalfedges_begin_; }
|
|
SHalfedge_const_iterator shalfedges_last() const
|
|
{ return shalfedges_last_; }
|
|
SHalfedge_const_iterator shalfedges_end() const
|
|
{ if ( shalfedges_last_ == sncp()->shalfedges_end() )
|
|
return shalfedges_last_;
|
|
else
|
|
return ++SHalfedge_const_iterator(shalfedges_last_); }
|
|
|
|
SFace_const_iterator sfaces_begin() const
|
|
{ return sfaces_begin_; }
|
|
SFace_const_iterator sfaces_last() const
|
|
{ return sfaces_last_; }
|
|
SFace_const_iterator sfaces_end() const
|
|
{ if ( sfaces_last_ == sncp()->sfaces_end() )
|
|
return sfaces_last_;
|
|
else
|
|
return ++SFace_const_iterator(sfaces_last_); }
|
|
|
|
SHalfloop_handle& shalfloop() { return shalfloop_; }
|
|
SHalfloop_handle shalfloop() const { return shalfloop_; }
|
|
|
|
bool has_shalfloop() const {
|
|
return shalfloop_ != sncp()->shalfloops_end();
|
|
}
|
|
|
|
Size_type number_of_svertices() const
|
|
/*{\Mop returns the number of vertices.}*/
|
|
{ Size_type n(0);
|
|
SVertex_const_iterator vit;
|
|
CGAL_forall_svertices(vit, *this) ++n;
|
|
return n; }
|
|
|
|
Size_type number_of_shalfedges() const
|
|
/*{\Mop returns the number of halfedges.}*/
|
|
{ Size_type n(0);
|
|
SHalfedge_const_iterator eit;
|
|
CGAL_forall_shalfedges(eit, *this) ++n;
|
|
return n;}
|
|
|
|
Size_type number_of_sedges() const
|
|
/*{\Mop returns the number of edges.}*/
|
|
{ return number_of_shalfedges()/2; }
|
|
|
|
Size_type number_of_shalfloops() const
|
|
/*{\Mop returns the number of halfloops.}*/
|
|
{ return ( has_shalfloop() ? 2 : 0); }
|
|
|
|
Size_type number_of_sloops() const
|
|
/*{\Mop returns the number of loops.}*/
|
|
{ return number_of_shalfloops()/2; }
|
|
|
|
Size_type number_of_sfaces() const
|
|
/*{\Mop returns the number of faces.}*/
|
|
{ Size_type n(0);
|
|
SFace_const_iterator fit;
|
|
CGAL_forall_sfaces(fit, *this) ++n;
|
|
return n; }
|
|
|
|
|
|
/*{\Xtext Vertices provide access to their local graphs via
|
|
the iterator ranges:
|
|
\begin{Mverb}
|
|
SVertex_iterator svertices_begin()/svertices_end()
|
|
SHalfedge_iterator shalfedges_begin()/shalfedges_end()
|
|
SFace_iterator sfaces_begin()/sfaces_end()
|
|
SHalfloop_handle shalfloop()
|
|
\end{Mverb}
|
|
}*/
|
|
|
|
void clear()
|
|
/*{\Xop clears the local graph.}*/ {
|
|
SFace_iterator fit = sfaces_begin(),
|
|
fend = sfaces_end();
|
|
while (fit != fend) {
|
|
SFace_iterator fdel = fit++;
|
|
/* TO VERIFY: next statement needs access to a private attribute */
|
|
sncp()->reset_sm_object_list(fdel->boundary_entry_objects_);
|
|
sncp()->delete_sface_only(fdel);
|
|
}
|
|
sfaces_begin_ = sfaces_last_ = sncp()->sfaces_end();
|
|
|
|
if ( shalfloop() != sncp()->shalfloops_end() ) {
|
|
sncp()->delete_shalfloop_only(shalfloop_->twin());
|
|
sncp()->delete_shalfloop_only(shalfloop_);
|
|
shalfloop_ = sncp()->shalfloops_end();
|
|
}
|
|
|
|
SHalfedge_iterator eit = shalfedges_begin(),
|
|
eend = shalfedges_end();
|
|
while (eit != eend) {
|
|
SHalfedge_iterator edel = eit++;
|
|
sncp()->delete_shalfedge_only(edel);
|
|
}
|
|
shalfedges_begin_ = shalfedges_last_ = sncp()->shalfedges_end();
|
|
|
|
SVertex_iterator vit = svertices_begin(),
|
|
vend = svertices_end();
|
|
while (vit != vend) {
|
|
SVertex_iterator vdel = vit++;
|
|
sncp()->delete_halfedge_only(vdel);
|
|
}
|
|
svertices_begin_ = svertices_last_ = sncp()->halfedges_end();
|
|
}
|
|
|
|
Point_3& point() { return point_at_center_; }
|
|
const Point_3& point() const { return point_at_center_; }
|
|
Mark& mark() { return mark_; }
|
|
const Mark& mark() const { return mark_;}
|
|
GenPtr& info() { return info_; }
|
|
const GenPtr& info() const { return info_; }
|
|
|
|
~Vertex_base() {
|
|
CGAL_NEF_TRACEN(" destroying Vertex item "<<&*this);
|
|
}
|
|
|
|
public:
|
|
std::string debug() const
|
|
{ std::stringstream os;
|
|
set_pretty_mode(os);
|
|
os<<"{ addr, point, mark, snc, svb, sve, seb, see, sfb, sfe, sl,"
|
|
<<" info }"<<std::endl;
|
|
os<<"{ "<<this<<", "<<point_at_center_<<", "<<mark_<<", "<<&*sncp_<<", "
|
|
<<&*svertices_begin_ <<", "<<&*svertices_last_ <<", "
|
|
<<&*shalfedges_begin_<<", "<<&*shalfedges_last_<<", "
|
|
<<&*sfaces_begin_ <<", "<<&*sfaces_last_ <<", "
|
|
<<&*shalfloop_ <<", "
|
|
<<info_<<" }";
|
|
return os.str();
|
|
}
|
|
|
|
bool check_basic_functions() {
|
|
/*
|
|
if(svertices_begin_ == sncp()->svertices_end())
|
|
CGAL_assertion(svertices_end() == sncp()->svertices_end());
|
|
if(shalfedges_begin_ == sncp()->shalfedges_end())
|
|
CGAL_assertion(shalfedges_end() == sncp()->shalfedges_end());
|
|
if(sfaces_begin_ == sncp()->sfaces_end())
|
|
CGAL_assertion(sfaces_end() == sncp()->sfaces_end());
|
|
*/
|
|
return true;
|
|
}
|
|
|
|
bool is_valid( bool verb = false, int level = 0) const {
|
|
|
|
Verbose_ostream verr(verb);
|
|
verr << "begin CGAL::SNC_items<...>::Vertex_base::is_valid( verb=true, "
|
|
"level = " << level << "):" << std::endl;
|
|
|
|
bool valid = (sncp_ != NULL);
|
|
valid = valid && (svertices_begin_ != NULL && svertices_begin_ != SVertex_iterator());
|
|
valid = valid && (svertices_last_ != NULL && svertices_last_ != SVertex_iterator());
|
|
valid = valid && (shalfedges_begin_ != NULL && shalfedges_begin_ != SHalfedge_iterator());
|
|
valid = valid && (shalfedges_last_ != NULL && shalfedges_last_ != SHalfedge_iterator());
|
|
valid = valid && (sfaces_begin_ != NULL && sfaces_begin_ != SFace_iterator());
|
|
valid = valid && (sfaces_last_ != NULL && sfaces_last_ != SFace_iterator());
|
|
valid = valid && (shalfloop_ != NULL && shalfloop_ != SHalfloop_iterator());
|
|
|
|
if(shalfedges_begin_ == sncp()->shalfedges_end()) { // point in volume or on plane, which is either isolated or has one outgoing edge
|
|
if(shalfloop_ != sncp()->shalfloops_end())
|
|
valid = valid && (++SFace_const_iterator(sfaces_begin_) == sfaces_last_);
|
|
else
|
|
valid = valid && (sfaces_begin_ == sfaces_last_);
|
|
}
|
|
|
|
valid = valid && (sfaces_begin_ != sncp()->sfaces_end());
|
|
if(sfaces_begin_ == sfaces_last_) {
|
|
valid = valid && (shalfloop_ == sncp()->shalfloops_end());
|
|
}
|
|
else
|
|
valid = valid && (sfaces_begin_->sface_cycles_begin() !=
|
|
sfaces_begin_->sface_cycles_end());
|
|
|
|
verr << "end of CGAL::SNC_items<...>::Vertex_base::is_valid(): structure is "
|
|
<< ( valid ? "valid." : "NOT VALID.") << std::endl;
|
|
return valid;
|
|
}
|
|
|
|
}; // Vertex_base
|
|
|
|
|
|
} //namespace CGAL
|
|
#endif // CGAL_NEF_VERTEX_H
|