595 lines
14 KiB
C++
595 lines
14 KiB
C++
/*
|
|
* This program is free software; 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 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#ifndef __FREESTYLE_VIEW_MAP_ITERATORS_H__
|
|
#define __FREESTYLE_VIEW_MAP_ITERATORS_H__
|
|
|
|
/** \file
|
|
* \ingroup freestyle
|
|
* \brief Iterators used to iterate over the various elements of the ViewMap
|
|
*/
|
|
|
|
#include "ViewMap.h"
|
|
|
|
#include "../system/Iterator.h" //soc
|
|
|
|
namespace Freestyle {
|
|
|
|
/**********************************/
|
|
/* */
|
|
/* */
|
|
/* ViewMap */
|
|
/* */
|
|
/* */
|
|
/**********************************/
|
|
|
|
/**********************************/
|
|
/* */
|
|
/* */
|
|
/* ViewVertex */
|
|
/* */
|
|
/* */
|
|
/**********************************/
|
|
|
|
namespace ViewVertexInternal {
|
|
|
|
/*! Class representing an iterator over oriented ViewEdges around a ViewVertex. This iterator
|
|
* allows a CCW iteration (in the image plane). An instance of an orientedViewEdgeIterator can only
|
|
* be obtained from a ViewVertex by calling edgesBegin() or edgesEnd().
|
|
*/
|
|
class orientedViewEdgeIterator : public Iterator {
|
|
public:
|
|
friend class ViewVertex;
|
|
friend class TVertex;
|
|
friend class NonTVertex;
|
|
friend class ViewEdge;
|
|
|
|
// FIXME
|
|
typedef TVertex::edge_pointers_container edge_pointers_container;
|
|
typedef NonTVertex::edges_container edges_container;
|
|
|
|
protected:
|
|
Nature::VertexNature _Nature; // the nature of the underlying vertex
|
|
// T vertex attributes
|
|
edge_pointers_container::iterator _tbegin;
|
|
edge_pointers_container::iterator _tend;
|
|
edge_pointers_container::iterator _tvertex_iter;
|
|
|
|
// Non TVertex attributes
|
|
edges_container::iterator _begin;
|
|
edges_container::iterator _end;
|
|
edges_container::iterator _nontvertex_iter;
|
|
|
|
public:
|
|
/*! Default constructor */
|
|
inline orientedViewEdgeIterator()
|
|
{
|
|
}
|
|
|
|
inline orientedViewEdgeIterator(Nature::VertexNature iNature)
|
|
{
|
|
_Nature = iNature;
|
|
}
|
|
|
|
/*! Copy constructor */
|
|
orientedViewEdgeIterator(const orientedViewEdgeIterator &iBrother)
|
|
{
|
|
_Nature = iBrother._Nature;
|
|
if (_Nature & Nature::T_VERTEX) {
|
|
_tbegin = iBrother._tbegin;
|
|
_tend = iBrother._tend;
|
|
_tvertex_iter = iBrother._tvertex_iter;
|
|
}
|
|
else {
|
|
_begin = iBrother._begin;
|
|
_end = iBrother._end;
|
|
_nontvertex_iter = iBrother._nontvertex_iter;
|
|
}
|
|
}
|
|
|
|
virtual ~orientedViewEdgeIterator()
|
|
{
|
|
}
|
|
|
|
public:
|
|
inline orientedViewEdgeIterator(edge_pointers_container::iterator begin,
|
|
edge_pointers_container::iterator end,
|
|
edge_pointers_container::iterator iter)
|
|
{
|
|
_Nature = Nature::T_VERTEX;
|
|
_tbegin = begin;
|
|
_tend = end;
|
|
_tvertex_iter = iter;
|
|
}
|
|
|
|
inline orientedViewEdgeIterator(edges_container::iterator begin,
|
|
edges_container::iterator end,
|
|
edges_container::iterator iter)
|
|
{
|
|
_Nature = Nature::NON_T_VERTEX;
|
|
_begin = begin;
|
|
_end = end;
|
|
_nontvertex_iter = iter;
|
|
}
|
|
|
|
public:
|
|
/*! Tells whether the ViewEdge pointed by this iterator is the first one of the iteration list or
|
|
* not. */
|
|
virtual bool isBegin() const
|
|
{
|
|
if (_Nature & Nature::T_VERTEX) {
|
|
return (_tvertex_iter == _tbegin);
|
|
}
|
|
else {
|
|
return (_nontvertex_iter == _begin);
|
|
}
|
|
}
|
|
|
|
/*! Tells whether the ViewEdge pointed by this iterator is after the last one of the iteration
|
|
* list or not. */
|
|
virtual bool isEnd() const
|
|
{
|
|
if (_Nature & Nature::T_VERTEX) {
|
|
return (_tvertex_iter == _tend);
|
|
}
|
|
else {
|
|
return (_nontvertex_iter == _end);
|
|
}
|
|
}
|
|
|
|
// operators
|
|
/*! Increments. In the scripting language, call "increment()". */
|
|
// operator corresponding to ++i
|
|
virtual orientedViewEdgeIterator &operator++()
|
|
{
|
|
increment();
|
|
return *this;
|
|
}
|
|
|
|
// operator corresponding to i++, i.e. which returns the value *and then* increments.
|
|
// That's why we store the value in a temp.
|
|
virtual orientedViewEdgeIterator operator++(int)
|
|
{
|
|
orientedViewEdgeIterator tmp = *this;
|
|
increment();
|
|
return tmp;
|
|
}
|
|
|
|
// comparibility
|
|
/*! operator != */
|
|
virtual bool operator!=(const orientedViewEdgeIterator &b) const
|
|
{
|
|
if (_Nature & Nature::T_VERTEX) {
|
|
return (_tvertex_iter != b._tvertex_iter);
|
|
}
|
|
else {
|
|
return (_nontvertex_iter != b._nontvertex_iter);
|
|
}
|
|
}
|
|
|
|
/*! operator == */
|
|
virtual bool operator==(const orientedViewEdgeIterator &b) const
|
|
{
|
|
return !(*this != b);
|
|
}
|
|
|
|
// dereferencing
|
|
/*! Returns a reference to the pointed orientedViewEdge.
|
|
* In the scripting language, you must call "getObject()" instead.
|
|
*/
|
|
virtual ViewVertex::directedViewEdge &operator*() const
|
|
{
|
|
if (_Nature & Nature::T_VERTEX) {
|
|
// return _tvertex_iter;
|
|
return **_tvertex_iter;
|
|
}
|
|
else {
|
|
return (*_nontvertex_iter);
|
|
}
|
|
}
|
|
/*! Returns a pointer to the pointed orientedViewEdge.
|
|
* Can't be called in the scripting language.
|
|
*/
|
|
virtual ViewVertex::directedViewEdge *operator->() const
|
|
{
|
|
return &(operator*());
|
|
}
|
|
|
|
public:
|
|
/*! increments.*/
|
|
virtual inline int increment()
|
|
{
|
|
if (_Nature & Nature::T_VERTEX) {
|
|
ViewVertex::directedViewEdge tmp = (**_tvertex_iter);
|
|
++_tvertex_iter;
|
|
if (_tvertex_iter != _tend) {
|
|
// FIXME : pquoi deja ?
|
|
ViewVertex::directedViewEdge tmp2 = (**_tvertex_iter);
|
|
if (tmp2.first == tmp.first) {
|
|
++_tvertex_iter;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
++_nontvertex_iter;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#ifdef WITH_CXX_GUARDEDALLOC
|
|
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:orientedViewEdgeIterator")
|
|
#endif
|
|
};
|
|
|
|
} // namespace ViewVertexInternal
|
|
|
|
/**********************************/
|
|
/* */
|
|
/* */
|
|
/* ViewEdge */
|
|
/* */
|
|
/* */
|
|
/**********************************/
|
|
|
|
namespace ViewEdgeInternal {
|
|
|
|
//
|
|
// SVertexIterator
|
|
//
|
|
/////////////////////////////////////////////////
|
|
|
|
class SVertexIterator : public Interface0DIteratorNested {
|
|
public:
|
|
SVertexIterator()
|
|
{
|
|
_vertex = NULL;
|
|
_begin = NULL;
|
|
_previous_edge = NULL;
|
|
_next_edge = NULL;
|
|
_t = 0;
|
|
}
|
|
|
|
SVertexIterator(const SVertexIterator &vi)
|
|
{
|
|
_vertex = vi._vertex;
|
|
_begin = vi._begin;
|
|
_previous_edge = vi._previous_edge;
|
|
_next_edge = vi._next_edge;
|
|
_t = vi._t;
|
|
}
|
|
|
|
SVertexIterator(SVertex *v, SVertex *begin, FEdge *prev, FEdge *next, float t)
|
|
{
|
|
_vertex = v;
|
|
_begin = begin;
|
|
_previous_edge = prev;
|
|
_next_edge = next;
|
|
_t = t;
|
|
}
|
|
|
|
SVertexIterator &operator=(const SVertexIterator &vi)
|
|
{
|
|
_vertex = vi._vertex;
|
|
_begin = vi._begin;
|
|
_previous_edge = vi._previous_edge;
|
|
_next_edge = vi._next_edge;
|
|
_t = vi._t;
|
|
return *this;
|
|
}
|
|
|
|
virtual ~SVertexIterator()
|
|
{
|
|
}
|
|
|
|
virtual string getExactTypeName() const
|
|
{
|
|
return "SVertexIterator";
|
|
}
|
|
|
|
virtual SVertex &operator*()
|
|
{
|
|
return *_vertex;
|
|
}
|
|
|
|
virtual SVertex *operator->()
|
|
{
|
|
return &(operator*());
|
|
}
|
|
|
|
virtual SVertexIterator &operator++()
|
|
{
|
|
increment();
|
|
return *this;
|
|
}
|
|
|
|
virtual SVertexIterator operator++(int)
|
|
{
|
|
SVertexIterator ret(*this);
|
|
increment();
|
|
return ret;
|
|
}
|
|
|
|
virtual SVertexIterator &operator--()
|
|
{
|
|
decrement();
|
|
return *this;
|
|
}
|
|
|
|
virtual SVertexIterator operator--(int)
|
|
{
|
|
SVertexIterator ret(*this);
|
|
decrement();
|
|
return ret;
|
|
}
|
|
|
|
virtual int increment()
|
|
{
|
|
if (!_next_edge) {
|
|
_vertex = NULL;
|
|
return 0;
|
|
}
|
|
_t += (float)_next_edge->getLength2D();
|
|
_vertex = _next_edge->vertexB();
|
|
_previous_edge = _next_edge;
|
|
_next_edge = _next_edge->nextEdge();
|
|
return 0;
|
|
}
|
|
|
|
virtual int decrement()
|
|
{
|
|
if (!_previous_edge) {
|
|
_vertex = NULL;
|
|
return 0;
|
|
}
|
|
if ((!_next_edge) && (!_vertex)) {
|
|
_vertex = _previous_edge->vertexB();
|
|
return 0;
|
|
}
|
|
_t -= (float)_previous_edge->getLength2D();
|
|
_vertex = _previous_edge->vertexA();
|
|
_next_edge = _previous_edge;
|
|
_previous_edge = _previous_edge->previousEdge();
|
|
return 0;
|
|
}
|
|
|
|
virtual bool isBegin() const
|
|
{
|
|
return _vertex == _begin;
|
|
}
|
|
|
|
virtual bool isEnd() const
|
|
{
|
|
return (!_vertex) || (_vertex == _begin && _previous_edge);
|
|
}
|
|
|
|
virtual float t() const
|
|
{
|
|
return _t;
|
|
}
|
|
|
|
virtual float u() const
|
|
{
|
|
return _t / (float)_next_edge->viewedge()->getLength2D();
|
|
}
|
|
|
|
virtual bool operator==(const Interface0DIteratorNested &it) const
|
|
{
|
|
const SVertexIterator *it_exact = dynamic_cast<const SVertexIterator *>(&it);
|
|
if (!it_exact) {
|
|
return false;
|
|
}
|
|
return (_vertex == it_exact->_vertex);
|
|
}
|
|
|
|
virtual SVertexIterator *copy() const
|
|
{
|
|
return new SVertexIterator(*this);
|
|
}
|
|
|
|
private:
|
|
SVertex *_vertex;
|
|
SVertex *_begin;
|
|
FEdge *_previous_edge;
|
|
FEdge *_next_edge;
|
|
float _t; // curvilinear abscissa
|
|
|
|
#ifdef WITH_CXX_GUARDEDALLOC
|
|
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SVertexIterator")
|
|
#endif
|
|
};
|
|
|
|
//
|
|
// ViewEdgeIterator (base class)
|
|
//
|
|
///////////////////////////////////////////////////////////
|
|
|
|
/*! Base class for iterators over ViewEdges of the ViewMap Graph.
|
|
* Basically the "increment()" operator of this class should be able to take the decision of
|
|
* "where" (on which ViewEdge) to go when pointing on a given ViewEdge.
|
|
* ::Caution::: the dereferencing operator returns a *pointer* to the pointed ViewEdge.
|
|
*/
|
|
class ViewEdgeIterator : public Iterator {
|
|
public:
|
|
/*! Builds a ViewEdgeIterator from a starting ViewEdge and its orientation.
|
|
* \param begin:
|
|
* The ViewEdge from where to start the iteration.
|
|
* \param orientation:
|
|
* If true, we'll look for the next ViewEdge among the ViewEdges that surround the ending
|
|
* ViewVertex of begin. If false, we'll search over the ViewEdges surrounding the ending
|
|
* ViewVertex of begin.
|
|
*/
|
|
ViewEdgeIterator(ViewEdge *begin = NULL, bool orientation = true)
|
|
{
|
|
_orientation = orientation;
|
|
_edge = begin;
|
|
_begin = begin;
|
|
}
|
|
|
|
/*! Copy constructor */
|
|
ViewEdgeIterator(const ViewEdgeIterator &it)
|
|
{
|
|
_orientation = it._orientation;
|
|
_edge = it._edge;
|
|
_begin = it._begin;
|
|
}
|
|
|
|
virtual ~ViewEdgeIterator()
|
|
{
|
|
}
|
|
|
|
/*! Returns the string "ViewEdgeIterator" */
|
|
virtual string getExactTypeName() const
|
|
{
|
|
return "ViewEdgeIterator";
|
|
}
|
|
|
|
/*! Returns the current pointed ViewEdge. */
|
|
ViewEdge *getCurrentEdge()
|
|
{
|
|
return _edge;
|
|
}
|
|
|
|
/*! Sets the current pointed ViewEdge. */
|
|
void setCurrentEdge(ViewEdge *edge)
|
|
{
|
|
_edge = edge;
|
|
}
|
|
|
|
/*! Returns the first ViewEdge used for the iteration. */
|
|
ViewEdge *getBegin()
|
|
{
|
|
return _begin;
|
|
}
|
|
|
|
/*! Sets the first ViewEdge used for the iteration. */
|
|
void setBegin(ViewEdge *begin)
|
|
{
|
|
_begin = begin;
|
|
}
|
|
|
|
/*! Gets the orientation of the pointed ViewEdge in the iteration. */
|
|
bool getOrientation() const
|
|
{
|
|
return _orientation;
|
|
}
|
|
|
|
/*! Sets the orientation of the pointed ViewEdge in the iteration. */
|
|
void setOrientation(bool orientation)
|
|
{
|
|
_orientation = orientation;
|
|
}
|
|
|
|
/*! Changes the current orientation. */
|
|
void changeOrientation()
|
|
{
|
|
_orientation = !_orientation;
|
|
}
|
|
|
|
/*! Returns a *pointer* to the pointed ViewEdge. */
|
|
virtual ViewEdge *operator*()
|
|
{
|
|
return _edge;
|
|
}
|
|
|
|
virtual ViewEdge *operator->()
|
|
{
|
|
return operator*();
|
|
}
|
|
|
|
/*! Increments. In the scripting language, call "increment()". */
|
|
virtual ViewEdgeIterator &operator++()
|
|
{
|
|
increment();
|
|
return *this;
|
|
}
|
|
|
|
/*! Increments. In the scripting language, call "increment()". */
|
|
virtual ViewEdgeIterator operator++(int)
|
|
{
|
|
ViewEdgeIterator tmp(*this);
|
|
increment();
|
|
return tmp;
|
|
}
|
|
|
|
/*! increments. */
|
|
virtual int increment()
|
|
{
|
|
cerr << "Warning: method increment() not implemented" << endl;
|
|
return 0;
|
|
}
|
|
|
|
/*! Decrements. In the scripting language, call "decrement()". */
|
|
virtual ViewEdgeIterator &operator--()
|
|
{
|
|
decrement();
|
|
return *this;
|
|
}
|
|
|
|
/*! Decrements. In the scripting language, call "decrement()". */
|
|
virtual ViewEdgeIterator operator--(int)
|
|
{
|
|
ViewEdgeIterator tmp(*this);
|
|
decrement();
|
|
return tmp;
|
|
}
|
|
|
|
/*! decrements. */
|
|
virtual int decrement()
|
|
{
|
|
cerr << "Warning: method decrement() not implemented" << endl;
|
|
return 0;
|
|
}
|
|
|
|
/*! Returns true if the pointed ViewEdge is the first one used for the iteration. */
|
|
virtual bool isBegin() const
|
|
{
|
|
return _edge == _begin;
|
|
}
|
|
|
|
/*! Returns true if the pointed ViewEdge* equals 0. */
|
|
virtual bool isEnd() const
|
|
{
|
|
return !_edge;
|
|
}
|
|
|
|
/*! operator == */
|
|
virtual bool operator==(ViewEdgeIterator &it) const
|
|
{
|
|
return _edge == it._edge;
|
|
}
|
|
|
|
/*! operator != */
|
|
virtual bool operator!=(ViewEdgeIterator &it) const
|
|
{
|
|
return !(*this == it);
|
|
}
|
|
|
|
protected:
|
|
bool _orientation;
|
|
ViewEdge *_edge;
|
|
ViewEdge *_begin;
|
|
|
|
#ifdef WITH_CXX_GUARDEDALLOC
|
|
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewEdgeIterator")
|
|
#endif
|
|
};
|
|
|
|
} // end of namespace ViewEdgeInternal
|
|
|
|
} /* namespace Freestyle */
|
|
|
|
#endif // __FREESTYLE_VIEW_MAP_ITERATORS_H__
|