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