/* * 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. */ #ifndef __FREESTYLE_OPERATORS_H__ #define __FREESTYLE_OPERATORS_H__ /** \file * \ingroup freestyle * \brief Class gathering stroke creation algorithms */ #include #include #include "Chain.h" #include "ChainingIterators.h" #include "Predicates0D.h" #include "Predicates1D.h" #include "StrokeShader.h" #include "../system/TimeStamp.h" #include "../view_map/Interface1D.h" #include "../view_map/ViewMap.h" #ifdef WITH_CXX_GUARDEDALLOC # include "MEM_guardedalloc.h" #endif namespace Freestyle { /*! Class defining the operators used in a style module. * There are 4 classes of operators: Selection, Chaining, Splitting and Creating. * All these operators are user controlled in the scripting language through Functors, Predicates * and Shaders that are taken as arguments. */ class Operators { public: typedef vector I1DContainer; typedef vector StrokesContainer; // // Operators // //////////////////////////////////////////////// /*! Selects the ViewEdges of the ViewMap verifying a specified condition. * \param pred: The predicate expressing this condition */ static int select(UnaryPredicate1D &pred); /*! Builds a set of chains from the current set of ViewEdges. * Each ViewEdge of the current list starts a new chain. * The chaining operator then iterates over the ViewEdges * of the ViewMap using the user specified iterator. * This operator only iterates using the increment operator and is therefore unidirectional. * \param it: * The iterator on the ViewEdges of the ViewMap. It contains the chaining rule. * \param pred: * The predicate on the ViewEdge that expresses the stopping condition. * \param modifier: * A function that takes a ViewEdge as argument and that is used to modify the * processed ViewEdge state (the timestamp incrementation is a typical illustration of * such a modifier) */ static int chain(ViewEdgeInternal::ViewEdgeIterator &it, UnaryPredicate1D &pred, UnaryFunction1D_void &modifier); /*! Builds a set of chains from the current set of ViewEdges. * Each ViewEdge of the current list starts a new chain. The chaining operator then iterates * over the ViewEdges * of the ViewMap using the user specified iterator. * This operator only iterates using the increment operator and is therefore unidirectional. * This chaining operator is different from the previous one because it doesn't take any * modifier as argument. Indeed, the time stamp (insuring that a ViewEdge is processed one time) * is automatically managed in this case. * \param it: * The iterator on the ViewEdges of the ViewMap. It contains the chaining rule. * \param pred: * The predicate on the ViewEdge that expresses the stopping condition. */ static int chain(ViewEdgeInternal::ViewEdgeIterator &it, UnaryPredicate1D &pred); /*! Builds a set of chains from the current set of ViewEdges. * Each ViewEdge of the current list potentially starts a new chain. The chaining operator then * iterates over the ViewEdges of the ViewMap using the user specified iterator. * This operator iterates both using the increment and decrement operators and is therefore * bidirectional. This operator works with a ChainingIterator which contains the chaining rules. * It is this last one which can be told to chain only edges that belong to the selection or not * to process twice a ViewEdge during the chaining. Each time a ViewEdge is added to a chain, * its chaining time stamp is incremented. This allows you to keep track of the number of chains * to which a ViewEdge belongs to. * \param it: * The ChainingIterator on the ViewEdges of the ViewMap. It contains the chaining rule. * \param pred: * The predicate on the ViewEdge that expresses the stopping condition. */ static int bidirectionalChain(ChainingIterator &it, UnaryPredicate1D &pred); /*! The only difference with the above bidirectional chaining algorithm is that we don't need to * pass a stopping criterion. This might be desirable when the stopping criterion is already * contained in the iterator definition. Builds a set of chains from the current set of * ViewEdges. Each ViewEdge of the current list potentially starts a new chain. The chaining * operator then iterates over the ViewEdges of the ViewMap using the user specified iterator. * This operator iterates both using the increment and decrement operators and is therefore * bidirectional. This operator works with a ChainingIterator which contains the chaining rules. * It is this last one which can be told to chain only edges that belong to the selection or not * to process twice a ViewEdge during the chaining. Each time a ViewEdge is added to a chain, * its chaining time stamp is incremented. This allows you to keep track of the number of chains * to which a ViewEdge belongs to. * \param it: * The ChainingIterator on the ViewEdges of the ViewMap. It contains the chaining rule. */ static int bidirectionalChain(ChainingIterator &it); /*! Splits each chain of the current set of chains in a sequential way. * The points of each chain are processed (with a specified sampling) sequentially. * Each time a user specified starting condition is verified, a new chain begins and ends as * soon as a user-defined stopping predicate is verified. * This allows chains overlapping rather than chains partitioning. * The first point of the initial chain is the first point of one of the resulting chains. * The splitting ends when no more chain can start. * \param startingPred: * The predicate on a point that expresses the starting condition * \param stoppingPred: * The predicate on a point that expresses the stopping condition * \param sampling: * The resolution used to sample the chain for the predicates evaluation. * (The chain is not actually resampled, a virtual point only progresses along the * curve using this resolution) */ static int sequentialSplit(UnaryPredicate0D &startingPred, UnaryPredicate0D &stoppingPred, float sampling = 0.0f); /*! Splits each chain of the current set of chains in a sequential way. * The points of each chain are processed (with a specified sampling) sequentially and each time * a user specified condition is verified, the chain is split into two chains. * The resulting set of chains is a partition of the initial chain * \param pred: * The predicate on a point that expresses the splitting condition * \param sampling: * The resolution used to sample the chain for the predicate evaluation. * (The chain is not actually resampled, a virtual point only progresses along the * curve using this resolution) */ static int sequentialSplit(UnaryPredicate0D &pred, float sampling = 0.0f); /*! Splits the current set of chains in a recursive way. * We process the points of each chain (with a specified sampling) to find the point * minimizing a specified function. The chain is split in two at this point and the two new * chains are processed in the same way. The recursivity level is controlled through a * predicate 1D that expresses a stopping condition on the chain that is about to be processed. * \param func: * The Unary Function evaluated at each point of the chain. * The splitting point is the point minimizing this function * \param pred: * The Unary Predicate ex pressing the recursivity stopping condition. * This predicate is evaluated for each curve before it actually gets split. * If pred(chain) is true, the curve won't be split anymore. * \param sampling: * The resolution used to sample the chain for the predicates evaluation. (The chain * is not actually resampled, a virtual point only progresses along the curve using * this resolution) */ static int recursiveSplit(UnaryFunction0D &func, UnaryPredicate1D &pred, float sampling = 0); /*! Splits the current set of chains in a recursive way. * We process the points of each chain (with a specified sampling) to find the point minimizing * a specified function. The chain is split in two at this point and the two new chains are * processed in the same way. The user can specify a 0D predicate to make a first selection on * the points that can potentially be split. A point that doesn't verify the 0D predicate * won't be candidate in realizing the min. The recursivity level is controlled through a * predicate 1D that expresses a stopping condition on the chain that is about to be processed. * \param func: * The Unary Function evaluated at each point of the chain. * The splitting point is the point minimizing this function * \param pred0d: * The Unary Predicate 0D used to select the candidate points where the split can * occur. For example, it is very likely that would rather have your chain splitting * around its middle point than around one of its extremities. A 0D predicate working * on the curvilinear abscissa allows to add this kind of constraints. * \param pred: * The Unary Predicate ex pressing the recursivity stopping condition. * This predicate is evaluated for each curve before it actually gets split. * If pred(chain) is true, the curve won't be split anymore. * \param sampling: * The resolution used to sample the chain for the predicates evaluation. (The chain * is not actually resampled, a virtual point only progresses along the curve using * this resolution) */ static int recursiveSplit(UnaryFunction0D &func, UnaryPredicate0D &pred0d, UnaryPredicate1D &pred, float sampling = 0.0f); /*! Sorts the current set of chains (or viewedges) * according to the comparison predicate given as argument. * \param pred: * The binary predicate used for the comparison */ static int sort(BinaryPredicate1D &pred); /*! Creates and shades the strokes from the current set of chains. * A predicate can be specified to make a selection pass on the chains. * \param pred: * The predicate that a chain must verify in order to be transform as a stroke * \param shaders: * The list of shaders used to shade the strokes */ static int create(UnaryPredicate1D &pred, vector shaders); // // Data access // //////////////////////////////////////////////// static ViewEdge *getViewEdgeFromIndex(unsigned i) { return dynamic_cast(_current_view_edges_set[i]); } static Chain *getChainFromIndex(unsigned i) { return dynamic_cast(_current_chains_set[i]); } static Stroke *getStrokeFromIndex(unsigned i) { return _current_strokes_set[i]; } static unsigned getViewEdgesSize() { return _current_view_edges_set.size(); } static unsigned getChainsSize() { return _current_chains_set.size(); } static unsigned getStrokesSize() { return _current_strokes_set.size(); } // // Not exported in Python // ////////////////////////////////////////////////// static StrokesContainer *getStrokesSet() { return &_current_strokes_set; } static void reset(bool removeStrokes = true); private: Operators() { } static I1DContainer _current_view_edges_set; static I1DContainer _current_chains_set; static I1DContainer *_current_set; static StrokesContainer _current_strokes_set; #ifdef WITH_CXX_GUARDEDALLOC MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Operators") #endif }; } /* namespace Freestyle */ #endif // __FREESTYLE_OPERATORS_H__