diff options
Diffstat (limited to 'source/blender/freestyle/intern/stroke/Curve.h')
-rw-r--r-- | source/blender/freestyle/intern/stroke/Curve.h | 589 |
1 files changed, 589 insertions, 0 deletions
diff --git a/source/blender/freestyle/intern/stroke/Curve.h b/source/blender/freestyle/intern/stroke/Curve.h new file mode 100644 index 00000000000..f451d83d65b --- /dev/null +++ b/source/blender/freestyle/intern/stroke/Curve.h @@ -0,0 +1,589 @@ +/* + * ***** 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_CURVE_H__ +#define __FREESTYLE_CURVE_H__ + +/** \file blender/freestyle/intern/stroke/Curve.h + * \ingroup freestyle + * \brief Class to define a container for curves + * \author Stephane Grabli + * \date 11/01/2003 + */ + +#include <deque> + +#include "../geometry/Geom.h" + +//#include "../scene_graph/FrsMaterial.h" + +#include "../view_map/Interface0D.h" +#include "../view_map/Interface1D.h" +#include "../view_map/Silhouette.h" +#include "../view_map/SilhouetteGeomEngine.h" + +#include "../system/BaseIterator.h" + +using namespace std; +using namespace Geometry; + +/**********************************/ +/* */ +/* */ +/* CurvePoint */ +/* */ +/* */ +/**********************************/ + +/*! Class to represent a point of a curve. + * A CurvePoint can be any point of a 1D curve (it doesn't have to be a vertex of the curve). + * Any Interface1D is built upon ViewEdges, themselves built upon FEdges. Therefore, a curve is basically + * a polyline made of a list SVertex. + * Thus, a CurvePoint is built by lineraly interpolating two SVertex. + * CurvePoint can be used as virtual points while querying 0D information along a curve at a given resolution. + */ +class LIB_STROKE_EXPORT CurvePoint : public Interface0D +{ +public: // Implementation of Interface0D + /*! Returns the string "CurvePoint"*/ + virtual string getExactTypeName() const + { + return "CurvePoint"; + } + + // Data access methods + /*! Returns the 3D X coordinate of the point */ + virtual real getX() const + { + return _Point3d.x(); + } + + /*! Returns the 3D Y coordinate of the point */ + virtual real getY() const + { + return _Point3d.y(); + } + + /*! Returns the 3D Z coordinate of the point */ + virtual real getZ() const + { + return _Point3d.z(); + } + + /*! Returns the 3D point. */ + virtual Vec3f getPoint3D() const + { + return _Point3d; + } + + /*! Returns the projected 3D X coordinate of the point */ + virtual real getProjectedX() const + { + return _Point2d.x(); + } + + /*! Returns the projected 3D Y coordinate of the point */ + virtual real getProjectedY() const + { + return _Point2d.y(); + } + + /*! Returns the projected 3D Z coordinate of the point */ + virtual real getProjectedZ() const + { + return _Point2d.z(); + } + + /*! Returns the 2D point. */ + virtual Vec2f getPoint2D() const + { + return Vec2f((float)_Point2d.x(), (float)_Point2d.y()); + } + + virtual FEdge* getFEdge(Interface0D& inter); + + /*! Returns the CurvePoint's Id */ + virtual Id getId() const + { + Id id; + if (_t2d == 0) + return __A->getId(); + else if (_t2d == 1) + return __B->getId(); + return id; + } + + /*! Returns the CurvePoint's Nature */ + virtual Nature::VertexNature getNature() const + { + Nature::VertexNature nature = Nature::POINT; + if (_t2d == 0) + nature |= __A->getNature(); + else if (_t2d == 1) + nature |= __B->getNature(); + return nature; + } + + /*! Cast the Interface0D in SVertex if it can be. */ + virtual SVertex * castToSVertex() + { + if (_t2d == 0) + return __A; + else if (_t2d == 1) + return __B; + return Interface0D::castToSVertex(); + } + + /*! Cast the Interface0D in ViewVertex if it can be. */ + virtual ViewVertex * castToViewVertex() + { + if (_t2d == 0) + return __A->castToViewVertex(); + else if (_t2d == 1) + return __B->castToViewVertex(); + return Interface0D::castToViewVertex(); + } + + /*! Cast the Interface0D in NonTVertex if it can be. */ + virtual NonTVertex * castToNonTVertex() + { + if (_t2d == 0) + return __A->castToNonTVertex(); + else if (_t2d == 1) + return __B->castToNonTVertex(); + return Interface0D::castToNonTVertex(); + } + + /*! Cast the Interface0D in TVertex if it can be. */ + virtual TVertex * castToTVertex() + { + if (_t2d == 0) + return __A->castToTVertex(); + else if (_t2d == 1) + return __B->castToTVertex(); + return Interface0D::castToTVertex(); + } + +public: + typedef SVertex vertex_type; + +protected: + SVertex *__A; + SVertex *__B; + float _t2d; + //float _t3d; + Vec3r _Point2d; + Vec3r _Point3d; + +public: + /*! Defult Constructor. */ + CurvePoint(); + + /*! Builds a CurvePoint from two SVertex and an interpolation parameter. + * \param iA + * The first SVertex + * \param iB + * The second SVertex + * \param t2d + * A 2D interpolation parameter used to linearly interpolate \a iA and \a iB + */ + CurvePoint(SVertex *iA, SVertex *iB, float t2d); + + /*! Builds a CurvePoint from two CurvePoint and an interpolation parameter. + * \param iA + * The first CurvePoint + * \param iB + * The second CurvePoint + * \param t2d + * The 2D interpolation parameter used to linearly interpolate \a iA and \a iB. + */ + CurvePoint(CurvePoint *iA, CurvePoint *iB, float t2d); + + //CurvePoint(SVertex *iA, SVertex *iB, float t2d, float t3d); + + /*! Copy Constructor. */ + CurvePoint(const CurvePoint& iBrother); + + /*! Operator = */ + CurvePoint& operator=(const CurvePoint& iBrother); + + /*! Destructor */ + virtual ~CurvePoint() {} + + /*! Operator == */ + bool operator==(const CurvePoint& b) + { + return ((__A == b.__A) && (__B == b.__B) && (_t2d == b._t2d)); + } + + /* accessors */ + /*! Returns the first SVertex upon which the CurvePoint is built. */ + inline SVertex *A() + { + return __A; + } + + /*! Returns the second SVertex upon which the CurvePoint is built. */ + inline SVertex *B() + { + return __B; + } + + /*! Returns the interpolation parameter. */ + inline float t2d() const + { + return _t2d; + } + +#if 0 + inline const float t3d() const + { + return _t3d; + } +#endif + + /* modifiers */ + /*! Sets the first SVertex upon which to build the CurvePoint. */ + inline void setA(SVertex *iA) + { + __A = iA; + } + + /*! Sets the second SVertex upon which to build the CurvePoint. */ + inline void setB(SVertex *iB) + { + __B = iB; + } + + /*! Sets the 2D interpolation parameter to use. */ + inline void setT2d(float t) + { + _t2d = t; + } + +#if 0 + inline void SetT3d(float t) + { + _t3d = t; + } +#endif + + /* Information access interface */ + + FEdge *fedge(); + + inline const Vec3r& point2d() const + { + return _Point2d; + } + + inline const Vec3r& point3d() const + { + return _Point3d; + } + + Vec3r normal() const; + //FrsMaterial material() const; + //Id shape_id() const; + const SShape *shape() const; + //float shape_importance() const; + + //const unsigned qi() const; + occluder_container::const_iterator occluders_begin() const; + occluder_container::const_iterator occluders_end() const; + bool occluders_empty() const; + int occluders_size() const; + const Polygon3r& occludee() const; + const SShape *occluded_shape() const; + const bool occludee_empty() const; + real z_discontinuity() const; +#if 0 + float local_average_depth() const; + float local_depth_variance() const; + real local_average_density(float sigma = 2.3f) const; + Vec3r shaded_color() const; + Vec3r orientation2d() const; + Vec3r orientation3d() const; + + real curvature2d() const + { + return viewedge()->curvature2d((_VertexA->point2d() + _VertexB->point2d()) / 2.0); + } + + Vec3r curvature2d_as_vector() const; + /*! angle in radians */ + real curvature2d_as_angle() const; +#endif + + real curvatureFredo() const; + Vec2d directionFredo() const; +}; + + +/**********************************/ +/* */ +/* */ +/* Curve */ +/* */ +/* */ +/**********************************/ + +namespace CurveInternal { + +class CurvePoint_const_traits; +class CurvePoint_nonconst_traits; +template<class Traits> class __point_iterator; +class CurvePointIterator; + +} // end of namespace CurveInternal + +/*! Base class for curves made of CurvePoints. + * SVertex is the type of the initial curve vertices. + * A Chain is a specialization of a Curve. + */ +class LIB_STROKE_EXPORT Curve : public Interface1D +{ +public: + typedef CurvePoint Vertex; + typedef CurvePoint Point; + typedef Point point_type; + typedef Vertex vertex_type; + typedef deque<Vertex*> vertex_container; + + /* Iterator to iterate over a vertex edges */ + + typedef CurveInternal::__point_iterator<CurveInternal::CurvePoint_nonconst_traits > point_iterator; + typedef CurveInternal::__point_iterator<CurveInternal::CurvePoint_const_traits > const_point_iterator; + typedef point_iterator vertex_iterator ; + typedef const_point_iterator const_vertex_iterator ; + +protected: + vertex_container _Vertices; + double _Length; + Id _Id; + unsigned _nSegments; // number of segments + +public: + /*! Default Constructor. */ + Curve() + { + _Length = 0; + _Id = 0; + _nSegments = 0; + } + + /*! Builds a Curve from its id */ + Curve(const Id& id) + { + _Length = 0; + _Id = id; + _nSegments = 0; + } + + /*! Copy Constructor. */ + Curve(const Curve& iBrother) + { + _Length = iBrother._Length; + _Vertices = iBrother._Vertices; + _Id = iBrother._Id; + _nSegments = 0; + } + + /*! Destructor. */ + virtual ~Curve(); + + /*! Returns the string "Curve" */ + virtual string getExactTypeName() const + { + return "Curve"; + } + + /* fredo's curvature storage */ + void computeCurvatureAndOrientation(); + + /*! Adds a single vertex (CurvePoint) at the end of the Curve */ + inline void push_vertex_back(Vertex *iVertex) + { + if (!_Vertices.empty()) { + Vec3r vec_tmp(iVertex->point2d() - _Vertices.back()->point2d()); + _Length += vec_tmp.norm(); + ++_nSegments; + } + Vertex *new_vertex = new Vertex(*iVertex); + _Vertices.push_back(new_vertex); + } + + /*! Adds a single vertex (SVertex) at the end of the Curve */ + inline void push_vertex_back(SVertex *iVertex) + { + if (!_Vertices.empty()) { + Vec3r vec_tmp(iVertex->point2d() - _Vertices.back()->point2d()); + _Length += vec_tmp.norm(); + ++_nSegments; + } + Vertex *new_vertex = new Vertex(iVertex, 0, 0); + _Vertices.push_back(new_vertex); + } + + /*! Adds a single vertex (CurvePoint) at the front of the Curve */ + inline void push_vertex_front(Vertex *iVertex) + { + if (!_Vertices.empty()) { + Vec3r vec_tmp(iVertex->point2d() - _Vertices.front()->point2d()); + _Length += vec_tmp.norm(); + ++_nSegments; + } + Vertex *new_vertex = new Vertex(*iVertex); + _Vertices.push_front(new_vertex); + } + + /*! Adds a single vertex (SVertex) at the front of the Curve */ + inline void push_vertex_front(SVertex *iVertex) + { + if (!_Vertices.empty()) { + Vec3r vec_tmp(iVertex->point2d() - _Vertices.front()->point2d()); + _Length += vec_tmp.norm(); + ++_nSegments; + } + Vertex *new_vertex = new Vertex(iVertex, 0, 0); + _Vertices.push_front(new_vertex); + } + + /*! Returns true is the Curve doesn't have any Vertex yet. */ + inline bool empty() const + { + return _Vertices.empty(); + } + + /*! Returns the 2D length of the Curve. */ + inline real getLength2D() const + { + return _Length; + } + + /*! Returns the Id of the 1D element. */ + virtual Id getId() const + { + return _Id; + } + + /*! Returns the number of segments in the polyline constituing the Curve. */ + inline unsigned int nSegments() const + { + return _nSegments; + } + + inline void setId(const Id& id) + { + _Id = id; + } + + /* Information access interface */ + +#if 0 + inline Vec3r shaded_color(int iCombination = 0) const; + inline Vec3r orientation2d(point_iterator it) const; + Vec3r orientation2d(int iCombination = 0) const; + Vec3r orientation3d(point_iterator it) const; + Vec3r orientation3d(int iCombination = 0) const; + + real curvature2d(point_iterator it) const + { + return (*it)->curvature2d(); + } + + real curvature2d(int iCombination = 0) const; + FrsMaterial material() const; + int qi() const; + occluder_container::const_iterator occluders_begin() const; + occluder_container::const_iterator occluders_end() const; + int occluders_size() const; + bool occluders_empty() const; + + const Polygon3r& occludee() const + { + return *(_FEdgeA->aFace()); + } + + const SShape *occluded_shape() const; + const bool occludee_empty() const; + real z_discontinuity(int iCombination = 0) const; + int shape_id() const; + const SShape *shape() const; + float shape_importance(int iCombination = 0) const; + float local_average_depth(int iCombination = 0) const; + float local_depth_variance(int iCombination = 0) const; + real local_average_density(float sigma = 2.3f, int iCombination = 0) const; + Vec3r curvature2d_as_vector(int iCombination = 0) const; + /*! angle in radians */ + real curvature2d_as_angle(int iCombination = 0) const; +#endif + + /* advanced iterators access */ + point_iterator points_begin(float step = 0); + const_point_iterator points_begin(float step = 0) const; + point_iterator points_end(float step = 0); + const_point_iterator points_end(float step = 0) const; + + /* methods given for convenience */ + point_iterator vertices_begin(); + const_point_iterator vertices_begin() const; + point_iterator vertices_end(); + const_point_iterator vertices_end() const; + + // specialized iterators access + CurveInternal::CurvePointIterator curvePointsBegin(float t = 0.0f); + CurveInternal::CurvePointIterator curvePointsEnd(float t = 0.0f); + + CurveInternal::CurvePointIterator curveVerticesBegin(); + CurveInternal::CurvePointIterator curveVerticesEnd(); + + // Iterators access + /*! Returns an Interface0DIterator pointing onto the first vertex of the Curve and that can iterate + * over the \a vertices of the Curve. + */ + virtual Interface0DIterator verticesBegin(); + + /*! Returns an Interface0DIterator pointing after the last vertex of the Curve and that can iterate + * over the \a vertices of the Curve. + */ + virtual Interface0DIterator verticesEnd(); + + /*! Returns an Interface0DIterator pointing onto the first point of the Curve and that can iterate + * over the \a points of the Curve at any resolution. + * At each iteration a virtual temporary CurvePoint is created. + */ + virtual Interface0DIterator pointsBegin(float t = 0.0f); + + /*! Returns an Interface0DIterator pointing after the last point of the Curve and that can iterate + * over the \a points of the Curve at any resolution. + * At each iteration a virtual temporary CurvePoint is created. + */ + virtual Interface0DIterator pointsEnd(float t = 0.0f); +}; + +#endif // __FREESTYLE_CURVE_H__ |