diff options
Diffstat (limited to 'source/blender/freestyle/intern/stroke/Stroke.h')
-rw-r--r-- | source/blender/freestyle/intern/stroke/Stroke.h | 822 |
1 files changed, 822 insertions, 0 deletions
diff --git a/source/blender/freestyle/intern/stroke/Stroke.h b/source/blender/freestyle/intern/stroke/Stroke.h new file mode 100644 index 00000000000..51733a058a9 --- /dev/null +++ b/source/blender/freestyle/intern/stroke/Stroke.h @@ -0,0 +1,822 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __FREESTYLE_STROKE_H__ +#define __FREESTYLE_STROKE_H__ + +/** \file blender/freestyle/intern/stroke/Stroke.h + * \ingroup freestyle + * \brief Classes to define a stroke + * \author Stephane Grabli + * \date 09/09/2002 + */ + +#include <map> +#include <vector> + +#include "Curve.h" + +#include "../view_map/Interface1D.h" +#include "../view_map/Silhouette.h" + +#include "../system/FreestyleConfig.h" +#include "../system/StringUtils.h" + + +// +// StrokeAttribute +// +//////////////////////////////////////////////////////// + +/*! Class to define an attribute associated to a Stroke Vertex. + * This attribute stores the color, alpha and thickness values for a Stroke Vertex. + */ +class LIB_STROKE_EXPORT StrokeAttribute +{ +public: + /*! default constructor */ + StrokeAttribute(); + + /*! Copy constructor */ + StrokeAttribute(const StrokeAttribute& iBrother); + + /*! Builds a stroke vertex attribute from a set of parameters. + * \param iRColor + * The Red Component value. + * \param iGColor + * The Green Component value. + * \param iBColor + * The Blue Component value. + * \param iAlpha + * The transparency value + * \param iRThickness + * The thickness of the stroke on the right + * \param iLThickness + * The Thickness of the stroke on the left + */ + StrokeAttribute(float iRColor, float iGColor, float iBColor, float iAlpha, float iRThickness, float iLThickness); + + /*! Interpolation constructor. + * Builds a StrokeAttribute from two StrokeAttributes and an interpolation parameter. + * \param a1 + * The first Attribute. + * \param a2 + * The second parameter. + * \param t + * The interpolation parameter. + */ + StrokeAttribute(const StrokeAttribute& a1, const StrokeAttribute& a2, float t); + + /*! destructor */ + virtual ~StrokeAttribute(); + + /* operators */ + /*! operator = */ + StrokeAttribute& operator=(const StrokeAttribute& iBrother); + + /* accessors */ + /*! Returns the attribute's color. + * \return The array of 3 floats containing the R,G,B values of the attribute's color. + */ + inline const float *getColor() const + { + return _color; + } + + /*! Returns the R color component. */ + inline const float getColorR() const + { + return _color[0]; + } + + /*! Returns the G color component. */ + inline const float getColorG() const + { + return _color[1]; + } + + /*! Returns the B color component. */ + inline const float getColorB() const + { + return _color[2]; + } + + /*! Returns the RGB color components. */ + inline Vec3f getColorRGB() const + { + return Vec3f(_color[0], _color[1], _color[2]); + } + + /*! Returns the alpha color component. */ + inline float getAlpha() const + { + return _alpha; + } + + /*! Returns the attribute's thickness. + * \return an array of 2 floats. the first value is the thickness on the right of the vertex when following + * the stroke, the second one is the thickness on the left. + */ + inline const float *getThickness() const + { + return _thickness; + } + + /*! Returns the thickness on the right of the vertex when following the stroke. */ + inline const float getThicknessR() const + { + return _thickness[0]; + } + + /*! Returns the thickness on the left of the vertex when following the stroke. */ + inline const float getThicknessL() const + { + return _thickness[1]; + } + + /*! Returns the thickness on the right and on the left of the vertex when following the stroke. */ + inline Vec2f getThicknessRL() const + { + return Vec2f(_thickness[0], _thickness[1]); + } + + /*! Returns true if the strokevertex is visible, false otherwise */ + inline bool isVisible() const + { + return _visible; + } + + /*! Returns an attribute of type real + * \param iName + * The name of the attribute + */ + float getAttributeReal(const char *iName) const; + + /*! Returns an attribute of type Vec2f + * \param iName + * The name of the attribute + */ + Vec2f getAttributeVec2f(const char *iName) const; + + /*! Returns an attribute of type Vec3f + * \param iName + * The name of the attribute + */ + Vec3f getAttributeVec3f(const char *iName) const; + + /*! Checks whether the attribute iName is availbale */ + bool isAttributeAvailableReal(const char *iName) const; + + /*! Checks whether the attribute iName is availbale */ + bool isAttributeAvailableVec2f(const char *iName) const; + + /*! Checks whether the attribute iName is availbale */ + bool isAttributeAvailableVec3f(const char *iName) const; + + /* modifiers */ + /*! sets the attribute's color. + * \param r + * The new R value. + * \param g + * The new G value. + * \param b + * The new B value. + */ + inline void setColor(float r, float g, float b) + { + _color[0] = r; + _color[1] = g; + _color[2] = b; + } + + /*! sets the attribute's color. + * \param iRGB + * The new RGB values. + */ + inline void setColor(const Vec3f& iRGB) + { + _color[0] = iRGB[0]; + _color[1] = iRGB[1]; + _color[2] = iRGB[2]; + } + + /*! sets the attribute's alpha value. + * \param alpha + * The new alpha value. + */ + inline void setAlpha(float alpha) + { + _alpha = alpha; + } + + /*! sets the attribute's thickness. + * \param tr + * The thickness on the right of the vertex when following the stroke. + * \param tl + * The thickness on the left of the vertex when following the stroke. + */ + inline void setThickness(float tr, float tl) + { + _thickness[0] = tr; + _thickness[1] = tl; + } + + /*! sets the attribute's thickness. + * \param tRL + * The thickness on the right and on the left of the vertex when following the stroke. + */ + inline void setThickness(const Vec2f& tRL) + { + _thickness[0] = tRL[0]; + _thickness[1] = tRL[1]; + } + + /*! sets the visible flag. True means visible. */ + inline void setVisible(bool iVisible) + { + _visible = iVisible; + } + + /*! Adds a user defined attribute of type real + * If there is no attribute of name iName, it is added. + * Otherwise, the new value replaces the old one. + * \param iName + * The name of the attribute + * \param att + * The attribute's value + */ + void setAttributeReal(const char *iName, float att); + + /*! Adds a user defined attribute of type Vec2f + * If there is no attribute of name iName, it is added. + * Otherwise, the new value replaces the old one. + * \param iName + * The name of the attribute + * \param att + * The attribute's value + */ + void setAttributeVec2f(const char *iName, const Vec2f& att); + + /*! Adds a user defined attribute of type Vec3f + * If there is no attribute of name iName, it is added. + * Otherwise, the new value replaces the old one. + * \param iName + * The name of the attribute + * \param att + * The attribute's value + */ + void setAttributeVec3f(const char *iName, const Vec3f& att); + +private: + typedef std::map<const char*, float, StringUtils::ltstr> realMap; + typedef std::map<const char*, Vec2f, StringUtils::ltstr> Vec2fMap; + typedef std::map<const char*, Vec3f, StringUtils::ltstr> Vec3fMap; + + float _color[3]; //! the color + float _alpha; //! alpha + float _thickness[2]; //! the thickness on the right and on the left of the backbone vertex (the stroke is oriented) + bool _visible; + realMap *_userAttributesReal; + Vec2fMap *_userAttributesVec2f; + Vec3fMap *_userAttributesVec3f; +}; + + +// +// StrokeVertex +// +//////////////////////////////////////////////////////// + +/*! Class to define a stroke vertex. */ +class LIB_STROKE_EXPORT StrokeVertex : public CurvePoint +{ +public: // Implementation of Interface0D + /*! Returns the string "StrokeVertex" */ + virtual string getExactTypeName() const + { + return "StrokeVertex"; + } + +private: + StrokeAttribute _Attribute; //! The attribute associated to the vertex + float _CurvilignAbscissa; //! the curvilign abscissa + float _StrokeLength; // stroke length + +public: + /*! default constructor */ + StrokeVertex(); + + /*! Copy constructor */ + StrokeVertex(const StrokeVertex& iBrother); + + /*! Builds a stroke vertex from a SVertex */ + StrokeVertex(SVertex *iSVertex); + + /*! Builds a stroke vertex from a CurvePoint */ + StrokeVertex(CurvePoint *iPoint); + + /*! Builds Stroke Vertex from 2 stroke vertices and an interpolation parameter*/ + StrokeVertex(StrokeVertex *iA, StrokeVertex *iB, float t3); + + /*! Builds a stroke from a view vertex and an attribute */ + StrokeVertex(SVertex *iSVertex, const StrokeAttribute& iAttribute); + + /*! destructor */ + virtual ~StrokeVertex(); + + /* operators */ + /*! operator = */ + StrokeVertex& operator=(const StrokeVertex& iBrother); + + /* accessors */ + /*! Returns the 2D point x coordinate */ + inline real x() const + { + return _Point2d[0]; + } + + /*! Returns the 2D point y coordinate */ + inline real y() const + { + return _Point2d[1]; + } + + /*! Returns the 2D point coordinates as a Vec2d */ + Vec2f getPoint () + { + return Vec2f((float)point2d()[0], (float)point2d()[1]); + } + + /*! Returns the ith 2D point coordinate (i=0 or 1)*/ + inline real operator[](const int i) const + { + return _Point2d[i]; + } + + /*! Returns the StrokeAttribute for this StrokeVertex */ + inline const StrokeAttribute& attribute() const + { + return _Attribute; + } + + /*! Returns a non-const reference to the StrokeAttribute of this StrokeVertex */ + inline StrokeAttribute& attribute() + { + return _Attribute; + } + + /*! Returns the curvilinear abscissa */ + inline float curvilinearAbscissa() const + { + return _CurvilignAbscissa; + } + + /*! Returns the length of the Stroke to which this StrokeVertex belongs */ + inline float strokeLength() const + { + return _StrokeLength; + } + + /*! Returns the curvilinear abscissa of this StrokeVertex in the Stroke */ + inline float u() const + { + return _CurvilignAbscissa / _StrokeLength; + } + + /* modifiers */ + /*! sets the 2D x value */ + inline void setX(real x) + { + _Point2d[0] = x; + } + + /*! sets the 2D y value */ + inline void setY(real y) + { + _Point2d[1] = y; + } + + /*! sets the 2D x and y values */ + inline void setPoint(real x, real y) + { + _Point2d[0] = x; + _Point2d[1] = y; + } + + /*! sets the 2D x and y values */ + inline void setPoint(const Vec2f& p) + { + _Point2d[0] = p[0]; + _Point2d[1] = p[1]; + } + + /*! Returns a reference to the ith 2D point coordinate (i=0 or 1) */ + inline real& operator[](const int i) + { + return _Point2d[i]; + } + + /*! sets the attribute. */ + inline void setAttribute(const StrokeAttribute& iAttribute) + { + _Attribute = iAttribute; + } + + /*! sets the curvilinear abscissa of this StrokeVertex in the Stroke */ + inline void setCurvilinearAbscissa(float iAbscissa) + { + _CurvilignAbscissa = iAbscissa; + } + + /*! sets the Stroke's length (it's only a value stored by the Stroke Vertex, it won't change the real + * Stroke's length.) + */ + inline void setStrokeLength(float iLength) + { + _StrokeLength = iLength; + } + + /* interface definition */ + /* inherited */ +}; + + +// +// Stroke +// +//////////////////////////////////////////////////////// + +class StrokeRenderer; +class StrokeRep; + +namespace StrokeInternal { + +class vertex_const_traits; +class vertex_nonconst_traits; +template<class Traits> class vertex_iterator_base; +class StrokeVertexIterator; + +} // end of namespace StrokeInternal + +/*! Class to define a stroke. + * A stroke is made of a set of 2D vertices (StrokeVertex), regularly spaced out. + * This set of vertices defines the stroke's backbone geometry. + * Each of these stroke vertices defines the stroke's shape and appearance at this vertex position. + */ +class LIB_STROKE_EXPORT Stroke : public Interface1D +{ +public: // Implementation of Interface1D + /*! Returns the string "Stroke" */ + virtual string getExactTypeName() const + { + return "Stroke"; + } + + // Data access methods + + /*! Returns the Id of the Stroke */ + virtual Id getId() const + { + return _id; + } + + /*! The different blending modes available to similate the interaction media-medium. */ + typedef enum { + DRY_MEDIUM, /*!< To simulate a dry medium such as Pencil or Charcoal.*/ + HUMID_MEDIUM, /*!< To simulate ink painting (color substraction blending).*/ + OPAQUE_MEDIUM, /*!< To simulate an opaque medium (oil, spray...).*/ + } MediumType; + +public: + typedef std::deque<StrokeVertex*> vertex_container; // the vertices container + typedef std::vector<ViewEdge*> viewedge_container; // the viewedges container + typedef StrokeInternal::vertex_iterator_base<StrokeInternal::vertex_nonconst_traits > vertex_iterator; + typedef StrokeInternal::vertex_iterator_base<StrokeInternal::vertex_const_traits> const_vertex_iterator; + +public: + //typedef StrokeVertex vertex_type; + +private: + vertex_container _Vertices; //! The stroke's backbone vertices + Id _id; + float _Length; // The stroke length + viewedge_container _ViewEdges; + float _sampling; + StrokeRenderer *_renderer; // mark implementation OpenGL renderer + MediumType _mediumType; + unsigned int _textureId; + bool _tips; + Vec2r _extremityOrientations[2]; // the orientations of the first and last extermity + StrokeRep *_rep; + +public: + /*! default constructor */ + Stroke(); + + /*! copy constructor */ + Stroke(const Stroke& iBrother); + + /*! Builds a stroke from a set of StrokeVertex. + * This constructor is templated by an iterator type. + * This iterator type must allow the vertices parsing using the ++ operator. + * \param iBegin + * The iterator pointing to the first vertex. + * \param iEnd + * The iterator pointing to the end of the vertex list. + */ + template<class InputVertexIterator> + Stroke(InputVertexIterator iBegin, InputVertexIterator iEnd); + + /*! Destructor */ + virtual ~Stroke(); + + /* operators */ + /*! operator = */ + Stroke& operator=(const Stroke& iBrother); + + /*! Compute the sampling needed to get iNVertices vertices. + * If the specified number of vertices is less than the actual number of vertices, the actual sampling value + * is returned. (To remove Vertices, use the RemoveVertex() method of this class). + * \param iNVertices + * The number of StrokeVertices we eventually want in our Stroke. + * \return the sampling that must be used in the Resample(float) method. + * @see Resample(int) + * @see Resample(float) + */ + float ComputeSampling(int iNVertices); + + /*! Resampling method. + * Resamples the curve so that it eventually has iNPoints. That means it is going to add iNPoints-vertices_size, + * if vertices_size is the number of points we already have. + * If vertices_size >= iNPoints, no resampling is done. + * \param iNPoints + * The number of vertices we eventually want in our stroke. + */ + void Resample(int iNPoints); + + /*! Resampling method. + * Resamples the curve with a given sampling. + * If this sampling is < to the actual sampling value, no resampling is done. + * \param iSampling + * The new sampling value. + */ + void Resample(float iSampling); + + /*! Removes the stroke vertex iVertex + * from the stroke. + * The length and curvilinear abscissa are updated + * consequently. + */ + void RemoveVertex(StrokeVertex *iVertex); + + /*! Inserts the stroke vertex iVertex in the stroke before next. + * The length, curvilinear abscissa are updated consequently. + * \param iVertex + * The StrokeVertex to insert in the Stroke. + * \param next + * A StrokeVertexIterator pointing to the StrokeVeretx before which iVertex must be inserted. + */ + void InsertVertex(StrokeVertex *iVertex, StrokeInternal::StrokeVertexIterator next); + + /*! Updates the 2D length of the Stroke */ + void UpdateLength(); + + /* Render method */ + void ScaleThickness(float iFactor); + void Render(const StrokeRenderer *iRenderer); + void RenderBasic(const StrokeRenderer *iRenderer); + + /* Iterator definition */ + + /* accessors */ + /*! Returns the 2D length of the Stroke */ + inline real getLength2D() const + { + return _Length; + } + + /*! Returns a reference to the time stamp value of the stroke. */ + /*! Returns the MediumType used for this Stroke. */ + inline MediumType getMediumType() const + { + return _mediumType; + } + + /*! Returns the id of the texture used to simulate th marks system for this Stroke */ + inline unsigned int getTextureId() {return _textureId;} + + /*! Returns true if this Stroke uses a texture with tips, false otherwise. */ + inline bool hasTips() const + { + return _tips; + } + + /* these advanced iterators are used only in C++ */ + inline int vertices_size() const + { + return _Vertices.size(); + } + + inline viewedge_container::const_iterator viewedges_begin() const + { + return _ViewEdges.begin(); + } + + inline viewedge_container::iterator viewedges_begin() + { + return _ViewEdges.begin(); + } + + inline viewedge_container::const_iterator viewedges_end() const + { + return _ViewEdges.end(); + } + + inline viewedge_container::iterator viewedges_end() + { + return _ViewEdges.end(); + } + + inline int viewedges_size() const + { + return _ViewEdges.size(); + } + + inline Vec2r getBeginningOrientation() const + { + return _extremityOrientations[0]; + } + + inline real getBeginningOrientationX() const + { + return _extremityOrientations[0].x(); + } + + inline real getBeginningOrientationY() const + { + return _extremityOrientations[0].y(); + } + + inline Vec2r getEndingOrientation() const + { + return _extremityOrientations[1]; + } + + inline real getEndingOrientationX() const + { + return _extremityOrientations[1].x(); + } + + inline real getEndingOrientationY() const + { + return _extremityOrientations[1].y(); + } + + + /* modifiers */ + /*! sets the Id of the Stroke. */ + inline void setId(const Id& id) + { + _id = id; + } + + /*! sets the 2D length of the Stroke. */ + void setLength(float iLength); + + /*! sets the medium type that must be used for this Stroke. */ + inline void setMediumType(MediumType iType) + { + _mediumType = iType; + } + + /*! sets the texture id to be used to simulate the marks system for this Stroke. */ + inline void setTextureId(unsigned int id) + { + _textureId = id; + } + + /*! sets the flag telling whether this stroke is using a texture with tips or not. */ + inline void setTips(bool iTips) + { + _tips = iTips; + } + + inline void push_back(StrokeVertex *iVertex) + { + _Vertices.push_back(iVertex); + } + + inline void push_front(StrokeVertex *iVertex) + { + _Vertices.push_front(iVertex); + } + + inline void AddViewEdge(ViewEdge *iViewEdge) + { + _ViewEdges.push_back(iViewEdge); + } + + inline void setBeginningOrientation(const Vec2r& iOrientation) + { + _extremityOrientations[0] = iOrientation; + } + + inline void setBeginningOrientation(real x, real y) + { + _extremityOrientations[0] = Vec2r(x, y); + } + + inline void setEndingOrientation(const Vec2r& iOrientation) + { + _extremityOrientations[1] = iOrientation; + } + + inline void setEndingOrientation(real x, real y) + { + _extremityOrientations[1] = Vec2r(x, y); + } + + /* Information access interface */ + + // embedding vertex iterator + const_vertex_iterator vertices_begin() const; + vertex_iterator vertices_begin(float t = 0.0f); + const_vertex_iterator vertices_end() const; + vertex_iterator vertices_end(); + + /*! Returns a StrokeVertexIterator pointing on the first StrokeVertex of the Stroke. One can specifly a sampling + * value to resample the Stroke on the fly if needed. + * \param t + * The resampling value with which we want our Stroke to be resampled. + * If 0 is specified, no resampling is done. + */ + StrokeInternal::StrokeVertexIterator strokeVerticesBegin(float t = 0.0f); + + /*! Returns a StrokeVertexIterator pointing after the last StrokeVertex of the Stroke. */ + StrokeInternal::StrokeVertexIterator strokeVerticesEnd(); + + /*! Returns the number of StrokeVertex constituing the Stroke. */ + inline unsigned int strokeVerticesSize() const + { + return _Vertices.size(); + } + + /*! Returns the i-th StrokeVertex constituting the Stroke. */ + inline StrokeVertex& strokeVerticeAt(unsigned int i) + { + return *(_Vertices.at(i)); + } + + // Iterator access (Interface1D) + /*! Returns an Interface0DIterator pointing on the first StrokeVertex of the Stroke. */ + virtual Interface0DIterator verticesBegin(); + + /*! Returns an Interface0DIterator pointing after the last StrokeVertex of the Stroke. */ + virtual Interface0DIterator verticesEnd(); + + virtual Interface0DIterator pointsBegin(float t = 0.0f); + virtual Interface0DIterator pointsEnd(float t = 0.0f); +}; + + +// +// Implementation +// +//////////////////////////////////////////////////////// + + +template<class InputVertexIterator> +Stroke::Stroke(InputVertexIterator iBegin, InputVertexIterator iEnd) +{ + for (InputVertexIterator v = iBegin, vend = iEnd; v != vend; v++) { + _Vertices.push_back(*v); + } + _Length = 0; + _id = 0; +} + +#endif // __FREESTYLE_STROKE_H__ |