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