diff options
Diffstat (limited to 'source/blender/freestyle/intern/stroke/ChainingIterators.cpp')
-rw-r--r-- | source/blender/freestyle/intern/stroke/ChainingIterators.cpp | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/source/blender/freestyle/intern/stroke/ChainingIterators.cpp b/source/blender/freestyle/intern/stroke/ChainingIterators.cpp new file mode 100644 index 00000000000..1883e494eab --- /dev/null +++ b/source/blender/freestyle/intern/stroke/ChainingIterators.cpp @@ -0,0 +1,202 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/freestyle/intern/stroke/ChainingIterators.cpp + * \ingroup freestyle + * \brief Chaining iterators + * \author Stephane Grabli + * \date 01/07/2003 + */ + +#include "ChainingIterators.h" + +#include "../system/TimeStamp.h" + +ViewEdge* AdjacencyIterator::operator*() +{ + return (*_internalIterator).first; +} + +bool AdjacencyIterator::isIncoming() const +{ + return (*_internalIterator).second; +} + +int AdjacencyIterator::increment() +{ + ++_internalIterator; + while((!_internalIterator.isEnd()) && (!isValid((*_internalIterator).first))) + ++_internalIterator; + return 0; +} + +bool AdjacencyIterator::isValid(ViewEdge* edge) +{ + if (_restrictToSelection) { + if (edge->getTimeStamp() != TimeStamp::instance()->getTimeStamp()) + return false; + } + if (_restrictToUnvisited) { + if (edge->getChainingTimeStamp() > TimeStamp::instance()->getTimeStamp()) + return false; + } + return true; +} + +int ChainingIterator::increment() +{ + _increment = true; + ViewVertex * vertex = getVertex(); + if (!vertex) { + _edge = 0; + return 0; + } + AdjacencyIterator it = AdjacencyIterator(vertex, _restrictToSelection, _restrictToUnvisited); + if (it.isEnd()) { + _edge = 0; + return 0; + } + if (traverse(it) < 0) + return -1; + _edge = result; + if(_edge == 0) + return 0; + if(_edge->A() == vertex) + _orientation = true; + else + _orientation = false; + return 0; +} + +int ChainingIterator::decrement() +{ + _increment = false; + ViewVertex * vertex = getVertex(); + if (!vertex) { + _edge = 0; + return 0; + } + AdjacencyIterator it = AdjacencyIterator(vertex, _restrictToSelection, _restrictToUnvisited); + if (it.isEnd()) { + _edge = 0; + return 0; + } + if (traverse(it) < 0) + return -1; + _edge = result; + if(_edge == 0) + return 0; + if(_edge->B() == vertex) + _orientation = true; + else + _orientation = false; + return 0; +} + +// +// ChainSilhouetteIterators +// +/////////////////////////////////////////////////////////// + +int ChainSilhouetteIterator::traverse(const AdjacencyIterator& ait) +{ + AdjacencyIterator it(ait); + ViewVertex* nextVertex = getVertex(); + // we can't get a NULL nextVertex here, it was intercepted before + if (nextVertex->getNature() & Nature::T_VERTEX) { + TVertex * tvertex = (TVertex*)nextVertex; + ViewEdge *mate = (tvertex)->mate(getCurrentEdge()); + while (!it.isEnd()) { + ViewEdge *ve = *it; + if (ve == mate) { + result = ve; + return 0; + } + ++it; + } + result = 0; + return 0; + } + if (nextVertex->getNature() & Nature::NON_T_VERTEX) { + //soc NonTVertex * nontvertex = (NonTVertex*)nextVertex; + ViewEdge * newEdge(0); + // we'll try to chain the edges by keeping the same nature... + // the preseance order is : SILHOUETTE, BORDER, CREASE, SUGGESTIVE, VALLEY, RIDGE + Nature::EdgeNature natures[6] = { + Nature::SILHOUETTE, + Nature::BORDER, + Nature::CREASE, + Nature::SUGGESTIVE_CONTOUR, + Nature::VALLEY, + Nature::RIDGE + }; + for (unsigned int i = 0; i < 6; ++i) { + if (getCurrentEdge()->getNature() & natures[i]) { + int n = 0; + while (!it.isEnd()) { + ViewEdge *ve = *it; + if(ve->getNature() & natures[i]) { + ++n; + newEdge = ve; + } + ++it; + } + if (n == 1) { + result = newEdge; + } + else { + result = 0; + } + return 0; + } + } + } + result = 0; + return 0; +} + +int ChainPredicateIterator::traverse(const AdjacencyIterator& ait) +{ + AdjacencyIterator it(ait); + // Iterates over next edges to see if one of them respects the predicate: + while (!it.isEnd()) { + ViewEdge *ve = *it; + if (_unary_predicate->operator()(*ve) < 0) + return -1; + if (_unary_predicate->result) { + if (_binary_predicate->operator()(*(getCurrentEdge()), *(ve)) < 0) + return -1; + if (_binary_predicate->result) { + result = ve; + return 0; + } + } + ++it; + } + result = 0; + return 0; +} |