Cleanup: misc spelling fixes
[blender.git] / source / blender / freestyle / intern / stroke / Stroke.h
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 #ifndef __FREESTYLE_STROKE_H__
18 #define __FREESTYLE_STROKE_H__
19
20 /** \file
21  * \ingroup freestyle
22  * \brief Classes to define a stroke
23  */
24
25 #include <map>
26 #include <vector>
27
28 #include "Curve.h"
29
30 #include "../view_map/Interface1D.h"
31 #include "../view_map/Silhouette.h"
32
33 #include "../system/FreestyleConfig.h"
34 #include "../system/StringUtils.h"
35
36 #ifdef WITH_CXX_GUARDEDALLOC
37 #  include "MEM_guardedalloc.h"
38 #endif
39
40 extern "C" {
41 struct MTex;
42 struct bNodeTree;
43 }
44
45 #ifndef MAX_MTEX
46 #  define MAX_MTEX 18
47 #endif
48
49 namespace Freestyle {
50
51 //
52 //  StrokeAttribute
53 //
54 ////////////////////////////////////////////////////////
55
56 /*! Class to define an attribute associated to a Stroke Vertex.
57  *  This attribute stores the color, alpha and thickness values for a Stroke Vertex.
58  */
59 class StrokeAttribute {
60  public:
61   /*! default constructor */
62   StrokeAttribute();
63
64   /*! Copy constructor */
65   StrokeAttribute(const StrokeAttribute &iBrother);
66
67   /*! Builds a stroke vertex attribute from a set of parameters.
68    *    \param iRColor:
69    *      The Red Component value.
70    *    \param iGColor:
71    *      The Green Component value.
72    *    \param iBColor:
73    *      The Blue Component value.
74    *    \param iAlpha:
75    *      The transparency value
76    *    \param iRThickness:
77    *      The thickness of the stroke on the right
78    *    \param iLThickness:
79    *      The Thickness of the stroke on the left
80    */
81   StrokeAttribute(float iRColor,
82                   float iGColor,
83                   float iBColor,
84                   float iAlpha,
85                   float iRThickness,
86                   float iLThickness);
87
88   /*! Interpolation constructor.
89    *  Builds a StrokeAttribute from two StrokeAttributes and an interpolation parameter.
90    *  \param a1:
91    *    The first Attribute.
92    *  \param a2:
93    *    The second parameter.
94    *  \param t:
95    *    The interpolation parameter.
96    */
97   StrokeAttribute(const StrokeAttribute &a1, const StrokeAttribute &a2, float t);
98
99   /*! destructor */
100   virtual ~StrokeAttribute();
101
102   /* operators */
103   /*! operator = */
104   StrokeAttribute &operator=(const StrokeAttribute &iBrother);
105
106   /* accessors */
107   /*! Returns the attribute's color.
108    *  \return The array of 3 floats containing the R,G,B values of the attribute's color.
109    */
110   inline const float *getColor() const
111   {
112     return _color;
113   }
114
115   /*! Returns the R color component. */
116   inline const float getColorR() const
117   {
118     return _color[0];
119   }
120
121   /*! Returns the G color component. */
122   inline const float getColorG() const
123   {
124     return _color[1];
125   }
126
127   /*! Returns the B color component. */
128   inline const float getColorB() const
129   {
130     return _color[2];
131   }
132
133   /*! Returns the RGB color components. */
134   inline Vec3f getColorRGB() const
135   {
136     return Vec3f(_color[0], _color[1], _color[2]);
137   }
138
139   /*! Returns the alpha color component. */
140   inline float getAlpha() const
141   {
142     return _alpha;
143   }
144
145   /*! Returns the attribute's thickness.
146    *  \return an array of 2 floats. the first value is the thickness on the right of the vertex
147    * when following the stroke, the second one is the thickness on the left.
148    */
149   inline const float *getThickness() const
150   {
151     return _thickness;
152   }
153
154   /*! Returns the thickness on the right of the vertex when following the stroke. */
155   inline const float getThicknessR() const
156   {
157     return _thickness[0];
158   }
159
160   /*! Returns the thickness on the left of the vertex when following the stroke. */
161   inline const float getThicknessL() const
162   {
163     return _thickness[1];
164   }
165
166   /*! Returns the thickness on the right and on the left of the vertex when following the stroke.
167    */
168   inline Vec2f getThicknessRL() const
169   {
170     return Vec2f(_thickness[0], _thickness[1]);
171   }
172
173   /*! Returns true if the strokevertex is visible, false otherwise */
174   inline bool isVisible() const
175   {
176     return _visible;
177   }
178
179   /*! Returns an attribute of type real
180    *  \param iName:
181    *    The name of the attribute
182    */
183   float getAttributeReal(const char *iName) const;
184
185   /*! Returns an attribute of type Vec2f
186    *  \param iName:
187    *    The name of the attribute
188    */
189   Vec2f getAttributeVec2f(const char *iName) const;
190
191   /*! Returns an attribute of type Vec3f
192    *  \param iName:
193    *    The name of the attribute
194    */
195   Vec3f getAttributeVec3f(const char *iName) const;
196
197   /*! Checks whether the attribute iName is available */
198   bool isAttributeAvailableReal(const char *iName) const;
199
200   /*! Checks whether the attribute iName is available */
201   bool isAttributeAvailableVec2f(const char *iName) const;
202
203   /*! Checks whether the attribute iName is available */
204   bool isAttributeAvailableVec3f(const char *iName) const;
205
206   /* modifiers */
207   /*! sets the attribute's color.
208    *    \param r:
209    *      The new R value.
210    *    \param g:
211    *      The new G value.
212    *    \param b:
213    *      The new B value.
214    */
215   inline void setColor(float r, float g, float b)
216   {
217     _color[0] = r;
218     _color[1] = g;
219     _color[2] = b;
220   }
221
222   /*! sets the attribute's color.
223    *    \param iRGB:
224    *      The new RGB values.
225    */
226   inline void setColor(const Vec3f &iRGB)
227   {
228     _color[0] = iRGB[0];
229     _color[1] = iRGB[1];
230     _color[2] = iRGB[2];
231   }
232
233   /*! sets the attribute's alpha value.
234    *  \param alpha:
235    *    The new alpha value.
236    */
237   inline void setAlpha(float alpha)
238   {
239     _alpha = alpha;
240   }
241
242   /*! sets the attribute's thickness.
243    *  \param tr:
244    *    The thickness on the right of the vertex when following the stroke.
245    *  \param tl:
246    *    The thickness on the left of the vertex when following the stroke.
247    */
248   inline void setThickness(float tr, float tl)
249   {
250     _thickness[0] = tr;
251     _thickness[1] = tl;
252   }
253
254   /*! sets the attribute's thickness.
255    *  \param tRL:
256    *    The thickness on the right and on the left of the vertex when following the stroke.
257    */
258   inline void setThickness(const Vec2f &tRL)
259   {
260     _thickness[0] = tRL[0];
261     _thickness[1] = tRL[1];
262   }
263
264   /*! sets the visible flag. True means visible. */
265   inline void setVisible(bool iVisible)
266   {
267     _visible = iVisible;
268   }
269
270   /*! Adds a user defined attribute of type real
271    *  If there is no attribute of name iName, it is added.
272    *  Otherwise, the new value replaces the old one.
273    *  \param iName:
274    *    The name of the attribute
275    *  \param att:
276    *    The attribute's value
277    */
278   void setAttributeReal(const char *iName, float att);
279
280   /*! Adds a user defined attribute of type Vec2f
281    *  If there is no attribute of name iName, it is added.
282    *  Otherwise, the new value replaces the old one.
283    *  \param iName:
284    *    The name of the attribute
285    *  \param att:
286    *    The attribute's value
287    */
288   void setAttributeVec2f(const char *iName, const Vec2f &att);
289
290   /*! Adds a user defined attribute of type Vec3f
291    *  If there is no attribute of name iName, it is added.
292    *  Otherwise, the new value replaces the old one.
293    *  \param iName:
294    *    The name of the attribute
295    *  \param att:
296    *    The attribute's value
297    */
298   void setAttributeVec3f(const char *iName, const Vec3f &att);
299
300  private:
301   typedef std::map<const char *, float, StringUtils::ltstr> realMap;
302   typedef std::map<const char *, Vec2f, StringUtils::ltstr> Vec2fMap;
303   typedef std::map<const char *, Vec3f, StringUtils::ltstr> Vec3fMap;
304
305   //! the color
306   float _color[3];
307   //! alpha
308   float _alpha;
309   //! the thickness on the right and on the left of the backbone vertex (the stroke is oriented)
310   float _thickness[2];
311   bool _visible;
312   realMap *_userAttributesReal;
313   Vec2fMap *_userAttributesVec2f;
314   Vec3fMap *_userAttributesVec3f;
315
316 #ifdef WITH_CXX_GUARDEDALLOC
317   MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:StrokeAttribute")
318 #endif
319 };
320
321 //
322 //  StrokeVertex
323 //
324 ////////////////////////////////////////////////////////
325
326 /*! Class to define a stroke vertex. */
327 class StrokeVertex : public CurvePoint {
328  public:  // Implementation of Interface0D
329   /*! Returns the string "StrokeVertex" */
330   virtual string getExactTypeName() const
331   {
332     return "StrokeVertex";
333   }
334
335  private:
336   StrokeAttribute _Attribute;  //! The attribute associated to the vertex
337   float _CurvilignAbscissa;    //! the curvilign abscissa
338   float _StrokeLength;         // stroke length
339
340  public:
341   /*! default constructor */
342   StrokeVertex();
343
344   /*! Copy constructor */
345   StrokeVertex(const StrokeVertex &iBrother);
346
347   /*! Builds a stroke vertex from a SVertex */
348   StrokeVertex(SVertex *iSVertex);
349
350   /*! Builds a stroke vertex from a CurvePoint */
351   StrokeVertex(CurvePoint *iPoint);
352
353   /*! Builds Stroke Vertex from 2 stroke vertices and an interpolation parameter*/
354   StrokeVertex(StrokeVertex *iA, StrokeVertex *iB, float t3);
355
356   /*! Builds a stroke from a view vertex and an attribute */
357   StrokeVertex(SVertex *iSVertex, const StrokeAttribute &iAttribute);
358
359   /*! destructor */
360   virtual ~StrokeVertex();
361
362   /* operators */
363   /*! operator = */
364   StrokeVertex &operator=(const StrokeVertex &iBrother);
365
366   /* accessors */
367   /*! Returns the 2D point x coordinate */
368   inline real x() const
369   {
370     return _Point2d[0];
371   }
372
373   /*! Returns the 2D point y coordinate */
374   inline real y() const
375   {
376     return _Point2d[1];
377   }
378
379   /*! Returns the 2D point coordinates as a Vec2r */
380   inline Vec2r getPoint() const
381   {
382     return getPoint2D();
383   }
384
385   /*! Returns the ith 2D point coordinate (i=0 or 1)*/
386   inline real operator[](const int i) const
387   {
388     return _Point2d[i];
389   }
390
391   /*! Returns the StrokeAttribute for this StrokeVertex */
392   inline const StrokeAttribute &attribute() const
393   {
394     return _Attribute;
395   }
396
397   /*! Returns a non-const reference to the StrokeAttribute of this StrokeVertex */
398   inline StrokeAttribute &attribute()
399   {
400     return _Attribute;
401   }
402
403   /*! Returns the curvilinear abscissa */
404   inline float curvilinearAbscissa() const
405   {
406     return _CurvilignAbscissa;
407   }
408
409   /*! Returns the length of the Stroke to which this StrokeVertex belongs */
410   inline float strokeLength() const
411   {
412     return _StrokeLength;
413   }
414
415   /*! Returns the curvilinear abscissa of this StrokeVertex in the Stroke */
416   inline float u() const
417   {
418     return _CurvilignAbscissa / _StrokeLength;
419   }
420
421   /* modifiers */
422   /*! sets the 2D x value */
423   inline void setX(real x)
424   {
425     _Point2d[0] = x;
426   }
427
428   /*! sets the 2D y value */
429   inline void setY(real y)
430   {
431     _Point2d[1] = y;
432   }
433
434   /*! sets the 2D x and y values */
435   inline void setPoint(real x, real y)
436   {
437     _Point2d[0] = x;
438     _Point2d[1] = y;
439   }
440
441   /*! sets the 2D x and y values */
442   inline void setPoint(const Vec2r &p)
443   {
444     _Point2d[0] = p[0];
445     _Point2d[1] = p[1];
446   }
447
448   /*! Returns a reference to the ith 2D point coordinate (i=0 or 1) */
449   inline real &operator[](const int i)
450   {
451     return _Point2d[i];
452   }
453
454   /*! sets the attribute. */
455   inline void setAttribute(const StrokeAttribute &iAttribute)
456   {
457     _Attribute = iAttribute;
458   }
459
460   /*! sets the curvilinear abscissa of this StrokeVertex in the Stroke */
461   inline void setCurvilinearAbscissa(float iAbscissa)
462   {
463     _CurvilignAbscissa = iAbscissa;
464   }
465
466   /*! sets the Stroke's length (it's only a value stored by the Stroke Vertex, it won't change the
467    * real Stroke's length.)
468    */
469   inline void setStrokeLength(float iLength)
470   {
471     _StrokeLength = iLength;
472   }
473
474   /* interface definition */
475   /* inherited */
476
477 #ifdef WITH_CXX_GUARDEDALLOC
478   MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:StrokeVertex")
479 #endif
480 };
481
482 //
483 //  Stroke
484 //
485 ////////////////////////////////////////////////////////
486
487 class StrokeRenderer;
488 class StrokeRep;
489
490 namespace StrokeInternal {
491
492 class vertex_const_traits;
493 class vertex_nonconst_traits;
494 template<class Traits> class vertex_iterator_base;
495 class StrokeVertexIterator;
496
497 }  // end of namespace StrokeInternal
498
499 /*! Class to define a stroke.
500  *  A stroke is made of a set of 2D vertices (StrokeVertex), regularly spaced out.
501  *  This set of vertices defines the stroke's backbone geometry.
502  *  Each of these stroke vertices defines the stroke's shape and appearance at this vertex
503  * position.
504  */
505 class Stroke : public Interface1D {
506  public:  // Implementation of Interface1D
507   /*! Returns the string "Stroke" */
508   virtual string getExactTypeName() const
509   {
510     return "Stroke";
511   }
512
513   // Data access methods
514
515   /*! Returns the Id of the Stroke */
516   virtual Id getId() const
517   {
518     return _id;
519   }
520
521   /*! The different blending modes available to similate the interaction media-medium. */
522   typedef enum {
523     DRY_MEDIUM,    /*!< To simulate a dry medium such as Pencil or Charcoal.*/
524     HUMID_MEDIUM,  /*!< To simulate ink painting (color subtraction blending).*/
525     OPAQUE_MEDIUM, /*!< To simulate an opaque medium (oil, spray...).*/
526   } MediumType;
527
528  public:
529   typedef std::deque<StrokeVertex *> vertex_container;  // the vertices container
530   typedef std::vector<ViewEdge *> viewedge_container;   // the viewedges container
531   typedef StrokeInternal::vertex_iterator_base<StrokeInternal::vertex_nonconst_traits>
532       vertex_iterator;
533   typedef StrokeInternal::vertex_iterator_base<StrokeInternal::vertex_const_traits>
534       const_vertex_iterator;
535
536  public:
537   // typedef StrokeVertex vertex_type;
538
539  private:
540   vertex_container _Vertices;  //! The stroke's backbone vertices
541   Id _id;
542   float _Length;  // The stroke length
543   viewedge_container _ViewEdges;
544   float _sampling;
545   float _textureStep;
546   // StrokeRenderer *_renderer; // mark implementation OpenGL renderer
547   MediumType _mediumType;
548   unsigned int _textureId;
549   MTex *_mtex[MAX_MTEX];
550   bNodeTree *_nodeTree;
551   bool _tips;
552   StrokeRep *_rep;
553   Vec2r _extremityOrientations[2];  // the orientations of the first and last extermity
554
555  public:
556   /*! default constructor */
557   Stroke();
558
559   /*! copy constructor */
560   Stroke(const Stroke &iBrother);
561
562   /*! Builds a stroke from a set of StrokeVertex.
563    *  This constructor is templated by an iterator type.
564    *  This iterator type must allow the vertices parsing using the ++ operator.
565    *    \param iBegin:
566    *      The iterator pointing to the first vertex.
567    *    \param iEnd:
568    *      The iterator pointing to the end of the vertex list.
569    */
570   template<class InputVertexIterator> Stroke(InputVertexIterator iBegin, InputVertexIterator iEnd);
571
572   /*! Destructor */
573   virtual ~Stroke();
574
575   /* operators */
576   /*! operator = */
577   Stroke &operator=(const Stroke &iBrother);
578
579   /*! Compute the sampling needed to get iNVertices vertices.
580    *  If the specified number of vertices is less than the actual number of vertices, the actual
581    * sampling value is returned. (To remove Vertices, use the RemoveVertex() method of this class).
582    *  \param iNVertices:
583    *    The number of StrokeVertices we eventually want in our Stroke.
584    *  \return the sampling that must be used in the Resample(float) method.
585    *  \see Resample(int)
586    *  \see Resample(float)
587    */
588   float ComputeSampling(int iNVertices);
589
590   /*! Resampling method.
591    *  Resamples the curve so that it eventually has iNPoints. That means it is going to add
592    * iNPoints-vertices_size, if vertices_size is the number of points we already have. If
593    * vertices_size >= iNPoints, no resampling is done. \param iNPoints: The number of vertices we
594    * eventually want in our stroke.
595    */
596   int Resample(int iNPoints);
597
598   /*! Resampling method.
599    *  Resamples the curve with a given sampling.
600    *  If this sampling is < to the actual sampling value, no resampling is done.
601    *  \param iSampling:
602    *    The new sampling value.
603    */
604   int Resample(float iSampling);
605
606   /*! Removes all vertices from the Stroke.
607    */
608   void RemoveAllVertices();
609
610   /*! Removes the stroke vertex iVertex
611    *  from the stroke.
612    *  The length and curvilinear abscissa are updated
613    *  consequently.
614    */
615   void RemoveVertex(StrokeVertex *iVertex);
616
617   /*! Inserts the stroke vertex iVertex in the stroke before next.
618    *  The length, curvilinear abscissa are updated consequently.
619    *  \param iVertex:
620    *    The StrokeVertex to insert in the Stroke.
621    *  \param next:
622    *    A StrokeVertexIterator pointing to the StrokeVeretx before which iVertex must be inserted.
623    */
624   void InsertVertex(StrokeVertex *iVertex, StrokeInternal::StrokeVertexIterator next);
625
626   /*! Updates the 2D length of the Stroke */
627   void UpdateLength();
628
629   /* Render method */
630   void ScaleThickness(float iFactor);
631   void Render(const StrokeRenderer *iRenderer);
632   void RenderBasic(const StrokeRenderer *iRenderer);
633
634   /* Iterator definition */
635
636   /* accessors */
637   /*! Returns the 2D length of the Stroke */
638   inline real getLength2D() const
639   {
640     return _Length;
641   }
642
643   /*! Returns a reference to the time stamp value of the stroke. */
644   /*! Returns the MediumType used for this Stroke. */
645   inline MediumType getMediumType() const
646   {
647     return _mediumType;
648   }
649
650   /*! Returns the id of the texture used to simulate th marks system for this Stroke */
651   inline unsigned int getTextureId()
652   {
653     return _textureId;
654   }
655
656   /*! Returns the spacing of texture coordinates along the stroke length */
657   inline float getTextureStep()
658   {
659     return _textureStep;
660   }
661
662   /*! Returns the texture used at given index to simulate the marks system for this Stroke */
663   inline MTex *getMTex(int idx)
664   {
665     return _mtex[idx];
666   }
667
668   /*! Return the shader node tree to define textures. */
669   inline bNodeTree *getNodeTree()
670   {
671     return _nodeTree;
672   }
673
674   /*! Returns true if this Stroke has textures assigned, false otherwise. */
675   inline bool hasTex() const
676   {
677     return (_mtex[0] != NULL) || _nodeTree;
678   }
679
680   /*! Returns true if this Stroke uses a texture with tips, false otherwise. */
681   inline bool hasTips() const
682   {
683     return _tips;
684   }
685
686   /* these advanced iterators are used only in C++ */
687   inline int vertices_size() const
688   {
689     return _Vertices.size();
690   }
691
692   inline viewedge_container::const_iterator viewedges_begin() const
693   {
694     return _ViewEdges.begin();
695   }
696
697   inline viewedge_container::iterator viewedges_begin()
698   {
699     return _ViewEdges.begin();
700   }
701
702   inline viewedge_container::const_iterator viewedges_end() const
703   {
704     return _ViewEdges.end();
705   }
706
707   inline viewedge_container::iterator viewedges_end()
708   {
709     return _ViewEdges.end();
710   }
711
712   inline int viewedges_size() const
713   {
714     return _ViewEdges.size();
715   }
716
717   inline Vec2r getBeginningOrientation() const
718   {
719     return _extremityOrientations[0];
720   }
721
722   inline real getBeginningOrientationX() const
723   {
724     return _extremityOrientations[0].x();
725   }
726
727   inline real getBeginningOrientationY() const
728   {
729     return _extremityOrientations[0].y();
730   }
731
732   inline Vec2r getEndingOrientation() const
733   {
734     return _extremityOrientations[1];
735   }
736
737   inline real getEndingOrientationX() const
738   {
739     return _extremityOrientations[1].x();
740   }
741
742   inline real getEndingOrientationY() const
743   {
744     return _extremityOrientations[1].y();
745   }
746
747   /* modifiers */
748   /*! sets the Id of the Stroke. */
749   inline void setId(const Id &id)
750   {
751     _id = id;
752   }
753
754   /*! sets the 2D length of the Stroke. */
755   void setLength(float iLength);
756
757   /*! sets the medium type that must be used for this Stroke. */
758   inline void setMediumType(MediumType iType)
759   {
760     _mediumType = iType;
761   }
762
763   /*! sets the texture id to be used to simulate the marks system for this Stroke. */
764   inline void setTextureId(unsigned int id)
765   {
766     _textureId = id;
767   }
768
769   /*! sets the spacing of texture coordinates along the stroke length. */
770   inline void setTextureStep(float step)
771   {
772     _textureStep = step;
773   }
774
775   /*! assigns a blender texture to the first available slot. */
776   inline int setMTex(MTex *mtex)
777   {
778     for (int a = 0; a < MAX_MTEX; a++) {
779       if (!_mtex[a]) {
780         _mtex[a] = mtex;
781         return 0;
782       }
783     }
784     return -1; /* no free slots */
785   }
786
787   /*! assigns a node tree (of new shading nodes) to define textures. */
788   inline void setNodeTree(bNodeTree *iNodeTree)
789   {
790     _nodeTree = iNodeTree;
791   }
792
793   /*! sets the flag telling whether this stroke is using a texture with tips or not. */
794   inline void setTips(bool iTips)
795   {
796     _tips = iTips;
797   }
798
799   inline void push_back(StrokeVertex *iVertex)
800   {
801     _Vertices.push_back(iVertex);
802   }
803
804   inline void push_front(StrokeVertex *iVertex)
805   {
806     _Vertices.push_front(iVertex);
807   }
808
809   inline void AddViewEdge(ViewEdge *iViewEdge)
810   {
811     _ViewEdges.push_back(iViewEdge);
812   }
813
814   inline void setBeginningOrientation(const Vec2r &iOrientation)
815   {
816     _extremityOrientations[0] = iOrientation;
817   }
818
819   inline void setBeginningOrientation(real x, real y)
820   {
821     _extremityOrientations[0] = Vec2r(x, y);
822   }
823
824   inline void setEndingOrientation(const Vec2r &iOrientation)
825   {
826     _extremityOrientations[1] = iOrientation;
827   }
828
829   inline void setEndingOrientation(real x, real y)
830   {
831     _extremityOrientations[1] = Vec2r(x, y);
832   }
833
834   /* Information access interface */
835
836   // embedding vertex iterator
837   const_vertex_iterator vertices_begin() const;
838   vertex_iterator vertices_begin(float t = 0.0f);
839   const_vertex_iterator vertices_end() const;
840   vertex_iterator vertices_end();
841
842   /*! Returns a StrokeVertexIterator pointing on the first StrokeVertex of the Stroke. One can
843    * specify a sampling value to resample the Stroke on the fly if needed. \param t: The resampling
844    * value with which we want our Stroke to be resampled. If 0 is specified, no resampling is done.
845    */
846   StrokeInternal::StrokeVertexIterator strokeVerticesBegin(float t = 0.0f);
847
848   /*! Returns a StrokeVertexIterator pointing after the last StrokeVertex of the Stroke. */
849   StrokeInternal::StrokeVertexIterator strokeVerticesEnd();
850
851   /*! Returns the number of StrokeVertex constituting the Stroke. */
852   inline unsigned int strokeVerticesSize() const
853   {
854     return _Vertices.size();
855   }
856
857   /*! Returns the i-th StrokeVertex constituting the Stroke. */
858   inline StrokeVertex &strokeVerticeAt(unsigned int i)
859   {
860     return *(_Vertices.at(i));
861   }
862
863   // Iterator access (Interface1D)
864   /*! Returns an Interface0DIterator pointing on the first StrokeVertex of the Stroke. */
865   virtual Interface0DIterator verticesBegin();
866
867   /*! Returns an Interface0DIterator pointing after the last StrokeVertex of the Stroke. */
868   virtual Interface0DIterator verticesEnd();
869
870   virtual Interface0DIterator pointsBegin(float t = 0.0f);
871   virtual Interface0DIterator pointsEnd(float t = 0.0f);
872
873 #ifdef WITH_CXX_GUARDEDALLOC
874   MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Stroke")
875 #endif
876 };
877
878 //
879 //  Implementation
880 //
881 ////////////////////////////////////////////////////////
882
883 template<class InputVertexIterator>
884 Stroke::Stroke(InputVertexIterator iBegin, InputVertexIterator iEnd)
885 {
886   for (InputVertexIterator v = iBegin, vend = iEnd; v != vend; v++) {
887     _Vertices.push_back(*v);
888   }
889   _Length = 0;
890   _id = 0;
891 }
892
893 } /* namespace Freestyle */
894
895 #endif  // __FREESTYLE_STROKE_H__