Listing the "Blender Foundation" as copyright holder implied the Blender Foundation holds copyright to files which may include work from many developers. While keeping copyright on headers makes sense for isolated libraries, Blender's own code may be refactored or moved between files in a way that makes the per file copyright holders less meaningful. Copyright references to the "Blender Foundation" have been replaced with "Blender Authors", with the exception of `./extern/` since these this contains libraries which are more isolated, any changed to license headers there can be handled on a case-by-case basis. Some directories in `./intern/` have also been excluded: - `./intern/cycles/` it's own `AUTHORS` file is planned. - `./intern/opensubdiv/`. An "AUTHORS" file has been added, using the chromium projects authors file as a template. Design task: #110784 Ref !110783.
572 lines
13 KiB
C++
572 lines
13 KiB
C++
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
#pragma once
|
|
|
|
/** \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 = nullptr;
|
|
_begin = nullptr;
|
|
_previous_edge = nullptr;
|
|
_next_edge = nullptr;
|
|
_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 = nullptr;
|
|
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 = nullptr;
|
|
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 = nullptr, 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 */
|