// // Filename : ChainingIterators // Author : Stephane Grabli // Purpose : Chaining iterators // Date of creation : 01/07/2003 // /////////////////////////////////////////////////////////////////////////////// // // Copyright (C) : Please refer to the COPYRIGHT file distributed // with this source distribution. // // 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // /////////////////////////////////////////////////////////////////////////////// #ifndef CHAININGITERATORS_H # define CHAININGITERATORS_H # include # include "../view_map/ViewMap.h" # include "../view_map/ViewMapIterators.h" # include "../view_map/ViewMapAdvancedIterators.h" # include "Predicates1D.h" #include "../system/Iterator.h" //soc //using namespace ViewEdgeInternal; // // Adjacency iterator used in the chaining process // /////////////////////////////////////////////////////////// class LIB_STROKE_EXPORT 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(){ return _internalIterator.isEnd(); } virtual inline bool isBegin(){ return _internalIterator.isBegin(); } /*! Returns true if the current ViewEdge is 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 void increment(); virtual void decrement(){ cerr << "Warning: method decrement() not implemented" << endl; } 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 LIB_STROKE_EXPORT ChainingIterator : public ViewEdgeInternal::ViewEdgeIterator{ protected: bool _restrictToSelection; bool _restrictToUnvisited; bool _increment; //true if we're currently incrementing, false when decrementing public: /*! 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 ot 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 = 0, bool orientation = true) : ViewEdgeIterator(begin, orientation) { _restrictToSelection = iRestrictToSelection; _restrictToUnvisited = iRestrictToUnvisited; _increment = true; } /*! Copy constructor */ ChainingIterator(const ChainingIterator& brother) : ViewEdgeIterator(brother) { _restrictToSelection = brother._restrictToSelection; _restrictToUnvisited = brother._restrictToUnvisited; _increment = brother._increment; } /*! Returns the string "ChainingIterator" */ virtual string getExactTypeName() const { return "ChainingIterator"; } /*! Inits 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 void 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 ViewEdge * traverse(const AdjacencyIterator &it){ cerr << "Warning: the traverse method was not defined" << endl; return 0; } /* 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 void increment() ; virtual void 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 LIB_STROKE_EXPORT 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 ViewEdge * traverse(const AdjacencyIterator& it); }; // // 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 LIB_STROKE_EXPORT 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 ViewEdge * traverse(const AdjacencyIterator &it); }; #endif // CHAININGITERATORS_H