- Removed CGAL_USE_POLYHEDRON_DESIGN_ONE parts.

- Incremental builder:
       - Changed ABSOLUTE to ABSOLUTE_INDEXING.
       - Changed RELATIVE to RELATIVE_INDEXING.
       - Made add_vertex(), begin_facet(), and end_facet() return
         useful handles.
       - Added test_facet() to check for valid facets before modifying.
       - Added vertex( size_t i) to return Vertex_handle for index i.
This commit is contained in:
Lutz Kettner 2003-05-05 19:21:56 +00:00
parent 367659b182
commit 213719f6aa
3 changed files with 287 additions and 129 deletions

View File

@ -44,22 +44,18 @@ not explicitly specified. They are derived from the vertex incidence
information provided from the facet polygons. The polygons are given as a
sequence of vertex indices. The halfedge data structure \ccc{HDS} must
support vertices (i.e., \ccc{Supports_halfedge_vertex} $\equiv$
\ccc{CGAL::Tag_true}). The correct order of allowed method calls to build a
polyhedral surface is given as a regular expression below. Vertices and
facets can be added in arbitrary order as long as
\ccc{add_vertex_to_facet()} refers only to vertex indices that are
already known.
\ccc{CGAL::Tag_true}). Vertices and facets can be added in arbitrary order
as long as a call to \ccc{add_vertex_to_facet()} refers only to a
vertex index that is already known. Some methods return already
handles to vertices, facets, and halfedges newly constructed. They can
be used to initialize additional fields, however, the incidences in
the halfedge-data structure are not stable and are not allowed to be
changed.
{\it
\hspace*{6mm} begin\_surface $($add\_vertex $|$
$($begin\_facet add\_vertex\_to\_facet$\:*$
end\_facet\/$))\:*$ end\_surface
}
The incremental builder can work in two modes: \ccc{RELATIVE} (the
The incremental builder can work in two modes: \ccc{RELATIVE_INDEXING} (the
default), in which a polyhedral surface already contained in the
halfedge data structure is ignored and all indices are relative to the
newly added surface, or \ccc{ABSOLUTE}, in which all indices are
newly added surface, or \ccc{ABSOLUTE_INDEXING}, in which all indices are
absolute indices including an already existing polyhedral surface. The
former mode allows to create easily independent connected components,
while the latter mode allows to to continue the construction of an
@ -70,7 +66,8 @@ vertices when creating new facets.
\ccTypes
\ccTwo{CGAL::Polyhedron_incremental_builder_3<HDS>:: HalfedgeDS}{}
\ccThree{typedef typename HalfedgeDS::Halfedge_handleMMMMM}{Halfedge_handle;}{}
\ccTwo{typedef typename HalfedgeDS::Halfedge_handleMMMMM}{}
\ccNestedType{HalfedgeDS}{halfedge data structure \ccc{HDS}.}
\ccGlue
@ -78,13 +75,19 @@ vertices when creating new facets.
\ccGlue
\ccNestedType{size_type}{size type.}
\ccTypedef{typedef typename HalfedgeDS::Vertex_handle Vertex_handle;}{}
\ccGlue
\ccTypedef{typedef typename HalfedgeDS::Halfedge_handle Halfedge_handle;}{}
\ccGlue
\ccTypedef{typedef typename HalfedgeDS::Face_handle Facet_handle;}{}
\ccConstants
\ccEnum{enum { RELATIVE, ABSOLUTE};}{two different indexing modes.}
\ccEnum{enum { RELATIVE_INDEXING, ABSOLUTE_INDEXING};}{two different indexing modes.}
\ccCreation
\ccThree{void}{B.remove_unconnected_vertices();;;}{}
\ccThree{Halfedge_handle}{B.add_vertex( Point}{}
\ccThreeToTwo
\ccConstructor{Polyhedron_incremental_builder_3(HDS& hds,
@ -96,10 +99,21 @@ vertices when creating new facets.
diagnostic messages will be printed to \ccc{cerr} in case of
malformed input data.}
\ccOperations
\ccHeading{Surface Creation}
To build a polyhedral surface, the following regular expression gives
the correct and allowed order and nesting of method calls from this
section:
{\it
\hspace*{6mm} begin\_surface $($add\_vertex $|$
$($begin\_facet add\_vertex\_to\_facet$\:*$
end\_facet\/$))\:*$ end\_surface
}
\ccMethod{void begin_surface( size_type v, size_type f, size_type h = 0,
int mode = RELATIVE);}
int mode = RELATIVE_INDEXING);}
{starts the construction. $v$ is the number of new vertices
to expect, $f$ the number of new facets, and $h$ the number of
new halfedges. If $h$ is unspecified (\ccc{== 0}) it is estimated using
@ -109,28 +123,55 @@ vertices when creating new facets.
insertion these values do not restrict the class of constructible
polyhedra. If the representation does not support insertion the
object must fit into the reserved sizes.\\
If \ccc{mode} is set to \ccc{ABSOLUTE} the incremental builder
If \ccc{mode} is set to \ccc{ABSOLUTE_INDEXING} the incremental builder
uses absolute indexing and the vertices of the old polyhedral surface
can be used in new facets (needs preprocessing time linear in the
size of the old surface). Otherwise relative indexing is used
starting with new indices for the new construction.}
\ccMethod{void add_vertex( const Point_3& p);}{
adds $p$ to the vertex list.}
\ccGlue
\ccMethod{void begin_facet();}{starts a facet.}
\ccGlue
\ccMethod{Vertex_handle add_vertex( const Point_3& p);}{
adds a new vertex for $p$ and returns its handle.}
\ccMethod{Facet_handle begin_facet();}{
starts a new facet and returns its handle.}
\ccMethod{void add_vertex_to_facet( size_type i);}{adds a vertex with
index $i$ to the current facet. The first point added with
\ccc{add_vertex()} has the index 0 if \ccc{mode} was set to \ccc{RELATIVE},
otherwise the first vertex in the referenced \ccc{hds} has the index 0.}
\ccGlue
\ccMethod{void end_facet();}{ends a facet.}
\ccGlue
\ccc{add_vertex()} has the index 0 if \ccc{mode} was set to
\ccc{RELATIVE_INDEXING}, otherwise the first vertex in the
referenced \ccc{hds} has the index 0.}
\ccMethod{Halfedge_handle end_facet();}{ends a newly constructed facet.
Returns the handle to the halfedge incident to the new facet that points
to the vertex added first. The halfedge can be safely used to traverse
the halfedge cycle around the new facet.}
\ccMethod{void end_surface();}{ends the construction.}
\ccHeading{Additional Operations}
\ccMethod{template <class InputIterator>
Halfedge_handle add_facet( InputIterator first, InputIterator beyond);}{
is a synonym for \ccc{begin_facet()}, a call to \ccc{add_facet()} for each
value in the range \ccc{[first,beyond)}, and a call to \ccc{end_facet()}.
Returns the return value of \ccc{end_facet()}.
\ccPrecond The value type of \ccc{InputIterator} is \ccc{std::size_t}.
All indices must refer to vertices already added.}
\ccMethod{template <class InputIterator>
bool test_facet( InputIterator first, InputIterator beyond);}{
returns \ccc{true} if a facet described by the vertex indices in the range
\ccc{[first,beyond)} can be successfully inserted, e.g., with
\ccc{add_facet(first,beyond)}.
\ccPrecond The value type of \ccc{InputIterator} is \ccc{std::size_t}.
All indices must refer to vertices already added.}
\ccMethod{Vertex_handle vertex( std::size_t i);}{
returns handle for the vertex of index $i$, or \ccc{Vertex_handle} if
there is no $i$-th vertex.}
\ccMethod{bool error() const;}{returns error status of the builder.}
\ccGlue
\ccMethod{void rollback();}{undoes all changes made to the halfedge
data structure since the last \ccc{begin_surface()} in relative
indexing, and deletes the whole surface in absolute indexing.

View File

@ -44,22 +44,18 @@ not explicitly specified. They are derived from the vertex incidence
information provided from the facet polygons. The polygons are given as a
sequence of vertex indices. The halfedge data structure \ccc{HDS} must
support vertices (i.e., \ccc{Supports_halfedge_vertex} $\equiv$
\ccc{CGAL::Tag_true}). The correct order of allowed method calls to build a
polyhedral surface is given as a regular expression below. Vertices and
facets can be added in arbitrary order as long as
\ccc{add_vertex_to_facet()} refers only to vertex indices that are
already known.
\ccc{CGAL::Tag_true}). Vertices and facets can be added in arbitrary order
as long as a call to \ccc{add_vertex_to_facet()} refers only to a
vertex index that is already known. Some methods return already
handles to vertices, facets, and halfedges newly constructed. They can
be used to initialize additional fields, however, the incidences in
the halfedge-data structure are not stable and are not allowed to be
changed.
{\it
\hspace*{6mm} begin\_surface $($add\_vertex $|$
$($begin\_facet add\_vertex\_to\_facet$\:*$
end\_facet\/$))\:*$ end\_surface
}
The incremental builder can work in two modes: \ccc{RELATIVE} (the
The incremental builder can work in two modes: \ccc{RELATIVE_INDEXING} (the
default), in which a polyhedral surface already contained in the
halfedge data structure is ignored and all indices are relative to the
newly added surface, or \ccc{ABSOLUTE}, in which all indices are
newly added surface, or \ccc{ABSOLUTE_INDEXING}, in which all indices are
absolute indices including an already existing polyhedral surface. The
former mode allows to create easily independent connected components,
while the latter mode allows to to continue the construction of an
@ -70,7 +66,8 @@ vertices when creating new facets.
\ccTypes
\ccTwo{CGAL::Polyhedron_incremental_builder_3<HDS>:: HalfedgeDS}{}
\ccThree{typedef typename HalfedgeDS::Halfedge_handleMMMMM}{Halfedge_handle;}{}
\ccTwo{typedef typename HalfedgeDS::Halfedge_handleMMMMM}{}
\ccNestedType{HalfedgeDS}{halfedge data structure \ccc{HDS}.}
\ccGlue
@ -78,13 +75,19 @@ vertices when creating new facets.
\ccGlue
\ccNestedType{size_type}{size type.}
\ccTypedef{typedef typename HalfedgeDS::Vertex_handle Vertex_handle;}{}
\ccGlue
\ccTypedef{typedef typename HalfedgeDS::Halfedge_handle Halfedge_handle;}{}
\ccGlue
\ccTypedef{typedef typename HalfedgeDS::Face_handle Facet_handle;}{}
\ccConstants
\ccEnum{enum { RELATIVE, ABSOLUTE};}{two different indexing modes.}
\ccEnum{enum { RELATIVE_INDEXING, ABSOLUTE_INDEXING};}{two different indexing modes.}
\ccCreation
\ccThree{void}{B.remove_unconnected_vertices();;;}{}
\ccThree{Halfedge_handle}{B.add_vertex( Point}{}
\ccThreeToTwo
\ccConstructor{Polyhedron_incremental_builder_3(HDS& hds,
@ -96,10 +99,21 @@ vertices when creating new facets.
diagnostic messages will be printed to \ccc{cerr} in case of
malformed input data.}
\ccOperations
\ccHeading{Surface Creation}
To build a polyhedral surface, the following regular expression gives
the correct and allowed order and nesting of method calls from this
section:
{\it
\hspace*{6mm} begin\_surface $($add\_vertex $|$
$($begin\_facet add\_vertex\_to\_facet$\:*$
end\_facet\/$))\:*$ end\_surface
}
\ccMethod{void begin_surface( size_type v, size_type f, size_type h = 0,
int mode = RELATIVE);}
int mode = RELATIVE_INDEXING);}
{starts the construction. $v$ is the number of new vertices
to expect, $f$ the number of new facets, and $h$ the number of
new halfedges. If $h$ is unspecified (\ccc{== 0}) it is estimated using
@ -109,28 +123,55 @@ vertices when creating new facets.
insertion these values do not restrict the class of constructible
polyhedra. If the representation does not support insertion the
object must fit into the reserved sizes.\\
If \ccc{mode} is set to \ccc{ABSOLUTE} the incremental builder
If \ccc{mode} is set to \ccc{ABSOLUTE_INDEXING} the incremental builder
uses absolute indexing and the vertices of the old polyhedral surface
can be used in new facets (needs preprocessing time linear in the
size of the old surface). Otherwise relative indexing is used
starting with new indices for the new construction.}
\ccMethod{void add_vertex( const Point_3& p);}{
adds $p$ to the vertex list.}
\ccGlue
\ccMethod{void begin_facet();}{starts a facet.}
\ccGlue
\ccMethod{Vertex_handle add_vertex( const Point_3& p);}{
adds a new vertex for $p$ and returns its handle.}
\ccMethod{Facet_handle begin_facet();}{
starts a new facet and returns its handle.}
\ccMethod{void add_vertex_to_facet( size_type i);}{adds a vertex with
index $i$ to the current facet. The first point added with
\ccc{add_vertex()} has the index 0 if \ccc{mode} was set to \ccc{RELATIVE},
otherwise the first vertex in the referenced \ccc{hds} has the index 0.}
\ccGlue
\ccMethod{void end_facet();}{ends a facet.}
\ccGlue
\ccc{add_vertex()} has the index 0 if \ccc{mode} was set to
\ccc{RELATIVE_INDEXING}, otherwise the first vertex in the
referenced \ccc{hds} has the index 0.}
\ccMethod{Halfedge_handle end_facet();}{ends a newly constructed facet.
Returns the handle to the halfedge incident to the new facet that points
to the vertex added first. The halfedge can be safely used to traverse
the halfedge cycle around the new facet.}
\ccMethod{void end_surface();}{ends the construction.}
\ccHeading{Additional Operations}
\ccMethod{template <class InputIterator>
Halfedge_handle add_facet( InputIterator first, InputIterator beyond);}{
is a synonym for \ccc{begin_facet()}, a call to \ccc{add_facet()} for each
value in the range \ccc{[first,beyond)}, and a call to \ccc{end_facet()}.
Returns the return value of \ccc{end_facet()}.
\ccPrecond The value type of \ccc{InputIterator} is \ccc{std::size_t}.
All indices must refer to vertices already added.}
\ccMethod{template <class InputIterator>
bool test_facet( InputIterator first, InputIterator beyond);}{
returns \ccc{true} if a facet described by the vertex indices in the range
\ccc{[first,beyond)} can be successfully inserted, e.g., with
\ccc{add_facet(first,beyond)}.
\ccPrecond The value type of \ccc{InputIterator} is \ccc{std::size_t}.
All indices must refer to vertices already added.}
\ccMethod{Vertex_handle vertex( std::size_t i);}{
returns handle for the vertex of index $i$, or \ccc{Vertex_handle} if
there is no $i$-th vertex.}
\ccMethod{bool error() const;}{returns error status of the builder.}
\ccGlue
\ccMethod{void rollback();}{undoes all changes made to the halfedge
data structure since the last \ccc{begin_surface()} in relative
indexing, and deletes the whole surface in absolute indexing.

View File

@ -29,18 +29,6 @@
#define CGAL_POLYHEDRON_INCREMENTAL_BUILDER_3_H 1
#include <CGAL/basic.h>
// MS Visual C++ 6.0 does not work with the new design.
#if defined( _MSC_VER) && (_MSC_VER <= 1200)
#ifndef CGAL_USE_POLYHEDRON_DESIGN_TWO
#define CGAL_USE_POLYHEDRON_DESIGN_ONE 1
#endif
#endif
#ifdef CGAL_USE_POLYHEDRON_DESIGN_ONE
#include <CGAL/Polyhedron_old/Polyhedron_incremental_builder_3.h>
#else // CGAL_USE_POLYHEDRON_DESIGN_ONE //
#define CGAL_USE_POLYHEDRON_DESIGN_TWO 1
#include <CGAL/Random_access_adaptor.h>
#include <CGAL/HalfedgeDS_decorator.h>
#include <CGAL/Unique_hash_map.h>
@ -61,6 +49,7 @@ public:
typedef typename HDS::Vertex_handle Vertex_handle;
typedef typename HDS::Halfedge_handle Halfedge_handle;
typedef typename HDS::Face_handle Face_handle;
typedef typename HDS::Face_handle Facet_handle;
typedef typename Vertex::Base VBase;
typedef typename Halfedge::Base HBase;
typedef typename Vertex::Point Point_3;
@ -184,8 +173,7 @@ protected:
public:
bool error() const { return m_error; }
Polyhedron_incremental_builder_3(HDS& h,
bool verbose = false)
Polyhedron_incremental_builder_3( HDS& h, bool verbose = false)
// stores a reference to the halfedge data structure `h' in the
// internal state. The previous polyhedral surface in `h'
// remains unchanged. The incremental builder adds the new
@ -199,11 +187,11 @@ public:
}
// OPERATIONS
enum { RELATIVE = 0, ABSOLUTE = 1};
enum { RELATIVE_INDEXING = 0, ABSOLUTE_INDEXING = 1};
void begin_surface( std::size_t v, std::size_t f, std::size_t h = 0,
int mode = RELATIVE);
int mode = RELATIVE_INDEXING);
// starts the construction. v is the number of new
// vertices to expect, f the number of new facets, and h the number of
// new halfedges. If h is unspecified (`== 0') it is estimated using
@ -213,13 +201,13 @@ public:
// supports insertion these values do not restrict the class of
// readable polyhedrons. If the representation does not support
// insertion the object must fit in the reserved sizes.
// If `mode' is set to ABSOLUTE the incremental builder uses
// absolute indexing and the vertices of the old polyhedral surface
// can be used in new facets. Otherwise relative indexing is used
// starting with new indices for the new construction.
// If `mode' is set to ABSOLUTE_INDEXING the incremental builder
// uses absolute indexing and the vertices of the old polyhedral
// surface can be used in new facets. Otherwise relative indexing is
// used starting with new indices for the new construction.
void add_vertex( const Point_3& p) {
Vertex_handle add_vertex( const Point_3& p) {
// adds p to the vertex list.
CGAL_assertion( check_protocoll == 1);
if ( hds.size_of_vertices() >= hds.capacity_of_vertices()) {
@ -230,7 +218,7 @@ public:
verr << "add_vertex(): capacity error: more than " << new_vertices
<< " vertices added." << std::endl;
m_error = true;
return;
return Vertex_handle();
}
HalfedgeDS_decorator<HDS> decorator(hds);
Vertex_handle v = decorator.vertices_push_back( Vertex(p));
@ -238,17 +226,95 @@ public:
decorator.set_vertex_halfedge( v, Halfedge_handle());
push_back_vertex_to_edge_map( Halfedge_handle());
++new_vertices;
return v;
}
void begin_facet();
// returns handle for the vertex of index i
Vertex_handle vertex( std::size_t i) {
if ( i < new_vertices)
return index_to_vertex_map[i];
return Vertex_handle();
}
Facet_handle begin_facet() {
// starts a facet.
if ( m_error)
return Facet_handle();
CGAL_assertion( check_protocoll == 1);
CGAL_assertion_code( check_protocoll = 2;)
if ( hds.size_of_faces() >= hds.capacity_of_faces()) {
Verbose_ostream verr( m_verbose);
verr << " " << std::endl;
verr << "CGAL::Polyhedron_incremental_builder_3<HDS>::"
<< std::endl;
verr << "begin_facet(): capacity error: more than " << new_vertices
<< " facets added." << std::endl;
m_error = true;
return Facet_handle();
}
// initialize all status variables.
first_vertex = true; // denotes 'no vertex yet'
g1 = Halfedge_handle(); // denotes 'no halfedge yet'
last_vertex = false;
HalfedgeDS_decorator<HDS> decorator(hds);
current_face = decorator.faces_push_back( Face());
return current_face;
}
void add_vertex_to_facet( std::size_t i);
// adds a vertex with index i to the current facet. The first
// point added with `add_vertex()' has the index 0.
void end_facet();
Halfedge_handle end_facet() {
// ends a facet.
if ( m_error)
return Halfedge_handle();
CGAL_assertion( check_protocoll == 2);
CGAL_assertion( ! first_vertex);
// cleanup all static status variables
add_vertex_to_facet( w1);
if ( m_error)
return Halfedge_handle();
last_vertex = true;
add_vertex_to_facet( w2);
if ( m_error)
return Halfedge_handle();
CGAL_assertion( check_protocoll == 2);
CGAL_assertion_code( check_protocoll = 1;)
HalfedgeDS_items_decorator<HDS> decorator;
Halfedge_handle h = get_vertex_to_edge_map(w1);
decorator.set_face_halfedge( current_face, h);
++new_faces;
return h;
}
template <class InputIterator>
Halfedge_handle add_facet( InputIterator first, InputIterator beyond) {
// synonym for begin_facet(), a call to add_facet() for each iterator
// value type, and end_facet().
begin_facet();
for ( ; ! m_error && first != beyond; ++first)
add_vertex_to_facet( *first);
if ( m_error)
return Halfedge_handle();
return end_facet();
}
template <class InputIterator>
bool test_facet( InputIterator first, InputIterator beyond) {
// tests if the facet described by the vertex indices in the
// range [first,beyond) can be inserted without creating a
// a non-manifold (and therefore invalid) situation.
// First, create a copy of the indices and close it cyclically
std::vector< std::size_t> indices( first, beyond);
if ( indices.size() < 3)
return false;
indices.push_back( indices[0]);
return test_facet_indices( indices);
}
bool test_facet_indices( std::vector< std::size_t> indices);
void end_surface();
// ends the construction.
@ -471,7 +537,7 @@ begin_surface( std::size_t v, std::size_t f, std::size_t h, int mode) {
CGAL_assertion( check_protocoll == 0);
CGAL_assertion_code( check_protocoll = 1;)
CGAL_assertion( ! m_error);
if ( mode == RELATIVE) {
if ( mode == RELATIVE_INDEXING) {
new_vertices = 0;
new_faces = 0;
new_halfedges = 0;
@ -496,7 +562,7 @@ begin_surface( std::size_t v, std::size_t f, std::size_t h, int mode) {
hds.reserve( hds.size_of_vertices() + v,
hds.size_of_halfedges() + h,
hds.size_of_faces() + f);
if ( mode == RELATIVE) {
if ( mode == RELATIVE_INDEXING) {
index_to_vertex_map = Random_access_index( hds.vertices_end());
index_to_vertex_map.reserve(v);
initialize_vertex_to_edge_map( v, false);
@ -508,33 +574,6 @@ begin_surface( std::size_t v, std::size_t f, std::size_t h, int mode) {
}
}
template < class HDS> CGAL_MEDIUM_INLINE
void
Polyhedron_incremental_builder_3<HDS>::
begin_facet() {
if ( m_error)
return;
CGAL_assertion( check_protocoll == 1);
CGAL_assertion_code( check_protocoll = 2;)
if ( hds.size_of_faces() >= hds.capacity_of_faces()) {
Verbose_ostream verr( m_verbose);
verr << " " << std::endl;
verr << "CGAL::Polyhedron_incremental_builder_3<HDS>::"
<< std::endl;
verr << "begin_facet(): capacity error: more than " << new_vertices
<< " facets added." << std::endl;
m_error = true;
return;
}
// initialize all status variables.
first_vertex = true; // denotes 'no vertex yet'
g1 = Halfedge_handle(); // denotes 'no halfedge yet'
last_vertex = false;
HalfedgeDS_decorator<HDS> decorator(hds);
current_face = decorator.faces_push_back( Face());
}
template < class HDS>
void
Polyhedron_incremental_builder_3<HDS>::
@ -684,24 +723,62 @@ add_vertex_to_facet( std::size_t v2) {
}
template < class HDS>
void
bool
Polyhedron_incremental_builder_3<HDS>::
end_facet() {
if ( m_error)
return;
CGAL_assertion( check_protocoll == 2);
CGAL_assertion( ! first_vertex);
// cleanup all static status variables
add_vertex_to_facet( w1);
last_vertex = true;
add_vertex_to_facet( w2);
CGAL_assertion( check_protocoll == 2);
CGAL_assertion_code( check_protocoll = 1;)
HalfedgeDS_items_decorator<HDS> decorator;
decorator.set_face_halfedge( current_face, get_vertex_to_edge_map(w1));
++new_faces;
test_facet_indices( std::vector< std::size_t> indices) {
typedef typename HDS::Supports_halfedge_vertex Supports_halfedge_vertex;
Assert_compile_time_tag( Supports_halfedge_vertex(), Tag_true());
// tests if the facet described by the vertex indices can be inserted
// without creating a a non-manifold (and therefore invalid) situation.
// indices are cyclically closed once.
std::size_t n = indices.size() - 1;
// Test if a vertex is not twice in the indices
for ( std::size_t i = 0; i < n; ++i) {
CGAL_precondition( indices[i] < new_vertices);
// check if vertex indices[i] is already in the sequence [0..i-1]
for ( std::size_t k = 0; k+1 < i; ++k) {
if ( indices[k] == indices[i])
return false;
}
}
// Test non-manifold edges
for ( std::size_t i = 0; i < n; ++i) {
// edge goes from vertex indices[i] to indices[i+1]
// we know already that the edge is only once in the sequence
// (otherwise the end-vertices would be twice in the sequence too)
// check if edge is already in the HDS and is not border edge
Halfedge_handle v = get_vertex_to_edge_map(indices[i]);
Vertex_handle w = index_to_vertex_map[indices[i+1]];
if ( v != Halfedge_handle()
&& get_vertex_to_edge_map(indices[i+1]) != Halfedge_handle()) {
// cycle through halfedge-loop and find edge to indices[i+1]
Halfedge_handle vstart = v;
do {
v = v->next()->opposite();
} while ( v->next()->vertex() != w && v != vstart);
if ( v->next()->vertex() == w && ! v->next()->is_border())
return false;
}
}
// test non-manifold vertices
for ( std::size_t i = 0; i < n; ++i) {
// since we don't allow duplicates in indices[..] and we
// tested for non-manifold edges already, we just need to check
// if the vertex indices[i] is not a closed manifold yet.
Halfedge_handle v = get_vertex_to_edge_map(indices[i]);
if ( v != Halfedge_handle()) {
Halfedge_handle vstart = v;
do {
v = v->next()->opposite();
} while ( ! v->is_border() && v != vstart);
if ( ! v->is_border())
return false;
}
}
return true;
}
template < class HDS> CGAL_MEDIUM_INLINE
void
Polyhedron_incremental_builder_3<HDS>::
@ -747,6 +824,5 @@ remove_unconnected_vertices( Tag_true) {
CGAL_END_NAMESPACE
#endif // CGAL_USE_POLYHEDRON_DESIGN_ONE //
#endif // CGAL_POLYHEDRON_INCREMENTAL_BUILDER_3_H //
// EOF //