647a3a530c65a834063a829af6803130ccfee6b1
[blender.git] / source / blender / freestyle / intern / view_map / Functions0D.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * ***** END GPL LICENSE BLOCK *****
19  */
20
21 #ifndef __FREESTYLE_FUNCTIONS_0D_H__
22 #define __FREESTYLE_FUNCTIONS_0D_H__
23
24 /** \file blender/freestyle/intern/view_map/Functions0D.h
25  *  \ingroup freestyle
26  *  \brief Functions taking 0D input
27  *  \author Stephane Grabli
28  *  \author Emmanuel Turquin
29  *  \date 01/07/2003
30  */
31
32 #include <set>
33 #include <vector>
34
35 #include "Interface0D.h"
36
37 #include "../geometry/Geom.h"
38
39 #include "../python/Director.h"
40
41 #include "../scene_graph/FrsMaterial.h"
42
43 #include "../system/Exception.h"
44 #include "../system/Precision.h"
45
46 #ifdef WITH_CXX_GUARDEDALLOC
47 #include "MEM_guardedalloc.h"
48 #endif
49
50 namespace Freestyle {
51
52 class FEdge;
53 class ViewEdge;
54 class SShape;
55
56 using namespace Geometry;
57
58 //
59 // UnaryFunction0D (base class for functions in 0D)
60 //
61 ///////////////////////////////////////////////////////////
62
63 /*! Base class for Unary Functions (functors) working on Interface0DIterator.
64  *  A unary function will be used by calling its operator() on an Interface0DIterator.
65  *  \attention In the scripting language, there exists several prototypes depending on the returned value type.
66  *  For example, you would inherit from a UnaryFunction0DDouble if you wish to define a function that returns a double.
67  *  The different existing prototypes are:
68  *    - UnaryFunction0DDouble
69  *    - UnaryFunction0DEdgeNature
70  *    - UnaryFunction0DFloat
71  *    - UnaryFunction0DId
72  *    - UnaryFunction0DMaterial
73  *    - UnaryFunction0DUnsigned
74  *    - UnaryFunction0DVec2f
75  *    - UnaryFunction0DVec3f
76  *    - UnaryFunction0DVectorViewShape
77  *    - UnaryFunction0DViewShape
78  *    - UnaryFunction0DVoid
79  */
80 template <class T>
81 class UnaryFunction0D
82 {
83 public:
84         T result;
85         void *py_uf0D;
86
87         /*! The type of the value returned by the functor. */
88         typedef T ReturnedValueType;
89
90         /*! Default constructor. */
91         UnaryFunction0D()
92         {
93                 py_uf0D = NULL;
94         }
95
96         /*! Destructor; */
97         virtual ~UnaryFunction0D() {}
98
99         /*! Returns the string "UnaryFunction0D" */
100         virtual string getName() const
101         {
102                 return "UnaryFunction0D";
103         }
104
105         /*! The operator ().
106          *  \param iter
107          *    An Interface0DIterator pointing onto the point at which we wish to evaluate the function.
108          *  \return the result of the function of type T.
109          */
110         /* FIXME move the implementation to Functions0D.cpp */
111         virtual int operator()(Interface0DIterator& iter)
112         {
113                 return Director_BPy_UnaryFunction0D___call__(this, py_uf0D, iter);
114         }
115
116 #ifdef WITH_CXX_GUARDEDALLOC
117         MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:UnaryFunction0D")
118 #endif
119 };
120
121 #ifdef SWIG
122 %feature("director")  UnaryFunction0D<void>;
123 %feature("director")  UnaryFunction0D<unsigned>;
124 %feature("director")  UnaryFunction0D<float>;
125 %feature("director")  UnaryFunction0D<double>;
126 %feature("director")  UnaryFunction0D<Vec2f>;
127 %feature("director")  UnaryFunction0D<Vec3f>;
128 %feature("director")  UnaryFunction0D<Id>;
129
130 %template(UnaryFunction0DVoid)             UnaryFunction0D<void>;
131 %template(UnaryFunction0DUnsigned)         UnaryFunction0D<unsigned>;
132 %template(UnaryFunction0DFloat)            UnaryFunction0D<float>;
133 %template(UnaryFunction0DDouble)           UnaryFunction0D<double>;
134 %template(UnaryFunction0DVec2f)            UnaryFunction0D<Vec2f>;
135 %template(UnaryFunction0DVec3f)            UnaryFunction0D<Vec3f>;
136 %template(UnaryFunction0DId)               UnaryFunction0D<Id>;
137 %template(UnaryFunction0DViewShape)        UnaryFunction0D<ViewShape*>;
138 %template(UnaryFunction0DVectorViewShape)  UnaryFunction0D<std::vector<ViewShape*> >;
139 #endif // SWIG
140
141 //
142 // Functions definitions
143 //
144 ///////////////////////////////////////////////////////////
145 class ViewShape;
146
147 namespace Functions0D {
148
149 // GetXF0D
150 /*! Returns the X 3D coordinate of an Interface0D. */
151 class GetXF0D : public UnaryFunction0D<double>
152 {
153 public:
154         /*! Returns the string "GetXF0D" */
155         string getName() const
156         {
157                 return "GetXF0D";
158         }
159
160         /*! the () operator. */
161         int operator()(Interface0DIterator& iter)
162         {
163                 result = iter->getX();
164                 return 0;
165         }
166 };
167
168 // GetYF0D
169 /*! Returns the Y 3D coordinate of an Interface0D. */
170 class GetYF0D : public UnaryFunction0D<double>
171 {
172 public:
173         /*! Returns the string "GetYF0D" */
174         string getName() const
175         {
176                 return "GetYF0D";
177         }
178
179         /*! the () operator. */
180         int operator()(Interface0DIterator& iter)
181         {
182                 result = iter->getY();
183                 return 0;
184         }
185 };
186
187 // GetZF0D
188 /*! Returns the Z 3D coordinate of an Interface0D. */
189 class GetZF0D : public UnaryFunction0D<double>
190 {
191 public:
192         /*! Returns the string "GetZF0D" */
193         string getName() const
194         {
195                 return "GetZF0D";
196         }
197
198         /*! the () operator. */
199         int operator()(Interface0DIterator& iter)
200         {
201                 result = iter->getZ();
202                 return 0;
203         }
204 };
205
206 // GetProjectedXF0D
207 /*! Returns the X 3D projected coordinate of an Interface0D. */
208 class GetProjectedXF0D : public UnaryFunction0D<double>
209 {
210 public:
211         /*! Returns the string "GetProjectedXF0D" */
212         string getName() const
213         {
214                 return "GetProjectedXF0D";
215         }
216
217         /*! the () operator. */
218         int operator()(Interface0DIterator& iter)
219         {
220                 result = iter->getProjectedX();
221                 return 0;
222         }
223 };
224
225 // GetProjectedYF0D
226 /*! Returns the Y projected 3D coordinate of an Interface0D. */
227 class GetProjectedYF0D : public UnaryFunction0D<double>
228 {
229 public:
230         /*! Returns the string "GetProjectedYF0D" */
231         string getName() const
232         {
233                 return "GetProjectedYF0D";
234         }
235
236         /*! the () operator. */
237         int operator()(Interface0DIterator& iter)
238         {
239                 result = iter->getProjectedY();
240                 return 0;
241         }
242 };
243
244 // GetProjectedZF0D
245 /*! Returns the Z projected 3D coordinate of an Interface0D. */
246 class GetProjectedZF0D : public UnaryFunction0D<double>
247 {
248 public:
249         /*! Returns the string "GetProjectedZF0D" */
250         string getName() const
251         {
252                 return "GetProjectedZF0D";
253         }
254
255         /*! the () operator. */
256         int operator()(Interface0DIterator& iter)
257         {
258                 result = iter->getProjectedZ();
259                 return 0;
260         }
261 };
262
263 // GetCurvilinearAbscissaF0D
264 /*! Returns the curvilinear abscissa of an Interface0D in the context of its 1D element. */
265 class GetCurvilinearAbscissaF0D : public UnaryFunction0D<float>
266 {
267 public:
268         /*! Returns the string "GetCurvilinearAbscissaF0D" */
269         string getName() const
270         {
271                 return "GetCurvilinearAbscissaF0D";
272         }
273
274         /*! the () operator. */
275         int operator()(Interface0DIterator& iter)
276         {
277                 result = iter.t();
278                 return 0;
279         }
280 };
281
282 // GetParameterF0D
283 /*! Returns the parameter of an Interface0D in the context of its 1D element. */
284 class GetParameterF0D : public UnaryFunction0D<float>
285 {
286 public:
287         /*! Returns the string "GetCurvilinearAbscissaF0D" */
288         string getName() const
289         {
290                 return "GetParameterF0D";
291         }
292
293         /*! the () operator. */
294         int operator()(Interface0DIterator& iter)
295         {
296                 result = iter.u();
297                 return 0;
298         }
299 };
300
301 // VertexOrientation2DF0D
302 /*! Returns a Vec2r giving the 2D oriented tangent to the 1D element to which the Interface0DIterator& belongs to and
303  *  evaluated at the Interface0D pointed by this Interface0DIterator&.
304  */
305 class VertexOrientation2DF0D : public UnaryFunction0D<Vec2f>
306 {
307 public:
308         /*! Returns the string "VertexOrientation2DF0D" */
309         string getName() const
310         {
311                 return "VertexOrientation2DF0D";
312         }
313
314         /*! the () operator. */
315         int operator()(Interface0DIterator& iter);
316 };
317
318 // VertexOrientation3DF0D
319 /*! Returns a Vec3r giving the 3D oriented tangent to the 1D element to which the Interface0DIterator& belongs to and
320  *  evaluated at the Interface0D pointed by this Interface0DIterator&.
321  */
322 class VertexOrientation3DF0D : public UnaryFunction0D<Vec3f>
323 {
324 public:
325         /*! Returns the string "VertexOrientation3DF0D" */
326         string getName() const
327         {
328                 return "VertexOrientation3DF0D";
329         }
330
331         /*! the () operator. */
332         int operator()(Interface0DIterator& iter);
333 };
334
335 // Curvature2DAngleF0D
336 /*! Returns a real giving the 2D curvature (as an angle) of the 1D element to which the Interface0DIterator&
337  *  belongs to and evaluated at the Interface0D pointed by this Interface0DIterator&.
338  */
339 class Curvature2DAngleF0D : public UnaryFunction0D<double>
340 {
341 public:
342         /*! Returns the string "Curvature2DAngleF0D" */
343         string getName() const
344         {
345                 return "Curvature2DAngleF0D";
346         }
347
348         /*! the () operator. */
349         int operator()(Interface0DIterator& iter);
350 };
351
352 // ZDiscontinuity
353 /*! Returns a real giving the distance between and Interface0D and the shape that lies behind (occludee).
354  *  This distance is evaluated in the camera space and normalized between 0 and 1. Therefore, if no object is occluded
355  *  by the shape to which the Interface0D belongs to, 1 is returned.
356  */
357 class ZDiscontinuityF0D : public UnaryFunction0D<double>
358 {
359 public:
360         /*! Returns the string "ZDiscontinuityF0D" */
361         string getName() const
362         {
363                 return "ZDiscontinuityF0D";
364         }
365
366         /*! the () operator. */
367         int operator()(Interface0DIterator& iter);
368 };
369
370 // Normal2DF0D
371 /*! Returns a Vec2f giving the normalized 2D normal to the 1D element to which the Interface0DIterator& belongs to and
372  *  evaluated at the Interface0D pointed by this Interface0DIterator&.
373  */
374 class Normal2DF0D : public UnaryFunction0D<Vec2f>
375 {
376 public:
377         /*! Returns the string "Normal2DF0D" */
378         string getName() const
379         {
380                 return "Normal2DF0D";
381         }
382
383         /*! the () operator. */
384         int operator()(Interface0DIterator& iter);
385 };
386
387 // MaterialF0D
388 /*! Returns the material of the object evaluated at the Interface0D.
389  *  This evaluation can be ambiguous (in the case of a TVertex for example.
390  *  This functor tries to remove this ambiguity using the context offered by the 1D element to which the
391  *  Interface0DIterator& belongs to and by arbitrary choosing the material of the face that lies on its left when
392  *  following the 1D element if there are two different materials on each side of the point.
393  *  However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
394  *  should implement its own getMaterial functor.
395  */
396 class MaterialF0D : public UnaryFunction0D<FrsMaterial>
397 {
398 public:
399         /*! Returns the string "MaterialF0D" */
400         string getName() const
401         {
402                 return "MaterialF0D";
403         }
404
405         /*! the () operator. */
406         int operator()(Interface0DIterator& iter);
407 };
408
409 // ShapeIdF0D
410 /*! Returns the Id of the Shape the Interface0D belongs to.
411  *  This evaluation can be ambiguous (in the case of a TVertex for example).
412  *  This functor tries to remove this ambiguity using the context offered by the 1D element to which the
413  *  Interface0DIterator& belongs to.
414  *  However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
415  *  should implement its own getShapeIdF0D functor.
416  */
417 class ShapeIdF0D : public UnaryFunction0D<Id>
418 {
419 public:
420         /*! Returns the string "ShapeIdF0D" */
421         string getName() const
422         {
423                 return "ShapeIdF0D";
424         }
425
426         /*! the () operator. */
427         int operator()(Interface0DIterator& iter);
428 };
429
430 // QiF0D
431 /*! Returns the quantitative invisibility of this Interface0D.
432 *  This evaluation can be ambiguous (in the case of a TVertex for example).
433 *  This functor tries to remove this ambiguity using the context offered by the 1D element to which the
434 *  Interface0DIterator& belongs to.
435 *  However, there still can be problematic cases, and the user willing to deal with this cases in a specific way
436 *  should implement its own getQIF0D functor.
437 */
438 class QuantitativeInvisibilityF0D : public UnaryFunction0D<unsigned int>
439 {
440 public:
441         /*! Returns the string "QuantitativeInvisibilityF0D" */
442         string getName() const
443         {
444                 return "QuantitativeInvisibilityF0D";
445         }
446
447         /*! the () operator. */
448         int operator()(Interface0DIterator& iter);
449 };
450
451 // CurveNatureF0D
452 /*! Returns the Nature::EdgeNature of the 1D element the Interface0DIterator& belongs to. */
453 class CurveNatureF0D : public UnaryFunction0D<Nature::EdgeNature>
454 {
455 public:
456         /*! Returns the string "QuantitativeInvisibilityF0D" */
457         string getName() const
458         {
459                 return "CurveNatureF0D";
460         }
461
462         /*! the () operator. */
463         int operator()(Interface0DIterator& iter);
464 };
465
466 // GetShapeF0D
467 /*! Returns the ViewShape* containing the Interface0D */
468 class GetShapeF0D : public UnaryFunction0D< ViewShape*>
469 {
470 public:
471         /*! Returns the string "GetShapeF0D" */
472         string getName() const
473         {
474                 return "GetShapeF0D";
475         }
476
477         /*! the () operator. */
478         int operator()(Interface0DIterator& iter);
479 };
480
481 // GetOccludersF0D
482 /*! Returns a vector containing the ViewShape* occluding the Interface0D */
483 class GetOccludersF0D : public UnaryFunction0D< std::vector<ViewShape*> >
484 {
485 public:
486         /*! Returns the string "GetOccludersF0D" */
487         string getName() const
488         {
489                 return "GetOccludersF0D";
490         }
491
492         /*! the () operator. */
493         int operator()(Interface0DIterator& iter);
494 };
495
496 // GetOccludeeF0D
497 /*! Returns the ViewShape* "occluded" by the Interface0D */
498 class GetOccludeeF0D: public UnaryFunction0D< ViewShape*>
499 {
500 public:
501         /*! Returns the string "GetOccludeeF0D" */
502         string getName() const
503         {
504                 return "GetOccludeeF0D";
505         }
506
507         /*! the () operator. */
508         int operator()(Interface0DIterator& iter);
509 };
510
511
512 /////////////////////////// Internal ////////////////////////////
513
514 // getFEdge
515 FEdge *getFEdge(Interface0D& it1, Interface0D& it2);
516
517 // getFEdges
518 void getFEdges(Interface0DIterator& it, FEdge *&fe1, FEdge *&fe2);
519
520 // getViewEdges
521 void getViewEdges(Interface0DIterator& it, ViewEdge *&ve1, ViewEdge *&ve2);
522
523 // getShapeF0D
524 ViewShape *getShapeF0D(Interface0DIterator& it);
525
526 // getOccludersF0D
527 void getOccludersF0D(Interface0DIterator& it, std::set<ViewShape*>& oOccluders);
528
529 // getOccludeeF0D
530 ViewShape *getOccludeeF0D(Interface0DIterator& it);
531
532 } // end of namespace Functions0D
533
534 } /* namespace Freestyle */
535
536 #endif // __FREESTYLE_FUNCTIONS_0D_H__