Files
test/source/blender/freestyle/intern/view_map/ViewMapIterators.h
Campbell Barton e955c94ed3 License Headers: Set copyright to "Blender Authors", add AUTHORS
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.
2023-08-16 00:20:26 +10:00

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 */