1 /* 2 * This program is free software; you can redistribute it and/or 3 * modify it under the terms of the GNU General Public License 4 * as published by the Free Software Foundation; either version 2 5 * of the License, or (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software Foundation, 14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 15 */ 16 17 #pragma once 18 19 /** \file 20 * \ingroup freestyle 21 * \brief Class gathering stroke creation algorithms 22 */ 23 24 #include <iostream> 25 #include <vector> 26 27 #include "Chain.h" 28 #include "ChainingIterators.h" 29 #include "Predicates0D.h" 30 #include "Predicates1D.h" 31 #include "StrokeShader.h" 32 33 #include "../system/TimeStamp.h" 34 35 #include "../view_map/Interface1D.h" 36 #include "../view_map/ViewMap.h" 37 38 #ifdef WITH_CXX_GUARDEDALLOC 39 # include "MEM_guardedalloc.h" 40 #endif 41 42 namespace Freestyle { 43 44 /*! Class defining the operators used in a style module. 45 * There are 4 classes of operators: Selection, Chaining, Splitting and Creating. 46 * All these operators are user controlled in the scripting language through Functors, Predicates 47 * and Shaders that are taken as arguments. 48 */ 49 class Operators { 50 51 public: 52 typedef vector<Interface1D *> I1DContainer; 53 typedef vector<Stroke *> StrokesContainer; 54 55 // 56 // Operators 57 // 58 //////////////////////////////////////////////// 59 60 /*! Selects the ViewEdges of the ViewMap verifying a specified condition. 61 * \param pred: The predicate expressing this condition 62 */ 63 static int select(UnaryPredicate1D &pred); 64 65 /*! Builds a set of chains from the current set of ViewEdges. 66 * Each ViewEdge of the current list starts a new chain. 67 * The chaining operator then iterates over the ViewEdges 68 * of the ViewMap using the user specified iterator. 69 * This operator only iterates using the increment operator and is therefore unidirectional. 70 * \param it: 71 * The iterator on the ViewEdges of the ViewMap. It contains the chaining rule. 72 * \param pred: 73 * The predicate on the ViewEdge that expresses the stopping condition. 74 * \param modifier: 75 * A function that takes a ViewEdge as argument and that is used to modify the 76 * processed ViewEdge state (the timestamp incrementation is a typical illustration of 77 * such a modifier) 78 */ 79 static int chain(ViewEdgeInternal::ViewEdgeIterator &it, 80 UnaryPredicate1D &pred, 81 UnaryFunction1D_void &modifier); 82 83 /*! Builds a set of chains from the current set of ViewEdges. 84 * Each ViewEdge of the current list starts a new chain. The chaining operator then iterates 85 * over the ViewEdges 86 * of the ViewMap using the user specified iterator. 87 * This operator only iterates using the increment operator and is therefore unidirectional. 88 * This chaining operator is different from the previous one because it doesn't take any 89 * modifier as argument. Indeed, the time stamp (insuring that a ViewEdge is processed one time) 90 * is automatically managed in this case. 91 * \param it: 92 * The iterator on the ViewEdges of the ViewMap. It contains the chaining rule. 93 * \param pred: 94 * The predicate on the ViewEdge that expresses the stopping condition. 95 */ 96 static int chain(ViewEdgeInternal::ViewEdgeIterator &it, UnaryPredicate1D &pred); 97 98 /*! Builds a set of chains from the current set of ViewEdges. 99 * Each ViewEdge of the current list potentially starts a new chain. The chaining operator then 100 * iterates over the ViewEdges of the ViewMap using the user specified iterator. 101 * This operator iterates both using the increment and decrement operators and is therefore 102 * bidirectional. This operator works with a ChainingIterator which contains the chaining rules. 103 * It is this last one which can be told to chain only edges that belong to the selection or not 104 * to process twice a ViewEdge during the chaining. Each time a ViewEdge is added to a chain, 105 * its chaining time stamp is incremented. This allows you to keep track of the number of chains 106 * to which a ViewEdge belongs to. 107 * \param it: 108 * The ChainingIterator on the ViewEdges of the ViewMap. It contains the chaining rule. 109 * \param pred: 110 * The predicate on the ViewEdge that expresses the stopping condition. 111 */ 112 static int bidirectionalChain(ChainingIterator &it, UnaryPredicate1D &pred); 113 114 /*! The only difference with the above bidirectional chaining algorithm is that we don't need to 115 * pass a stopping criterion. This might be desirable when the stopping criterion is already 116 * contained in the iterator definition. Builds a set of chains from the current set of 117 * ViewEdges. Each ViewEdge of the current list potentially starts a new chain. The chaining 118 * operator then iterates over the ViewEdges of the ViewMap using the user specified iterator. 119 * This operator iterates both using the increment and decrement operators and is therefore 120 * bidirectional. This operator works with a ChainingIterator which contains the chaining rules. 121 * It is this last one which can be told to chain only edges that belong to the selection or not 122 * to process twice a ViewEdge during the chaining. Each time a ViewEdge is added to a chain, 123 * its chaining time stamp is incremented. This allows you to keep track of the number of chains 124 * to which a ViewEdge belongs to. 125 * \param it: 126 * The ChainingIterator on the ViewEdges of the ViewMap. It contains the chaining rule. 127 */ 128 static int bidirectionalChain(ChainingIterator &it); 129 130 /*! Splits each chain of the current set of chains in a sequential way. 131 * The points of each chain are processed (with a specified sampling) sequentially. 132 * Each time a user specified starting condition is verified, a new chain begins and ends as 133 * soon as a user-defined stopping predicate is verified. 134 * This allows chains overlapping rather than chains partitioning. 135 * The first point of the initial chain is the first point of one of the resulting chains. 136 * The splitting ends when no more chain can start. 137 * \param startingPred: 138 * The predicate on a point that expresses the starting condition 139 * \param stoppingPred: 140 * The predicate on a point that expresses the stopping condition 141 * \param sampling: 142 * The resolution used to sample the chain for the predicates evaluation. 143 * (The chain is not actually resampled, a virtual point only progresses along the 144 * curve using this resolution) 145 */ 146 static int sequentialSplit(UnaryPredicate0D &startingPred, 147 UnaryPredicate0D &stoppingPred, 148 float sampling = 0.0f); 149 150 /*! Splits each chain of the current set of chains in a sequential way. 151 * The points of each chain are processed (with a specified sampling) sequentially and each time 152 * a user specified condition is verified, the chain is split into two chains. 153 * The resulting set of chains is a partition of the initial chain 154 * \param pred: 155 * The predicate on a point that expresses the splitting condition 156 * \param sampling: 157 * The resolution used to sample the chain for the predicate evaluation. 158 * (The chain is not actually resampled, a virtual point only progresses along the 159 * curve using this resolution) 160 */ 161 static int sequentialSplit(UnaryPredicate0D &pred, float sampling = 0.0f); 162 163 /*! Splits the current set of chains in a recursive way. 164 * We process the points of each chain (with a specified sampling) to find the point 165 * minimizing a specified function. The chain is split in two at this point and the two new 166 * chains are processed in the same way. The recursivity level is controlled through a 167 * predicate 1D that expresses a stopping condition on the chain that is about to be processed. 168 * \param func: 169 * The Unary Function evaluated at each point of the chain. 170 * The splitting point is the point minimizing this function 171 * \param pred: 172 * The Unary Predicate ex pressing the recursivity stopping condition. 173 * This predicate is evaluated for each curve before it actually gets split. 174 * If pred(chain) is true, the curve won't be split anymore. 175 * \param sampling: 176 * The resolution used to sample the chain for the predicates evaluation. (The chain 177 * is not actually resampled, a virtual point only progresses along the curve using 178 * this resolution) 179 */ 180 static int recursiveSplit(UnaryFunction0D<double> &func, 181 UnaryPredicate1D &pred, 182 float sampling = 0); 183 184 /*! Splits the current set of chains in a recursive way. 185 * We process the points of each chain (with a specified sampling) to find the point minimizing 186 * a specified function. The chain is split in two at this point and the two new chains are 187 * processed in the same way. The user can specify a 0D predicate to make a first selection on 188 * the points that can potentially be split. A point that doesn't verify the 0D predicate 189 * won't be candidate in realizing the min. The recursivity level is controlled through a 190 * predicate 1D that expresses a stopping condition on the chain that is about to be processed. 191 * \param func: 192 * The Unary Function evaluated at each point of the chain. 193 * The splitting point is the point minimizing this function 194 * \param pred0d: 195 * The Unary Predicate 0D used to select the candidate points where the split can 196 * occur. For example, it is very likely that would rather have your chain splitting 197 * around its middle point than around one of its extremities. A 0D predicate working 198 * on the curvilinear abscissa allows to add this kind of constraints. 199 * \param pred: 200 * The Unary Predicate ex pressing the recursivity stopping condition. 201 * This predicate is evaluated for each curve before it actually gets split. 202 * If pred(chain) is true, the curve won't be split anymore. 203 * \param sampling: 204 * The resolution used to sample the chain for the predicates evaluation. (The chain 205 * is not actually resampled, a virtual point only progresses along the curve using 206 * this resolution) 207 */ 208 static int recursiveSplit(UnaryFunction0D<double> &func, 209 UnaryPredicate0D &pred0d, 210 UnaryPredicate1D &pred, 211 float sampling = 0.0f); 212 213 /*! Sorts the current set of chains (or viewedges) 214 * according to the comparison predicate given as argument. 215 * \param pred: 216 * The binary predicate used for the comparison 217 */ 218 static int sort(BinaryPredicate1D &pred); 219 220 /*! Creates and shades the strokes from the current set of chains. 221 * A predicate can be specified to make a selection pass on the chains. 222 * \param pred: 223 * The predicate that a chain must verify in order to be transform as a stroke 224 * \param shaders: 225 * The list of shaders used to shade the strokes 226 */ 227 static int create(UnaryPredicate1D &pred, vector<StrokeShader *> shaders); 228 229 // 230 // Data access 231 // 232 //////////////////////////////////////////////// 233 getViewEdgeFromIndex(unsigned i)234 static ViewEdge *getViewEdgeFromIndex(unsigned i) 235 { 236 return dynamic_cast<ViewEdge *>(_current_view_edges_set[i]); 237 } 238 getChainFromIndex(unsigned i)239 static Chain *getChainFromIndex(unsigned i) 240 { 241 return dynamic_cast<Chain *>(_current_chains_set[i]); 242 } 243 getStrokeFromIndex(unsigned i)244 static Stroke *getStrokeFromIndex(unsigned i) 245 { 246 return _current_strokes_set[i]; 247 } 248 getViewEdgesSize()249 static unsigned getViewEdgesSize() 250 { 251 return _current_view_edges_set.size(); 252 } 253 getChainsSize()254 static unsigned getChainsSize() 255 { 256 return _current_chains_set.size(); 257 } 258 getStrokesSize()259 static unsigned getStrokesSize() 260 { 261 return _current_strokes_set.size(); 262 } 263 264 // 265 // Not exported in Python 266 // 267 ////////////////////////////////////////////////// 268 getStrokesSet()269 static StrokesContainer *getStrokesSet() 270 { 271 return &_current_strokes_set; 272 } 273 274 static void reset(bool removeStrokes = true); 275 276 private: Operators()277 Operators() 278 { 279 } 280 281 static I1DContainer _current_view_edges_set; 282 static I1DContainer _current_chains_set; 283 static I1DContainer *_current_set; 284 static StrokesContainer _current_strokes_set; 285 286 #ifdef WITH_CXX_GUARDEDALLOC 287 MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Operators") 288 #endif 289 }; 290 291 } /* namespace Freestyle */ 292