cleanup of the helper files, and a partial fix of the slicer (which will be red in the testsuite)

This commit is contained in:
Andreas Fabri 2014-06-11 18:16:58 +02:00
parent 3a940e4fb5
commit 144d206a75
12 changed files with 68 additions and 285 deletions

View File

@ -1,187 +0,0 @@
// Copyright (c) 2012 GeometryFactory (France). All rights reserved.
// All rights reserved.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; version 2.1 of the License.
// See the file LICENSE.LGPL distributed with CGAL.
//
// 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$
//
//
// Author(s) : Philipp Moeller
#ifndef CGAL_FREE_ITERATOR_FROM_CIRCULATOR_H
#define CGAL_FREE_ITERATOR_FROM_CIRCULATOR_H
#include <iostream>
#include <cstddef>
#include <CGAL/circulator.h>
#include <boost/operators.hpp>
#include <boost/concept_check.hpp>
#include <boost/mpl/if.hpp>
#include <boost/utility/enable_if.hpp>
namespace CGAL {
// adapted from circulator.h, does not support
// random_access_circulators and returns the underlying circulator
// instead of dereferencing it
template <class C, bool Prevent_deref = true>
class Free_iterator_from_circulator {
private:
// The m_anchor is normalized to be a minimal circulator.
C m_anchor;
C current;
int m_winding;
typedef std::iterator_traits<C> I_traits;
typedef typename I_traits::iterator_category I_Iter_cat;
typedef I_Iterator_from_circulator_traits<I_Iter_cat> I__traits;
public:
typedef C Circulator;
typedef Free_iterator_from_circulator<C, Prevent_deref> Self;
typedef typename I__traits::iterator_category iterator_category;
typedef typename
boost::mpl::if_c< Prevent_deref
, C
, typename C::value_type
>::type value_type;
typedef typename C::difference_type difference_type;
typedef typename
boost::mpl::if_c< Prevent_deref
, C&
, typename C::reference
>::type reference;
typedef typename
boost::mpl::if_c< Prevent_deref
, C*
, typename C::reference
>::type pointer;
Free_iterator_from_circulator(){}
Free_iterator_from_circulator(const C circ, int n)
: m_anchor(circ), current(circ), m_winding(n) {}
bool operator==( const Self& i) const {
CGAL_assertion( m_anchor == i.m_anchor); // same anchor?
return ( current == i.current) && ( m_winding == i.m_winding);
}
bool operator!=( const Self& i) const {
return !(*this == i);
}
// we cannot enable_if on operator* and operator-> because they do not
// depend on template parameters directly and default template
// arguments for functions are C++11. we redirect on helper member
// templates as a work-around.
private:
template <bool Prevent_deref_>
typename boost::enable_if_c<Prevent_deref_, reference>::type
indirection() const {
CGAL_assertion( current != NULL);
return const_cast<Self*>(this)->current;
}
template <bool Prevent_deref_>
typename boost::disable_if_c<Prevent_deref_, reference>::type
indirection() const {
CGAL_assertion( current != NULL);
return *current;
}
public:
reference operator*() const {
return indirection<Prevent_deref>();
}
private:
template <bool Prevent_deref_>
typename boost::disable_if_c<Prevent_deref_, pointer>::type
structure_dereference() {
CGAL_assertion( current != NULL);
return &(*current);
}
template <bool Prevent_deref_>
typename boost::enable_if_c<Prevent_deref_, pointer>::type
structure_dereference() {
CGAL_assertion( current != NULL);
return &current;
}
public:
pointer operator->() const {
return structure_dereference<Prevent_deref>();
}
Self& operator++() {
CGAL_assertion( current != NULL);
++current;
if ( current == m_anchor)
++m_winding;
return *this;
}
Self operator++(int) {
Self tmp = *this;
++*this;
return tmp;
}
Self& operator--() {
CGAL_assertion( current != NULL);
if ( current == m_anchor)
--m_winding;
--current;
return *this;
}
Self operator--(int) {
Self tmp = *this;
--*this;
return tmp;
}
Self& operator+=( difference_type n) {
CGAL_assertion( current != NULL);
if ( n < 0 && current == m_anchor) // We are leaving the anchor.
--m_winding;
current += n;
if ( n > 0 && current == m_anchor) // Back again at the anchor.
++m_winding;
return *this;
}
bool operator<( const Self& i) const {
CGAL_assertion( m_anchor != NULL);
CGAL_assertion( current != NULL);
CGAL_assertion( m_anchor == i.m_anchor);
return ( (m_winding < i.m_winding)
|| ( (m_winding == i.m_winding)
&& (current - m_anchor) < (i.current - m_anchor)
)
);
}
bool operator> ( const Self& i) const { return i < *this; }
bool operator<=( const Self& i) const { return !(i < *this); }
bool operator>=( const Self& i) const { return !(*this < i); }
const C* anchor() const { return m_anchor;}
int winding() const { return m_winding;}
Circulator current_circulator() const { return current;}
};
} // CGAL
#endif /* CGAL_FREE_ITERATOR_FROM_CIRCULATOR_H */

View File

@ -26,7 +26,8 @@
#include <boost/graph/graph_traits.hpp>
#include <CGAL/assertions.h>
#include <CGAL/BGL/Helper.h>
#include <CGAL/boost/graph/helpers.h>
#include <CGAL/boost/graph/internal/helpers.h>
namespace CGAL {
@ -51,10 +52,10 @@ join_face(typename boost::graph_traits<Graph>::halfedge_descriptor h,
internal::remove_tip(gprev, g);
if(! internal::is_border(hop,g)){
if(! is_border(hop,g)){
remove_face(f2, g);
}
bool fnull = internal::is_border(h,g);
bool fnull = is_border(h,g);
halfedge_descriptor hprev2 = hprev;
@ -322,10 +323,10 @@ join_loop(typename boost::graph_traits<Graph>::halfedge_descriptor h1,
typedef typename Traits::halfedge_descriptor halfedge_descriptor;
typedef typename Traits::face_descriptor face_descriptor;
CGAL_precondition( internal::is_border(h1,g) || face(h1, g) != face(h2, g));
if (! internal::is_border(h1,g))
CGAL_precondition( is_border(h1,g) || face(h1, g) != face(h2, g));
if (! is_border(h1,g))
remove_face(face(h1, g), g);
if (! internal::is_border(h2,g))
if (! is_border(h2,g))
remove_face(face(h2,g), g);
halfedge_descriptor hi = h1;
halfedge_descriptor gi = h2;
@ -497,15 +498,15 @@ void remove_face(typename boost::graph_traits<Graph>::halfedge_descriptor h,
typedef typename Traits::halfedge_descriptor halfedge_descriptor;
typedef typename Traits::face_descriptor face_descriptor;
CGAL_precondition(! internal::is_border(h,g));
CGAL_precondition(! is_border(h,g));
face_descriptor f = face(h, g);
halfedge_descriptor end = h;
do {
internal::set_border(h,g);
halfedge_descriptor nh = next(h, g);
bool h_border = internal::is_border(opposite(h, g),g);
bool nh_bborder = internal::is_border(opposite(nh, g),g);
bool h_border = is_border(opposite(h, g),g);
bool nh_bborder = is_border(opposite(nh, g),g);
if(h_border && nh_bborder && next(opposite(nh, g), g) == opposite(h, g)) {
remove_vertex(target(h, g), g);
@ -528,7 +529,7 @@ void remove_face(typename boost::graph_traits<Graph>::halfedge_descriptor h,
h = nh;
} while(h != end);
remove_face(f, g);
if(internal::is_border(opposite(h, g),g))
if(is_border(opposite(h, g),g))
remove_edge(edge(h, g), g);
}
@ -547,13 +548,13 @@ void make_hole(typename boost::graph_traits<Graph>::halfedge_descriptor h,
typedef typename Traits::face_descriptor face_descriptor;
typedef Halfedge_around_face_iterator<Graph> halfedge_around_face_iterator;
CGAL_precondition(! internal::is_border(h,g));
CGAL_precondition(! is_border(h,g));
face_descriptor fd = face(h, g);
halfedge_around_face_iterator hafib, hafie;
for(boost::tie(hafib, hafie) = halfedges_around_face(h, g);
hafib != hafie;
++hafib){
CGAL_assertion(! internal::is_border(opposite(*hafib,g),g));
CGAL_assertion(! is_border(opposite(*hafib,g),g));
internal::set_border(*hafib, g);
}
remove_face(fd,g);
@ -718,8 +719,8 @@ add_face_to_border(typename boost::graph_traits<Graph>::halfedge_descriptor h1,
typename boost::graph_traits<Graph>::halfedge_descriptor h2,
Graph& g)
{
CGAL_precondition(internal::is_border(h1,g) == true);
CGAL_precondition(internal::is_border(h2,g) == true);
CGAL_precondition(is_border(h1,g) == true);
CGAL_precondition(is_border(h2,g) == true);
CGAL_precondition(h1 != h2);
CGAL_precondition(next(h1, g) != h2);
@ -800,10 +801,10 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
halfedge_descriptor pt = opposite(prev(pq, g), g);
halfedge_descriptor qb = opposite(prev(qp, g), g);
bool lTopFaceExists = ! internal::is_border(pq,g);
bool lBottomFaceExists = ! internal::is_border(qp,g);
bool lTopLeftFaceExists = lTopFaceExists && ! internal::is_border(pt,g);
bool lBottomRightFaceExists = lBottomFaceExists && ! internal::is_border(qb,g);
bool lTopFaceExists = ! is_border(pq,g);
bool lBottomFaceExists = ! is_border(qp,g);
bool lTopLeftFaceExists = lTopFaceExists && ! is_border(pt,g);
bool lBottomRightFaceExists = lBottomFaceExists && ! is_border(qb,g);
CGAL_precondition( !lTopFaceExists || (lTopFaceExists && ( degree(target(pt, g), g) > 2 ) ) ) ;
CGAL_precondition( !lBottomFaceExists || (lBottomFaceExists && ( degree(target(qb, g), g) > 2 ) ) ) ;
@ -858,7 +859,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
if ( lTopFaceExists )
{
CGAL_precondition( ! internal::is_border(opposite(pt, g),g) ) ; // p-q-t is a face of the mesh
CGAL_precondition( ! is_border(opposite(pt, g),g) ) ; // p-q-t is a face of the mesh
if ( lTopLeftFaceExists )
{
//CGAL_ECMS_TRACE(3, "Removing p-t E" << pt.idx() << " (V"
@ -885,7 +886,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
if ( lBottomFaceExists )
{
CGAL_precondition( ! internal::is_border(opposite(qb, g),g) ) ; // p-q-b is a face of the mesh
CGAL_precondition( ! is_border(opposite(qb, g),g) ) ; // p-q-b is a face of the mesh
if ( lBottomRightFaceExists )
{
//CGAL_ECMS_TRACE(3, "Removing q-b E" << qb.idx() << " (V"
@ -946,8 +947,8 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
halfedge_descriptor tq = opposite(next(pq,g),g);
halfedge_descriptor bp = opposite(next(qp,g),g);
bool lTopFaceExists = ! internal::is_border(pq,g) ;
bool lBottomFaceExists = ! internal::is_border(qp,g) ;
bool lTopFaceExists = ! is_border(pq,g) ;
bool lBottomFaceExists = ! is_border(qp,g) ;
vertex_descriptor q = target(pq,g);
vertex_descriptor p = source(pq,g);
@ -986,7 +987,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
if (lTopFaceExists && lBottomFaceExists)
{
if ( face(edges_to_erase[0],g) == face(edges_to_erase[1],g)
&& (! internal::is_border(edges_to_erase[0],g)) )
&& (! is_border(edges_to_erase[0],g)) )
{
// the vertex is of valence 3 and we simply need to remove the vertex
// and its indicent edges
@ -1001,11 +1002,11 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
}
else
{
if (!(internal::is_border(edges_to_erase[0],g)))
if (!(is_border(edges_to_erase[0],g)))
join_face(edges_to_erase[0],g);
else
remove_face(opposite(edges_to_erase[0],g),g);
if (!internal::is_border(edges_to_erase[1],g))
if (!is_border(edges_to_erase[1],g))
join_face(edges_to_erase[1],g);
else
remove_face(opposite(edges_to_erase[1],g),g);
@ -1017,22 +1018,22 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
{
if (lTopFaceExists)
{
if (!(internal::is_border(edges_to_erase[0],g))){
if (!(is_border(edges_to_erase[0],g))){
join_face(edges_to_erase[0],g);
join_vertex(pq,g);
return q;
}
bool lQ_Erased = internal::is_border(opposite(next(pq,g),g),g);
bool lQ_Erased = is_border(opposite(next(pq,g),g),g);
remove_face(opposite(edges_to_erase[0],g),g);
return lQ_Erased?p:q;
}
if (! (internal::is_border(edges_to_erase[0],g))){
if (! (is_border(edges_to_erase[0],g))){
join_face(edges_to_erase[0],g);
join_vertex(qp,g);
return p;
}
bool lP_Erased= internal::is_border(opposite(next(qp,g),g),g);
bool lP_Erased= is_border(opposite(next(qp,g),g),g);
remove_face(opposite(edges_to_erase[0],g),g);
return lP_Erased?q:p;
};

View File

@ -205,25 +205,7 @@ triangle(const HalfedgeGraph& g,
}
/**
* Check if all faces in a \ref FaceListGraph are triangles.
*
* @tparam FaceListGraph Must be a model of \ref FaceListGraph.
*
* @return true, if all faces are triangles, false otherwise.
*/
template<typename FaceListGraph>
bool
is_pure_triangle(const FaceListGraph& g)
{
typedef boost::graph_traits<FaceListGraph> Traits;
typedef typename Traits::face_iterator face_iterator;
face_iterator fb, fe;
for(boost::tie(fb, fe) = faces(g); fb != fe; ++fb) {
if(boost::distance(halfedges_around_face(halfedge(*fb,g), g)) != 3) return false;
}
return true;
}
/// @}

View File

@ -26,7 +26,7 @@
#include <boost/iterator/transform_iterator.hpp>
#include <CGAL/boost/graph/properties_PolyMesh_ArrayKernelT.h>
#include <CGAL/BGL/OM_iterator_from_circulator.h>
#include <CGAL/boost/graph/internal/OM_iterator_from_circulator.h>
#include <CGAL/boost/graph/iterator.h>
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>

View File

@ -7,15 +7,12 @@
namespace CGAL {
#if 0
todo: cleanup as this also is in CGAL/BGL/Helpers.h
template <typename FaceGraph>
bool is_border(typename boost::graph_traits<FaceGraph>::halfedge_descriptor hd, const FaceGraph& g)
{
return face(hd,g) == boost::graph_traits<FaceGraph>::null_face();
}
#endif
/*!
returns `true` if there are no

View File

@ -1,5 +1,5 @@
#ifndef CGAL_BGL_HELPERS_H
#define CGAL_BGL_HELPERS_H
#ifndef CGAL_BOOST_GRAPH_INTERNAL_HELPERS_H
#define CGAL_BOOST_GRAPH_INTERNAL_HELPERS_H
#include <boost/graph/graph_traits.hpp>
#include <boost/optional.hpp>
@ -7,23 +7,12 @@
namespace CGAL {
// breaks a dependency loop between <CGAL/BGL/Helper.h> and
// <CGAL/boost/graph/iterator.h>
// breaks a dependency loop between <CGAL/boost/graph/helpers.h>
// and <CGAL/boost/graph/iterator.h>
template <typename Graph> class Halfedge_around_target_iterator;
namespace internal {
template <typename Graph>
bool
is_border(typename boost::graph_traits<Graph>::halfedge_descriptor const& h
, const Graph& g)
{
return face(h,g) == boost::graph_traits<Graph>::null_face();
}
template <typename Graph>
void
set_border(typename boost::graph_traits<Graph>::halfedge_descriptor const& h
@ -278,4 +267,4 @@ bool is_valid(const Graph& g)
} // CGAL
#endif /* CGAL_BGL_HELPERS_H */
#endif // CGAL_BOOST_GRAPH_INTERNAL_HELPERS_H

View File

@ -28,7 +28,7 @@
#include <CGAL/assertions.h>
#include <CGAL/circulator_bases.h>
#include <CGAL/BGL/Helper.h>
#include <CGAL/boost/graph/internal/helpers.h>
namespace CGAL {

View File

@ -59,13 +59,13 @@ class Polyhedron_edge_index_map_external
: public boost::put_get_helper<std::size_t, Polyhedron_edge_index_map_external<Polyhedron> >
{
public:
typedef boost::readable_property_map_tag category;
typedef std::size_t value_type;
typedef std::size_t reference;
typedef typename boost::graph_traits<Polyhedron>::halfedge_descriptor key_type;
typedef boost::readable_property_map_tag category;
typedef std::size_t value_type;
typedef std::size_t reference;
typedef typename boost::graph_traits<Polyhedron>::edge_descriptor key_type;
Polyhedron_edge_index_map_external(Polyhedron& p)
: map_(std::size_t(-1), num_halfedges(p))
: map_(std::size_t(-1), num_halfedges(p)), p(p)
{
unsigned int data = 0;
typename boost::graph_traits<Polyhedron>::edge_iterator it, end;
@ -75,10 +75,11 @@ public:
}
}
reference operator[](const key_type& k) const { return map_[k]; }
reference operator[](const key_type& k) const { return map_[halfedge(k,p)]; }
private:
CGAL::Unique_hash_map<typename boost::graph_traits<Polyhedron>::halfedge_descriptor,
std::size_t> map_;
Polyhedron& p;
};
template<typename Handle>

View File

@ -22,8 +22,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( join_face_test, T, test_graphs )
set_halfedge(f.f1, e, f.m);
CGAL::Euler::join_face(e,f.m);
CGAL::internal::set_constant_vertex_is_border(f.m);
BOOST_CHECK(CGAL::internal::exact_num_faces(f.m) == 2);
BOOST_CHECK(CGAL::internal::exact_num_edges(f.m) == 6);

View File

@ -50,7 +50,7 @@ typedef CGAL::Surface_mesh<Point_3> SM;
typedef OpenMesh::PolyMesh_ArrayKernelT</* MyTraits*/> OMesh;
#endif
#include <CGAL/BGL/Helper.h>
#include <CGAL/boost/graph/helpers.h>
// helper to easily define all graph_traits members
#define CGAL_GRAPH_TRAITS_MEMBERS(T) \

View File

@ -24,7 +24,7 @@
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/AABB_halfedge_graph_segment_primitive.h>
#include <CGAL/boost/graph/halfedge_graph_traits_Polyhedron_3.h>
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
#include <CGAL/Vector_3.h>
#include <CGAL/Point_3.h>
@ -48,7 +48,7 @@ template<class Polyhedron, class Kernel>
class Polyhedron_slicer_3
{
private:
typedef AABB_halfedge_graph_segment_primitive<const Polyhedron> AABB_primitive;
typedef AABB_halfedge_graph_segment_primitive<Polyhedron> AABB_primitive;
typedef AABB_traits<Kernel, AABB_primitive> AABB_traits_;
typedef AABB_tree<AABB_traits_> AABB_tree_;
@ -59,12 +59,12 @@ private:
typedef typename Kernel::Segment_3 Segment;
typedef typename Kernel::Point_3 Point;
typedef typename Polyhedron::Edge_const_iterator Edge_const_iterator;
typedef typename Polyhedron::Halfedge_const_handle Halfedge_const_handle;
typedef typename Polyhedron::Facet_const_handle Facet_const_handle;
typedef typename Polyhedron::Vertex_const_handle Vertex_const_handle;
typedef typename Polyhedron::Halfedge_around_vertex_const_circulator Halfedge_around_vertex_const_circulator;
typedef typename Polyhedron::Halfedge_around_facet_const_circulator Halfedge_around_facet_const_circulator;
typedef typename boost::graph_traits<Polyhedron>::edge_iterator Edge_const_iterator;
typedef typename boost::graph_traits<Polyhedron>::halfedge_descriptor Halfedge_const_handle;
typedef typename boost::graph_traits<Polyhedron>::face_descriptor Facet_const_handle;
typedef typename boost::graph_traits<Polyhedron>::vertex_descriptor Vertex_const_handle;
typedef Halfedge_around_target_circulator<Polyhedron> Halfedge_around_vertex_const_circulator;
typedef Halfedge_around_face_circulator<Polyhedron> Halfedge_around_facet_const_circulator;
// to unite halfedges under an "edge"
struct Edge_comparator {
@ -127,6 +127,7 @@ private:
typename Kernel::Intersect_3 intersect_3_functor;
AABB_tree_ tree;
mutable Node_graph node_graph;
Polyhedron& polyhedron;
boost::tuple<Point, Intersection_type, Vertex_const_handle>
halfedge_intersection(Halfedge_const_handle hf, const Plane& plane) const
@ -177,11 +178,11 @@ private:
Vertex_g v_g = boost::add_vertex(node_graph);
node_graph[v_g].point = v->point();
Halfedge_around_vertex_const_circulator around_vertex_c = v->vertex_begin();
Halfedge_around_vertex_const_circulator around_vertex_c(v,polyhedron), done(around_vertex_c);
do {
edge_node_map[around_vertex_c].put(v_g);
edge_node_map[*around_vertex_c].put(v_g);
}
while(++around_vertex_c != v->vertex_begin());
while(++around_vertex_c != done);
}
void add_intersection_edge_to_facet_neighbors(Halfedge_const_handle hf, Edge_node_map& edge_node_map) const {
@ -212,11 +213,11 @@ private:
Node_pair& hf_node_pair = edge_node_map.find(hf)->second;
Vertex_g v_g = node_graph[hf_node_pair.v1].point == v->point() ? hf_node_pair.v1 : hf_node_pair.v2;// find node containing v
Halfedge_around_vertex_const_circulator around_vertex_c = v->vertex_begin();
Halfedge_around_vertex_const_circulator around_vertex_c(v, polyhedron), done(around_vertex_c);
do {
if(around_vertex_c->is_border()) { continue;}
Node_pair& around_vertex_node_pair = edge_node_map.find(around_vertex_c)->second;
Halfedge_around_facet_const_circulator around_facet_c = around_vertex_c->facet_begin();
if((*around_vertex_c)->is_border()) { continue;}
Node_pair& around_vertex_node_pair = edge_node_map.find(*around_vertex_c)->second;
Halfedge_around_facet_const_circulator around_facet_c(*around_vertex_c,polyhedron), done2(around_facet_c);
do {
CGAL_assertion(around_vertex_node_pair.vertex_count != 0);
if(around_vertex_node_pair.v1 != v_g) {
@ -226,9 +227,9 @@ private:
boost::add_edge(around_vertex_node_pair.v2, v_g, node_graph);
}
}
while(++around_facet_c != around_vertex_c->facet_begin());
while(++around_facet_c != done2);
}
while(++around_vertex_c != v->vertex_begin());
while(++around_vertex_c != done);
}
template<class OutputIterator>
@ -419,9 +420,10 @@ public:
*/
Polyhedron_slicer_3(const Polyhedron& polyhedron, const Kernel& kernel = Kernel())
: intersect_3_functor(kernel.intersect_3_object()),
tree( undirected_edges(polyhedron).first,
undirected_edges(polyhedron).second,
polyhedron)
tree( edges(polyhedron).first,
edges(polyhedron).second,
polyhedron),
polyhedron(const_cast<Polyhedron&>(polyhedron))
{ }
/**