Files
test/source/blender/freestyle/intern/stroke/ChainingIterators.h
Campbell Barton c434782e3a File headers: SPDX License migration
Use a shorter/simpler license convention, stops the header taking so
much space.

Follow the SPDX license specification: https://spdx.org/licenses

- C/C++/objc/objc++
- Python
- Shell Scripts
- CMake, GNUmakefile

While most of the source tree has been included

- `./extern/` was left out.
- `./intern/cycles` & `./intern/atomic` are also excluded because they
  use different header conventions.

doc/license/SPDX-license-identifiers.txt has been added to list SPDX all
used identifiers.

See P2788 for the script that automated these edits.

Reviewed By: brecht, mont29, sergey

Ref D14069
2022-02-11 09:14:36 +11:00

403 lines
12 KiB
C++

/* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
/** \file
* \ingroup freestyle
* \brief Chaining iterators
*/
#include <iostream>
#include "Predicates1D.h"
#include "../system/Iterator.h"
#include "../view_map/ViewMap.h"
#include "../view_map/ViewMapAdvancedIterators.h"
#include "../view_map/ViewMapIterators.h"
// using namespace ViewEdgeInternal;
namespace Freestyle {
//
// Adjacency iterator used in the chaining process
//
///////////////////////////////////////////////////////////
class AdjacencyIterator : public Iterator {
protected:
ViewVertexInternal::orientedViewEdgeIterator _internalIterator;
bool _restrictToSelection;
bool _restrictToUnvisited;
public:
AdjacencyIterator()
{
_restrictToSelection = true;
_restrictToUnvisited = true;
}
AdjacencyIterator(ViewVertex *iVertex,
bool iRestrictToSelection = true,
bool iRestrictToUnvisited = true)
{
_restrictToSelection = iRestrictToSelection;
_restrictToUnvisited = iRestrictToUnvisited;
_internalIterator = iVertex->edgesBegin();
while ((!_internalIterator.isEnd()) && (!isValid((*_internalIterator).first))) {
++_internalIterator;
}
}
AdjacencyIterator(const AdjacencyIterator &iBrother)
{
_internalIterator = iBrother._internalIterator;
_restrictToSelection = iBrother._restrictToSelection;
_restrictToUnvisited = iBrother._restrictToUnvisited;
}
AdjacencyIterator &operator=(const AdjacencyIterator &iBrother)
{
_internalIterator = iBrother._internalIterator;
_restrictToSelection = iBrother._restrictToSelection;
_restrictToUnvisited = iBrother._restrictToUnvisited;
return *this;
}
virtual ~AdjacencyIterator()
{
}
virtual string getExactTypeName() const
{
return "AdjacencyIterator";
}
virtual inline bool isEnd() const
{
return _internalIterator.isEnd();
}
virtual inline bool isBegin() const
{
return _internalIterator.isBegin();
}
/** Returns true if the current ViewEdge is coming towards the iteration vertex.
* False otherwise. */
bool isIncoming() const;
/** Returns a *pointer* to the pointed ViewEdge. */
virtual ViewEdge *operator*();
virtual ViewEdge *operator->()
{
return operator*();
}
virtual AdjacencyIterator &operator++()
{
increment();
return *this;
}
virtual AdjacencyIterator operator++(int)
{
AdjacencyIterator tmp(*this);
increment();
return tmp;
}
virtual int increment();
virtual int decrement()
{
cerr << "Warning: method decrement() not implemented" << endl;
return 0;
}
protected:
bool isValid(ViewEdge *edge);
};
//
// Base class for Chaining Iterators
//
///////////////////////////////////////////////////////////
/** Base class for chaining iterators.
* This class is designed to be overloaded in order to describe chaining rules.
* It makes the works of chaining rules description easier.
* The two main methods that need to overloaded are traverse() and init().
* traverse() tells which ViewEdge to follow, among the adjacent ones.
* If you specify restriction rules (such as "Chain only ViewEdges of the selection"),
* they will be included in the adjacency iterator.
* (i.e, the adjacent iterator will only stop on "valid" edges).
*/
class ChainingIterator : public ViewEdgeInternal::ViewEdgeIterator {
protected:
bool _restrictToSelection;
bool _restrictToUnvisited;
bool _increment; // true if we're currently incrementing, false when decrementing
public:
ViewEdge *result;
void *py_c_it;
/** Builds a Chaining Iterator from the first ViewEdge used for iteration and its orientation.
* \param iRestrictToSelection:
* Indicates whether to force the chaining to stay within
* the set of selected ViewEdges or not.
* \param iRestrictToUnvisited:
* Indicates whether a ViewEdge that has already been chained must be ignored or not.
* \param begin:
* The ViewEdge from which to start the chain.
* \param orientation:
* The direction to follow to explore the graph. If true,
* the direction indicated by the first ViewEdge is used.
*/
ChainingIterator(bool iRestrictToSelection = true,
bool iRestrictToUnvisited = true,
ViewEdge *begin = NULL,
bool orientation = true)
: ViewEdgeIterator(begin, orientation)
{
_restrictToSelection = iRestrictToSelection;
_restrictToUnvisited = iRestrictToUnvisited;
_increment = true;
py_c_it = NULL;
}
/** Copy constructor */
ChainingIterator(const ChainingIterator &brother) : ViewEdgeIterator(brother)
{
_restrictToSelection = brother._restrictToSelection;
_restrictToUnvisited = brother._restrictToUnvisited;
_increment = brother._increment;
py_c_it = brother.py_c_it;
}
/** Returns the string "ChainingIterator" */
virtual string getExactTypeName() const
{
return "ChainingIterator";
}
/** Initializes the iterator context.
* This method is called each time a new chain is started.
* It can be used to reset some history information that you might want to keep.
*/
virtual int init();
/** This method iterates over the potential next ViewEdges and returns the one that will be
* followed next. returns the next ViewEdge to follow or 0 when the end of the chain is reached.
* \param it:
* The iterator over the ViewEdges adjacent to the end vertex of the current ViewEdge.
* The Adjacency iterator reflects the restriction rules by only iterating over the valid
* ViewEdges.
*/
virtual int traverse(const AdjacencyIterator &it);
/* accessors */
/** Returns true if the orientation of the current ViewEdge corresponds to its natural
* orientation */
// inline bool getOrientation() const {}
/** Returns the vertex which is the next crossing */
inline ViewVertex *getVertex()
{
if (_increment) {
if (_orientation) {
return _edge->B();
}
else {
return _edge->A();
}
}
else {
if (_orientation) {
return _edge->A();
}
else {
return _edge->B();
}
}
}
/** Returns true if the current iteration is an incrementation */
inline bool isIncrementing() const
{
return _increment;
}
/* Increments. */
virtual int increment();
virtual int decrement();
};
//
// Chaining iterators definitions
//
///////////////////////////////////////////////////////////
/** A ViewEdge Iterator used to follow ViewEdges the most naturally.
* For example, it will follow visible ViewEdges of same nature.
* As soon, as the nature or the visibility changes, the iteration stops (by setting the pointed
* ViewEdge to 0). In the case of an iteration over a set of ViewEdge that are both Silhouette
* and Crease, there will be a precedence of the silhouette over the crease criterion.
*/
class ChainSilhouetteIterator : public ChainingIterator {
public:
/** Builds a ChainSilhouetteIterator from the first ViewEdge used for iteration and its
* orientation.
* \param iRestrictToSelection:
* Indicates whether to force the chaining to stay within the set of selected ViewEdges or
* not.
* \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.
*/
ChainSilhouetteIterator(bool iRestrictToSelection = true,
ViewEdge *begin = NULL,
bool orientation = true)
: ChainingIterator(iRestrictToSelection, true, begin, orientation)
{
}
/** Copy constructor */
ChainSilhouetteIterator(const ChainSilhouetteIterator &brother) : ChainingIterator(brother)
{
}
/** Returns the string "ChainSilhouetteIterator" */
virtual string getExactTypeName() const
{
return "ChainSilhouetteIterator";
}
/** This method iterates over the potential next ViewEdges and returns the one that will be
* followed next.
* When reaching the end of a chain, 0 is returned.
*/
virtual int traverse(const AdjacencyIterator &it);
/** Initializes the iterator context */
virtual int init()
{
return 0;
}
};
//
// ChainPredicateIterator
//
///////////////////////////////////////////////////////////
/** A "generic" user-controlled ViewEdge iterator. This iterator is in particular built from a
* unary predicate and a binary predicate.
* First, the unary predicate is evaluated for all potential next ViewEdges in order to only
* keep the ones respecting a certain constraint.
* Then, the binary predicate is evaluated on the current ViewEdge together with each ViewEdge
* of the previous selection. The first ViewEdge respecting both the unary predicate and the
* binary predicate is kept as the next one. If none of the potential next ViewEdge respects
* these 2 predicates, 0 is returned.
*/
class ChainPredicateIterator : public ChainingIterator {
protected:
BinaryPredicate1D
*_binary_predicate; // the caller is responsible for the deletion of this object
UnaryPredicate1D *_unary_predicate; // the caller is responsible for the deletion of this object
public:
/** Builds a ChainPredicateIterator from a starting ViewEdge and its orientation.
* \param iRestrictToSelection:
* Indicates whether to force the chaining to stay
* within the set of selected ViewEdges or not.
* \param iRestrictToUnvisited:
* Indicates whether a ViewEdge that has already been chained must be ignored ot not.
* \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.
*/
ChainPredicateIterator(bool iRestrictToSelection = true,
bool iRestrictToUnvisited = true,
ViewEdge *begin = NULL,
bool orientation = true)
: ChainingIterator(iRestrictToSelection, iRestrictToUnvisited, begin, orientation)
{
_binary_predicate = 0;
_unary_predicate = 0;
}
/** Builds a ChainPredicateIterator from a unary predicate, a binary predicate, a starting
* ViewEdge and its orientation.
* \param iRestrictToSelection:
* Indicates whether to force the chaining to stay
* within the set of selected ViewEdges or not.
* \param iRestrictToUnvisited:
* Indicates whether a ViewEdge that has already been chained must be ignored ot not.
* \param upred:
* The unary predicate that the next ViewEdge must satisfy.
* \param bpred:
* The binary predicate that the next ViewEdge must satisfy together with the actual pointed
* ViewEdge.
* \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.
*/
ChainPredicateIterator(UnaryPredicate1D &upred,
BinaryPredicate1D &bpred,
bool iRestrictToSelection = true,
bool iRestrictToUnvisited = true,
ViewEdge *begin = NULL,
bool orientation = true)
: ChainingIterator(iRestrictToSelection, iRestrictToUnvisited, begin, orientation)
{
_unary_predicate = &upred;
_binary_predicate = &bpred;
}
/** Copy constructor */
ChainPredicateIterator(const ChainPredicateIterator &brother) : ChainingIterator(brother)
{
_unary_predicate = brother._unary_predicate;
_binary_predicate = brother._binary_predicate;
}
/** Destructor. */
virtual ~ChainPredicateIterator()
{
_unary_predicate = 0;
_binary_predicate = 0;
}
/** Returns the string "ChainPredicateIterator" */
virtual string getExactTypeName() const
{
return "ChainPredicateIterator";
}
/** This method iterates over the potential next ViewEdges and returns the one that will be
* followed next. When reaching the end of a chain, 0 is returned.
*/
virtual int traverse(const AdjacencyIterator &it);
/** Initializes the iterator context. */
virtual int init()
{
return 0;
}
};
} /* namespace Freestyle */