Merged changes in the trunk up to revision 28600.
[blender.git] / source / blender / freestyle / intern / stroke / BasicStrokeShaders.h
1 //
2 //  Filename         : BasicStrokeShaders.h
3 //  Author           : Stephane Grabli
4 //  Purpose          : Class gathering basic stroke shaders
5 //  Date of creation : 17/12/2002
6 //
7 ///////////////////////////////////////////////////////////////////////////////
8
9
10 //
11 //  Copyright (C) : Please refer to the COPYRIGHT file distributed 
12 //   with this source distribution. 
13 //
14 //  This program is free software; you can redistribute it and/or
15 //  modify it under the terms of the GNU General Public License
16 //  as published by the Free Software Foundation; either version 2
17 //  of the License, or (at your option) any later version.
18 //
19 //  This program is distributed in the hope that it will be useful,
20 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 //  GNU General Public License for more details.
23 //
24 //  You should have received a copy of the GNU General Public License
25 //  along with this program; if not, write to the Free Software
26 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27 //
28 ///////////////////////////////////////////////////////////////////////////////
29
30 #ifndef  BASIC_STROKE_SHADERS_H
31 # define BASIC_STROKE_SHADERS_H
32
33 # include "Stroke.h"
34 # include "../geometry/Geom.h"
35 # include "../geometry/Bezier.h"
36 # include "StrokeShader.h"
37 # include <fstream>
38
39 using namespace std;
40 using namespace Geometry;
41
42 namespace StrokeShaders {
43
44   //
45   //  Thickness modifiers
46   //
47   //////////////////////////////////////////////////////
48   /*! [ Thickness Shader ].
49    *  Assigns an absolute constant thickness to every
50    *  vertices of the Stroke.
51    */
52   class LIB_STROKE_EXPORT ConstantThicknessShader : public StrokeShader
53   {
54   public:
55     /*! Builds the shader.
56      *  \param thickness
57      *    The thickness that must be assigned
58      *    to the stroke.
59      */
60     ConstantThicknessShader(float thickness) : StrokeShader() {
61       _thickness = thickness;
62     }
63     /*! Destructor. */
64     virtual ~ConstantThicknessShader() {}
65     /*! Returns the string "ConstantThicknessShader".*/
66     virtual string getName() const {
67       return "ConstantThicknessShader";
68     }
69     /*! The shading method. */
70     virtual int shade(Stroke& stroke) const;
71
72   private:
73     float _thickness;
74   };
75
76   /* [ Thickness Shader ].
77    *  Assigns an absolute constant external thickness to every
78    *  vertices of the Stroke. The external thickness of a point
79    *  is its thickness from the point to the strip border
80    *  in the direction pointing outside the object the
81    *  Stroke delimitates.
82    */
83   class LIB_STROKE_EXPORT ConstantExternThicknessShader : public StrokeShader
84   {
85   public:
86
87     ConstantExternThicknessShader(float thickness) : StrokeShader() {
88       _thickness = thickness;
89     }
90
91     virtual ~ConstantExternThicknessShader() {}
92
93     virtual string getName() const {
94       return "ConstantExternThicknessShader";
95     }
96
97     virtual int shade(Stroke& stroke) const;
98
99   private:
100
101     float _thickness;
102   };
103
104   /*! [ Thickness Shader ].
105    *  Assigns thicknesses values such as the thickness
106    *  increases from a thickness value A to a thickness value B
107    *  between the first vertex to the midpoint vertex and
108    *  then decreases from B to a A between this midpoint vertex
109    *  and the last vertex.
110    *  The thickness is linearly interpolated from A to B.
111    */
112   class LIB_STROKE_EXPORT IncreasingThicknessShader : public StrokeShader
113   {
114   public:
115     /*! Builds the shader.
116      *  \param iThicknessMin
117      *    The first thickness value.
118      *  \param iThicknessMax
119      *    The second thickness value.
120      */
121     IncreasingThicknessShader(float iThicknessMin, float iThicknessMax)
122       : StrokeShader()
123     {
124       _ThicknessMin = iThicknessMin;
125       _ThicknessMax = iThicknessMax;
126     }
127     /*! Destructor.*/
128     virtual ~IncreasingThicknessShader() {}
129
130         virtual string getName() const {
131       return "IncreasingThicknessShader";
132     }
133
134     /*! The shading method. */
135     virtual int shade(Stroke& stroke) const;
136
137   private:
138
139     float _ThicknessMin;
140     float _ThicknessMax;
141   };
142
143   /*! [ Thickness shader ].
144    *  Same as previous but 
145    *  here we allow the user to control the ratio thickness/length so that 
146    *  we don't get fat short lines
147    */
148   class LIB_STROKE_EXPORT ConstrainedIncreasingThicknessShader : public StrokeShader
149   {
150   private:
151     float _ThicknessMin;
152     float _ThicknessMax;
153     float _ratio;
154   public:
155     /*! Builds the shader.
156      *  \param iThicknessMin
157      *    The first thickness value.
158      *  \param iThicknessMax
159      *    The second thickness value.
160      *  \param iRatio
161      *    The ration thickness/length we don't want to
162      *    exceed.
163      */ 
164     ConstrainedIncreasingThicknessShader(float iThicknessMin, float iThicknessMax, float iRatio)
165       : StrokeShader()
166     {
167       _ThicknessMin = iThicknessMin;
168       _ThicknessMax = iThicknessMax;
169       _ratio = iRatio;
170     }
171     /*! Destructor.*/
172     virtual ~ConstrainedIncreasingThicknessShader() {}
173
174         virtual string getName() const {
175       return "ConstrainedIncreasingThicknessShader";
176     }
177
178     /*! The shading method. */
179     virtual int shade(Stroke& stroke) const;
180   };
181
182   /*  [ Thickness Shader ].
183    *  Modifys the thickness in a relative way
184    *  depending on its length.
185    */
186   class LIB_STROKE_EXPORT LengthDependingThicknessShader : public StrokeShader
187   {
188   private:
189     float _minThickness;
190     float _maxThickness;
191     // We divide the strokes in 4 categories:
192     // l > 300
193     // 100 < l < 300
194     // 50 < l < 100
195     // l < 50
196   public:
197     LengthDependingThicknessShader(float iMinThickness, float iMaxThickness)
198       : StrokeShader()
199     {
200       _minThickness = iMinThickness;
201       _maxThickness = iMaxThickness;
202     }
203     virtual ~LengthDependingThicknessShader() {}
204
205         virtual string getName() const {
206       return "LengthDependingThicknessShader";
207     }
208
209     virtual int shade(Stroke& stroke) const;
210   };
211
212   /*! [ Thickness Shader ].
213    *  Applys a pattern (texture) to vary thickness.
214    *  The new thicknesses are the result of the multiplication
215    *  of the pattern and the original thickness
216    */
217   class LIB_STROKE_EXPORT ThicknessVariationPatternShader : public StrokeShader
218   {
219   public:
220
221     /*! Builds the shader.
222      *  \param pattern_name
223      *    The texture file name.
224      *  \param iMinThickness
225      *    The minimum thickness we don't want to exceed.
226      *  \param iMaxThickness
227      *    The maximum thickness we don't want to exceed.
228      *  \param stretch
229      *    Tells whether the pattern texture must
230      *    be stretched or repeted to fit the stroke.
231      */
232     ThicknessVariationPatternShader(const string pattern_name,
233                                     float iMinThickness = 1.f,
234                                     float iMaxThickness = 5.f,
235                                     bool stretch = true);
236     /*! Destructor.*/
237     virtual ~ThicknessVariationPatternShader()
238     {
239       if(0 != _aThickness)
240         {
241           delete [] _aThickness;
242           _aThickness = 0;
243         }
244     }
245         
246         virtual string getName() const {
247       return "ThicknessVariationPatternShader";
248     }
249
250     /*! The shading method. */
251     virtual int shade(Stroke& stroke) const;
252
253   private:
254
255     float*      _aThickness; // array of thickness values, in % of the max (i.e comprised between 0 and 1)
256     unsigned    _size;
257     float       _minThickness;
258     float       _maxThickness;
259     bool        _stretch;
260   };
261
262   /*!  [ Thickness Shader ].
263    *   Adds some noise to the stroke thickness.
264    *   \see \htmlonly <a href=noise/noise.html>noise/noise.html</a>\endhtmlonly
265    */
266   class LIB_STROKE_EXPORT ThicknessNoiseShader : public StrokeShader
267   {
268   private:
269     float _amplitude;
270     float _scale;
271   public:
272     ThicknessNoiseShader();
273     /*! Builds a Thickness Noise Shader
274      *    \param iAmplitude
275      *      The amplitude of the noise signal
276      *    \param iPeriod
277      *      The period of the noise signal
278      */
279     ThicknessNoiseShader(float iAmplitude, float iPeriod);
280
281         virtual string getName() const {
282       return "ThicknessNoiseShader";
283     }
284
285     /*! The shading method. */
286     virtual int shade(Stroke& stroke) const;
287   };
288
289
290   //
291   //  Color shaders
292   //
293   /////////////////////////////////////////////////////////
294   /*!  [ Color Shader ].
295    *   Assigns a constant color to every vertices of the Stroke.
296    */
297   class LIB_STROKE_EXPORT ConstantColorShader : public StrokeShader
298   {
299   public:
300     /*! Builds the shader from a user-specified color.
301      *  \param iR
302      *    The red component
303      *  \param iG
304      *    The green component
305      *  \param iB
306      *    The blue component
307      *  \param iAlpha
308      *    The alpha value
309      */
310     ConstantColorShader(float iR, float iG, float iB, float iAlpha=1.f)
311       : StrokeShader()
312     {
313       _color[0] = iR;
314       _color[1] = iG;
315       _color[2] = iB;
316       _color[3] = iAlpha;
317     }
318
319     virtual string getName() const {
320       return "ConstantColorShader";
321     }
322     /*! The shading method. */
323     virtual int shade(Stroke& stroke) const;
324
325   private:
326
327     float _color[4];
328   };
329
330   /*!  [ Color Shader ].
331    *   Assigns a varying color to the stroke.
332    *   The user specifies 2 colors A and B. The stroke
333    *   color will change linearly from A to B between the
334    *   first and the last vertex.
335    */
336   class LIB_STROKE_EXPORT IncreasingColorShader : public StrokeShader
337   {
338   private:
339     float _colorMin[4];
340     float _colorMax[4];
341   public:
342     /*! Builds the shader from 2 user-specified colors.
343      *  \param iRm
344      *    The first color red component
345      *  \param iGm
346      *    The first color green component
347      *  \param iBm
348      *    The first color blue component
349      *  \param iAlpham
350      *    The first color alpha value
351      *  \param iRM
352      *    The second color red component
353      *  \param iGM
354      *    The second color green component
355      *  \param iBM
356      *    The second color blue component
357      *  \param iAlphaM
358      *    The second color alpha value
359      */
360     IncreasingColorShader(float iRm, float iGm, float iBm, float iAlpham, 
361                                 float iRM, float iGM, float iBM, float iAlphaM)
362       : StrokeShader() 
363     {
364       _colorMin[0] = iRm;
365       _colorMin[1] = iGm;
366       _colorMin[2] = iBm;
367       _colorMin[3] = iAlpham;
368
369       _colorMax[0] = iRM;
370       _colorMax[1] = iGM;
371       _colorMax[2] = iBM;
372       _colorMax[3] = iAlphaM;
373     }
374
375         virtual string getName() const {
376       return "IncreasingColorShader";
377     }
378
379     /*! The shading method. */
380     virtual int shade(Stroke& stroke) const;
381   };
382
383   /*! [ Color Shader ].
384    *  Applys a pattern to vary original color.
385    *  The new color is the result of the multiplication
386    *  of the pattern and the original color
387    */
388   class LIB_STROKE_EXPORT ColorVariationPatternShader : public StrokeShader
389   {
390   public:
391     /*! Builds the shader from the pattern texture file name.
392      *  \param pattern_name
393      *    The file name of the texture file to use as pattern
394      *  \param stretch
395      *    Tells whether the texture must be strecthed or repeted
396      *    to fit the stroke.
397      */
398     ColorVariationPatternShader(const string pattern_name, bool stretch = true);
399     /*! Destructor */
400     virtual ~ColorVariationPatternShader()
401     {
402       if(0 != _aVariation)
403         {
404           delete [] _aVariation;
405           _aVariation = 0;
406         }
407     }
408
409         virtual string getName() const {
410       return "ColorVariationPatternShader";
411     }
412
413     /*! The shading method. */
414     virtual int shade(Stroke& stroke) const;
415
416   private:
417
418     float*      _aVariation; // array of coef values, in % of the max (i.e comprised between 0 and 1)
419     unsigned    _size;
420     bool        _stretch;
421   };
422
423   /* [ Color Shader ].
424    *  Assigns a color to the stroke depending
425    *  on the material of the shape to which ot belongs
426    *  to. (Disney shader)
427    */
428   class LIB_STROKE_EXPORT MaterialColorShader : public StrokeShader
429   {
430   private:
431     float _coefficient;
432   public:
433     MaterialColorShader(float coeff=1.f)
434       : StrokeShader()
435     {_coefficient=coeff;}
436
437         virtual string getName() const {
438       return "MaterialColorShader";
439     }
440
441     virtual int shade(Stroke& stroke) const;
442   };
443
444   class LIB_STROKE_EXPORT CalligraphicColorShader : public StrokeShader
445   {
446   private:
447     int _textureId;
448     Vec2d _orientation;
449   public:
450     CalligraphicColorShader(
451                             const Vec2d &iOrientation)
452       : StrokeShader()
453     { 
454       _orientation=iOrientation;
455       _orientation.normalize();
456     } 
457
458         virtual string getName() const {
459       return "CalligraphicColorShader";
460     }
461
462     virtual int shade(Stroke& stroke) const;
463
464   };
465
466   /*! [ Color Shader ].
467    *  Shader to add noise to the stroke colors.
468    */ 
469   class LIB_STROKE_EXPORT ColorNoiseShader : public StrokeShader
470   {
471   private:
472     float _amplitude; 
473     float _scale;     
474
475   public:
476     ColorNoiseShader();
477     /*! Builds a Color Noise Shader
478      *    \param iAmplitude
479      *      The amplitude of the noise signal
480      *    \param iPeriod
481      *      The period of the noise signal
482      */
483     ColorNoiseShader(float iAmplitude, float iPeriod);
484
485         virtual string getName() const {
486           return "ColorNoiseShader";
487         }
488
489     /*! The shading method. */
490     virtual int shade(Stroke& stroke) const;
491   };
492
493   //
494   //  Texture Shaders
495   //
496   ///////////////////////////////////////////////////////////////////////////////
497   /*! [ Texture Shader ].
498    *  Assigns a texture to the stroke in order to simulate
499    *  its marks system. This shader takes as input an integer value
500    *  telling which texture and blending mode to use among a set of
501    *  predefined textures.
502    *  Here are the different presets:
503    *  0) -> /brushes/charcoalAlpha.bmp, HUMID_MEDIUM
504    *  1) -> /brushes/washbrushAlpha.bmp, HUMID_MEDIUM
505    *  2) -> /brushes/oil.bmp, HUMID_MEDIUM
506    *  3) -> /brushes/oilnoblend.bmp, HUMID_MEDIUM
507    *  4) -> /brushes/charcoalAlpha.bmp, DRY_MEDIUM
508    *  5) -> /brushes/washbrushAlpha.bmp, DRY_MEDIUM
509    *  6) -> /brushes/opaqueDryBrushAlpha.bmp, OPAQUE_MEDIUM
510    *  7) -> /brushes/opaqueBrushAlpha.bmp, Stroke::OPAQUE_MEDIUM
511    *  Any other value will lead to the following preset:
512    *  default) -> /brushes/smoothAlpha.bmp, OPAQUE_MEDIUM.
513    */
514   class LIB_STROKE_EXPORT TextureAssignerShader : public StrokeShader // FIXME
515   {
516   private:
517     int _textureId;
518   public:
519     /*! Builds the shader.
520      *  \param id
521      *    The number of the preset to use.
522      */
523     TextureAssignerShader(int id)
524       : StrokeShader()
525     {
526       _textureId = id;
527     }
528
529         virtual string getName() const {
530       return "TextureAssignerShader";
531     }
532
533     /*! The shading method */
534     virtual int shade(Stroke& stroke) const;
535   
536   };
537   /*! [ Texture Shader ].
538    *  Assigns a texture and a blending mode to the stroke
539    *  in order to simulate its marks system.
540    */
541   class LIB_STROKE_EXPORT StrokeTextureShader : public StrokeShader
542   {
543   private:
544     string _texturePath;
545     Stroke::MediumType _mediumType;
546     bool _tips; // 0 or 1
547     
548   public:
549     /*! Builds the shader from the texture file name and the blending mode to use.
550      *  \param textureFile
551      *    The the texture file name.
552      *    \attention The textures must be placed in the $FREESTYLE_DIR/data/textures/brushes
553      *    directory.
554      *  \param mediumType
555      *    The medium type and therefore, the blending mode that must
556      *    be used for the rendering of this stroke.
557      *  \param iTips
558      *    Tells whether the texture includes tips or not.
559      *    If it is the case, the texture image must respect the following
560      *    format:
561      *    \verbatim
562      *     __________
563      *    |          |
564      *    |    A     |
565      *    |__________|
566      *    |     |    |
567      *    |  B  | C  |
568      *    |_____|____|
569      * 
570      *    \endverbatim
571      *    - A : The stroke's corpus texture
572      *    - B : The stroke's left extremity texture
573      *    - C : The stroke's right extremity texture
574      */
575     StrokeTextureShader(const string textureFile, Stroke::MediumType mediumType = Stroke::OPAQUE_MEDIUM, bool iTips = false)
576       : StrokeShader()
577     {
578       _texturePath = textureFile;
579       _mediumType = mediumType;
580       _tips = iTips;
581     }
582
583         virtual string getName() const {
584       return "StrokeTextureShader";
585     }
586
587     /*! The shading method */
588     virtual int shade(Stroke& stroke) const;
589   
590   };
591
592
593   //
594   //  Geometry Shaders
595   //
596   ///////////////////////////////////////////////////////////////////////////////
597   /*! [ Geometry Shader ].
598    *  Stretches the stroke at its two extremities and following the
599    *  respective directions: v(1)v(0) and v(n-1)v(n).
600    */
601   class LIB_STROKE_EXPORT BackboneStretcherShader : public StrokeShader
602   {
603   private:
604     float _amount; 
605   public:
606     /*! Builds the shader.
607      *  \param iAmount
608      *    The stretching amount value.
609      */
610     BackboneStretcherShader(float iAmount=2.f)
611       : StrokeShader()
612     {
613       _amount = iAmount;
614     }
615
616         virtual string getName() const {
617       return "BackboneStretcherShader";
618     }
619
620     /*! The shading method */
621     virtual int shade(Stroke& stroke) const;
622   };
623
624   /*! [ Geometry Shader. ]
625    *  Resamples the stroke.
626    *  @see Stroke::Resample(float).
627    */
628   class LIB_STROKE_EXPORT SamplingShader: public StrokeShader
629   {
630   private:
631     float _sampling;
632   public:
633     /*! Builds the shader.
634      *  \param sampling
635      *    The sampling to use for the
636      *    stroke resampling
637      */
638     SamplingShader(float  sampling)
639       : StrokeShader()
640     {
641       _sampling = sampling;
642     }
643
644         virtual string getName() const {
645       return "SamplingShader";
646     }
647
648     /*! The shading method */
649     virtual int shade(Stroke& stroke) const;
650   };
651
652
653   class LIB_STROKE_EXPORT ExternalContourStretcherShader : public StrokeShader
654   {
655   private:
656     float _amount; 
657   public:
658     ExternalContourStretcherShader(float iAmount=2.f)
659       : StrokeShader()
660     {
661       _amount = iAmount;
662     }
663
664         virtual string getName() const {
665       return "ExternalContourStretcherShader";
666     }
667
668     virtual int shade(Stroke& stroke) const;
669   };
670
671   // B-Spline stroke shader
672   class LIB_STROKE_EXPORT BSplineShader: public StrokeShader
673   { 
674   public:
675     BSplineShader()
676       : StrokeShader()
677     {}
678
679         virtual string getName() const {
680           return "BSplineShader";
681         }
682
683     virtual int shade(Stroke& stroke) const;
684   };
685
686
687   // Bezier curve stroke shader
688   /*! [ Geometry Shader ].
689    *  Transforms the stroke backbone geometry
690    *  so that it corresponds to a Bezier Curve
691    *  approximation of the original backbone geometry.
692    *  @see \htmlonly <a href=bezier/bezier.html>bezier/bezier.html</a> \endhtmlonly
693    */
694   class LIB_STROKE_EXPORT BezierCurveShader : public StrokeShader
695   { 
696   private:
697     float _error;
698   public:
699     /*! Builds the shader.
700      *  \param error
701      *    The error we're allowing for the approximation.
702      *    This error is the max distance allowed between
703      *    the new curve and the original geometry.
704      */
705     BezierCurveShader(float error = 4.0)
706       : StrokeShader()
707     {_error=error;}
708
709         virtual string getName() const {
710       return "BezierCurveShader";
711     }
712
713     /*! The shading method */
714     virtual int shade(Stroke& stroke) const;
715   };
716
717   /* Shader to inflate the curves. It keeps the extreme
718    *  points positions and moves the other ones along 
719    *  the 2D normal. The displacement value is proportional
720    *  to the 2d curvature at the considered point (the higher 
721    *  the curvature, the smaller the displacement) and to a value 
722    *  specified by the user.
723    */
724   class LIB_STROKE_EXPORT InflateShader : public StrokeShader
725   {
726   private:
727     float _amount; 
728     float _curvatureThreshold;
729   public:
730     /*! Builds an inflate shader
731      *    \param iAmount
732      *      A multiplicative coefficient that 
733      *      acts on the amount and direction of displacement
734      *    \param iThreshold
735      *      The curves having a 2d curvature > iThreshold
736      *      at one of their points is not inflated 
737      */
738     InflateShader(float iAmount,float iThreshold)
739       : StrokeShader()
740     {
741       _amount = iAmount;
742       _curvatureThreshold = iThreshold;
743     }
744
745         virtual string getName() const {
746       return "InflateShader";
747     }
748
749     /*! The shading method */
750     virtual int shade(Stroke& stroke) const;
751   };
752
753   /*! [ Geometry Shader ].
754    *  Shader to modify the Stroke geometry so that 
755    *  it looks more "polygonal".
756    *  The basic idea is to start from the
757    *  minimal stroke approximation consisting in
758    *  a line joining the first vertex to the last one and
759    *  to subdivide using the original stroke vertices
760    *  until a certain error is reached.
761    */
762   class LIB_STROKE_EXPORT PolygonalizationShader : public StrokeShader
763   {
764   private:
765     float _error;
766   public:
767     /*! Builds the shader.
768      *  \param iError
769      *    The error we want our polygonal approximation
770      *    to have with respect to the original geometry.
771      *    The smaller, the closer the new stroke to
772      *    the orinal one.
773      *    This error corresponds to the maximum distance
774      *    between the new stroke and the old one.
775      */
776     PolygonalizationShader(float iError) : StrokeShader() 
777     {_error = iError;}
778
779         virtual string getName() const {
780       return "PolygonalizationShader";
781     }
782
783     /*! The shading method */
784     virtual int shade(Stroke& stroke) const;
785   };
786
787
788   /*! [ Geometry Shader ].
789    *  Shader to modify the Stroke geometry so that 
790    *  it corresponds to its main direction line.
791    *  This shader must be used together with the 
792    *  splitting operator using the curvature criterion.
793    *  Indeed, the precision of the approximation
794    *  will depend on the size of the stroke's pieces.
795    *  The bigger the pieces, the rougher the approximation.
796    */
797   class LIB_STROKE_EXPORT GuidingLinesShader : public StrokeShader
798   {
799   private:
800     float _offset;
801   public:
802     /*! Builds a Guiding Lines shader
803      *    \param iOffset
804      *      The line that replaces the stroke
805      *      is initially in the middle 
806      *      of the initial stroke "bbox".
807      *      iOffset is the value of the displacement 
808      *      which is applied to this line along its 
809      *      normal.
810      */
811     GuidingLinesShader(float iOffset) : StrokeShader()
812     {_offset = iOffset;}
813
814         virtual string getName() const {
815       return "GuidingLinesShader";
816     }
817
818     /*! The shading method */
819     virtual int shade(Stroke& stroke) const;
820   };
821
822   /*! [ Geometry Shader ].
823    *  Removes the stroke's extremities.
824    */
825   class LIB_STROKE_EXPORT TipRemoverShader : public StrokeShader 
826   {
827   public:
828     /*! Builds the shader.
829      *  \param tipLength
830      *    The length of the piece of stroke
831      *    we want to remove at each extremity.
832      */
833     TipRemoverShader (real tipLength);
834     /*! Destructor. */
835     virtual ~TipRemoverShader () {}
836     /*! The shading method */
837         virtual string getName() const {
838       return "TipRemoverShader";
839     }
840
841     virtual int shade(Stroke &stroke) const;
842
843   protected:
844
845     real _tipLength; 
846   };
847
848   /*! [ output Shader ].
849    *  streams the Stroke
850    */
851   class LIB_STROKE_EXPORT streamShader : public StrokeShader
852   {
853   public:
854     /*! Destructor. */
855     virtual ~streamShader() {}
856     /*! Returns the string "streamShader".*/
857     virtual string getName() const {
858       return "streamShader";
859     }
860     /*! The shading method. */
861     virtual int shade(Stroke& stroke) const;
862   };
863
864   /*! [ output Shader ].
865    *  streams the Stroke in a file
866    */
867   class LIB_STROKE_EXPORT fstreamShader : public StrokeShader
868   {
869   protected:
870     mutable ofstream _stream;
871   public:
872     /*! Builds the shader from the output file name */
873     fstreamShader(const char *iFileName) : StrokeShader(){
874       _stream .open(iFileName);
875       if(!_stream.is_open()){
876         cout << "couldn't open file " << iFileName << endl;
877       }
878     }
879     /*! Destructor. */
880     virtual ~fstreamShader() {_stream.close();}
881     /*! Returns the string "fstreamShader".*/
882     virtual string getName() const {
883       return "fstreamShader";
884     }
885     /*! The shading method. */
886     virtual int shade(Stroke& stroke) const;
887   };
888 } // end of namespace StrokeShaders
889
890 #endif // BASIC_STROKE_SHADERS_H