Loading...
Searching...
No Matches
Skeleton_blockers_triangles_iterators.h
/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
* See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
* Author(s): David Salinas
*
* Copyright (C) 2014 Inria
*
* Modification(s):
* - YYYY/MM Author: Description of the modification
*/
#ifndef SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_TRIANGLES_ITERATORS_H_
#define SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_TRIANGLES_ITERATORS_H_
#include <boost/iterator/iterator_facade.hpp>
#include <memory>
namespace Gudhi {
namespace skeleton_blocker {
template<typename Complex, typename LinkType>
class Triangle_around_vertex_iterator : public boost::iterator_facade
< Triangle_around_vertex_iterator <Complex, LinkType>
, typename Complex::Simplex const
, boost::forward_traversal_tag
, typename Complex::Simplex const> {
friend class boost::iterator_core_access;
template<typename T> friend class Triangle_iterator;
private:
typedef typename LinkType::Vertex_handle Vertex_handle;
typedef typename LinkType::Root_vertex_handle Root_vertex_handle;
typedef typename LinkType::Simplex Simplex;
typedef typename Complex::Complex_edge_iterator Complex_edge_iterator_;
const Complex* complex_;
Vertex_handle v_;
std::shared_ptr<LinkType> link_;
Complex_edge_iterator_ current_edge_;
bool is_end_;
public:
Triangle_around_vertex_iterator(const Complex* complex, Vertex_handle v) :
complex_(complex), v_(v), link_(new LinkType(*complex, v_)),
current_edge_(link_->edge_range().begin()),
is_end_(current_edge_ == link_->edge_range().end()) { }
Triangle_around_vertex_iterator(const Complex* complex, Vertex_handle v, bool is_end) :
complex_(complex), v_(v), link_(0), is_end_(true) { }
Triangle_around_vertex_iterator() :
complex_(0), v_(-1), link_(0), is_end_(true) { }
Triangle_around_vertex_iterator(const Triangle_around_vertex_iterator& other) {
v_ = other.v_;
complex_ = other.complex_;
is_end_ = other.is_end_;
if (!is_end_) {
link_ = other.link_;
current_edge_ = other.current_edge_;
}
}
bool equal(const Triangle_around_vertex_iterator& other) const {
return (complex_ == other.complex_) && ((finished() && other.finished()) || current_edge_ == other.current_edge_);
}
Simplex dereference() const {
Root_vertex_handle v1 = (*link_)[*current_edge_].first();
Root_vertex_handle v2 = (*link_)[*current_edge_].second();
return Simplex(v_, *(complex_->get_address(v1)), *(complex_->get_address(v2)));
}
void increment() {
++current_edge_;
}
private:
bool finished() const {
return is_end_ || (current_edge_ == link_->edge_range().end());
}
};
template<typename SkeletonBlockerComplex>
class Triangle_iterator : public boost::iterator_facade<
Triangle_iterator <SkeletonBlockerComplex>,
typename SkeletonBlockerComplex::Simplex const
, boost::forward_traversal_tag
, typename SkeletonBlockerComplex::Simplex const> {
friend class boost::iterator_core_access;
private:
typedef typename SkeletonBlockerComplex::Vertex_handle Vertex_handle;
typedef typename SkeletonBlockerComplex::Root_vertex_handle Root_vertex_handle;
typedef typename SkeletonBlockerComplex::Simplex Simplex;
typedef typename SkeletonBlockerComplex::Superior_triangle_around_vertex_iterator STAVI;
typedef typename SkeletonBlockerComplex::Complex_vertex_iterator Complex_vertex_iterator;
const SkeletonBlockerComplex* complex_;
Complex_vertex_iterator current_vertex_;
STAVI current_triangle_;
bool is_end_;
public:
/*
* @remark assume that the complex is non-empty
*/
Triangle_iterator(const SkeletonBlockerComplex* complex) :
complex_(complex),
current_vertex_(complex->vertex_range().begin()),
current_triangle_(complex, *current_vertex_), // this line is problematic is the complex is empty
is_end_(false) {
assert(!complex->empty());
gotoFirstTriangle();
}
private:
// goto to the first triangle or to the end if none
void gotoFirstTriangle() {
if (!is_finished() && current_triangle_.finished()) {
goto_next_vertex();
}
}
public:
Triangle_iterator(const SkeletonBlockerComplex* complex, bool is_end) :
complex_(complex),
current_vertex_(complex->vertex_range().end()),
current_triangle_(), // xxx this line is problematic is the complex is empty
is_end_(true) { }
Triangle_iterator& operator=(const Triangle_iterator & other) {
complex_ = other.complex_;
Complex_vertex_iterator current_vertex_;
STAVI current_triangle_;
return *this;
}
bool equal(const Triangle_iterator& other) const {
bool both_are_finished = is_finished() && other.is_finished();
bool both_arent_finished = !is_finished() && !other.is_finished();
// if the two iterators are not finished, they must have the same state
return (complex_ == other.complex_) && (both_are_finished || ((both_arent_finished) &&
current_vertex_ == other.current_vertex_ &&
current_triangle_ == other.current_triangle_));
}
Simplex dereference() const {
return *current_triangle_;
}
private:
// goto the next vertex that has a triangle pending or the
// end vertex iterator if none exists
void goto_next_vertex() {
// we must have consume all triangles passing through the vertex
assert(current_triangle_.finished());
// we must not be done
assert(!is_finished());
++current_vertex_;
if (!is_finished()) {
current_triangle_ = STAVI(complex_, *current_vertex_);
if (current_triangle_.finished())
goto_next_vertex();
}
}
public:
void increment() {
if (!current_triangle_.finished()) {
++current_triangle_; // problem here
if (current_triangle_.finished())
goto_next_vertex();
} else {
assert(!is_finished());
goto_next_vertex();
}
}
private:
bool is_finished() const {
return is_end_ || current_vertex_ == complex_->vertex_range().end();
}
};
} // namespace skeleton_blocker
namespace skbl = skeleton_blocker;
} // namespace Gudhi
#endif // SKELETON_BLOCKER_ITERATORS_SKELETON_BLOCKERS_TRIANGLES_ITERATORS_H_
Gudhi::skeleton_blocker::Triangle_around_vertex_iterator
Iterator over the triangles that are adjacent to a vertex of the simplicial complex.
Definition Skeleton_blockers_triangles_iterators.h:31
Gudhi::skeleton_blocker::Triangle_around_vertex_iterator::Triangle_around_vertex_iterator
Triangle_around_vertex_iterator(const Complex *complex, Vertex_handle v, bool is_end)
ugly hack to get an iterator to the end
Definition Skeleton_blockers_triangles_iterators.h:55
Gudhi::skeleton_blocker::Triangle_around_vertex_iterator::Triangle_around_vertex_iterator
Triangle_around_vertex_iterator()
ugly hack to get an iterator to the end
Definition Skeleton_blockers_triangles_iterators.h:61
Gudhi::skeleton_blocker::Triangle_iterator
Iterator over the triangles of the simplicial complex.
Definition Skeleton_blockers_triangles_iterators.h:106
Gudhi::skeleton_blocker::Triangle_iterator::Triangle_iterator
Triangle_iterator(const SkeletonBlockerComplex *complex, bool is_end)
ugly hack to get an iterator to the end
Definition Skeleton_blockers_triangles_iterators.h:146
Gudhi
Gudhi namespace.
Definition SimplicialComplexForAlpha.h:14