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