From e5791cf48e10ec1336f463b7fccff6b302621eb9 Mon Sep 17 00:00:00 2001 From: Tamito Kajiyama Date: Fri, 28 Dec 2012 20:21:05 +0000 Subject: Another mega (literally :p) code clean-up patch by Bastien Montagne, thanks again! --- .../freestyle/intern/scene_graph/DrawingStyle.h | 176 +- .../freestyle/intern/scene_graph/FrsMaterial.h | 573 ++--- .../intern/scene_graph/IndexedFaceSet.cpp | 589 +++-- .../freestyle/intern/scene_graph/IndexedFaceSet.h | 475 ++-- .../freestyle/intern/scene_graph/LineRep.cpp | 115 +- .../blender/freestyle/intern/scene_graph/LineRep.h | 266 ++- source/blender/freestyle/intern/scene_graph/Node.h | 188 +- .../freestyle/intern/scene_graph/NodeCamera.cpp | 203 +- .../freestyle/intern/scene_graph/NodeCamera.h | 354 +-- .../intern/scene_graph/NodeDrawingStyle.cpp | 68 +- .../intern/scene_graph/NodeDrawingStyle.h | 155 +- .../freestyle/intern/scene_graph/NodeGroup.cpp | 192 +- .../freestyle/intern/scene_graph/NodeGroup.h | 135 +- .../freestyle/intern/scene_graph/NodeLight.cpp | 132 +- .../freestyle/intern/scene_graph/NodeLight.h | 173 +- .../freestyle/intern/scene_graph/NodeShape.cpp | 96 +- .../freestyle/intern/scene_graph/NodeShape.h | 168 +- .../freestyle/intern/scene_graph/NodeTransform.cpp | 274 +-- .../freestyle/intern/scene_graph/NodeTransform.h | 197 +- .../intern/scene_graph/OrientedLineRep.cpp | 65 +- .../freestyle/intern/scene_graph/OrientedLineRep.h | 105 +- .../blender/freestyle/intern/scene_graph/Rep.cpp | 34 + source/blender/freestyle/intern/scene_graph/Rep.h | 256 ++- .../intern/scene_graph/ScenePrettyPrinter.cpp | 126 +- .../intern/scene_graph/ScenePrettyPrinter.h | 198 +- .../freestyle/intern/scene_graph/SceneVisitor.cpp | 34 + .../freestyle/intern/scene_graph/SceneVisitor.h | 134 +- .../freestyle/intern/scene_graph/TriangleRep.cpp | 114 +- .../freestyle/intern/scene_graph/TriangleRep.h | 228 +- .../freestyle/intern/scene_graph/VertexRep.cpp | 56 +- .../freestyle/intern/scene_graph/VertexRep.h | 208 +- .../intern/stroke/AdvancedFunctions0D.cpp | 183 +- .../freestyle/intern/stroke/AdvancedFunctions0D.h | 410 ++-- .../intern/stroke/AdvancedFunctions1D.cpp | 220 +- .../freestyle/intern/stroke/AdvancedFunctions1D.h | 554 ++--- .../freestyle/intern/stroke/AdvancedPredicates1D.h | 149 +- .../intern/stroke/AdvancedStrokeShaders.cpp | 647 +++--- .../intern/stroke/AdvancedStrokeShaders.h | 340 +-- .../freestyle/intern/stroke/BasicStrokeShaders.cpp | 2128 +++++++++--------- .../freestyle/intern/stroke/BasicStrokeShaders.h | 1758 +++++++-------- source/blender/freestyle/intern/stroke/Canvas.cpp | 718 +++--- source/blender/freestyle/intern/stroke/Canvas.h | 383 ++-- source/blender/freestyle/intern/stroke/Chain.cpp | 275 +-- source/blender/freestyle/intern/stroke/Chain.h | 177 +- .../freestyle/intern/stroke/ChainingIterators.cpp | 320 +-- .../freestyle/intern/stroke/ChainingIterators.h | 683 +++--- .../freestyle/intern/stroke/ContextFunctions.cpp | 133 +- .../freestyle/intern/stroke/ContextFunctions.h | 204 +- source/blender/freestyle/intern/stroke/Curve.cpp | 1670 +++++++------- source/blender/freestyle/intern/stroke/Curve.h | 990 +++++---- .../intern/stroke/CurveAdvancedIterators.h | 755 +++---- .../freestyle/intern/stroke/CurveIterators.h | 591 ++--- source/blender/freestyle/intern/stroke/Modifiers.h | 105 +- source/blender/freestyle/intern/stroke/Module.h | 122 +- .../blender/freestyle/intern/stroke/Operators.cpp | 2287 ++++++++++---------- source/blender/freestyle/intern/stroke/Operators.h | 561 +++-- .../freestyle/intern/stroke/PSStrokeRenderer.cpp | 167 +- .../freestyle/intern/stroke/PSStrokeRenderer.h | 96 +- .../blender/freestyle/intern/stroke/Predicates0D.h | 270 +-- .../blender/freestyle/intern/stroke/Predicates1D.h | 1027 ++++----- .../freestyle/intern/stroke/QInformationMap.h | 107 +- source/blender/freestyle/intern/stroke/Stroke.cpp | 1609 +++++++------- source/blender/freestyle/intern/stroke/Stroke.h | 1264 ++++++----- .../intern/stroke/StrokeAdvancedIterators.h | 317 +-- .../blender/freestyle/intern/stroke/StrokeIO.cpp | 110 +- source/blender/freestyle/intern/stroke/StrokeIO.h | 80 +- .../freestyle/intern/stroke/StrokeIterators.h | 444 ++-- .../freestyle/intern/stroke/StrokeLayer.cpp | 92 +- .../blender/freestyle/intern/stroke/StrokeLayer.h | 162 +- .../freestyle/intern/stroke/StrokeRenderer.cpp | 135 +- .../freestyle/intern/stroke/StrokeRenderer.h | 219 +- .../blender/freestyle/intern/stroke/StrokeRep.cpp | 1384 ++++++------ source/blender/freestyle/intern/stroke/StrokeRep.h | 305 ++- .../blender/freestyle/intern/stroke/StrokeShader.h | 165 +- .../freestyle/intern/stroke/StrokeTesselator.cpp | 146 +- .../freestyle/intern/stroke/StrokeTesselator.h | 113 +- .../blender/freestyle/intern/stroke/StyleModule.h | 298 +-- .../freestyle/intern/stroke/TextStrokeRenderer.h | 2 +- .../blender/freestyle/intern/system/BaseIterator.h | 127 +- .../blender/freestyle/intern/system/BaseObject.cpp | 35 + .../blender/freestyle/intern/system/BaseObject.h | 118 +- source/blender/freestyle/intern/system/Cast.h | 83 +- .../blender/freestyle/intern/system/Exception.cpp | 51 +- source/blender/freestyle/intern/system/Exception.h | 106 +- .../freestyle/intern/system/FreestyleConfig.h | 150 +- source/blender/freestyle/intern/system/Id.h | 244 ++- .../blender/freestyle/intern/system/Interpreter.h | 97 +- .../blender/freestyle/intern/system/Iterator.cpp | 31 + source/blender/freestyle/intern/system/Iterator.h | 86 +- .../freestyle/intern/system/PointerSequence.h | 161 +- source/blender/freestyle/intern/system/Precision.h | 71 +- .../blender/freestyle/intern/system/ProgressBar.h | 161 +- .../freestyle/intern/system/PseudoNoise.cpp | 167 +- .../blender/freestyle/intern/system/PseudoNoise.h | 98 +- .../freestyle/intern/system/PythonInterpreter.cpp | 55 +- .../freestyle/intern/system/PythonInterpreter.h | 296 +-- source/blender/freestyle/intern/system/RandGen.cpp | 174 +- source/blender/freestyle/intern/system/RandGen.h | 86 +- .../freestyle/intern/system/RenderMonitor.h | 82 +- .../freestyle/intern/system/StringUtils.cpp | 111 +- .../blender/freestyle/intern/system/StringUtils.h | 105 +- .../blender/freestyle/intern/system/TimeStamp.cpp | 55 +- source/blender/freestyle/intern/system/TimeStamp.h | 123 +- source/blender/freestyle/intern/system/TimeUtils.h | 102 +- 104 files changed, 17992 insertions(+), 15945 deletions(-) (limited to 'source/blender/freestyle/intern') diff --git a/source/blender/freestyle/intern/scene_graph/DrawingStyle.h b/source/blender/freestyle/intern/scene_graph/DrawingStyle.h index 58dcf4fede9..000b6c8575d 100644 --- a/source/blender/freestyle/intern/scene_graph/DrawingStyle.h +++ b/source/blender/freestyle/intern/scene_graph/DrawingStyle.h @@ -1,82 +1,128 @@ -// -// Filename : DrawingStyle.h -// Author(s) : Stephane Grabli -// Purpose : Class to define the drawing style of a node -// Date of creation : 10/10/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef DRAWINGSTYLE_H -# define DRAWINGSTYLE_H +/* + * ***** 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_DRAWING_STYLE_H__ +#define __FREESTYLE_DRAWING_STYLE_H__ + +/** \file blender/freestyle/intern/scene_graph/DrawingStyle.h + * \ingroup freestyle + * \brief Class to define the drawing style of a node + * \author Stephane Grabli + * \date 10/10/2002 + */ class DrawingStyle { public: - enum STYLE - {FILLED, LINES, POINTS, INVISIBLE}; - - inline DrawingStyle() {Style = FILLED; LineWidth = 2.f; PointSize = 2.f; LightingEnabled = true;} - inline explicit DrawingStyle(const DrawingStyle& iBrother); - - virtual ~DrawingStyle() {} - - /*! operators */ - inline DrawingStyle& operator=(const DrawingStyle& ds); - - inline void setStyle(const STYLE iStyle) {Style = iStyle;} - inline void setLineWidth(const float iLineWidth) {LineWidth = iLineWidth;} - inline void setPointSize(const float iPointSize) {PointSize = iPointSize;} - inline void setLightingEnabled(const bool on) {LightingEnabled = on;} - - inline STYLE style() const {return Style;} - inline float lineWidth() const {return LineWidth;} - inline float pointSize() const {return PointSize;} - inline bool lightingEnabled() const {return LightingEnabled;} + enum STYLE { + FILLED, + LINES, + POINTS, + INVISIBLE, + }; + + inline DrawingStyle() + { + Style = FILLED; + LineWidth = 2.0f; + PointSize = 2.0f; + LightingEnabled = true; + } + + inline explicit DrawingStyle(const DrawingStyle& iBrother); + + virtual ~DrawingStyle() {} + + /*! operators */ + inline DrawingStyle& operator=(const DrawingStyle& ds); + + inline void setStyle(const STYLE iStyle) + { + Style = iStyle; + } + + inline void setLineWidth(const float iLineWidth) + { + LineWidth = iLineWidth; + } + + inline void setPointSize(const float iPointSize) + { + PointSize = iPointSize; + } + + inline void setLightingEnabled(const bool on) + { + LightingEnabled = on; + } + + inline STYLE style() const + { + return Style; + } + + inline float lineWidth() const + { + return LineWidth; + } + + inline float pointSize() const + { + return PointSize; + } + + inline bool lightingEnabled() const + { + return LightingEnabled; + } private: - STYLE Style; - float LineWidth; - float PointSize; - bool LightingEnabled; + STYLE Style; + float LineWidth; + float PointSize; + bool LightingEnabled; }; DrawingStyle::DrawingStyle(const DrawingStyle& iBrother) { - Style = iBrother.Style; - LineWidth = iBrother.LineWidth; - PointSize = iBrother.PointSize; - LightingEnabled = iBrother.LightingEnabled; + Style = iBrother.Style; + LineWidth = iBrother.LineWidth; + PointSize = iBrother.PointSize; + LightingEnabled = iBrother.LightingEnabled; } DrawingStyle& DrawingStyle::operator=(const DrawingStyle& ds) { - Style = ds.Style; - LineWidth = ds.LineWidth; - PointSize = ds.PointSize; - LightingEnabled = ds.LightingEnabled; + Style = ds.Style; + LineWidth = ds.LineWidth; + PointSize = ds.PointSize; + LightingEnabled = ds.LightingEnabled; - return *this; + return *this; } -#endif // DRAWINGSTYLE_H +#endif // __FREESTYLE_DRAWING_STYLE_H__ diff --git a/source/blender/freestyle/intern/scene_graph/FrsMaterial.h b/source/blender/freestyle/intern/scene_graph/FrsMaterial.h index 1cbadab2bd3..831c384d472 100644 --- a/source/blender/freestyle/intern/scene_graph/FrsMaterial.h +++ b/source/blender/freestyle/intern/scene_graph/FrsMaterial.h @@ -1,304 +1,379 @@ -// -// Filename : FrsMaterial.h -// Author(s) : Stephane Grabli -// Purpose : Class used to handle materials. -// Date of creation : 10/10/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef FRS_MATERIAL_H -# define FRS_MATERIAL_H - -# include "../system/FreestyleConfig.h" +/* + * ***** 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_MATERIAL_H__ +#define __FREESTYLE_MATERIAL_H__ + +/** \file blender/freestyle/intern/scene_graph/FrsMaterial.h + * \ingroup freestyle + * \brief Class used to handle materials. + * \author Stephane Grabli + * \date 10/10/2002 + */ + +#include "../system/FreestyleConfig.h" /*! Class defining a material */ class FrsMaterial { public: - /*! Default constructor */ - inline FrsMaterial(); - /*! Builds a Material from its diffuse, ambiant, specular, emissive - * colors and a shininess coefficient. - * \param iDiffuse - * A 4 element float-array containing the diffuse color. - * \param iAmbiant - * A 4 element float-array containing the ambiant color. - * \param iSpecular - * A 4 element float-array containing the specular color. - * \param iEmission - * A 4 element float-array containing the emissive color. - * \param iShininess - * The shininess coefficient. - */ - inline FrsMaterial(const float *iDiffuse, - const float *iAmbiant, - const float *iSpecular, - const float *iEmission, - const float iShininess); - - /*! Copy constructor */ - inline FrsMaterial(const FrsMaterial& m); - /*! Destructor */ - virtual ~FrsMaterial() {} - - - /*! Returns the diffuse color as a 4 float array */ - inline const float * diffuse() const { return Diffuse; } - /*! Returns the red component of the diffuse color */ - inline const float diffuseR() const { return Diffuse[0]; } - /*! Returns the green component of the diffuse color */ - inline const float diffuseG() const { return Diffuse[1]; } - /*! Returns the blue component of the diffuse color */ - inline const float diffuseB() const { return Diffuse[2]; } - /*! Returns the alpha component of the diffuse color */ - inline const float diffuseA() const { return Diffuse[3]; } - - /*! Returns the specular color as a 4 float array */ - inline const float * specular() const { return Specular; } - /*! Returns the red component of the specular color */ - inline const float specularR() const { return Specular[0]; } - /*! Returns the green component of the specular color */ - inline const float specularG() const { return Specular[1]; } - /*! Returns the blue component of the specular color */ - inline const float specularB() const { return Specular[2]; } - /*! Returns the alpha component of the specular color */ - inline const float specularA() const { return Specular[3]; } - - /*! Returns the ambiant color as a 4 float array */ - inline const float * ambient() const { return Ambient; } - /*! Returns the red component of the ambiant color */ - inline const float ambientR() const { return Ambient[0]; } - /*! Returns the green component of the ambiant color */ - inline const float ambientG() const { return Ambient[1]; } - /*! Returns the blue component of the ambiant color */ - inline const float ambientB() const { return Ambient[2]; } - /*! Returns the alpha component of the ambiant color */ - inline const float ambientA() const { return Ambient[3]; } - - /*! Returns the emissive color as a 4 float array */ - inline const float * emission() const { return Emission; } - /*! Returns the red component of the emissive color */ - inline const float emissionR() const { return Emission[0]; } - /*! Returns the green component of the emissive color */ - inline const float emissionG() const { return Emission[1]; } - /*! Returns the blue component of the emissive color */ - inline const float emissionB() const { return Emission[2]; } - /*! Returns the alpha component of the emissive color */ - inline const float emissionA() const { return Emission[3]; } - - /*! Returns the shininess coefficient */ - inline const float shininess() const { return Shininess; } - - /*! Sets the diffuse color. - * \param r - * Red component - * \param g - * Green component - * \param b - * Blue component - * \param a - * Alpha component - */ - inline void setDiffuse(const float r, const float g, const float b, const float a); - /*! Sets the specular color. - * \param r - * Red component - * \param g - * Green component - * \param b - * Blue component - * \param a - * Alpha component - */ - inline void setSpecular(const float r, const float g, const float b, const float a); - /*! Sets the ambiant color. - * \param r - * Red component - * \param g - * Green component - * \param b - * Blue component - * \param a - * Alpha component - */ - inline void setAmbient(const float r, const float g, const float b, const float a); - - /*! Sets the emissive color. - * \param r - * Red component - * \param g - * Green component - * \param b - * Blue component - * \param a - * Alpha component - */ - inline void setEmission(const float r, const float g, const float b, const float a); - - /*! Sets the shininess. - * \param s - * Shininess - */ - inline void setShininess(const float s); - - /* operators */ - inline FrsMaterial& operator=(const FrsMaterial& m); - inline bool operator!=(const FrsMaterial& m) const; - inline bool operator==(const FrsMaterial& m) const; + /*! Default constructor */ + inline FrsMaterial(); + + /*! Builds a Material from its diffuse, ambiant, specular, emissive colors and a shininess coefficient. + * \param iDiffuse + * A 4 element float-array containing the diffuse color. + * \param iAmbiant + * A 4 element float-array containing the ambiant color. + * \param iSpecular + * A 4 element float-array containing the specular color. + * \param iEmission + * A 4 element float-array containing the emissive color. + * \param iShininess + * The shininess coefficient. + */ + inline FrsMaterial(const float *iDiffuse, const float *iAmbiant, const float *iSpecular, const float *iEmission, + const float iShininess); + + /*! Copy constructor */ + inline FrsMaterial(const FrsMaterial& m); + + /*! Destructor */ + virtual ~FrsMaterial() {} + + + /*! Returns the diffuse color as a 4 float array */ + inline const float *diffuse() const + { + return Diffuse; + } + + /*! Returns the red component of the diffuse color */ + inline const float diffuseR() const + { + return Diffuse[0]; + } + + /*! Returns the green component of the diffuse color */ + inline const float diffuseG() const + { + return Diffuse[1]; + } + + /*! Returns the blue component of the diffuse color */ + inline const float diffuseB() const + { + return Diffuse[2]; + } + + /*! Returns the alpha component of the diffuse color */ + inline const float diffuseA() const + { + return Diffuse[3]; + } + + /*! Returns the specular color as a 4 float array */ + inline const float *specular() const + { + return Specular; + } + + /*! Returns the red component of the specular color */ + inline const float specularR() const + { + return Specular[0]; + } + + /*! Returns the green component of the specular color */ + inline const float specularG() const + { + return Specular[1]; + } + + /*! Returns the blue component of the specular color */ + inline const float specularB() const + { + return Specular[2]; + } + + /*! Returns the alpha component of the specular color */ + inline const float specularA() const + { + return Specular[3]; + } + + /*! Returns the ambiant color as a 4 float array */ + inline const float *ambient() const + { + return Ambient; + } + + /*! Returns the red component of the ambiant color */ + inline const float ambientR() const + { + return Ambient[0]; + } + + /*! Returns the green component of the ambiant color */ + inline const float ambientG() const + { + return Ambient[1]; + } + + /*! Returns the blue component of the ambiant color */ + inline const float ambientB() const + { + return Ambient[2]; + } + + /*! Returns the alpha component of the ambiant color */ + inline const float ambientA() const + { + return Ambient[3]; + } + + /*! Returns the emissive color as a 4 float array */ + inline const float *emission() const + { + return Emission; + } + + /*! Returns the red component of the emissive color */ + inline const float emissionR() const + { + return Emission[0]; + } + + /*! Returns the green component of the emissive color */ + inline const float emissionG() const + { + return Emission[1]; + } + + /*! Returns the blue component of the emissive color */ + inline const float emissionB() const + { + return Emission[2]; + } + + /*! Returns the alpha component of the emissive color */ + inline const float emissionA() const + { + return Emission[3]; + } + + /*! Returns the shininess coefficient */ + inline const float shininess() const + { + return Shininess; + } + + /*! Sets the diffuse color. + * \param r + * Red component + * \param g + * Green component + * \param b + * Blue component + * \param a + * Alpha component + */ + inline void setDiffuse(const float r, const float g, const float b, const float a); + + /*! Sets the specular color. + * \param r + * Red component + * \param g + * Green component + * \param b + * Blue component + * \param a + * Alpha component + */ + inline void setSpecular(const float r, const float g, const float b, const float a); + + /*! Sets the ambiant color. + * \param r + * Red component + * \param g + * Green component + * \param b + * Blue component + * \param a + * Alpha component + */ + inline void setAmbient(const float r, const float g, const float b, const float a); + + /*! Sets the emissive color. + * \param r + * Red component + * \param g + * Green component + * \param b + * Blue component + * \param a + * Alpha component + */ + inline void setEmission(const float r, const float g, const float b, const float a); + + /*! Sets the shininess. + * \param s + * Shininess + */ + inline void setShininess(const float s); + + /* operators */ + inline FrsMaterial& operator=(const FrsMaterial& m); + inline bool operator!=(const FrsMaterial& m) const; + inline bool operator==(const FrsMaterial& m) const; private: - - /*! Material properties */ - float Diffuse[4]; - float Specular[4]; - float Ambient[4]; - float Emission[4]; - float Shininess; - + /*! Material properties */ + float Diffuse[4]; + float Specular[4]; + float Ambient[4]; + float Emission[4]; + float Shininess; }; FrsMaterial::FrsMaterial() { - Ambient[0] = Ambient[1] = Ambient[2] = 0.2f; - Ambient[3] = 1.f; + Ambient[0] = Ambient[1] = Ambient[2] = 0.2f; + Ambient[3] = 1.0f; - Diffuse[0] = Diffuse[1] = Diffuse[2] = 0.8f; - Diffuse[3] = 1.f; + Diffuse[0] = Diffuse[1] = Diffuse[2] = 0.8f; + Diffuse[3] = 1.0f; - Emission[0] = Emission[1] = Emission[2] = 0.f; - Emission[3] = 1.f; + Emission[0] = Emission[1] = Emission[2] = 0.0f; + Emission[3] = 1.0f; - Specular[0] = Specular[1] = Specular[2] = 0.f; - Specular[3] = 1.f; + Specular[0] = Specular[1] = Specular[2] = 0.0f; + Specular[3] = 1.0f; - Shininess = 0.f; + Shininess = 0.0f; } -FrsMaterial::FrsMaterial(const float *iDiffuse, - const float *iAmbiant, - const float *iSpecular, - const float *iEmission, - const float iShininess) +FrsMaterial::FrsMaterial(const float *iDiffuse, const float *iAmbiant, const float *iSpecular, const float *iEmission, + const float iShininess) { - for(int i=0; i<4; i++) - { - Diffuse[i] = iDiffuse[i]; - Specular[i] = iSpecular[i]; - Ambient[i] = iAmbiant[i]; - Emission[i] = iEmission[i]; - } - - Shininess = iShininess; + for (int i = 0; i < 4; i++) { + Diffuse[i] = iDiffuse[i]; + Specular[i] = iSpecular[i]; + Ambient[i] = iAmbiant[i]; + Emission[i] = iEmission[i]; + } + + Shininess = iShininess; } FrsMaterial::FrsMaterial(const FrsMaterial& m) { - for(int i=0; i<4; i++) - { - Diffuse[i] = m.diffuse()[i]; - Specular[i] = m.specular()[i]; - Ambient[i] = m.ambient()[i]; - Emission[i] = m.emission()[i]; - } - - Shininess = m.shininess(); + for (int i = 0; i < 4; i++) { + Diffuse[i] = m.diffuse()[i]; + Specular[i] = m.specular()[i]; + Ambient[i] = m.ambient()[i]; + Emission[i] = m.emission()[i]; + } + + Shininess = m.shininess(); } void FrsMaterial::setDiffuse(const float r, const float g, const float b, const float a) { - Diffuse[0] = r; - Diffuse[1] = g; - Diffuse[2] = b; - Diffuse[3] = a; + Diffuse[0] = r; + Diffuse[1] = g; + Diffuse[2] = b; + Diffuse[3] = a; } void FrsMaterial::setSpecular(const float r, const float g, const float b, const float a) { - Specular[0] = r; - Specular[1] = g; - Specular[2] = b; - Specular[3] = a; + Specular[0] = r; + Specular[1] = g; + Specular[2] = b; + Specular[3] = a; } - + void FrsMaterial::setAmbient(const float r, const float g, const float b, const float a) { - Ambient[0] = r; - Ambient[1] = g; - Ambient[2] = b; - Ambient[3] = a; + Ambient[0] = r; + Ambient[1] = g; + Ambient[2] = b; + Ambient[3] = a; } void FrsMaterial::setEmission(const float r, const float g, const float b, const float a) { - Emission[0] = r; - Emission[1] = g; - Emission[2] = b; - Emission[3] = a; + Emission[0] = r; + Emission[1] = g; + Emission[2] = b; + Emission[3] = a; } void FrsMaterial::setShininess(const float s) { - Shininess = s; + Shininess = s; } FrsMaterial& FrsMaterial::operator=(const FrsMaterial& m) { - for(int i=0; i<4; i++) - { - Diffuse[i] = m.diffuse()[i]; - Specular[i] = m.specular()[i]; - Ambient[i] = m.ambient()[i]; - Emission[i] = m.emission()[i]; - } - - Shininess = m.shininess(); - - return *this; + for (int i = 0; i < 4; i++) { + Diffuse[i] = m.diffuse()[i]; + Specular[i] = m.specular()[i]; + Ambient[i] = m.ambient()[i]; + Emission[i] = m.emission()[i]; + } + + Shininess = m.shininess(); + return *this; } bool FrsMaterial::operator!=(const FrsMaterial& m) const { - if(Shininess != m.shininess()) - return true; - for(int i=0; i<4; i++) - { - if(Diffuse[i] != m.diffuse()[i]) - return true; - if(Specular[i] != m.specular()[i]) - return true; - if(Ambient[i] != m.ambient()[i]) - return true; - if(Emission[i] != m.emission()[i]) - return true; - } - - return false; + if (Shininess != m.shininess()) + return true; + + for (int i = 0; i < 4; i++) { + if (Diffuse[i] != m.diffuse()[i]) + return true; + if (Specular[i] != m.specular()[i]) + return true; + if (Ambient[i] != m.ambient()[i]) + return true; + if (Emission[i] != m.emission()[i]) + return true; + } + + return false; } bool FrsMaterial::operator==(const FrsMaterial& m) const { - return (!((*this)!=m)); + return (!((*this) != m)); } -#endif // FRS_MATERIAL_H +#endif // __FREESTYLE_MATERIAL_H__ diff --git a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp index aaeba943ab6..f373b730d0f 100644 --- a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp +++ b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp @@ -1,336 +1,331 @@ - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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 ***** + */ + +/** \file blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp + * \ingroup freestyle + * \brief A Set of indexed faces to represent a surfacic object + * \author Stephane Grabli + * \date 22/01/2002 + */ #include "IndexedFaceSet.h" -IndexedFaceSet::IndexedFaceSet() -: Rep() +IndexedFaceSet::IndexedFaceSet() : Rep() { - _Vertices = NULL; - _Normals = NULL; - _FrsMaterials = 0; - _TexCoords = 0; - _FaceEdgeMarks = 0; - _VSize = 0; - _NSize = 0; - _MSize = 0; - _TSize = 0; - _NumFaces = 0; - _NumVertexPerFace = NULL; - _FaceStyle = NULL; - _VIndices = NULL; - _VISize = 0; - _NIndices = NULL; - _NISize = 0; - _MIndices = NULL; - _MISize = 0; - _TIndices = NULL; - _TISize = 0; - _displayList = 0; + _Vertices = NULL; + _Normals = NULL; + _FrsMaterials = 0; + _TexCoords = 0; + _FaceEdgeMarks = 0; + _VSize = 0; + _NSize = 0; + _MSize = 0; + _TSize = 0; + _NumFaces = 0; + _NumVertexPerFace = NULL; + _FaceStyle = NULL; + _VIndices = NULL; + _VISize = 0; + _NIndices = NULL; + _NISize = 0; + _MIndices = NULL; + _MISize = 0; + _TIndices = NULL; + _TISize = 0; + _displayList = 0; } -IndexedFaceSet::IndexedFaceSet( real *iVertices, unsigned iVSize, - real *iNormals, unsigned iNSize, - FrsMaterial **iMaterials, unsigned iMSize, - real *iTexCoords, unsigned iTSize, - unsigned iNumFaces, unsigned *iNumVertexPerFace, TRIANGLES_STYLE *iFaceStyle, - FaceEdgeMark *iFaceEdgeMarks, - unsigned *iVIndices, unsigned iVISize, - unsigned *iNIndices, unsigned iNISize, - unsigned *iMIndices, unsigned iMISize, - unsigned *iTIndices, unsigned iTISize, - unsigned iCopy) - : Rep() +IndexedFaceSet::IndexedFaceSet(real *iVertices, unsigned iVSize, real *iNormals, unsigned iNSize, + FrsMaterial **iMaterials, unsigned iMSize, real *iTexCoords, unsigned iTSize, + unsigned iNumFaces, unsigned *iNumVertexPerFace, TRIANGLES_STYLE *iFaceStyle, + FaceEdgeMark *iFaceEdgeMarks, unsigned *iVIndices, unsigned iVISize, + unsigned *iNIndices, unsigned iNISize, unsigned *iMIndices, unsigned iMISize, + unsigned *iTIndices, unsigned iTISize, unsigned iCopy) +: Rep() { - if(1 == iCopy) - { - _VSize = iVSize; - _Vertices = new real[_VSize]; - memcpy(_Vertices, iVertices, iVSize*sizeof(real)); - - _NSize = iNSize; - _Normals = new real[_NSize]; - memcpy(_Normals, iNormals, iNSize*sizeof(real)); - - _MSize = iMSize; - _FrsMaterials = 0; - if(iMaterials){ - _FrsMaterials = new FrsMaterial*[_MSize]; - for(unsigned i=0; i<_MSize; ++i) - _FrsMaterials[i] = new FrsMaterial(*(iMaterials[i])); - } - _TSize = iTSize; - _TexCoords = 0; - if(_TSize){ - _TexCoords = new real[_TSize]; - memcpy(_TexCoords, iTexCoords, iTSize*sizeof(real)); - } - - _NumFaces = iNumFaces; - _NumVertexPerFace = new unsigned[_NumFaces]; - memcpy(_NumVertexPerFace, iNumVertexPerFace, _NumFaces*sizeof(unsigned)); - - _FaceStyle = new TRIANGLES_STYLE[_NumFaces]; - memcpy(_FaceStyle, iFaceStyle, _NumFaces*sizeof(TRIANGLES_STYLE)); - - _FaceEdgeMarks = new FaceEdgeMark[_NumFaces]; - memcpy(_FaceEdgeMarks, iFaceEdgeMarks, _NumFaces*sizeof(FaceEdgeMark)); - - _VISize = iVISize; - _VIndices = new unsigned[_VISize]; - memcpy(_VIndices, iVIndices, _VISize*sizeof(unsigned)); - - _NISize = iNISize; - _NIndices = new unsigned[_NISize]; - memcpy(_NIndices, iNIndices, _NISize*sizeof(unsigned)); - - _MISize = iMISize; + if (1 == iCopy) { + _VSize = iVSize; + _Vertices = new real[_VSize]; + memcpy(_Vertices, iVertices, iVSize * sizeof(real)); + + _NSize = iNSize; + _Normals = new real[_NSize]; + memcpy(_Normals, iNormals, iNSize * sizeof(real)); + + _MSize = iMSize; + _FrsMaterials = 0; + if (iMaterials) { + _FrsMaterials = new FrsMaterial * [_MSize]; + for (unsigned int i = 0; i < _MSize; ++i) + _FrsMaterials[i] = new FrsMaterial(*(iMaterials[i])); + } + _TSize = iTSize; + _TexCoords = 0; + if (_TSize) { + _TexCoords = new real[_TSize]; + memcpy(_TexCoords, iTexCoords, iTSize * sizeof(real)); + } + + _NumFaces = iNumFaces; + _NumVertexPerFace = new unsigned[_NumFaces]; + memcpy(_NumVertexPerFace, iNumVertexPerFace, _NumFaces * sizeof(unsigned)); + + _FaceStyle = new TRIANGLES_STYLE[_NumFaces]; + memcpy(_FaceStyle, iFaceStyle, _NumFaces * sizeof(TRIANGLES_STYLE)); + + _FaceEdgeMarks = new FaceEdgeMark[_NumFaces]; + memcpy(_FaceEdgeMarks, iFaceEdgeMarks, _NumFaces * sizeof(FaceEdgeMark)); + + _VISize = iVISize; + _VIndices = new unsigned[_VISize]; + memcpy(_VIndices, iVIndices, _VISize * sizeof(unsigned)); + + _NISize = iNISize; + _NIndices = new unsigned[_NISize]; + memcpy(_NIndices, iNIndices, _NISize * sizeof(unsigned)); + + _MISize = iMISize; _MIndices = 0; - if(iMIndices){ + if (iMIndices) { _MIndices = new unsigned[_MISize]; - memcpy(_MIndices, iMIndices, _MISize*sizeof(unsigned)); + memcpy(_MIndices, iMIndices, _MISize * sizeof(unsigned)); } - _TISize = iTISize; - _TIndices = 0; - if(_TISize){ - _TIndices = new unsigned[_TISize]; - memcpy(_TIndices, iTIndices, _TISize*sizeof(unsigned)); - } - } - else - { - _VSize = iVSize; - _Vertices = iVertices; - - _NSize = iNSize; - _Normals = iNormals; - - _MSize = iMSize; + _TISize = iTISize; + _TIndices = 0; + if (_TISize) { + _TIndices = new unsigned[_TISize]; + memcpy(_TIndices, iTIndices, _TISize * sizeof(unsigned)); + } + } + else { + _VSize = iVSize; + _Vertices = iVertices; + + _NSize = iNSize; + _Normals = iNormals; + + _MSize = iMSize; _FrsMaterials = 0; - if(iMaterials) + if (iMaterials) _FrsMaterials = iMaterials; - - _TSize = iTSize; - _TexCoords = iTexCoords; - - _NumFaces = iNumFaces; - _NumVertexPerFace = iNumVertexPerFace; - _FaceStyle = iFaceStyle; - _FaceEdgeMarks = iFaceEdgeMarks; - - _VISize = iVISize; - _VIndices = iVIndices; - - _NISize = iNISize; - _NIndices = iNIndices; - - _MISize = iMISize; + + _TSize = iTSize; + _TexCoords = iTexCoords; + + _NumFaces = iNumFaces; + _NumVertexPerFace = iNumVertexPerFace; + _FaceStyle = iFaceStyle; + _FaceEdgeMarks = iFaceEdgeMarks; + + _VISize = iVISize; + _VIndices = iVIndices; + + _NISize = iNISize; + _NIndices = iNIndices; + + _MISize = iMISize; _MIndices = 0; - if(iMISize) + if (iMISize) _MIndices = iMIndices; - _TISize = iTISize; - _TIndices = iTIndices; - } + _TISize = iTISize; + _TIndices = iTIndices; + } - _displayList = 0; + _displayList = 0; } -IndexedFaceSet::IndexedFaceSet( const IndexedFaceSet& iBrother) -:Rep(iBrother) +IndexedFaceSet::IndexedFaceSet(const IndexedFaceSet& iBrother) : Rep(iBrother) { - _VSize = iBrother.vsize(); - _Vertices = new real[_VSize]; - memcpy(_Vertices, iBrother.vertices(), _VSize*sizeof(real)); - - _NSize = iBrother.nsize(); - _Normals = new real[_NSize]; - memcpy(_Normals, iBrother.normals(), _NSize*sizeof(real)); - - _MSize = iBrother.msize(); - if(_MSize){ - _FrsMaterials = new FrsMaterial*[_MSize]; - for(unsigned i=0; i<_MSize; ++i){ + _VSize = iBrother.vsize(); + _Vertices = new real[_VSize]; + memcpy(_Vertices, iBrother.vertices(), _VSize * sizeof(real)); + + _NSize = iBrother.nsize(); + _Normals = new real[_NSize]; + memcpy(_Normals, iBrother.normals(), _NSize * sizeof(real)); + + _MSize = iBrother.msize(); + if (_MSize) { + _FrsMaterials = new FrsMaterial * [_MSize]; + for (unsigned int i = 0; i < _MSize; ++i) { _FrsMaterials[i] = new FrsMaterial(*(iBrother._FrsMaterials[i])); } - }else{ + } + else { _FrsMaterials = 0; } - _TSize = iBrother.tsize(); - _TexCoords = 0; - if(_TSize){ - _TexCoords = new real[_TSize]; - memcpy(_TexCoords, iBrother.texCoords(), _TSize*sizeof(real)); - } - - _NumFaces = iBrother.numFaces(); - _NumVertexPerFace = new unsigned[_NumFaces]; - memcpy(_NumVertexPerFace, iBrother.numVertexPerFaces(), _NumFaces*sizeof(unsigned)); - - _FaceStyle = new TRIANGLES_STYLE[_NumFaces]; - memcpy(_FaceStyle, iBrother.trianglesStyle(), _NumFaces*sizeof(TRIANGLES_STYLE)); - - _FaceEdgeMarks = new FaceEdgeMark[_NumFaces]; - memcpy(_FaceEdgeMarks, iBrother.faceEdgeMarks(), _NumFaces*sizeof(FaceEdgeMark)); - - _VISize = iBrother.visize(); - _VIndices = new unsigned[_VISize]; - memcpy(_VIndices, iBrother.vindices(), _VISize*sizeof(unsigned)); - - _NISize = iBrother.nisize(); - _NIndices = new unsigned[_NISize]; - memcpy(_NIndices, iBrother.nindices(), _NISize*sizeof(unsigned)); - - _MISize = iBrother.misize(); - if(_MISize){ + _TSize = iBrother.tsize(); + _TexCoords = 0; + if (_TSize) { + _TexCoords = new real[_TSize]; + memcpy(_TexCoords, iBrother.texCoords(), _TSize * sizeof(real)); + } + + _NumFaces = iBrother.numFaces(); + _NumVertexPerFace = new unsigned[_NumFaces]; + memcpy(_NumVertexPerFace, iBrother.numVertexPerFaces(), _NumFaces * sizeof(unsigned)); + + _FaceStyle = new TRIANGLES_STYLE[_NumFaces]; + memcpy(_FaceStyle, iBrother.trianglesStyle(), _NumFaces * sizeof(TRIANGLES_STYLE)); + + _FaceEdgeMarks = new FaceEdgeMark[_NumFaces]; + memcpy(_FaceEdgeMarks, iBrother.faceEdgeMarks(), _NumFaces * sizeof(FaceEdgeMark)); + + _VISize = iBrother.visize(); + _VIndices = new unsigned[_VISize]; + memcpy(_VIndices, iBrother.vindices(), _VISize * sizeof(unsigned)); + + _NISize = iBrother.nisize(); + _NIndices = new unsigned[_NISize]; + memcpy(_NIndices, iBrother.nindices(), _NISize * sizeof(unsigned)); + + _MISize = iBrother.misize(); + if (_MISize) { _MIndices = new unsigned[_MISize]; - memcpy(_MIndices, iBrother.mindices(), _MISize*sizeof(unsigned)); - }else{ - _MIndices=0; + memcpy(_MIndices, iBrother.mindices(), _MISize * sizeof(unsigned)); + } + else { + _MIndices = 0; } - _TISize = iBrother.tisize(); - _TIndices = 0; - if(_TISize){ - _TIndices = new unsigned[_TISize]; - memcpy(_TIndices, iBrother.tindices(), _TISize*sizeof(unsigned)); - } + _TISize = iBrother.tisize(); + _TIndices = 0; + if (_TISize) { + _TIndices = new unsigned[_TISize]; + memcpy(_TIndices, iBrother.tindices(), _TISize * sizeof(unsigned)); + } - _displayList = 0; + _displayList = 0; } IndexedFaceSet::~IndexedFaceSet() { - if(NULL != _Vertices) - { - delete [] _Vertices; - _Vertices = NULL; - } - - if(NULL != _Normals) - { - delete [] _Normals; - _Normals = NULL; - } - - if(NULL != _FrsMaterials) - { - for(unsigned i=0; i<_MSize; ++i) - delete _FrsMaterials[i]; - delete [] _FrsMaterials; - _FrsMaterials = NULL; - } - - if(NULL != _TexCoords) - { - delete [] _TexCoords; - _TexCoords = NULL; - } - - if(NULL != _NumVertexPerFace) - { - delete [] _NumVertexPerFace; - _NumVertexPerFace = NULL; - } - - if(NULL != _FaceStyle) - { - delete [] _FaceStyle; - _FaceStyle = NULL; - } - - if(NULL != _FaceEdgeMarks) - { - delete [] _FaceEdgeMarks; - _FaceEdgeMarks = NULL; - } - - if(NULL != _VIndices) - { - delete [] _VIndices; - _VIndices = NULL; - } - - if(NULL != _NIndices) - { - delete [] _NIndices; - _NIndices = NULL; - } - - if(NULL != _MIndices) - { - delete [] _MIndices; - _MIndices = NULL; - } - if(NULL != _TIndices) - { - delete [] _TIndices; - _TIndices = NULL; - } - // should find a way to deallocates the displayList - // glDeleteLists(GLuint list, GLSizei range) - _displayList = 0; + if (NULL != _Vertices) { + delete[] _Vertices; + _Vertices = NULL; + } + + if (NULL != _Normals) + { + delete[] _Normals; + _Normals = NULL; + } + + if (NULL != _FrsMaterials) { + for (unsigned int i = 0; i < _MSize; ++i) + delete _FrsMaterials[i]; + delete[] _FrsMaterials; + _FrsMaterials = NULL; + } + + if (NULL != _TexCoords) { + delete[] _TexCoords; + _TexCoords = NULL; + } + + if (NULL != _NumVertexPerFace) { + delete[] _NumVertexPerFace; + _NumVertexPerFace = NULL; + } + + if (NULL != _FaceStyle) { + delete[] _FaceStyle; + _FaceStyle = NULL; + } + + if (NULL != _FaceEdgeMarks) { + delete[] _FaceEdgeMarks; + _FaceEdgeMarks = NULL; + } + + if (NULL != _VIndices) { + delete[] _VIndices; + _VIndices = NULL; + } + + if (NULL != _NIndices) { + delete[] _NIndices; + _NIndices = NULL; + } + + if (NULL != _MIndices) { + delete[] _MIndices; + _MIndices = NULL; + } + if (NULL != _TIndices) { + delete[] _TIndices; + _TIndices = NULL; + } + + // should find a way to deallocates the displayList + // glDeleteLists(GLuint list, GLSizei range) + _displayList = 0; } -void IndexedFaceSet::accept(SceneVisitor& v) { - Rep::accept(v); - v.visitIndexedFaceSet(*this); +void IndexedFaceSet::accept(SceneVisitor& v) +{ + Rep::accept(v); + v.visitIndexedFaceSet(*this); } void IndexedFaceSet::ComputeBBox() { - real XMax = _Vertices[0]; - real YMax = _Vertices[1]; - real ZMax = _Vertices[2]; - - real XMin = _Vertices[0]; - real YMin = _Vertices[1]; - real ZMin = _Vertices[2]; - - // parse all the coordinates to find - // the Xmax, YMax, ZMax - real *v = _Vertices; - - for(unsigned i=0; i<_VSize/3; i++) - { - // X - if(*v > XMax) - XMax = *v; - if(*v < XMin) - XMin = *v; - v++; - - if(*v > YMax) - YMax = *v; - if(*v < YMin) - YMin = *v; - v++; - - if(*v > ZMax) - ZMax = *v; - if(*v < ZMin) - ZMin = *v; - v++; - } - - setBBox(BBox(Vec3r(XMin, YMin, ZMin), Vec3r(XMax, YMax, ZMax))); + real XMax = _Vertices[0]; + real YMax = _Vertices[1]; + real ZMax = _Vertices[2]; + + real XMin = _Vertices[0]; + real YMin = _Vertices[1]; + real ZMin = _Vertices[2]; + + // parse all the coordinates to find the Xmax, YMax, ZMax + real *v = _Vertices; + + for (unsigned int i = 0; i < (_VSize / 3); ++i) { + if (*v > XMax) + XMax = *v; + if (*v < XMin) + XMin = *v; + ++v; + + if (*v > YMax) + YMax = *v; + if (*v < YMin) + YMin = *v; + ++v; + + if (*v > ZMax) + ZMax = *v; + if (*v < ZMin) + ZMin = *v; + ++v; + } + + setBBox(BBox(Vec3r(XMin, YMin, ZMin), Vec3r(XMax, YMax, ZMax))); } diff --git a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h index b578dc1257e..6ec769f4caf 100644 --- a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h +++ b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h @@ -1,143 +1,145 @@ -// -// Filename : IndexedFaceSet.h -// Author(s) : Stephane Grabli -// Purpose : A Set of indexed faces to represent a surfacic object -// Date of creation : 22/01/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef INDEXEDFACESET_H -# define INDEXEDFACESET_H - -# include -# include - -//! inherits from class Rep -# include "Rep.h" - -# include "../system/FreestyleConfig.h" +/* + * ***** 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_INDEXED_FACE_SET_H__ +#define __FREESTYLE_INDEXED_FACE_SET_H__ + +/** \file blender/freestyle/intern/scene_graph/IndexedFaceSet.h + * \ingroup freestyle + * \brief A Set of indexed faces to represent a surfacic object + * \author Stephane Grabli + * \date 22/01/2002 + */ + +#include +#include + +//! inherits from class Rep +#include "Rep.h" + +#include "../system/FreestyleConfig.h" class LIB_SCENE_GRAPH_EXPORT IndexedFaceSet : public Rep - { +{ public: + /*! Triangles description style:*/ + enum TRIANGLES_STYLE { + TRIANGLE_STRIP, + TRIANGLE_FAN, + TRIANGLES, + }; - /*! Triangles description style:*/ - enum TRIANGLES_STYLE{TRIANGLE_STRIP, TRIANGLE_FAN, TRIANGLES}; - - /*! User-specified face and edge marks for feature edge detection */ - typedef unsigned char FaceEdgeMark; - static const FaceEdgeMark FACE_MARK = 1; - static const FaceEdgeMark EDGE_MARK_V1V2 = 2; - static const FaceEdgeMark EDGE_MARK_V2V3 = 4; - static const FaceEdgeMark EDGE_MARK_V3V1 = 8; - - /*! Builds an empty indexed face set - */ - IndexedFaceSet(); - /*! Builds an indexed face set - iVertices - The array of object vertices 3D coordinates (for all faces). - If iCopy != 0, the array is copied; you must desallocate iVertices. Else you must not. - iVSize - The size of iVertices (must be a multiple of 3) - iNormals - The array of object normals 3D coordinates. - If iCopy != 0, the array is copied; you must desallocate iNormals. Else you must not. - iNSize - The size of iNormals - iMaterials - The array of materials - iMSize - The size of iMaterials - iTexCoords - The array of texture coordinates. - iTSize - The size of iTexCoords (must be multiple of 2) - iNumFaces - The number of faces - iNumVertexPerFace - Array containing the number of vertices per face. - iFaceStyle - Array containing the description style of each faces. - The style belongs to: - - TRIANGLE_STRIP: the face indices describe a triangle strip - - TRIANGLE_FAN : the face indices describe a triangle fan - - TRIANGLES : the face indices describe single triangles - If iCopy != 0, the array is copied; you must desallocate iFaceStyle. Else you must not. - iVIndices, - Array of vertices indices. - The integers contained in this array must be multiple of 3. - If iCopy != 0, the array is copied; you must desallocate iVIndices. Else you must not. - iVISize - The size of iVIndices. - iNIndices - Array of normals indices. - The integers contained in this array must be multiple of 3. - If iCopy != 0, the array is copied; you must desallocate iNIndices. Else you must not. - iNISize - The size of iNIndices - iMIndices - The Material indices (per vertex) - iMISize - The size of iMIndices - iTIndices - The Texture coordinates indices (per vertex). The integers contained in this array must be multiple of 2. - iTISize - The size of iMIndices - iCopy - 0 : the arrays are not copied. The pointers passed as arguments are used. - IndexedFaceSet takes these arrays desallocation in charge. - 1 : the arrays are copied. The caller is in charge of the arrays, passed - as arguments desallocation. - */ - IndexedFaceSet( real *iVertices, unsigned iVSize, - real *iNormals, unsigned iNSize, - FrsMaterial **iMaterials, unsigned iMSize, - real *iTexCoords, unsigned iTSize, - unsigned iNumFaces, unsigned *iNumVertexPerFace, TRIANGLES_STYLE *iFaceStyle, - FaceEdgeMark *iFaceEdgeMarks, - unsigned *iVIndices, unsigned iVISize, - unsigned *iNIndices, unsigned iNISize, - unsigned *iMIndices, unsigned iMISize, - unsigned *iTIndices, unsigned iTISize, - unsigned iCopy = 1 - ); - - /*! Builds an indexed face set from an other indexed face set */ - IndexedFaceSet(const IndexedFaceSet& iBrother); - - void swap(IndexedFaceSet& ioOther){ + /*! User-specified face and edge marks for feature edge detection */ + /* XXX Why in hel not use an enum here too? */ + typedef unsigned char FaceEdgeMark; + static const FaceEdgeMark FACE_MARK = 1 << 0; + static const FaceEdgeMark EDGE_MARK_V1V2 = 1 << 1; + static const FaceEdgeMark EDGE_MARK_V2V3 = 1 << 2; + static const FaceEdgeMark EDGE_MARK_V3V1 = 1 << 3; + + /*! Builds an empty indexed face set */ + IndexedFaceSet(); + + /*! Builds an indexed face set + * iVertices + * The array of object vertices 3D coordinates (for all faces). + * If iCopy != 0, the array is copied; you must desallocate iVertices. Else you must not. + * iVSize + * The size of iVertices (must be a multiple of 3) + * iNormals + * The array of object normals 3D coordinates. + * If iCopy != 0, the array is copied; you must desallocate iNormals. Else you must not. + * iNSize + * The size of iNormals + * iMaterials + * The array of materials + * iMSize + * The size of iMaterials + * iTexCoords + * The array of texture coordinates. + * iTSize + * The size of iTexCoords (must be multiple of 2) + * iNumFaces + * The number of faces + * iNumVertexPerFace + * Array containing the number of vertices per face. + * iFaceStyle + * Array containing the description style of each faces. + * The style belongs to: + * - TRIANGLE_STRIP: the face indices describe a triangle strip + * - TRIANGLE_FAN : the face indices describe a triangle fan + * - TRIANGLES : the face indices describe single triangles + * If iCopy != 0, the array is copied; you must desallocate iFaceStyle. Else you must not. + * iVIndices, + * Array of vertices indices. + * The integers contained in this array must be multiple of 3. + * If iCopy != 0, the array is copied; you must desallocate iVIndices. Else you must not. + * iVISize + * The size of iVIndices. + * iNIndices + * Array of normals indices. + * The integers contained in this array must be multiple of 3. + * If iCopy != 0, the array is copied; you must desallocate iNIndices. Else you must not. + * iNISize + * The size of iNIndices + * iMIndices + * The Material indices (per vertex) + * iMISize + * The size of iMIndices + * iTIndices + * The Texture coordinates indices (per vertex). The integers contained in this array must be multiple of 2. + * iTISize + * The size of iMIndices + * iCopy + * 0 : the arrays are not copied. The pointers passed as arguments are used. IndexedFaceSet takes these + * arrays desallocation in charge. + * 1 : the arrays are copied. The caller is in charge of the arrays, passed as arguments desallocation. + */ + IndexedFaceSet(real *iVertices, unsigned iVSize, real *iNormals, unsigned iNSize, FrsMaterial **iMaterials, + unsigned iMSize, real *iTexCoords, unsigned iTSize, unsigned iNumFaces, unsigned *iNumVertexPerFace, + TRIANGLES_STYLE *iFaceStyle, FaceEdgeMark *iFaceEdgeMarks, unsigned *iVIndices, unsigned iVISize, + unsigned *iNIndices, unsigned iNISize, unsigned *iMIndices, unsigned iMISize, unsigned *iTIndices, + unsigned iTISize, unsigned iCopy = 1); + + /*! Builds an indexed face set from an other indexed face set */ + IndexedFaceSet(const IndexedFaceSet& iBrother); + + void swap(IndexedFaceSet& ioOther) + { std::swap(_Vertices, ioOther._Vertices); std::swap(_Normals, ioOther._Normals); std::swap(_FrsMaterials, ioOther._FrsMaterials); - std::swap(_TexCoords, ioOther._TexCoords); + std::swap(_TexCoords, ioOther._TexCoords); std::swap(_FaceEdgeMarks, ioOther._FaceEdgeMarks); std::swap(_VSize, ioOther._VSize); std::swap(_NSize, ioOther._NSize); std::swap(_MSize, ioOther._MSize); - std::swap(_TSize, ioOther._TSize); + std::swap(_TSize, ioOther._TSize); std::swap(_NumFaces, ioOther._NumFaces); std::swap(_NumVertexPerFace, ioOther._NumVertexPerFace); @@ -146,88 +148,175 @@ public: std::swap(_VIndices, ioOther._VIndices); std::swap(_NIndices, ioOther._NIndices); std::swap(_MIndices, ioOther._MIndices); // Material Indices - std::swap(_TIndices, ioOther._TIndices); + std::swap(_TIndices, ioOther._TIndices); std::swap(_VISize, ioOther._VISize); std::swap(_NISize, ioOther._NISize); std::swap(_MISize, ioOther._MISize); - std::swap(_TISize, ioOther._TISize); + std::swap(_TISize, ioOther._TISize); std::swap(_displayList, ioOther._displayList); Rep::swap(ioOther); } - IndexedFaceSet& operator=(const IndexedFaceSet& iBrother){ + IndexedFaceSet& operator=(const IndexedFaceSet& iBrother) + { IndexedFaceSet tmp(iBrother); swap(tmp); return *this; } - /*! Desctructor - desallocates all the ressources */ - virtual ~IndexedFaceSet(); - - /*! Accept the corresponding visitor */ - virtual void accept(SceneVisitor& v); - - /*! Compute the Bounding Box */ - virtual void ComputeBBox(); - - /*! modifiers */ - inline void setDisplayList(unsigned int index) {_displayList = index;} - - /*! Accessors */ - virtual const real * vertices() const {return _Vertices;} - virtual const real * normals() const {return _Normals;} - virtual const FrsMaterial*const* frs_materials() const {return _FrsMaterials;} - virtual const real* texCoords() const {return _TexCoords;} - virtual const unsigned vsize() const {return _VSize;} - virtual const unsigned nsize() const {return _NSize;} - virtual const unsigned msize() const {return _MSize;} - virtual const unsigned tsize() const {return _TSize;} - virtual const unsigned numFaces() const {return _NumFaces;} - virtual const unsigned * numVertexPerFaces() const {return _NumVertexPerFace;} - virtual const TRIANGLES_STYLE * trianglesStyle() const {return _FaceStyle;} - virtual const unsigned char * faceEdgeMarks() const {return _FaceEdgeMarks;} - virtual const unsigned* vindices() const {return _VIndices;} - virtual const unsigned* nindices() const {return _NIndices;} - virtual const unsigned* mindices() const {return _MIndices;} - virtual const unsigned* tindices() const {return _TIndices;} - virtual const unsigned visize() const {return _VISize;} - virtual const unsigned nisize() const {return _NISize;} - virtual const unsigned misize() const {return _MISize;} - virtual const unsigned tisize() const {return _TISize;} - inline unsigned int displayList() const {return _displayList;} + /*! Desctructor + * desallocates all the ressources + */ + virtual ~IndexedFaceSet(); + + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v); + + /*! Compute the Bounding Box */ + virtual void ComputeBBox(); + + /*! modifiers */ + inline void setDisplayList(unsigned int index) + { + _displayList = index; + } + + /*! Accessors */ + virtual const real * vertices() const + { + return _Vertices; + } + + virtual const real * normals() const + { + return _Normals; + } + + virtual const FrsMaterial*const* frs_materials() const + { + return _FrsMaterials; + } + + virtual const real* texCoords() const + { + return _TexCoords; + } + + virtual const unsigned vsize() const + { + return _VSize; + } + + virtual const unsigned nsize() const + { + return _NSize; + } + + virtual const unsigned msize() const + { + return _MSize; + } + + virtual const unsigned tsize() const + { + return _TSize; + } + + virtual const unsigned numFaces() const + { + return _NumFaces; + } + + virtual const unsigned * numVertexPerFaces() const + { + return _NumVertexPerFace; + } + + virtual const TRIANGLES_STYLE * trianglesStyle() const + { + return _FaceStyle; + } + + virtual const unsigned char * faceEdgeMarks() const + { + return _FaceEdgeMarks; + } + + virtual const unsigned* vindices() const + { + return _VIndices; + } + + virtual const unsigned* nindices() const + { + return _NIndices; + } + + virtual const unsigned* mindices() const + { + return _MIndices; + } + + virtual const unsigned* tindices() const + { + return _TIndices; + } + + virtual const unsigned visize() const + { + return _VISize; + } + + virtual const unsigned nisize() const + { + return _NISize; + } + + virtual const unsigned misize() const + { + return _MISize; + } + + virtual const unsigned tisize() const + { + return _TISize; + } + + inline unsigned int displayList() const + { + return _displayList; + } protected: - real *_Vertices; - real *_Normals; - FrsMaterial** _FrsMaterials; - real *_TexCoords; - - unsigned _VSize; - unsigned _NSize; - unsigned _MSize; - unsigned _TSize; - - unsigned _NumFaces; - unsigned *_NumVertexPerFace; - TRIANGLES_STYLE *_FaceStyle; - FaceEdgeMark *_FaceEdgeMarks; - - unsigned *_VIndices; - unsigned *_NIndices; - unsigned *_MIndices; // Material Indices - unsigned *_TIndices; // Texture coordinates Indices - - unsigned _VISize; - unsigned _NISize; - unsigned _MISize; - unsigned _TISize; - - unsigned int _displayList; + real *_Vertices; + real *_Normals; + FrsMaterial **_FrsMaterials; + real *_TexCoords; + + unsigned _VSize; + unsigned _NSize; + unsigned _MSize; + unsigned _TSize; + + unsigned _NumFaces; + unsigned *_NumVertexPerFace; + TRIANGLES_STYLE *_FaceStyle; + FaceEdgeMark *_FaceEdgeMarks; + + unsigned *_VIndices; + unsigned *_NIndices; + unsigned *_MIndices; // Material Indices + unsigned *_TIndices; // Texture coordinates Indices + + unsigned _VISize; + unsigned _NISize; + unsigned _MISize; + unsigned _TISize; + unsigned int _displayList; }; -#endif // INDEXEDFACESET_H +#endif // __FREESTYLE_INDEXED_FACE_SET_H__ diff --git a/source/blender/freestyle/intern/scene_graph/LineRep.cpp b/source/blender/freestyle/intern/scene_graph/LineRep.cpp index 504db06acf4..bf442bccbc1 100644 --- a/source/blender/freestyle/intern/scene_graph/LineRep.cpp +++ b/source/blender/freestyle/intern/scene_graph/LineRep.cpp @@ -1,58 +1,71 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/scene_graph/LineRep.cpp + * \ingroup freestyle + * \brief Class to define the representation of 3D Line. + * \author Stephane Grabli + * \date 26/03/2002 + */ #include "LineRep.h" void LineRep::ComputeBBox() { - real XMax = _vertices.front()[0]; - real YMax = _vertices.front()[1]; - real ZMax = _vertices.front()[2]; - - real XMin = _vertices.front()[0]; - real YMin = _vertices.front()[1]; - real ZMin = _vertices.front()[2]; - - // parse all the coordinates to find - // the XMax, YMax, ZMax - vector::iterator v; - for(v=_vertices.begin(); v!=_vertices.end(); v++) { - // X - if((*v)[0] > XMax) - XMax = (*v)[0]; - if((*v)[0] < XMin) - XMin = (*v)[0]; - - // Y - if((*v)[1] > YMax) - YMax = (*v)[1]; - if((*v)[1] < YMin) - YMin = (*v)[1]; - - // Z - if((*v)[2] > ZMax) - ZMax = (*v)[2]; - if((*v)[2] < ZMin) - ZMin = (*v)[2]; - } - - setBBox(BBox(Vec3r(XMin, YMin, ZMin), Vec3r(XMax, YMax, ZMax))); + real XMax = _vertices.front()[0]; + real YMax = _vertices.front()[1]; + real ZMax = _vertices.front()[2]; + + real XMin = _vertices.front()[0]; + real YMin = _vertices.front()[1]; + real ZMin = _vertices.front()[2]; + + // parse all the coordinates to find + // the XMax, YMax, ZMax + vector::iterator v; + for (v = _vertices.begin(); v != _vertices.end(); ++v) { + // X + if ((*v)[0] > XMax) + XMax = (*v)[0]; + if ((*v)[0] < XMin) + XMin = (*v)[0]; + + // Y + if ((*v)[1] > YMax) + YMax = (*v)[1]; + if ((*v)[1] < YMin) + YMin = (*v)[1]; + + // Z + if ((*v)[2] > ZMax) + ZMax = (*v)[2]; + if ((*v)[2] < ZMin) + ZMin = (*v)[2]; + } + + setBBox(BBox(Vec3r(XMin, YMin, ZMin), Vec3r(XMax, YMax, ZMax))); } diff --git a/source/blender/freestyle/intern/scene_graph/LineRep.h b/source/blender/freestyle/intern/scene_graph/LineRep.h index 232557af857..3d93db4835d 100644 --- a/source/blender/freestyle/intern/scene_graph/LineRep.h +++ b/source/blender/freestyle/intern/scene_graph/LineRep.h @@ -1,39 +1,46 @@ -// -// Filename : LineRep.h -// Author(s) : Stephane Grabli -// Purpose : Class to define the representation of 3D Line. -// Date of creation : 26/03/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LINEREP_H -# define LINEREP_H - -# include -# include -# include "Rep.h" -# include "../system/FreestyleConfig.h" +/* + * ***** 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_LINE_REP_H__ +#define __FREESTYLE_LINE_REP_H__ + +/** \file blender/freestyle/intern/scene_graph/LineRep.h + * \ingroup freestyle + * \brief Class to define the representation of 3D Line. + * \author Stephane Grabli + * \date 26/03/2002 + */ + +#include +#include + +#include "Rep.h" + +#include "../system/FreestyleConfig.h" using namespace std; @@ -41,90 +48,111 @@ using namespace std; class LIB_SCENE_GRAPH_EXPORT LineRep : public Rep { public: - - /*! Line description style */ - enum LINES_STYLE{LINES, LINE_STRIP, LINE_LOOP}; - inline LineRep() : Rep() {_width = 0.f;} - - /*! Builds a single line from 2 vertices - * v1 - * first vertex - * v2 - * second vertex - */ - inline LineRep(const Vec3r& v1, const Vec3r& v2) - : Rep() - { - setStyle(LINES); - AddVertex(v1); - AddVertex(v2); - _width = 0.f; - } - - /*! Builds a line rep from a vertex chain */ - inline LineRep(const vector& vertices) - : Rep() - { - _vertices = vertices; - setStyle(LINE_STRIP); - _width = 0.f; - } - - /*! Builds a line rep from a vertex chain */ - inline LineRep(const list& vertices) - : Rep() - { - for(list::const_iterator v=vertices.begin(), end=vertices.end(); - v!=end; - v++) - { - _vertices.push_back(*v); - } - setStyle(LINE_STRIP); - _width = 0.f; - } - - virtual ~LineRep() - { - _vertices.clear(); - } - - /*! accessors */ - inline const LINES_STYLE style() const {return _Style;} - inline const vector& vertices() const {return _vertices;} - inline float width() const {return _width;} - - /*! modifiers */ - inline void setStyle(const LINES_STYLE iStyle) {_Style = iStyle;} - inline void AddVertex(const Vec3r& iVertex) {_vertices.push_back(iVertex);} - inline void setVertices(const vector& iVertices) - { - if(0 != _vertices.size()) - { - _vertices.clear(); - } - for(vector::const_iterator v=iVertices.begin(), end=iVertices.end(); - v!=end; - v++) - { - _vertices.push_back(*v); - } - } - inline void setWidth(float iWidth) {_width=iWidth;} - - /*! Accept the corresponding visitor */ - virtual void accept(SceneVisitor& v) { - Rep::accept(v); - v.visitLineRep(*this); - } - - /*! Computes the line bounding box.*/ - virtual void ComputeBBox(); + /*! Line description style */ + enum LINES_STYLE { + LINES, + LINE_STRIP, + LINE_LOOP, + }; + + inline LineRep() : Rep() + { + _width = 0.0f; + } + + /*! Builds a single line from 2 vertices + * v1 + * first vertex + * v2 + * second vertex + */ + inline LineRep(const Vec3r& v1, const Vec3r& v2) : Rep() + { + setStyle(LINES); + AddVertex(v1); + AddVertex(v2); + _width = 0.0f; + } + + /*! Builds a line rep from a vertex chain */ + inline LineRep(const vector& vertices) : Rep() + { + _vertices = vertices; + setStyle(LINE_STRIP); + _width = 0.0f; + } + + /*! Builds a line rep from a vertex chain */ + inline LineRep(const list& vertices) : Rep() + { + for (list::const_iterator v = vertices.begin(), end = vertices.end(); v != end; ++v) { + _vertices.push_back(*v); + } + setStyle(LINE_STRIP); + _width = 0.0f; + } + + virtual ~LineRep() + { + _vertices.clear(); + } + + /*! accessors */ + inline const LINES_STYLE style() const + { + return _Style; + } + + inline const vector& vertices() const + { + return _vertices; + } + + inline float width() const + { + return _width; + } + + /*! modifiers */ + inline void setStyle(const LINES_STYLE iStyle) + { + _Style = iStyle; + } + + inline void AddVertex(const Vec3r& iVertex) + { + _vertices.push_back(iVertex); + } + + inline void setVertices(const vector& iVertices) + { + if (0 != _vertices.size()) { + _vertices.clear(); + } + for (vector::const_iterator v = iVertices.begin(), end = iVertices.end(); v != end; ++v) { + _vertices.push_back(*v); + } + } + + inline void setWidth(float iWidth) + { + _width = iWidth; + } + + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v) + { + Rep::accept(v); + v.visitLineRep(*this); + } + + /*! Computes the line bounding box.*/ + virtual void ComputeBBox(); private: - LINES_STYLE _Style; - vector _vertices; - float _width; + LINES_STYLE _Style; + vector _vertices; + float _width; }; -#endif // LINEREP_H +#endif // __FREESTYLE_LINE_REP_H__ diff --git a/source/blender/freestyle/intern/scene_graph/Node.h b/source/blender/freestyle/intern/scene_graph/Node.h index 41afaa353be..626a0913233 100644 --- a/source/blender/freestyle/intern/scene_graph/Node.h +++ b/source/blender/freestyle/intern/scene_graph/Node.h @@ -1,42 +1,48 @@ -// -// Filename : Node.h -// Author(s) : Stephane Grabli -// Purpose : Abstract class for scene graph nodes. Inherits from -// BaseObject which defines the addRef release mechanism. -// Date of creation : 24/01/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef NODE_H -# define NODE_H - -# include "../system/FreestyleConfig.h" -# include "../system/BaseObject.h" -# include "SceneVisitor.h" -# include "../geometry/BBox.h" -# include "../geometry/Geom.h" -# include "../system/Precision.h" +/* + * ***** 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_NODE_H__ +#define __FREESTYLE_NODE_H__ + +/** \file blender/freestyle/intern/scene_graph/Node.h + * \ingroup freestyle + * \brief Abstract class for scene graph nodes. Inherits from BaseObject which defines the addRef release mechanism. + * \author Stephane Grabli + * \date 24/01/2002 + */ + +#include "SceneVisitor.h" + +#include "../system/BaseObject.h" +#include "../system/FreestyleConfig.h" +#include "../system/Precision.h" + +#include "../geometry/BBox.h" +#include "../geometry/Geom.h" using namespace std; using namespace Geometry; @@ -44,54 +50,66 @@ using namespace Geometry; class LIB_SCENE_GRAPH_EXPORT Node : public BaseObject { public: + inline Node() : BaseObject() {} + + inline Node(const Node& iBrother) : BaseObject() + { + _BBox = iBrother.bbox(); + } + + virtual ~Node(){} + + /*! Accept the corresponding visitor + * Each inherited node must overload this method + */ + virtual void accept(SceneVisitor& v) + { + v.visitNode(*this); + } + + /*! bounding box management */ + /*! Returns the node bounding box + * If no bounding box exists, an empty bbox is returned + */ + virtual const BBox& bbox() const + { + return _BBox; + } + + /*! Sets the Node bounding box */ + virtual void setBBox(const BBox& iBox) + { + _BBox = iBox; + } + + /*! Makes the union of _BBox and iBox */ + virtual void AddBBox(const BBox& iBox) + { + if(iBox.empty()) + return; + + if(_BBox.empty()) + _BBox = iBox; + else + _BBox += iBox; + } + + /*! Updates the BBox */ + virtual const BBox& UpdateBBox() + { + return _BBox; + } + + /*! Clears the bounding box */ + virtual void clearBBox() + { + _BBox.clear(); + } - inline Node() : BaseObject() {} - inline Node(const Node& iBrother) : BaseObject() - { - _BBox = iBrother.bbox(); - } - virtual ~Node(){} - - /*! Accept the corresponding visitor - * Each inherited node - * must overload this method - */ - virtual void accept(SceneVisitor& v) { - v.visitNode(*this); - } - - /*! bounding box management */ - /*! Returns the node bounding box - * If no bounding box exists, an empty bbox - * is returned - */ - virtual const BBox& bbox() const {return _BBox;} - - /*! Sets the Node bounding box */ - virtual void setBBox(const BBox& iBox) {_BBox = iBox;} - - /*! Makes the union of _BBox and iBox */ - virtual void AddBBox(const BBox& iBox) - { - if(iBox.empty()) - return; - - if(_BBox.empty()) - _BBox = iBox; - else - _BBox += iBox; - } - - /*! Updates the BBox */ - virtual const BBox& UpdateBBox() {return _BBox;} - - /*! Clears the bounding box */ - virtual void clearBBox() { _BBox.clear(); } - protected: - + private: - BBox _BBox; + BBox _BBox; }; -#endif // NODE_H +#endif // __FREESTYLE_NODE_H__ diff --git a/source/blender/freestyle/intern/scene_graph/NodeCamera.cpp b/source/blender/freestyle/intern/scene_graph/NodeCamera.cpp index f299c44de40..d8b01bf3f64 100644 --- a/source/blender/freestyle/intern/scene_graph/NodeCamera.cpp +++ b/source/blender/freestyle/intern/scene_graph/NodeCamera.cpp @@ -1,120 +1,143 @@ +/* + * ***** 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 ***** + */ + +/** \file blender/freestyle/intern/scene_graph/NodeCamera.cpp + * \ingroup freestyle + * \brief Class to represent a light node + * \author Stephane Grabli + * \date 25/01/2002 + */ + +#include #include // for memcpy + #include "NodeCamera.h" -#include -static void loadIdentity(double * matrix){ - int i; - - // Build Identity matrix - for(i=0;i<16;++i){ - double value ; - if((i % 5) == 0) - value = 1.0; - else - value = 0; - matrix[i] = value; - } +static void loadIdentity(double * matrix) +{ + int i; + + // Build Identity matrix + for (i = 0; i < 16; ++i) { + double value ; + if ((i % 5) == 0) + value = 1.0; + else + value = 0; + matrix[i] = value; + } } -NodeCamera::NodeCamera(CameraType camera_type) -:camera_type_(camera_type){ - loadIdentity(modelview_matrix_); - loadIdentity(projection_matrix_); +NodeCamera::NodeCamera(CameraType camera_type) : camera_type_(camera_type) +{ + loadIdentity(modelview_matrix_); + loadIdentity(projection_matrix_); } -NodeCamera::NodeCamera(const NodeCamera& iBrother) -:camera_type_(iBrother.camera_type_){ - memcpy(modelview_matrix_, iBrother.modelview_matrix_, 16*sizeof(double)); - memcpy(projection_matrix_, iBrother.projection_matrix_, 16*sizeof(double)); +NodeCamera::NodeCamera(const NodeCamera& iBrother) : camera_type_(iBrother.camera_type_) +{ + memcpy(modelview_matrix_, iBrother.modelview_matrix_, 16 * sizeof(double)); + memcpy(projection_matrix_, iBrother.projection_matrix_, 16 * sizeof(double)); } -void NodeCamera::accept(SceneVisitor& v){ - v.visitNodeCamera(*this) ; +void NodeCamera::accept(SceneVisitor& v) +{ + v.visitNodeCamera(*this); } -void NodeCamera::setModelViewMatrix(double modelview_matrix[16]){ - memcpy(modelview_matrix_, modelview_matrix,16*sizeof(double)); +void NodeCamera::setModelViewMatrix(double modelview_matrix[16]) +{ + memcpy(modelview_matrix_, modelview_matrix, 16 * sizeof(double)); } -void NodeCamera::setProjectionMatrix(double projection_matrix[16]){ - memcpy(projection_matrix_, projection_matrix,16*sizeof(double)); +void NodeCamera::setProjectionMatrix(double projection_matrix[16]) +{ + memcpy(projection_matrix_, projection_matrix, 16 * sizeof(double)); } NodeOrthographicCamera::NodeOrthographicCamera() -:NodeCamera(NodeCamera::ORTHOGRAPHIC), -left_(0),right_(0),bottom_(0),top_(0),zNear_(0),zFar_(0){ - loadIdentity(projection_matrix_); - loadIdentity(modelview_matrix_); +: NodeCamera(NodeCamera::ORTHOGRAPHIC), left_(0), right_(0), bottom_(0), top_(0), zNear_(0), zFar_(0) +{ + loadIdentity(projection_matrix_); + loadIdentity(modelview_matrix_); } -NodeOrthographicCamera::NodeOrthographicCamera(double left - , double right - , double bottom - , double top - , double zNear - , double zFar - ) -:NodeCamera(NodeCamera::ORTHOGRAPHIC), -left_(left), -right_(right), -bottom_(bottom), -top_(top), -zNear_(zNear), -zFar_(zFar){ - - loadIdentity(projection_matrix_); - - projection_matrix_[0] = 2.0/(right-left); - projection_matrix_[3] = -(right + left) / (right - left) ; - projection_matrix_[5] = 2.0/(top-bottom); - projection_matrix_[7] = -(top + bottom) / (top - bottom) ; - projection_matrix_[10] = -2.0/(zFar-zNear); - projection_matrix_[11] = -(zFar + zNear) / (zFar - zNear); - +NodeOrthographicCamera::NodeOrthographicCamera(double left, double right, double bottom, double top, + double zNear, double zFar) +: NodeCamera(NodeCamera::ORTHOGRAPHIC), left_(left), right_(right), bottom_(bottom), top_(top), + zNear_(zNear), zFar_(zFar) +{ + loadIdentity(projection_matrix_); + + projection_matrix_[0] = 2.0 / (right - left); + projection_matrix_[3] = -(right + left) / (right - left) ; + projection_matrix_[5] = 2.0 / (top - bottom); + projection_matrix_[7] = -(top + bottom) / (top - bottom) ; + projection_matrix_[10] = -2.0 / (zFar - zNear); + projection_matrix_[11] = -(zFar + zNear) / (zFar - zNear); } NodeOrthographicCamera::NodeOrthographicCamera(const NodeOrthographicCamera& iBrother) -:NodeCamera(iBrother),left_(iBrother.left_),right_(iBrother.right_),bottom_(iBrother.bottom_),top_(iBrother.top_),zNear_(iBrother.zNear_),zFar_(iBrother.zFar_){ +: NodeCamera(iBrother), left_(iBrother.left_), right_(iBrother.right_), bottom_(iBrother.bottom_), top_(iBrother.top_), + zNear_(iBrother.zNear_), zFar_(iBrother.zFar_) +{ } -NodePerspectiveCamera::NodePerspectiveCamera() -:NodeCamera(NodeCamera::PERSPECTIVE){ +NodePerspectiveCamera::NodePerspectiveCamera() : NodeCamera(NodeCamera::PERSPECTIVE) +{ } -NodePerspectiveCamera::NodePerspectiveCamera(double fovy - , double aspect - , double zNear - , double zFar) -:NodeCamera(NodeCamera::PERSPECTIVE){ - loadIdentity(projection_matrix_); - - double f = cos(fovy/2.0)/sin(fovy/2.0); // cotangent +NodePerspectiveCamera::NodePerspectiveCamera(double fovy, double aspect, double zNear, double zFar) +: NodeCamera(NodeCamera::PERSPECTIVE) +{ + loadIdentity(projection_matrix_); - projection_matrix_[0] = f/aspect; - projection_matrix_[5] = f; - projection_matrix_[10] = (zNear+zFar)/(zNear-zFar); - projection_matrix_[11] = (2.0*zNear*zFar)/(zNear-zFar); - projection_matrix_[14] = -1.0; - projection_matrix_[15] = 0; + double f = cos(fovy / 2.0) / sin(fovy / 2.0); // cotangent + projection_matrix_[0] = f / aspect; + projection_matrix_[5] = f; + projection_matrix_[10] = (zNear + zFar) / (zNear - zFar); + projection_matrix_[11] = (2.0 * zNear * zFar) / (zNear - zFar); + projection_matrix_[14] = -1.0; + projection_matrix_[15] = 0; } -NodePerspectiveCamera::NodePerspectiveCamera(double left, - double right, - double bottom, - double top, - double zNear, - double zFar) -:NodeCamera(NodeCamera::PERSPECTIVE){ - loadIdentity(projection_matrix_); - - projection_matrix_[0] = (2.0*zNear)/(right-left); - projection_matrix_[2] = (right+left)/(right-left); - projection_matrix_[5] = (2.0*zNear)/(top-bottom); - projection_matrix_[6] = (top+bottom)/(top-bottom); - projection_matrix_[10] = - (zFar+zNear)/(zFar-zNear); - projection_matrix_[11] = - (2.0*zFar*zNear)/(zFar-zNear); - projection_matrix_[14] = -1.0; - projection_matrix_[15] = 0; +NodePerspectiveCamera::NodePerspectiveCamera(double left, double right, double bottom, double top, + double zNear, double zFar) +: NodeCamera(NodeCamera::PERSPECTIVE) +{ + loadIdentity(projection_matrix_); + + projection_matrix_[0] = (2.0 * zNear) / (right - left); + projection_matrix_[2] = (right + left) / (right - left); + projection_matrix_[5] = (2.0 * zNear) / (top - bottom); + projection_matrix_[6] = (top + bottom) / (top - bottom); + projection_matrix_[10] = -(zFar + zNear) / (zFar - zNear); + projection_matrix_[11] = -(2.0 * zFar * zNear) / (zFar - zNear); + projection_matrix_[14] = -1.0; + projection_matrix_[15] = 0; } - diff --git a/source/blender/freestyle/intern/scene_graph/NodeCamera.h b/source/blender/freestyle/intern/scene_graph/NodeCamera.h index cdd6fa83048..f7141a72a51 100644 --- a/source/blender/freestyle/intern/scene_graph/NodeCamera.h +++ b/source/blender/freestyle/intern/scene_graph/NodeCamera.h @@ -1,192 +1,216 @@ -// -// Filename : NodeCamera.h -// Author(s) : Stephane Grabli -// Purpose : Class to represent a light node -// Date of creation : 25/01/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - - -#ifndef NODE_CAMERA_H_ -#define NODE_CAMERA_H_ - -# include "../geometry/Geom.h" -# include "../system/FreestyleConfig.h" -# include "Node.h" +/* + * ***** 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_NODE_CAMERA_H__ +#define __FREESTYLE_NODE_CAMERA_H__ + +/** \file blender/freestyle/intern/scene_graph/NodeCamera.h + * \ingroup freestyle + * \brief Class to represent a light node + * \author Stephane Grabli + * \date 25/01/2002 + */ + +#include "Node.h" + +#include "../geometry/Geom.h" + +#include "../system/FreestyleConfig.h" using namespace Geometry; class NodeOrthographicCamera; + class NodePerspectiveCamera; + class LIB_SCENE_GRAPH_EXPORT NodeCamera : public Node { public: - typedef enum {PERSPECTIVE,ORTHOGRAPHIC,GENERIC} CameraType; + typedef enum { + PERSPECTIVE, + ORTHOGRAPHIC, + GENERIC, + } CameraType; + + /*! Default matrices: Identity for both projection and modelview. */ + NodeCamera(CameraType camera_type = GENERIC); + NodeCamera(const NodeCamera& iBrother); - /*! Default matrices: Identity for both projection and modelview. */ - NodeCamera(CameraType camera_type = GENERIC); - NodeCamera(const NodeCamera& iBrother); + virtual ~NodeCamera() {} - virtual ~NodeCamera() {} + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v); - /*! Accept the corresponding visitor */ - virtual void accept(SceneVisitor& v); + /*! Matrix is copied */ + void setModelViewMatrix(double modelview_matrix[16]); - /*! Matrix is copied */ - void setModelViewMatrix(double modelview_matrix[16]); - /*! Matrix is copied */ - void setProjectionMatrix(double projection_matrix[16]); + /*! Matrix is copied */ + void setProjectionMatrix(double projection_matrix[16]); - double * modelViewMatrix() {return modelview_matrix_;} - double * projectionMatrix() {return projection_matrix_;} + double * modelViewMatrix() + { + return modelview_matrix_; + } + + double * projectionMatrix() + { + return projection_matrix_; + } protected: - // row major right handed matrix - double modelview_matrix_[16]; - // row major right handed matrix - double projection_matrix_[16]; + // row major right handed matrix + double modelview_matrix_[16]; + // row major right handed matrix + double projection_matrix_[16]; - CameraType camera_type_; + CameraType camera_type_; }; -class LIB_SCENE_GRAPH_EXPORT NodeOrthographicCamera : public NodeCamera{ +class LIB_SCENE_GRAPH_EXPORT NodeOrthographicCamera : public NodeCamera +{ public: - NodeOrthographicCamera(); - /*! Builds a parallel projection matrix a la glOrtho. - A 0 0 tx - 0 B 0 ty - 0 0 C tz - 0 0 0 1 - - where - - A = - 2 / (right - left) - B = - 2 / (top - bottom) - C = - -2 / (far - near) - tx = - -(right + left) / (right - left) - ty = - -(top + bottom) / (top - bottom) - tz = - -(zFar + zNear) / (zFar - zNear) - */ - NodeOrthographicCamera(double left - , double right - , double bottom - , double top - , double zNear - , double zFar - ); - - double left() const {return left_;} - double right() const {return right_;} - double bottom() const {return bottom_;} - double top() const {return top_;} - double zNear() const {return zNear_;} - double zFar() const {return zFar_;} - - NodeOrthographicCamera(const NodeOrthographicCamera& iBrother); + NodeOrthographicCamera(); + + /*! Builds a parallel projection matrix a la glOrtho. + * A 0 0 tx + * 0 B 0 ty + * 0 0 C tz + * 0 0 0 1 + * + * where + * A = 2 / (right - left) + * B = 2 / (top - bottom) + * C = -2 / (far - near) + * tx = -(right + left) / (right - left) + * ty = -(top + bottom) / (top - bottom) + * tz = -(zFar + zNear) / (zFar - zNear) + */ + NodeOrthographicCamera(double left, double right, double bottom, double top, double zNear, double zFar); + + double left() const + { + return left_; + } + + double right() const + { + return right_; + } + + double bottom() const + { + return bottom_; + } + + double top() const + { + return top_; + } + + double zNear() const + { + return zNear_; + } + + double zFar() const + { + return zFar_; + } + + NodeOrthographicCamera(const NodeOrthographicCamera& iBrother); private: - double left_; - double right_; - double bottom_; - double top_; - double zNear_; - double zFar_; + double left_; + double right_; + double bottom_; + double top_; + double zNear_; + double zFar_; }; -class LIB_SCENE_GRAPH_EXPORT NodePerspectiveCamera : public NodeCamera { +class LIB_SCENE_GRAPH_EXPORT NodePerspectiveCamera : public NodeCamera +{ public: - NodePerspectiveCamera(); - /*! Builds a perspective projection matrix a la gluPerspective. - Given f defined as follows: - fovy - f = cotangent(____) - 2 - The generated matrix is - - - ( f ) - | ______ | - | aspect 0 0 0 | - | | - | 0 f 0 0 | - | | - | zNear+zFar 2*zNear*zFar | - | __________ ____________ | - | 0 0 zNear-zFar zNear-zFar | - | | - ( 0 0 -1 0 ) - \param fovy - Field of View specified in radians. - */ - NodePerspectiveCamera(double fovy - , double aspect - , double zNear - , double zFar); - - /*! Builds a perspective projection matrix a la glFrustum. - ( 2*zNear ) - | __________ | - | right-left 0 A 0 | - | | - | 2*zNear | - | 0 __________ B 0 | - | top-bottom | - | | - | 0 0 C D | - | | - | 0 0 -1 0 | - ( ) - - right+left - A = __________ - right-left - - top+bottom - B = __________ - top-bottom - - zFar+zNear - C = - __________ - zFar-zNear - - 2*zFar*zNear - D = - ____________ - zFar-zNear - */ - NodePerspectiveCamera(double left, - double right, - double bottom, - double top, - double zNear, - double zFar); + NodePerspectiveCamera(); + + /*! Builds a perspective projection matrix a la gluPerspective. + * Given f defined as follows: + * fovy + * f = cotangent(____) + * 2 + * The generated matrix is + * ( f ) + * | ______ 0 0 0 | + * | aspect | + * | | + * | 0 f 0 0 | + * | | + * | zNear+zFar 2*zNear*zFar | + * | 0 0 __________ ____________ | + * | zNear-zFar zNear-zFar | + * | | + * ( 0 0 -1 0 ) + * \param fovy + * Field of View specified in radians. + */ + NodePerspectiveCamera(double fovy, double aspect, double zNear, double zFar); + + /*! Builds a perspective projection matrix a la glFrustum. + * ( 2*zNear ) + * | __________ 0 A 0 | + * | right-left | + * | | + * | 2*zNear | + * | 0 __________ B 0 | + * | top-bottom | + * | | + * | 0 0 C D | + * | | + * | 0 0 -1 0 | + * ( ) + * + * right+left + * A = __________ + * right-left + * + * top+bottom + * B = __________ + * top-bottom + * + * zFar+zNear + * C = - __________ + * zFar-zNear + * + * 2*zFar*zNear + * D = - ____________ + * zFar-zNear + */ + NodePerspectiveCamera(double left, double right, double bottom, double top, double zNear, double zFar); }; -#endif // NODE_CAMERA_H_ +#endif // __FREESTYLE_NODE_CAMERA_H__ diff --git a/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.cpp b/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.cpp index acd740ee055..fed589b17c5 100644 --- a/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.cpp +++ b/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.cpp @@ -1,34 +1,46 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/scene_graph/NodeDrawingStyle.cpp + * \ingroup freestyle + * \brief Class to define a Drawing Style to be applied to the underlying children. Inherits from NodeGroup. + * \author Stephane Grabli + * \date 06/02/2002 + */ #include "NodeDrawingStyle.h" -void NodeDrawingStyle::accept(SceneVisitor& v) { - v.visitNodeDrawingStyle(*this); +void NodeDrawingStyle::accept(SceneVisitor& v) +{ + v.visitNodeDrawingStyle(*this); - v.visitNodeDrawingStyleBefore(*this); - v.visitDrawingStyle(_DrawingStyle); - for(vector::iterator node=_Children.begin(), end=_Children.end(); - node!=end; - node++) - (*node)->accept(v); - v.visitNodeDrawingStyleAfter(*this); + v.visitNodeDrawingStyleBefore(*this); + v.visitDrawingStyle(_DrawingStyle); + for (vector::iterator node = _Children.begin(), end = _Children.end(); node != end; ++node) + (*node)->accept(v); + v.visitNodeDrawingStyleAfter(*this); } diff --git a/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h b/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h index 012f963ea8c..29a05290df1 100644 --- a/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h +++ b/source/blender/freestyle/intern/scene_graph/NodeDrawingStyle.h @@ -1,70 +1,111 @@ -// -// Filename : NodeDrawingStyle.h -// Author(s) : Stephane Grabli -// Purpose : Class to define a Drawing Style to be applied -// to the underlying children. Inherits from NodeGroup. -// Date of creation : 06/02/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef NODEDRAWINGSTYLE_H -# define NODEDRAWINGSTYLE_H - -# include "../system/FreestyleConfig.h" -# include "NodeGroup.h" -# include "DrawingStyle.h" +/* + * ***** 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_NODE_DRAWING_STYLE_H__ +#define __FREESTYLE_NODE_DRAWING_STYLE_H__ + +/** \file blender/freestyle/intern/scene_graph/NodeDrawingStyle.h + * \ingroup freestyle + * \brief Class to define a Drawing Style to be applied to the underlying children. Inherits from NodeGroup. + * \author Stephane Grabli + * \date 06/02/2002 + */ + +#include "DrawingStyle.h" +#include "NodeGroup.h" + +#include "../system/FreestyleConfig.h" class LIB_SCENE_GRAPH_EXPORT NodeDrawingStyle : public NodeGroup { public: + inline NodeDrawingStyle() : NodeGroup() {} + virtual ~NodeDrawingStyle() {} + + inline const DrawingStyle& drawingStyle() const + { + return _DrawingStyle; + } + + inline void setDrawingStyle(const DrawingStyle& iDrawingStyle) + { + _DrawingStyle = iDrawingStyle; + } + + /*! Sets the style. Must be one of FILLED, LINES, POINTS, INVISIBLE. */ + inline void setStyle(const DrawingStyle::STYLE iStyle) + { + _DrawingStyle.setStyle(iStyle); + } + + /*! Sets the line width in the LINES style case */ + inline void setLineWidth(const float iLineWidth) + { + _DrawingStyle.setLineWidth(iLineWidth); + } + + /*! Sets the Point size in the POINTS style case */ + inline void setPointSize(const float iPointSize) + { + _DrawingStyle.setPointSize(iPointSize); + } + + /*! Enables or disables the lighting. TRUE = enable */ + inline void setLightingEnabled(const bool iEnableLighting) + { + _DrawingStyle.setLightingEnabled(iEnableLighting); + } - inline NodeDrawingStyle() : NodeGroup() {} - virtual ~NodeDrawingStyle() {} + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v); - inline const DrawingStyle& drawingStyle() const { return _DrawingStyle; } - inline void setDrawingStyle(const DrawingStyle& iDrawingStyle) { _DrawingStyle = iDrawingStyle; } + /*! accessors */ + inline DrawingStyle::STYLE style() const + { + return _DrawingStyle.style(); + } - /*! Sets the style. Must be one of FILLED, LINES, POINTS, INVISIBLE. */ - inline void setStyle(const DrawingStyle::STYLE iStyle) { _DrawingStyle.setStyle(iStyle); } - /*! Sets the line width in the LINES style case */ - inline void setLineWidth(const float iLineWidth) { _DrawingStyle.setLineWidth(iLineWidth); } - /*! Sets the Point size in the POINTS style case */ - inline void setPointSize(const float iPointSize) { _DrawingStyle.setPointSize(iPointSize); } - /*! Enables or disables the lighting. TRUE = enable */ - inline void setLightingEnabled(const bool iEnableLighting) { _DrawingStyle.setLightingEnabled(iEnableLighting); } + inline float lineWidth() const + { + return _DrawingStyle.lineWidth(); + } - /*! Accept the corresponding visitor */ - virtual void accept(SceneVisitor& v); + inline float pointSize() const + { + return _DrawingStyle.pointSize(); + } - /*! accessors */ - inline DrawingStyle::STYLE style() const {return _DrawingStyle.style();} - inline float lineWidth() const {return _DrawingStyle.lineWidth();} - inline float pointSize() const {return _DrawingStyle.pointSize();} - inline bool lightingEnabled() const {return _DrawingStyle.lightingEnabled();} + inline bool lightingEnabled() const + { + return _DrawingStyle.lightingEnabled(); + } private: - DrawingStyle _DrawingStyle; + DrawingStyle _DrawingStyle; }; -#endif // NODEDRAWINGSTYLE_H +#endif // __FREESTYLE_NODE_DRAWING_STYLE_H__ diff --git a/source/blender/freestyle/intern/scene_graph/NodeGroup.cpp b/source/blender/freestyle/intern/scene_graph/NodeGroup.cpp index 3d2aa2c8694..5426c60d3e1 100644 --- a/source/blender/freestyle/intern/scene_graph/NodeGroup.cpp +++ b/source/blender/freestyle/intern/scene_graph/NodeGroup.cpp @@ -1,122 +1,126 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/scene_graph/NodeGroup.cpp + * \ingroup freestyle + * \brief Class to represent a group node. This node can contains several children. + * \brief It also contains a transform matrix indicating the transform state of the underlying children. + * \author Stephane Grabli + * \date 24/01/2002 + */ #include "NodeGroup.h" void NodeGroup::AddChild(Node *iChild) { - if(NULL == iChild) - return; + if (NULL == iChild) + return; - _Children.push_back(iChild); - iChild->addRef(); + _Children.push_back(iChild); + iChild->addRef(); } int NodeGroup::destroy() { - /*! Node::destroy makes a release on the object - * and then returns the reference counter. - * If the reference counter is equal to 0, - * that means that nobody else is linking - * this node group and that we can destroy the whole - * underlying tree. - * Else, one or several Node link this node group, - * and we only returns the reference counter - * decremented by Node::destroy(); - */ - int refThis = Node::destroy(); - - // if refThis != 0, we can't destroy the tree - if(0 != refThis) - return refThis; - - // If we are here, that means that nobody else - // needs our NodeGroup and we can destroy it. - int refCount = 0; - vector::iterator node; - - for(node=_Children.begin(); node!=_Children.end(); node++) - { - refCount = (*node)->destroy(); - if(0 == refCount) - delete (*node); - } - - _Children.clear(); - - return refThis; + /*! Node::destroy makes a release on the object and then returns the reference counter. + * If the reference counter is equal to 0, that means that nobody else is linking this node group and + * that we can destroy the whole underlying tree. + * Else, one or several Node link this node group, and we only returns the reference counter + * decremented by Node::destroy(); + */ + int refThis = Node::destroy(); + + // if refThis != 0, we can't destroy the tree + if (0 != refThis) + return refThis; + + // If we are here, that means that nobody else needs our NodeGroup and we can destroy it. + int refCount = 0; + vector::iterator node; + + for (node = _Children.begin(); node != _Children.end(); ++node) { + refCount = (*node)->destroy(); + if (0 == refCount) + delete (*node); + } + + _Children.clear(); + + return refThis; } -void NodeGroup::accept(SceneVisitor& v) { - v.visitNodeGroup(*this); - - v.visitNodeGroupBefore(*this); - for(vector::iterator node=_Children.begin(), end=_Children.end(); - node!=end; - node++) - (*node)->accept(v); - v.visitNodeGroupAfter(*this); +void NodeGroup::accept(SceneVisitor& v) +{ + v.visitNodeGroup(*this); + + v.visitNodeGroupBefore(*this); + for (vector::iterator node = _Children.begin(), end = _Children.end(); node != end; ++node) + (*node)->accept(v); + v.visitNodeGroupAfter(*this); } void NodeGroup::DetachChildren() { - vector::iterator node; - - for(node=_Children.begin(); node!=_Children.end(); node++) - { - (*node)->release(); - } - - _Children.clear(); + vector::iterator node; + + for (node = _Children.begin(); node != _Children.end(); ++node) { + (*node)->release(); + } + + _Children.clear(); } void NodeGroup::DetachChild(Node *iChild) { - int found = 0; - vector::iterator node; - - for(node=_Children.begin(); node!=_Children.end(); node++) - { - if((*node) == iChild) - { - (*node)->release(); - _Children.erase(node); - found = 1; - break; - } - } + int found = 0; + vector::iterator node; + + for (node = _Children.begin(); node != _Children.end(); ++node) { + if ((*node) == iChild) { + (*node)->release(); + _Children.erase(node); + found = 1; + break; + } + } } -void NodeGroup::RetrieveChildren(vector& oNodes){ - oNodes = _Children; +void NodeGroup::RetrieveChildren(vector& oNodes) +{ + oNodes = _Children; } const BBox& NodeGroup::UpdateBBox() { - vector::iterator node; - clearBBox(); - for(node=_Children.begin(); node!=_Children.end(); node++) - { - AddBBox((*node)->UpdateBBox()); - } - - return Node::UpdateBBox(); + vector::iterator node; + clearBBox(); + for (node = _Children.begin(); node != _Children.end(); ++node) { + AddBBox((*node)->UpdateBBox()); + } + + return Node::UpdateBBox(); } diff --git a/source/blender/freestyle/intern/scene_graph/NodeGroup.h b/source/blender/freestyle/intern/scene_graph/NodeGroup.h index a1bd2b57e56..1c5b106d5c6 100644 --- a/source/blender/freestyle/intern/scene_graph/NodeGroup.h +++ b/source/blender/freestyle/intern/scene_graph/NodeGroup.h @@ -1,84 +1,89 @@ -// -// Filename : NodeGroup.h -// Author(s) : Stephane Grabli -// Purpose : Class to represent a group node. This node can contains -// several children. It also contains a transform matrix -// indicating the transform state of the underlying -// children. -// Date of creation : 24/01/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef NODEGROUP_H -# define NODEGROUP_H - -# include -# include "../system/FreestyleConfig.h" -# include "Node.h" +/* + * ***** 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_NODE_GROUP_H__ +#define __FREESTYLE_NODE_GROUP_H__ + +/** \file blender/freestyle/intern/scene_graph/NodeGroup.h + * \ingroup freestyle + * \brief Class to represent a group node. This node can contains several children. + * \brief It also contains a transform matrix indicating the transform state of the underlying children. + * \author Stephane Grabli + * \date 24/01/2002 + */ + +#include + +#include "Node.h" + +#include "../system/FreestyleConfig.h" using namespace std; class LIB_SCENE_GRAPH_EXPORT NodeGroup : public Node { public: + inline NodeGroup(): Node() {} + virtual ~NodeGroup(){} - inline NodeGroup(): Node() {} - virtual ~NodeGroup(){} + /*! Adds a child. Makes a addRef on the iChild reference counter */ + virtual void AddChild(Node *iChild); - /*! Adds a child. Makes a addRef on the - * iChild reference counter */ - virtual void AddChild(Node *iChild); + /*! destroys all the underlying nodes + * Returns the reference counter after having done a release() + */ + virtual int destroy(); - /*! destroys all the underlying nodes - * Returns the reference counter - * after having done a release() */ - virtual int destroy(); + /*! Detaches all the children */ + virtual void DetachChildren(); - /*! Detaches all the children */ - virtual void DetachChildren(); + /*! Detached the sepcified child */ + virtual void DetachChild(Node *iChild); - /*! Detached the sepcified child */ - virtual void DetachChild(Node *iChild); + /*! Retrieve children */ + virtual void RetrieveChildren(vector& oNodes); - /*! Retrieve children */ - virtual void RetrieveChildren(vector& oNodes); + /*! Renders every children */ +// virtual void Render(Renderer *iRenderer); + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v); - /*! Renders every children */ - // virtual void Render(Renderer *iRenderer); + /*! Updates the BBox */ + virtual const BBox& UpdateBBox(); - /*! Accept the corresponding visitor */ - virtual void accept(SceneVisitor& v); - - /*! Updates the BBox */ - virtual const BBox& UpdateBBox(); - - /*! Returns the number of children */ - virtual int numberOfChildren() {return _Children.size();} + /*! Returns the number of children */ + virtual int numberOfChildren() + { + return _Children.size(); + } protected: - vector _Children; + vector _Children; }; -#endif // NODEGROUP_H +#endif // __FREESTYLE_NODE_GROUP_H__ diff --git a/source/blender/freestyle/intern/scene_graph/NodeLight.cpp b/source/blender/freestyle/intern/scene_graph/NodeLight.cpp index 61a46155cfa..f410d2da18e 100644 --- a/source/blender/freestyle/intern/scene_graph/NodeLight.cpp +++ b/source/blender/freestyle/intern/scene_graph/NodeLight.cpp @@ -1,80 +1,86 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/scene_graph/NodeLight.cpp + * \ingroup freestyle + * \brief Class to represent a light node + * \author Stephane Grabli + * \date 25/01/2002 + */ #include "NodeLight.h" int NodeLight::numberOfLights = 0; -NodeLight::NodeLight() -: Node() +NodeLight::NodeLight() : Node() { - if(numberOfLights > 7) - { - _number = 7; - } - else - { - _number = numberOfLights; - numberOfLights++; - } - - Ambient[0] = Ambient[1] = Ambient[2] = 0.f; - Ambient[3] = 1.f; - - for(int i=0; i<4; i++) - { - Diffuse[i] = 1.f; - Specular[i] = 1.f; - } + if (numberOfLights > 7) { + _number = 7; + } + else { + _number = numberOfLights; + numberOfLights++; + } - Position[0] = Position[1] = Position[3] = 0.f; - Position[2] = 1.f; + Ambient[0] = Ambient[1] = Ambient[2] = 0.0f; + Ambient[3] = 1.0f; - on = true; + for (int i = 0; i < 4; i++) { + Diffuse[i] = 1.0f; + Specular[i] = 1.0f; + } + + Position[0] = Position[1] = Position[3] = 0.0f; + Position[2] = 1.0f; + + on = true; } -NodeLight::NodeLight(NodeLight& iBrother) -: Node(iBrother) +NodeLight::NodeLight(NodeLight& iBrother) : Node(iBrother) { - if(numberOfLights > 7) - { - _number = 7; - } - else - { - _number = numberOfLights; - numberOfLights++; - } + if (numberOfLights > 7) { + _number = 7; + } + else { + _number = numberOfLights; + numberOfLights++; + } - for(int i=0; i<4; i++) - { - Ambient[i] = iBrother.ambient()[i]; - Diffuse[i] = iBrother.diffuse()[i]; - Specular[i] = iBrother.specular()[i]; - Position[i] = iBrother.position()[i]; - } + for (int i = 0; i < 4; i++) { + Ambient[i] = iBrother.ambient()[i]; + Diffuse[i] = iBrother.diffuse()[i]; + Specular[i] = iBrother.specular()[i]; + Position[i] = iBrother.position()[i]; + } - on = iBrother.isOn(); + on = iBrother.isOn(); } -void NodeLight::accept(SceneVisitor& v) { - v.visitNodeLight(*this); +void NodeLight::accept(SceneVisitor& v) +{ + v.visitNodeLight(*this); } diff --git a/source/blender/freestyle/intern/scene_graph/NodeLight.h b/source/blender/freestyle/intern/scene_graph/NodeLight.h index 0689505fb24..49484d8b9b3 100644 --- a/source/blender/freestyle/intern/scene_graph/NodeLight.h +++ b/source/blender/freestyle/intern/scene_graph/NodeLight.h @@ -1,86 +1,113 @@ -// -// Filename : NodeLight.h -// Author(s) : Stephane Grabli -// Purpose : Class to represent a light node -// Date of creation : 25/01/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef NODELIGHT_H -# define NODELIGHT_H - -# include "../geometry/Geom.h" -# include "../system/FreestyleConfig.h" -# include "Node.h" +/* + * ***** 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_NODE_LIGHT_H__ +#define __FREESTYLE_NODE_LIGHT_H__ + +/** \file blender/freestyle/intern/scene_graph/NodeLight.h + * \ingroup freestyle + * \brief Class to represent a light node + * \author Stephane Grabli + * \date 25/01/2002 + */ + +#include "Node.h" + +#include "../geometry/Geom.h" + +#include "../system/FreestyleConfig.h" using namespace Geometry; class LIB_SCENE_GRAPH_EXPORT NodeLight : public Node { public: + NodeLight(); + NodeLight(NodeLight& iBrother); + + virtual ~NodeLight() {} + + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v); - NodeLight(); - NodeLight(NodeLight& iBrother); + /*! Accessors for the light properties */ + inline const float * ambient() const + { + return Ambient; + } - virtual ~NodeLight() {} + inline const float * diffuse() const + { + return Diffuse; + } - /*! Accept the corresponding visitor */ - virtual void accept(SceneVisitor& v); + inline const float * specular() const + { + return Specular; + } + + inline const float * position() const + { + return Position; + } + + inline bool isOn() const + { + return on; + } + + inline int number() const + { + return _number; + } - /*! Accessors for the light properties */ - inline const float * ambient() const {return Ambient;} - inline const float * diffuse() const {return Diffuse;} - inline const float * specular() const {return Specular;} - inline const float * position() const {return Position;} - inline bool isOn() const {return on;} - inline int number() const {return _number;} - private: - // Data members - // ============ - - /*! on=true, the light is on */ - bool on; - - /*! The color definition */ - float Ambient[4]; - float Diffuse[4]; - float Specular[4]; - - /*! Light position. if w = 0, the light is - * placed at infinite. - */ - float Position[4]; - - /*! used to manage the number of lights */ - /*! numberOfLights - * the number of lights in the scene. - * Initially, 0. - */ - static int numberOfLights; - /*! The current lignt number */ - int _number; + // Data members + // ============ + + /*! on=true, the light is on */ + bool on; + + /*! The color definition */ + float Ambient[4]; + float Diffuse[4]; + float Specular[4]; + + /*! Light position. if w = 0, the light is placed at infinite. */ + float Position[4]; + + /*! used to manage the number of lights */ + /*! numberOfLights + * the number of lights in the scene. + * Initially, 0. + */ + static int numberOfLights; + /*! The current lignt number */ + int _number; }; -#endif // NODELIGHT_H +#endif // __FREESTYLE_NODE_LIGHT_H__ diff --git a/source/blender/freestyle/intern/scene_graph/NodeShape.cpp b/source/blender/freestyle/intern/scene_graph/NodeShape.cpp index 9083c852d36..b1593c9f43b 100644 --- a/source/blender/freestyle/intern/scene_graph/NodeShape.cpp +++ b/source/blender/freestyle/intern/scene_graph/NodeShape.cpp @@ -1,51 +1,63 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/scene_graph/NodeShape.cpp + * \ingroup freestyle + * \brief Class to build a shape node. It contains a Rep, which is the shape geometry + * \author Stephane Grabli + * \date 25/01/2002 + */ #include "NodeShape.h" NodeShape::~NodeShape() { - vector::iterator rep; - - if(0 != _Shapes.size()) - { - for(rep=_Shapes.begin(); rep!=_Shapes.end(); rep++) - { - int refCount = (*rep)->destroy(); - if(0 == refCount) - delete (*rep); - } - - _Shapes.clear(); - } + vector::iterator rep; + + if (0 != _Shapes.size()) { + for (rep = _Shapes.begin(); rep != _Shapes.end(); ++rep) { + int refCount = (*rep)->destroy(); + if (0 == refCount) + delete (*rep); + } + + _Shapes.clear(); + } } -void NodeShape::accept(SceneVisitor& v) { - v.visitNodeShape(*this); - - v.visitFrsMaterial(_FrsMaterial); - - v.visitNodeShapeBefore(*this); - vector::iterator rep; - for(rep = _Shapes.begin(); rep != _Shapes.end(); rep++) - (*rep)->accept(v); - v.visitNodeShapeAfter(*this); +void NodeShape::accept(SceneVisitor& v) +{ + v.visitNodeShape(*this); + + v.visitFrsMaterial(_FrsMaterial); + + v.visitNodeShapeBefore(*this); + vector::iterator rep; + for (rep = _Shapes.begin(); rep != _Shapes.end(); ++rep) + (*rep)->accept(v); + v.visitNodeShapeAfter(*this); } diff --git a/source/blender/freestyle/intern/scene_graph/NodeShape.h b/source/blender/freestyle/intern/scene_graph/NodeShape.h index 9849d4661b8..046d8b0e392 100644 --- a/source/blender/freestyle/intern/scene_graph/NodeShape.h +++ b/source/blender/freestyle/intern/scene_graph/NodeShape.h @@ -1,43 +1,50 @@ -// -// Filename : NodeShape.h -// Author(s) : Stephane Grabli -// Purpose : Class to build a shape node. It contains a Rep, -// which is the shape geometry -// Date of creation : 25/01/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef NODESHAPE_H -# define NODESHAPE_H - -# include -# include "../system/FreestyleConfig.h" -# include "Node.h" -# include "Rep.h" -# include "../geometry/BBox.h" -# include "../geometry/Geom.h" -# include "FrsMaterial.h" +/* + * ***** 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_NODE_SHAPE_H__ +#define __FREESTYLE_NODE_SHAPE_H__ + +/** \file blender/freestyle/intern/scene_graph/NodeShape.h + * \ingroup freestyle + * \brief Class to build a shape node. It contains a Rep, which is the shape geometry + * \author Stephane Grabli + * \date 25/01/2002 + */ + +#include + +#include "../geometry/BBox.h" +#include "../geometry/Geom.h" + +#include "../system/FreestyleConfig.h" + +#include "FrsMaterial.h" +#include "Node.h" +#include "Rep.h" using namespace std; using namespace Geometry; @@ -45,45 +52,52 @@ using namespace Geometry; class LIB_SCENE_GRAPH_EXPORT NodeShape : public Node { public: - - inline NodeShape() : Node() {} - - virtual ~NodeShape(); - - /*! Adds a Rep to the _Shapes list - * The delete of the rep is done - * when it is not used any more by - * the Scene Manager. So, it must not - * be deleted by the caller - */ - virtual void AddRep(Rep *iRep) - { - if(NULL == iRep) - return; - _Shapes.push_back(iRep); - iRep->addRef(); - - // updates bbox: - AddBBox(iRep->bbox()); - } - - /*! Accept the corresponding visitor */ - virtual void accept(SceneVisitor& v); - - /*! Sets the shape material */ - inline void setFrsMaterial(const FrsMaterial& iMaterial) { _FrsMaterial = iMaterial; } - - /*! accessors */ - /*! returns the shape's material */ - inline FrsMaterial& frs_material() { return _FrsMaterial; } - inline const vector& shapes() {return _Shapes;} + inline NodeShape() : Node() {} + + virtual ~NodeShape(); + + /*! Adds a Rep to the _Shapes list + * The delete of the rep is done when it is not used any more by the Scene Manager. + * So, it must not be deleted by the caller + */ + virtual void AddRep(Rep *iRep) + { + if (NULL == iRep) + return; + _Shapes.push_back(iRep); + iRep->addRef(); + + // updates bbox: + AddBBox(iRep->bbox()); + } + + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v); + + /*! Sets the shape material */ + inline void setFrsMaterial(const FrsMaterial& iMaterial) + { + _FrsMaterial = iMaterial; + } + + /*! accessors */ + /*! returns the shape's material */ + inline FrsMaterial& frs_material() + { + return _FrsMaterial; + } + + inline const vector& shapes() + { + return _Shapes; + } private: - /*! list of shapes */ - vector _Shapes; + /*! list of shapes */ + vector _Shapes; - /*! Shape Material */ - FrsMaterial _FrsMaterial; + /*! Shape Material */ + FrsMaterial _FrsMaterial; }; -#endif // NODESHAPE_H +#endif // __FREESTYLE_NODE_SHAPE_H__ diff --git a/source/blender/freestyle/intern/scene_graph/NodeTransform.cpp b/source/blender/freestyle/intern/scene_graph/NodeTransform.cpp index 8f706c78259..aa01200a4d2 100644 --- a/source/blender/freestyle/intern/scene_graph/NodeTransform.cpp +++ b/source/blender/freestyle/intern/scene_graph/NodeTransform.cpp @@ -1,166 +1,178 @@ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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 ***** + */ + +/** \file blender/freestyle/intern/scene_graph/NodeTransform.cpp + * \ingroup freestyle + * \brief Class to represent a transform node. A Transform node contains one or several children, + * \brief all affected by the transformation. + * \author Stephane Grabli + * \date 06/02/2002 + */ +#include "NodeTransform.h" #include "../system/FreestyleConfig.h" -#include "NodeTransform.h" void NodeTransform::Translate(real x, real y, real z) { - _Matrix(0, 3) += x; - _Matrix(1, 3) += y; - _Matrix(2, 3) += z; + _Matrix(0, 3) += x; + _Matrix(1, 3) += y; + _Matrix(2, 3) += z; } void NodeTransform::Rotate(real iAngle, real x, real y, real z) { - //Normalize the x,y,z vector; - real norm = (real)sqrt(x*x+y*y+z*z); - if(0 == norm) - return; - - x /= norm; - y /= norm; - z /= norm; - - // find the corresponding matrix with the Rodrigues formula: - // R = I + sin(iAngle)*Ntilda + (1-cos(iAngle))*Ntilda*Ntilda - Matrix33r Ntilda; - Ntilda(0,0) = Ntilda(1,1) = Ntilda(2,2) = 0.f; - Ntilda(0,1) = -z; - Ntilda(0,2) = y; - Ntilda(1,0) = z; - Ntilda(1,2) = -x; - Ntilda(2,0) = -y; - Ntilda(2,1) = x; - - const Matrix33r Ntilda2(Ntilda * Ntilda); - - - const real sinAngle = (real)sin((iAngle/180.f)*M_PI); - const real cosAngle = (real)cos((iAngle/180.f)*M_PI); - - Matrix33r NS(Ntilda*sinAngle); - Matrix33r NC(Ntilda2*(1.f-cosAngle)); - Matrix33r R; - R = Matrix33r::identity(); - R += NS + NC; - - //R4 is the corresponding 4x4 matrix - Matrix44r R4; - R4 = Matrix44r::identity(); - - for(int i=0; i<3; i++) - for(int j=0; j<3; j++) - R4(i,j) = R(i,j); - - // Finally, we multiply our current matrix by R4: - Matrix44r mat_tmp(_Matrix); - _Matrix = mat_tmp * R4; + //Normalize the x,y,z vector; + real norm = (real)sqrt(x * x + y * y + z * z); + if (0 == norm) + return; + + x /= norm; + y /= norm; + z /= norm; + + /* find the corresponding matrix with the Rodrigues formula: + * R = I + sin(iAngle)*Ntilda + (1-cos(iAngle))*Ntilda*Ntilda + */ + Matrix33r Ntilda; + Ntilda(0, 0) = Ntilda(1, 1) = Ntilda(2, 2) = 0.0f; + Ntilda(0, 1) = -z; + Ntilda(0, 2) = y; + Ntilda(1, 0) = z; + Ntilda(1, 2) = -x; + Ntilda(2, 0) = -y; + Ntilda(2, 1) = x; + + const Matrix33r Ntilda2(Ntilda * Ntilda); + + + const real sinAngle = (real)sin((iAngle / 180.0f) * M_PI); + const real cosAngle = (real)cos((iAngle / 180.0f) * M_PI); + + Matrix33r NS(Ntilda * sinAngle); + Matrix33r NC(Ntilda2 * (1.0f - cosAngle)); + Matrix33r R; + R = Matrix33r::identity(); + R += NS + NC; + + // R4 is the corresponding 4x4 matrix + Matrix44r R4; + R4 = Matrix44r::identity(); + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) + R4(i, j) = R(i, j); + } + + // Finally, we multiply our current matrix by R4: + Matrix44r mat_tmp(_Matrix); + _Matrix = mat_tmp * R4; } void NodeTransform::Scale(real x, real y, real z) { - _Matrix(0,0) *= x; - _Matrix(1,1) *= y; - _Matrix(2,2) *= z; + _Matrix(0, 0) *= x; + _Matrix(1, 1) *= y; + _Matrix(2, 2) *= z; - _Scaled = true; + _Scaled = true; } void NodeTransform::MultiplyMatrix(const Matrix44r &iMatrix) { - Matrix44r mat_tmp(_Matrix); - _Matrix = mat_tmp * iMatrix; + Matrix44r mat_tmp(_Matrix); + _Matrix = mat_tmp * iMatrix; } void NodeTransform::setMatrix(const Matrix44r &iMatrix) { - _Matrix = iMatrix; - if(isScaled(iMatrix)) - _Scaled = true; + _Matrix = iMatrix; + if (isScaled(iMatrix)) + _Scaled = true; } -void NodeTransform::accept(SceneVisitor& v) { - v.visitNodeTransform(*this); +void NodeTransform::accept(SceneVisitor& v) +{ + v.visitNodeTransform(*this); - v.visitNodeTransformBefore(*this); - for(vector::iterator node=_Children.begin(), end=_Children.end(); - node!=end; - node++) - (*node)->accept(v); - v.visitNodeTransformAfter(*this); + v.visitNodeTransformBefore(*this); + for (vector::iterator node = _Children.begin(), end = _Children.end(); node != end; ++node) + (*node)->accept(v); + v.visitNodeTransformAfter(*this); } void NodeTransform::AddBBox(const BBox& iBBox) { - Vec3r oldMin(iBBox.getMin()); - Vec3r oldMax(iBBox.getMax()); - - // compute the 8 corners of the bbox - HVec3r box[8]; - box[0] = HVec3r(iBBox.getMin()); - box[1] = HVec3r(oldMax[0], oldMin[1], oldMin[2]); - box[2] = HVec3r(oldMax[0], oldMax[1], oldMin[2]); - box[3] = HVec3r(oldMin[0], oldMax[1], oldMin[2]); - box[4] = HVec3r(oldMin[0], oldMin[1], oldMax[2]); - box[5] = HVec3r(oldMax[0], oldMin[1], oldMax[2]); - box[6] = HVec3r(oldMax[0], oldMax[1], oldMax[2]); - box[7] = HVec3r(oldMin[0], oldMax[1], oldMax[2]); - - // Computes the transform iBBox - HVec3r tbox[8]; - unsigned i; - for(i = 0; i < 8; i++) - tbox[i] = _Matrix * box[i]; - - Vec3r newMin(tbox[0]); - Vec3r newMax(tbox[0]); - for (i=0; i<8; i++) - { - for (unsigned int j=0; j<3; j++) - { - if (newMin[j] > tbox[i][j]) - newMin[j] = tbox[i][j]; - if (newMax[j] < tbox[i][j]) - newMax[j] = tbox[i][j]; - } - } - - BBox transformBox(newMin, newMax); - - Node::AddBBox(transformBox); + Vec3r oldMin(iBBox.getMin()); + Vec3r oldMax(iBBox.getMax()); + + // compute the 8 corners of the bbox + HVec3r box[8]; + box[0] = HVec3r(iBBox.getMin()); + box[1] = HVec3r(oldMax[0], oldMin[1], oldMin[2]); + box[2] = HVec3r(oldMax[0], oldMax[1], oldMin[2]); + box[3] = HVec3r(oldMin[0], oldMax[1], oldMin[2]); + box[4] = HVec3r(oldMin[0], oldMin[1], oldMax[2]); + box[5] = HVec3r(oldMax[0], oldMin[1], oldMax[2]); + box[6] = HVec3r(oldMax[0], oldMax[1], oldMax[2]); + box[7] = HVec3r(oldMin[0], oldMax[1], oldMax[2]); + + // Computes the transform iBBox + HVec3r tbox[8]; + unsigned int i; + for (i = 0; i < 8; i++) + tbox[i] = _Matrix * box[i]; + + Vec3r newMin(tbox[0]); + Vec3r newMax(tbox[0]); + for (i = 0; i < 8; i++) { + for (unsigned int j = 0; j < 3; j++) { + if (newMin[j] > tbox[i][j]) + newMin[j] = tbox[i][j]; + if (newMax[j] < tbox[i][j]) + newMax[j] = tbox[i][j]; + } + } + + BBox transformBox(newMin, newMax); + + Node::AddBBox(transformBox); } bool NodeTransform::isScaled(const Matrix44r &M) { - for(unsigned int j=0; j<3; j++) - { - real norm = 0; - for(unsigned int i=0; i<3; i++) - { - norm += M(i,j)*M(i,j); - } - if((norm > 1.01) || (norm < 0.99)) - return true; - } - - return false; + for (unsigned int j = 0; j < 3; j++) { + real norm = 0; + for (unsigned int i = 0; i < 3; i++) { + norm += M(i, j) * M(i, j); + } + if ((norm > 1.01) || (norm < 0.99)) + return true; + } + + return false; } diff --git a/source/blender/freestyle/intern/scene_graph/NodeTransform.h b/source/blender/freestyle/intern/scene_graph/NodeTransform.h index e75132466f0..e98045989d3 100644 --- a/source/blender/freestyle/intern/scene_graph/NodeTransform.h +++ b/source/blender/freestyle/intern/scene_graph/NodeTransform.h @@ -1,107 +1,110 @@ -// -// Filename : NodeTransform.h -// Author(s) : Stephane Grabli -// Purpose : Class to represent a transform node. A Transform node -// contains one or several children, all affected by the -// transformation. -// Date of creation : 06/02/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef NODETRANSFORM_H -# define NODETRANSFORM_H - -# include "../geometry/Geom.h" -# include "../system/FreestyleConfig.h" -# include "NodeGroup.h" +/* + * ***** 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_NODE_TRANSFORM_H__ +#define __FREESTYLE_NODE_TRANSFORM_H__ + +/** \file blender/freestyle/intern/scene_graph/NodeTransform.h + * \ingroup freestyle + * \brief Class to represent a transform node. A Transform node contains one or several children, + * \brief all affected by the transformation. + * \author Stephane Grabli + * \date 06/02/2002 + */ + +#include "NodeGroup.h" + +#include "../geometry/Geom.h" + +#include "../system/FreestyleConfig.h" using namespace Geometry; class LIB_SCENE_GRAPH_EXPORT NodeTransform : public NodeGroup { public: - - inline NodeTransform() : NodeGroup() { - _Matrix = Matrix44r::identity(); - _Scaled=false; - } - - virtual ~NodeTransform() {} - - /*! multiplys the current matrix by the - * x, y, z translation matrix. - */ - void Translate(real x, real y, real z); - - /*! multiplys the current matrix by a - * rotation matrix - * iAngle - * The rotation angle - * x, y, z - * The rotation axis - */ - void Rotate(real iAngle, real x, real y, real z); - - /*! multiplys the current matrix by a - * scaling matrix. - * x, y, z - * The scaling coefficients - * with respect to the x,y,z axis - */ - void Scale(real x, real y, real z); - - /*! Multiplys the current matrix - * by iMatrix - */ - void MultiplyMatrix(const Matrix44r &iMatrix); - - /*! Sets the current matrix to iMatrix */ - void setMatrix(const Matrix44r &iMatrix); - - /*! Accept the corresponding visitor */ - virtual void accept(SceneVisitor& v); - - /*! Overloads the Node::AddBBox in order to take care - * about the transformation - */ - virtual void AddBBox(const BBox& iBBox); - - /*! Checks whether a matrix contains a scale factor - * or not. - * Returns true if yes. - * iMatrix - * The matrix to check - */ - bool isScaled(const Matrix44r &M); - - /*! accessors */ - inline const Matrix44r& matrix() const { return _Matrix; } - inline bool scaled() const {return _Scaled;} + inline NodeTransform() : NodeGroup() + { + _Matrix = Matrix44r::identity(); + _Scaled = false; + } + + virtual ~NodeTransform() {} + + /*! multiplys the current matrix by the x, y, z translation matrix. */ + void Translate(real x, real y, real z); + + /*! multiplys the current matrix by a rotation matrix + * iAngle + * The rotation angle + * x, y, z + * The rotation axis + */ + void Rotate(real iAngle, real x, real y, real z); + + /*! multiplys the current matrix by a scaling matrix. + * x, y, z + * The scaling coefficients with respect to the x,y,z axis + */ + void Scale(real x, real y, real z); + + /*! Multiplys the current matrix by iMatrix */ + void MultiplyMatrix(const Matrix44r &iMatrix); + + /*! Sets the current matrix to iMatrix */ + void setMatrix(const Matrix44r &iMatrix); + + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v); + + /*! Overloads the Node::AddBBox in order to take care about the transformation */ + virtual void AddBBox(const BBox& iBBox); + + /*! Checks whether a matrix contains a scale factor or not. + * Returns true if yes. + * M + * The matrix to check + */ + bool isScaled(const Matrix44r &M); + + /*! accessors */ + inline const Matrix44r& matrix() const + { + return _Matrix; + } + + inline bool scaled() const + { + return _Scaled; + } private: - Matrix44r _Matrix; - bool _Scaled; + Matrix44r _Matrix; + bool _Scaled; }; -#endif // NODETRANSFORM_H +#endif // __FREESTYLE_NODE_TRANSFORM_H__ diff --git a/source/blender/freestyle/intern/scene_graph/OrientedLineRep.cpp b/source/blender/freestyle/intern/scene_graph/OrientedLineRep.cpp index 94068983596..8b29c0256ff 100644 --- a/source/blender/freestyle/intern/scene_graph/OrientedLineRep.cpp +++ b/source/blender/freestyle/intern/scene_graph/OrientedLineRep.cpp @@ -1,31 +1,46 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/scene_graph/OrientedLineRep.cpp + * \ingroup freestyle + * \brief Class to display an oriented line representation. + * \author Stephane Grabli + * \date 24/10/2002 + */ #include "OrientedLineRep.h" + #include "../system/BaseObject.h" -void OrientedLineRep::accept(SceneVisitor& v) { - Rep::accept(v); - if(!frs_material()) - v.visitOrientedLineRep(*this); - else - v.visitLineRep(*this); +void OrientedLineRep::accept(SceneVisitor& v) +{ + Rep::accept(v); + if (!frs_material()) + v.visitOrientedLineRep(*this); + else + v.visitLineRep(*this); } diff --git a/source/blender/freestyle/intern/scene_graph/OrientedLineRep.h b/source/blender/freestyle/intern/scene_graph/OrientedLineRep.h index 4274581e39a..45cda3610f2 100644 --- a/source/blender/freestyle/intern/scene_graph/OrientedLineRep.h +++ b/source/blender/freestyle/intern/scene_graph/OrientedLineRep.h @@ -1,67 +1,66 @@ -// -// Filename : OrientedLineRep.h -// Author(s) : Stephane Grabli -// Purpose : Class to display an oriented line representation. -// Date of creation : 24/10/2002 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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_ORIENTED_LINE_REP_H__ +#define __FREESTYLE_ORIENTED_LINE_REP_H__ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/scene_graph/OrientedLineRep.h + * \ingroup freestyle + * \brief Class to display an oriented line representation. + * \author Stephane Grabli + * \date 24/10/2002 + */ -#ifndef VIEWEDGEREP_H -# define VIEWEDGEREP_H +#include "LineRep.h" -# include "../system/FreestyleConfig.h" -# include "LineRep.h" +#include "../system/FreestyleConfig.h" class LIB_SCENE_GRAPH_EXPORT OrientedLineRep : public LineRep { public: + OrientedLineRep() : LineRep() {} + /*! Builds a single line from 2 vertices + * v1 + * first vertex + * v2 + * second vertex + */ + inline OrientedLineRep(const Vec3r& v1, const Vec3r& v2) : LineRep(v1,v2) {} - OrientedLineRep() : LineRep() {} - /*! Builds a single line from 2 vertices - * v1 - * first vertex - * v2 - * second vertex - */ - inline OrientedLineRep(const Vec3r& v1, const Vec3r& v2) - : LineRep(v1,v2) - {} + /*! Builds a line rep from a vertex chain */ + inline OrientedLineRep(const vector& vertices) : LineRep(vertices) {} - /*! Builds a line rep from a vertex chain */ - inline OrientedLineRep(const vector& vertices) - : LineRep(vertices) - {} + /*! Builds a line rep from a vertex chain */ + inline OrientedLineRep(const list& vertices) : LineRep(vertices) {} - /*! Builds a line rep from a vertex chain */ - inline OrientedLineRep(const list& vertices) - : LineRep(vertices) - {} + virtual ~OrientedLineRep() {} - virtual ~OrientedLineRep() {} - - /*! Accept the corresponding visitor */ - virtual void accept(SceneVisitor& v); + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v); }; -#endif // VIEWEDGEREP_H +#endif // __FREESTYLE_ORIENTED_LINE_REP_H__ diff --git a/source/blender/freestyle/intern/scene_graph/Rep.cpp b/source/blender/freestyle/intern/scene_graph/Rep.cpp index 84ad2c2a966..0319a617a68 100644 --- a/source/blender/freestyle/intern/scene_graph/Rep.cpp +++ b/source/blender/freestyle/intern/scene_graph/Rep.cpp @@ -1 +1,35 @@ +/* + * ***** 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 ***** + */ + +/** \file blender/freestyle/intern/scene_graph/Rep.cpp + * \ingroup freestyle + * \brief Base class for all shapes. Inherits from BasicObjects for references counter management (addRef, release). + * \author Stephane Grabli + * \date 25/01/2002 + */ + #include "Rep.h" diff --git a/source/blender/freestyle/intern/scene_graph/Rep.h b/source/blender/freestyle/intern/scene_graph/Rep.h index 58be0374ae4..c1b29d3fceb 100644 --- a/source/blender/freestyle/intern/scene_graph/Rep.h +++ b/source/blender/freestyle/intern/scene_graph/Rep.h @@ -1,133 +1,173 @@ -// -// Filename : Rep.h -// Author(s) : Stephane Grabli -// Purpose : Base class for all shapes. Inherits from BasicObjects -// for references counter management (addRef, release). -// Date of creation : 25/01/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef REP_H -# define REP_H - -# include "../system/BaseObject.h" -# include "SceneVisitor.h" -# include "../geometry/BBox.h" -# include "../geometry/Geom.h" -# include "../system/Precision.h" -# include "FrsMaterial.h" -# include "../system/Id.h" +/* + * ***** 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_REP_H__ +#define __FREESTYLE_REP_H__ + +/** \file blender/freestyle/intern/scene_graph/Rep.h + * \ingroup freestyle + * \brief Base class for all shapes. Inherits from BasicObjects for references counter management (addRef, release). + * \author Stephane Grabli + * \date 25/01/2002 + */ + +#include "FrsMaterial.h" +#include "SceneVisitor.h" + +#include "../geometry/BBox.h" +#include "../geometry/Geom.h" + +#include "../system/BaseObject.h" +#include "../system/Id.h" +#include "../system/Precision.h" using namespace Geometry; class LIB_SCENE_GRAPH_EXPORT Rep : public BaseObject { public: - - inline Rep() : BaseObject() {_Id = 0; _FrsMaterial=0;} - inline Rep(const Rep& iBrother) - : BaseObject() - { - _Id = iBrother._Id; - _Name = iBrother._Name; - if(0 == iBrother._FrsMaterial) - _FrsMaterial = 0; - else - _FrsMaterial = new FrsMaterial(*(iBrother._FrsMaterial)); - - _BBox = iBrother.bbox(); - } - inline void swap(Rep& ioOther){ + inline Rep() : BaseObject() + { + _Id = 0; + _FrsMaterial = 0; + } + + inline Rep(const Rep& iBrother) : BaseObject() + { + _Id = iBrother._Id; + _Name = iBrother._Name; + if (0 == iBrother._FrsMaterial) + _FrsMaterial = 0; + else + _FrsMaterial = new FrsMaterial(*(iBrother._FrsMaterial)); + + _BBox = iBrother.bbox(); + } + + inline void swap(Rep& ioOther) + { std::swap(_BBox,ioOther._BBox); std::swap(_Id, ioOther._Id); std::swap(_Name, ioOther._Name); std::swap(_FrsMaterial,ioOther._FrsMaterial); } - Rep& operator=(const Rep& iBrother){ - if(&iBrother != this){ + + Rep& operator=(const Rep& iBrother) + { + if (&iBrother != this) { _Id = iBrother._Id; _Name = iBrother._Name; - if(0 == iBrother._FrsMaterial) + if (0 == iBrother._FrsMaterial) { _FrsMaterial = 0; - else{ - if(_FrsMaterial == 0){ + } + else { + if (_FrsMaterial == 0) { _FrsMaterial = new FrsMaterial(*iBrother._FrsMaterial); - }else{ - (*_FrsMaterial)=(*(iBrother._FrsMaterial)); + } + else { + (*_FrsMaterial) = (*(iBrother._FrsMaterial)); } _BBox = iBrother.bbox(); } } return *this; } - virtual ~Rep() - { - if(0 != _FrsMaterial) - { - delete _FrsMaterial; - _FrsMaterial = 0; - } - } - - /*! Accept the corresponding visitor - * Must be overload by - * inherited classes - */ - virtual void accept(SceneVisitor& v) { - if(_FrsMaterial) - v.visitFrsMaterial(*_FrsMaterial); - v.visitRep(*this); - } - - /*! Computes the rep bounding box. - * Each Inherited rep must compute - * its bbox depending on the way the data - * are stored. So, each inherited class - * must overload this method - */ - virtual void ComputeBBox() = 0; - - /*! Returns the rep bounding box */ - virtual const BBox& bbox() const {return _BBox;} - inline Id getId() const {return _Id;} - inline const string& getName() const {return _Name;} - inline const FrsMaterial * frs_material() const {return _FrsMaterial;} - - /*! Sets the Rep bounding box */ - virtual void setBBox(const BBox& iBox) {_BBox = iBox;} - inline void setId(const Id& id) {_Id = id;} - inline void setName(const string& name) {_Name = name;} - inline void setFrsMaterial(const FrsMaterial& iMaterial) - { - _FrsMaterial = new FrsMaterial(iMaterial); - } + + virtual ~Rep() + { + if (0 != _FrsMaterial) { + delete _FrsMaterial; + _FrsMaterial = 0; + } + } + + /*! Accept the corresponding visitor + * Must be overload by inherited classes + */ + virtual void accept(SceneVisitor& v) + { + if (_FrsMaterial) + v.visitFrsMaterial(*_FrsMaterial); + v.visitRep(*this); + } + + /*! Computes the rep bounding box. + * Each Inherited rep must compute its bbox depending on the way the data are stored. So, each inherited class + * must overload this method + */ + virtual void ComputeBBox() = 0; + + /*! Returns the rep bounding box */ + virtual const BBox& bbox() const + { + return _BBox; + } + + inline Id getId() const + { + return _Id; + } + + inline const string& getName() const + { + return _Name; + } + + inline const FrsMaterial * frs_material() const + { + return _FrsMaterial; + } + + /*! Sets the Rep bounding box */ + virtual void setBBox(const BBox& iBox) + { + _BBox = iBox; + } + + inline void setId(const Id& id) + { + _Id = id; + } + + inline void setName(const string& name) + { + _Name = name; + } + + inline void setFrsMaterial(const FrsMaterial& iMaterial) + { + _FrsMaterial = new FrsMaterial(iMaterial); + } private: - BBox _BBox; - Id _Id; - string _Name; - FrsMaterial *_FrsMaterial; + BBox _BBox; + Id _Id; + string _Name; + FrsMaterial *_FrsMaterial; }; -#endif // REP_H +#endif // __FREESTYLE_REP_H__ diff --git a/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.cpp b/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.cpp index aeee87f8222..8be3f2527b6 100644 --- a/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.cpp +++ b/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.cpp @@ -1,32 +1,48 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/scene_graph/ScenePrettyPrinter.cpp + * \ingroup freestyle + * \brief Class to display textual information about a scene graph. + * \author Stephane Grabli + * \author Emmanuel Turquin + * \date 26/04/2003 + */ #include -#include "ScenePrettyPrinter.h" + #include "IndexedFaceSet.h" +#include "ScenePrettyPrinter.h" -#define VISIT(CLASS) \ - void ScenePrettyPrinter::visit##CLASS(CLASS&) { \ - _ofs << _space << #CLASS << endl; \ - } +#define VISIT(CLASS) \ + void ScenePrettyPrinter::visit##CLASS(CLASS&) \ + { \ + _ofs << _space << #CLASS << endl; \ + } VISIT(Node) VISIT(NodeShape) @@ -35,36 +51,44 @@ VISIT(NodeLight) VISIT(NodeDrawingStyle) VISIT(NodeTransform) -void ScenePrettyPrinter::visitNodeShapeBefore(NodeShape&) { - increaseSpace(); +void ScenePrettyPrinter::visitNodeShapeBefore(NodeShape&) +{ + increaseSpace(); } -void ScenePrettyPrinter::visitNodeShapeAfter(NodeShape&) { - decreaseSpace(); +void ScenePrettyPrinter::visitNodeShapeAfter(NodeShape&) +{ + decreaseSpace(); } -void ScenePrettyPrinter::visitNodeGroupBefore(NodeGroup&) { - increaseSpace(); +void ScenePrettyPrinter::visitNodeGroupBefore(NodeGroup&) +{ + increaseSpace(); } -void ScenePrettyPrinter::visitNodeGroupAfter(NodeGroup&) { - decreaseSpace(); +void ScenePrettyPrinter::visitNodeGroupAfter(NodeGroup&) +{ + decreaseSpace(); } -void ScenePrettyPrinter::visitNodeDrawingStyleBefore(NodeDrawingStyle&) { - increaseSpace(); +void ScenePrettyPrinter::visitNodeDrawingStyleBefore(NodeDrawingStyle&) +{ + increaseSpace(); } -void ScenePrettyPrinter::visitNodeDrawingStyleAfter(NodeDrawingStyle&) { - decreaseSpace(); +void ScenePrettyPrinter::visitNodeDrawingStyleAfter(NodeDrawingStyle&) +{ + decreaseSpace(); } -void ScenePrettyPrinter::visitNodeTransformBefore(NodeTransform&) { - increaseSpace(); +void ScenePrettyPrinter::visitNodeTransformBefore(NodeTransform&) +{ + increaseSpace(); } -void ScenePrettyPrinter::visitNodeTransformAfter(NodeTransform&) { - decreaseSpace(); +void ScenePrettyPrinter::visitNodeTransformAfter(NodeTransform&) +{ + decreaseSpace(); } VISIT(LineRep) @@ -72,15 +96,15 @@ VISIT(OrientedLineRep) VISIT(TriangleRep) VISIT(VertexRep) -void ScenePrettyPrinter::visitIndexedFaceSet(IndexedFaceSet& ifs) { - const real* vertices = ifs.vertices(); - unsigned vsize = ifs.vsize(); - - _ofs << _space << "IndexedFaceSet" << endl; - const real *p = vertices; - for (unsigned i = 0; i < vsize / 3; i++) { - _ofs << _space << " " << setw(3) << setfill('0') << i << ": " - << p[0] << ", " << p[1] << ", " << p[2] << endl; - p += 3; - } +void ScenePrettyPrinter::visitIndexedFaceSet(IndexedFaceSet& ifs) +{ + const real *vertices = ifs.vertices(); + unsigned vsize = ifs.vsize(); + + _ofs << _space << "IndexedFaceSet" << endl; + const real *p = vertices; + for (unsigned int i = 0; i < vsize / 3; i++) { + _ofs << _space << " " << setw(3) << setfill('0') << i << ": " << p[0] << ", " << p[1] << ", " << p[2] << endl; + p += 3; + } } diff --git a/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.h b/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.h index 4e83825ff55..39fb9eceef8 100644 --- a/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.h +++ b/source/blender/freestyle/intern/scene_graph/ScenePrettyPrinter.h @@ -1,105 +1,109 @@ -// -// Filename : ScenePrettyPrinter.h -// Author(s) : Stephane Grabli, Emmanuel Turquin -// Purpose : Class to display textual information -// about a scene graph. -// Date of creation : 26/04/2003 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef SCENE_PRETTY_PRINTER_H -# define SCENE_PRETTY_PRINTER_H - -# include -# include -# include -# include "SceneVisitor.h" +/* + * ***** 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_SCENE_PRETTY_PRINTER_H__ +#define __FREESTYLE_SCENE_PRETTY_PRINTER_H__ + +/** \file blender/freestyle/intern/scene_graph/ScenePrettyPrinter.h + * \ingroup freestyle + * \brief Class to display textual information about a scene graph. + * \author Stephane Grabli + * \author Emmanuel Turquin + * \date 26/04/2003 + */ + +#include +#include +#include + +#include "SceneVisitor.h" using namespace std; class ScenePrettyPrinter : public SceneVisitor { public: - - ScenePrettyPrinter(const string filename = "SceneLog.txt") - : SceneVisitor() { - if (!filename.empty()) - _ofs.open(filename.c_str()); - if (!_ofs.is_open()) - cerr << "Warning, unable to open file \"" << filename << "\"" << endl; - _space = ""; - } - - virtual ~ScenePrettyPrinter() { - if (_ofs.is_open()) - _ofs.close(); - } - - - // - // visitClass methods - // - ////////////////////////////////////////////// - - VISIT_DECL(Node) - VISIT_DECL(NodeShape) - VISIT_DECL(NodeGroup) - VISIT_DECL(NodeLight) - VISIT_DECL(NodeDrawingStyle) - VISIT_DECL(NodeTransform) - - VISIT_DECL(LineRep) - VISIT_DECL(OrientedLineRep) - VISIT_DECL(TriangleRep) - VISIT_DECL(VertexRep) - VISIT_DECL(IndexedFaceSet) - - virtual void visitNodeShapeBefore(NodeShape&); - virtual void visitNodeShapeAfter(NodeShape&); - virtual void visitNodeGroupBefore(NodeGroup&); - virtual void visitNodeGroupAfter(NodeGroup&); - virtual void visitNodeDrawingStyleBefore(NodeDrawingStyle&); - virtual void visitNodeDrawingStyleAfter(NodeDrawingStyle&); - virtual void visitNodeTransformBefore(NodeTransform&); - virtual void visitNodeTransformAfter(NodeTransform&); - - protected: - - void increaseSpace() - { - _space += " "; - } - - void decreaseSpace() - { - _space.erase(0, 2); - } - - private: - - ofstream _ofs; - string _space; + ScenePrettyPrinter(const string filename = "SceneLog.txt") : SceneVisitor() + { + if (!filename.empty()) + _ofs.open(filename.c_str()); + if (!_ofs.is_open()) + cerr << "Warning, unable to open file \"" << filename << "\"" << endl; + _space = ""; + } + + virtual ~ScenePrettyPrinter() + { + if (_ofs.is_open()) + _ofs.close(); + } + + + // + // visitClass methods + // + ////////////////////////////////////////////// + + VISIT_DECL(Node); + VISIT_DECL(NodeShape); + VISIT_DECL(NodeGroup); + VISIT_DECL(NodeLight); + VISIT_DECL(NodeDrawingStyle); + VISIT_DECL(NodeTransform); + + VISIT_DECL(LineRep); + VISIT_DECL(OrientedLineRep); + VISIT_DECL(TriangleRep); + VISIT_DECL(VertexRep); + VISIT_DECL(IndexedFaceSet); + + virtual void visitNodeShapeBefore(NodeShape&); + virtual void visitNodeShapeAfter(NodeShape&); + virtual void visitNodeGroupBefore(NodeGroup&); + virtual void visitNodeGroupAfter(NodeGroup&); + virtual void visitNodeDrawingStyleBefore(NodeDrawingStyle&); + virtual void visitNodeDrawingStyleAfter(NodeDrawingStyle&); + virtual void visitNodeTransformBefore(NodeTransform&); + virtual void visitNodeTransformAfter(NodeTransform&); + +protected: + void increaseSpace() + { + _space += " "; + } + + void decreaseSpace() + { + _space.erase(0, 2); + } + +private: + ofstream _ofs; + string _space; }; -#endif // SCENE_PRETTY_PRINTER_H +#endif // __FREESTYLE_SCENE_PRETTY_PRINTER_H__ diff --git a/source/blender/freestyle/intern/scene_graph/SceneVisitor.cpp b/source/blender/freestyle/intern/scene_graph/SceneVisitor.cpp index da9c94930bd..32ba38ece80 100644 --- a/source/blender/freestyle/intern/scene_graph/SceneVisitor.cpp +++ b/source/blender/freestyle/intern/scene_graph/SceneVisitor.cpp @@ -1 +1,35 @@ +/* + * ***** 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 ***** + */ + +/** \file blender/freestyle/intern/scene_graph/SceneVisitor.cpp + * \ingroup freestyle + * \brief Class to visit (without doing anything) a scene graph structure + * \author Emmanuel Turquin + * \date 26/04/2003 + */ + #include "SceneVisitor.h" diff --git a/source/blender/freestyle/intern/scene_graph/SceneVisitor.h b/source/blender/freestyle/intern/scene_graph/SceneVisitor.h index 5f67b4b44aa..57d3f9189ed 100644 --- a/source/blender/freestyle/intern/scene_graph/SceneVisitor.h +++ b/source/blender/freestyle/intern/scene_graph/SceneVisitor.h @@ -1,49 +1,54 @@ -// -// Filename : SceneVisitor.h -// Author(s) : Emmanuel Turquin -// Purpose : Class to visit (without doing anything) -// a scene graph structure -// Date of creation : 26/04/2003 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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_SCENE_VISITOR_H__ +#define __FREESTYLE_SCENE_VISITOR_H__ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/scene_graph/SceneVisitor.h + * \ingroup freestyle + * \brief Class to visit (without doing anything) a scene graph structure + * \author Emmanuel Turquin + * \date 26/04/2003 + */ -#ifndef SCENE_VISITOR_H -# define SCENE_VISITOR_H - -# define VISIT_COMPLETE_DEF(type) \ -virtual void visit##type(type&) {} \ -virtual void visit##type##Before(type&) {} \ -virtual void visit##type##After(type&) {} +#include "../system/FreestyleConfig.h" -# define VISIT_DECL(type) virtual void visit##type(type&); +#define VISIT_COMPLETE_DEF(type) \ + virtual void visit##type(type&) {} \ + virtual void visit##type##Before(type&) {} \ + virtual void visit##type##After(type&) {} -# define VISIT_COMPLETE_DECL(type) \ - virtual void visit##type##Before(type&); \ - virtual void visit##type(type&); \ - virtual void visit##type##After(type&); +#define VISIT_DECL(type) \ + virtual void visit##type(type&); -#include "../system/FreestyleConfig.h" +#define VISIT_COMPLETE_DECL(type) \ + virtual void visit##type##Before(type&); \ + virtual void visit##type(type&); \ + virtual void visit##type##After(type&); class Node; class NodeShape; @@ -65,34 +70,33 @@ class FrsMaterial; class LIB_SCENE_GRAPH_EXPORT SceneVisitor { public: - - SceneVisitor() {} - virtual ~SceneVisitor() {} + SceneVisitor() {} + virtual ~SceneVisitor() {} - virtual void beginScene() {} - virtual void endScene() {} + virtual void beginScene() {} + virtual void endScene() {} - // - // visitClass methods - // - ////////////////////////////////////////////// + // + // visitClass methods + // + ////////////////////////////////////////////// - VISIT_COMPLETE_DEF(Node) - VISIT_COMPLETE_DEF(NodeShape) - VISIT_COMPLETE_DEF(NodeGroup) - VISIT_COMPLETE_DEF(NodeLight) - VISIT_COMPLETE_DEF(NodeCamera) - VISIT_COMPLETE_DEF(NodeDrawingStyle) - VISIT_COMPLETE_DEF(NodeTransform) + VISIT_COMPLETE_DEF(Node) + VISIT_COMPLETE_DEF(NodeShape) + VISIT_COMPLETE_DEF(NodeGroup) + VISIT_COMPLETE_DEF(NodeLight) + VISIT_COMPLETE_DEF(NodeCamera) + VISIT_COMPLETE_DEF(NodeDrawingStyle) + VISIT_COMPLETE_DEF(NodeTransform) - VISIT_COMPLETE_DEF(Rep) - VISIT_COMPLETE_DEF(LineRep) - VISIT_COMPLETE_DEF(OrientedLineRep) - VISIT_COMPLETE_DEF(TriangleRep) - VISIT_COMPLETE_DEF(VertexRep) - VISIT_COMPLETE_DEF(IndexedFaceSet) - VISIT_COMPLETE_DEF(DrawingStyle) - VISIT_COMPLETE_DEF(FrsMaterial) + VISIT_COMPLETE_DEF(Rep) + VISIT_COMPLETE_DEF(LineRep) + VISIT_COMPLETE_DEF(OrientedLineRep) + VISIT_COMPLETE_DEF(TriangleRep) + VISIT_COMPLETE_DEF(VertexRep) + VISIT_COMPLETE_DEF(IndexedFaceSet) + VISIT_COMPLETE_DEF(DrawingStyle) + VISIT_COMPLETE_DEF(FrsMaterial) }; -#endif // SCENEVISITOR_H +#endif // __FREESTYLE_SCENE_VISITOR_H__ diff --git a/source/blender/freestyle/intern/scene_graph/TriangleRep.cpp b/source/blender/freestyle/intern/scene_graph/TriangleRep.cpp index f73a8498714..01053561aae 100644 --- a/source/blender/freestyle/intern/scene_graph/TriangleRep.cpp +++ b/source/blender/freestyle/intern/scene_graph/TriangleRep.cpp @@ -1,59 +1,69 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/scene_graph/TriangleRep.cpp + * \ingroup freestyle + * \brief Class to define the represenation of a triangle + * \author Stephane Grabli + * \date 16/12/2002 + */ #include "TriangleRep.h" void TriangleRep::ComputeBBox() { - real XMax = _vertices[0][0]; - real YMax = _vertices[0][1]; - real ZMax = _vertices[0][2]; - - real XMin = _vertices[0][0]; - real YMin = _vertices[0][1]; - real ZMin = _vertices[0][2]; - - // parse all the coordinates to find - // the XMax, YMax, ZMax - for(int i=0; i<3; ++i) - { - // X - if(_vertices[i][0] > XMax) - XMax = _vertices[i][0]; - if(_vertices[i][0] < XMin) - XMin = _vertices[i][0]; - - // Y - if(_vertices[i][1] > YMax) - YMax = _vertices[i][1]; - if(_vertices[i][1] < YMin) - YMin = _vertices[i][1]; - - // Z - if(_vertices[i][2] > ZMax) - ZMax = _vertices[i][2]; - if(_vertices[i][2] < ZMin) - ZMin = _vertices[i][2]; - - } - - setBBox(BBox(Vec3r(XMin, YMin, ZMin), Vec3r(XMax, YMax, ZMax))); + real XMax = _vertices[0][0]; + real YMax = _vertices[0][1]; + real ZMax = _vertices[0][2]; + + real XMin = _vertices[0][0]; + real YMin = _vertices[0][1]; + real ZMin = _vertices[0][2]; + + // parse all the coordinates to find the XMax, YMax, ZMax + for (int i = 0; i < 3; ++i) { + // X + if (_vertices[i][0] > XMax) + XMax = _vertices[i][0]; + if (_vertices[i][0] < XMin) + XMin = _vertices[i][0]; + + // Y + if (_vertices[i][1] > YMax) + YMax = _vertices[i][1]; + if (_vertices[i][1] < YMin) + YMin = _vertices[i][1]; + + // Z + if (_vertices[i][2] > ZMax) + ZMax = _vertices[i][2]; + if (_vertices[i][2] < ZMin) + ZMin = _vertices[i][2]; + } + + setBBox(BBox(Vec3r(XMin, YMin, ZMin), Vec3r(XMax, YMax, ZMax))); } diff --git a/source/blender/freestyle/intern/scene_graph/TriangleRep.h b/source/blender/freestyle/intern/scene_graph/TriangleRep.h index 9d986857060..c65eee72e03 100644 --- a/source/blender/freestyle/intern/scene_graph/TriangleRep.h +++ b/source/blender/freestyle/intern/scene_graph/TriangleRep.h @@ -1,34 +1,39 @@ -// -// Filename : TriangleRep.h -// Author(s) : Stephane Grabli -// Purpose : Class to define the represenation of a triangle -// Date of creation : 16/12/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef TRIANGLEREP_H -# define TRIANGLEREP_H +/* + * ***** 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_TRIANGLE_REP_H__ +#define __FREESTYLE_TRIANGLE_REP_H__ + +/** \file blender/freestyle/intern/scene_graph/TriangleRep.h + * \ingroup freestyle + * \brief Class to define the represenation of a triangle + * \author Stephane Grabli + * \date 16/12/2002 + */ //! inherits from class Rep #include "Rep.h" @@ -37,70 +42,109 @@ class LIB_SCENE_GRAPH_EXPORT TriangleRep : public Rep { public: - - /*! Line description style */ - enum TRIANGLE_STYLE{FILL, LINES}; + /*! Line description style */ + enum TRIANGLE_STYLE { + FILL, + LINES, + }; + private: - TRIANGLE_STYLE _Style; - Vec3r _vertices[3]; - Vec3r _colors[3]; + TRIANGLE_STYLE _Style; + Vec3r _vertices[3]; + Vec3r _colors[3]; + public: - inline TriangleRep() : Rep() {_Style = FILL;} - - /*! Builds a triangle from 3 vertices - * v0 - * first vertex - * v1 - * second vertex - * v2 - * third vertex - */ - inline TriangleRep(const Vec3r& v0, const Vec3r& v1, const Vec3r& v2) - : Rep() - { - _vertices[0] = v0; - _vertices[1] = v1; - _vertices[2] = v2; - _Style = FILL; - } - inline TriangleRep( const Vec3r& v0, const Vec3r& c0, - const Vec3r& v1, const Vec3r& c1, - const Vec3r& v2, const Vec3r& c2) - : Rep() - { - _vertices[0] = v0; - _vertices[1] = v1; - _vertices[2] = v2; - _colors[0] = c0; - _colors[1] = c1; - _colors[2] = c2; - _Style = FILL; - } - - virtual ~TriangleRep() - {} - - /*! accessors */ - inline const TRIANGLE_STYLE style() const {return _Style;} - inline const Vec3r& vertex(int index) const {return _vertices[index];} - inline const Vec3r& color(int index) const {return _colors[index];} - /*! modifiers */ - inline void setStyle(const TRIANGLE_STYLE iStyle) {_Style = iStyle;} - inline void setVertex(int index, const Vec3r& iVertex) {_vertices[index] = iVertex;} - inline void setColor(int index, const Vec3r& iColor) {_colors[index] = iColor;} - inline void setVertices(const Vec3r& v0, const Vec3r& v1, const Vec3r& v2) {_vertices[0] = v0; _vertices[1] = v1; _vertices[2] = v2;} - inline void setColors(const Vec3r& c0, const Vec3r& c1, const Vec3r& c2) {_colors[0] = c0; _colors[1] = c1; _colors[2] = c2;} - - /*! Accept the corresponding visitor */ - virtual void accept(SceneVisitor& v) { - Rep::accept(v); - v.visitTriangleRep(*this); - } - - /*! Computes the triangle bounding box.*/ - virtual void ComputeBBox(); + inline TriangleRep() : Rep() + { + _Style = FILL; + } + + /*! Builds a triangle from 3 vertices + * v0 + * first vertex + * v1 + * second vertex + * v2 + * third vertex + */ + inline TriangleRep(const Vec3r& v0, const Vec3r& v1, const Vec3r& v2) : Rep() + { + _vertices[0] = v0; + _vertices[1] = v1; + _vertices[2] = v2; + _Style = FILL; + } + + inline TriangleRep(const Vec3r& v0, const Vec3r& c0, const Vec3r& v1, const Vec3r& c1, + const Vec3r& v2, const Vec3r& c2) + : Rep() + { + _vertices[0] = v0; + _vertices[1] = v1; + _vertices[2] = v2; + _colors[0] = c0; + _colors[1] = c1; + _colors[2] = c2; + _Style = FILL; + } + + virtual ~TriangleRep() {} + + /*! accessors */ + inline const TRIANGLE_STYLE style() const + { + return _Style; + } + + inline const Vec3r& vertex(int index) const + { + return _vertices[index]; + } + + inline const Vec3r& color(int index) const + { + return _colors[index]; + } + + /*! modifiers */ + inline void setStyle(const TRIANGLE_STYLE iStyle) + { + _Style = iStyle; + } + + inline void setVertex(int index, const Vec3r& iVertex) + { + _vertices[index] = iVertex; + } + + inline void setColor(int index, const Vec3r& iColor) + { + _colors[index] = iColor; + } + + inline void setVertices(const Vec3r& v0, const Vec3r& v1, const Vec3r& v2) + { + _vertices[0] = v0; + _vertices[1] = v1; + _vertices[2] = v2; + } + + inline void setColors(const Vec3r& c0, const Vec3r& c1, const Vec3r& c2) + { + _colors[0] = c0; + _colors[1] = c1; + _colors[2] = c2; + } + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v) + { + Rep::accept(v); + v.visitTriangleRep(*this); + } + /*! Computes the triangle bounding box.*/ + virtual void ComputeBBox(); }; -#endif +#endif // __FREESTYLE_TRIANGLE_REP_H__ diff --git a/source/blender/freestyle/intern/scene_graph/VertexRep.cpp b/source/blender/freestyle/intern/scene_graph/VertexRep.cpp index e4f774bfb84..75b0d4b91b3 100644 --- a/source/blender/freestyle/intern/scene_graph/VertexRep.cpp +++ b/source/blender/freestyle/intern/scene_graph/VertexRep.cpp @@ -1,29 +1,41 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/scene_graph/VertexRep.cpp + * \ingroup freestyle + * \brief Class to define the representation of a vertex for displaying purpose. + * \author Stephane Grabli + * \date 03/04/2002 + */ #include "VertexRep.h" void VertexRep::ComputeBBox() { - - setBBox(BBox(Vec3r(_coordinates[0], _coordinates[1], _coordinates[2]), - Vec3r(_coordinates[0], _coordinates[1], _coordinates[2]))); + setBBox(BBox(Vec3r(_coordinates[0], _coordinates[1], _coordinates[2]), + Vec3r(_coordinates[0], _coordinates[1], _coordinates[2]))); } diff --git a/source/blender/freestyle/intern/scene_graph/VertexRep.h b/source/blender/freestyle/intern/scene_graph/VertexRep.h index 9e31b4b8ef9..7483806f1fe 100644 --- a/source/blender/freestyle/intern/scene_graph/VertexRep.h +++ b/source/blender/freestyle/intern/scene_graph/VertexRep.h @@ -1,87 +1,141 @@ -// -// Filename : VertexRep.h -// Author(s) : Stephane Grabli -// Purpose : Class to define the representation of a vertex for -// displaying purpose. -// Date of creation : 03/04/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef VERTEXREP_H -# define VERTEXREP_H +/* + * ***** 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_VERTEX_REP_H__ +#define __FREESTYLE_VERTEX_REP_H__ + +/** \file blender/freestyle/intern/scene_graph/VertexRep.h + * \ingroup freestyle + * \brief Class to define the representation of a vertex for displaying purpose. + * \author Stephane Grabli + * \date 03/04/2002 + */ #include "Rep.h" class LIB_SCENE_GRAPH_EXPORT VertexRep : public Rep { public: - - inline VertexRep() : Rep() {_vid = 0;_PointSize = 0.f;} - inline VertexRep(real x, real y, real z, int id = 0) - : Rep() - { - _coordinates[0] = x; - _coordinates[1] = y; - _coordinates[2] = z; - - _vid = id; - _PointSize = 0.f; - } - - inline ~VertexRep() {} - - /*! Accept the corresponding visitor */ - - virtual void accept(SceneVisitor& v) { - Rep::accept(v); - v.visitVertexRep(*this); - } - - /*! Computes the rep bounding box. - */ - virtual void ComputeBBox(); - - /*! accessors */ - inline const int vid() const {return _vid;} - inline const real * coordinates() const {return _coordinates;} - inline real x() const {return _coordinates[0];} - inline real y() const {return _coordinates[1];} - inline real z() const {return _coordinates[2];} - inline float pointSize() const {return _PointSize;} - - /*! modifiers */ - inline void setVid(int id) {_vid = id;} - inline void setX(real x) {_coordinates[0] = x;} - inline void setY(real y) {_coordinates[1] = y;} - inline void setZ(real z) {_coordinates[2] = z;} - inline void setCoordinates(real x, real y, real z) {_coordinates[0] = x;_coordinates[1] = y; _coordinates[2] = z;} - inline void setPointSize(float iPointSize) {_PointSize = iPointSize;} + inline VertexRep() : Rep() + { + _vid = 0; + _PointSize = 0.0f; + } + + inline VertexRep(real x, real y, real z, int id = 0) : Rep() + { + _coordinates[0] = x; + _coordinates[1] = y; + _coordinates[2] = z; + + _vid = id; + _PointSize = 0.0f; + } + + inline ~VertexRep() {} + + /*! Accept the corresponding visitor */ + virtual void accept(SceneVisitor& v) + { + Rep::accept(v); + v.visitVertexRep(*this); + } + + /*! Computes the rep bounding box. */ + virtual void ComputeBBox(); + + /*! accessors */ + inline const int vid() const + { + return _vid; + } + + inline const real * coordinates() const + { + return _coordinates; + } + + inline real x() const + { + return _coordinates[0]; + } + + inline real y() const + { + return _coordinates[1]; + } + + inline real z() const + { + return _coordinates[2]; + } + + inline float pointSize() const + { + return _PointSize; + } + + /*! modifiers */ + inline void setVid(int id) + { + _vid = id; + } + + inline void setX(real x) + { + _coordinates[0] = x; + } + + inline void setY(real y) + { + _coordinates[1] = y; + } + + inline void setZ(real z) + { + _coordinates[2] = z; + } + + inline void setCoordinates(real x, real y, real z) + { + _coordinates[0] = x; + _coordinates[1] = y; + _coordinates[2] = z; + } + + inline void setPointSize(float iPointSize) + { + _PointSize = iPointSize; + } private: - int _vid; // vertex id - real _coordinates[3]; - float _PointSize; + int _vid; // vertex id + real _coordinates[3]; + float _PointSize; }; -#endif // VERTEXREP_H +#endif // __FREESTYLE_VERTEX_REP_H__ diff --git a/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.cpp b/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.cpp index 7a51a1a78df..9d955722ac7 100644 --- a/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.cpp +++ b/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.cpp @@ -1,92 +1,117 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -# include "../view_map/Functions0D.h" -# include "AdvancedFunctions0D.h" -# include "../view_map/SteerableViewMap.h" -# include "Canvas.h" +/** \file blender/freestyle/intern/stroke/AdvancedFunctions0D.cpp + * \ingroup freestyle + * \brief Functions taking 0D input + * \author Stephane Grabli + * \author Emmanuel Turquin + * \date 01/07/2003 + */ + +#include "AdvancedFunctions0D.h" +#include "Canvas.h" + +#include "../view_map/Functions0D.h" +#include "../view_map/SteerableViewMap.h" namespace Functions0D { - int DensityF0D::operator()(Interface0DIterator& iter) { - Canvas* canvas = Canvas::getInstance(); - int bound = _filter.getBound(); - if( (iter->getProjectedX()-bound < 0) || (iter->getProjectedX()+bound>canvas->width()) - || (iter->getProjectedY()-bound < 0) || (iter->getProjectedY()+bound>canvas->height())) { - result = 0.0; - return 0; +int DensityF0D::operator()(Interface0DIterator& iter) +{ + Canvas* canvas = Canvas::getInstance(); + int bound = _filter.getBound(); + + if ((iter->getProjectedX()-bound < 0) || (iter->getProjectedX()+bound>canvas->width()) || + (iter->getProjectedY()-bound < 0) || (iter->getProjectedY()+bound>canvas->height())) { + result = 0.0; + return 0; } - RGBImage image; - canvas->readColorPixels((int)iter->getProjectedX() - bound, - (int)iter->getProjectedY() - bound, - _filter.maskSize(), - _filter.maskSize(), - image); - result = _filter.getSmoothedPixel(&image, (int)iter->getProjectedX(), - (int)iter->getProjectedY()); + + RGBImage image; + canvas->readColorPixels((int)iter->getProjectedX() - bound, (int)iter->getProjectedY() - bound, + _filter.maskSize(), _filter.maskSize(), image); + result = _filter.getSmoothedPixel(&image, (int)iter->getProjectedX(), (int)iter->getProjectedY()); + return 0; - } +} + +int LocalAverageDepthF0D::operator()(Interface0DIterator& iter) +{ + Canvas * iViewer = Canvas::getInstance(); + int bound = _filter.getBound(); - int LocalAverageDepthF0D::operator()(Interface0DIterator& iter) { - Canvas * iViewer = Canvas::getInstance(); - int bound = _filter.getBound(); - - if( (iter->getProjectedX()-bound < 0) || (iter->getProjectedX()+bound>iViewer->width()) - || (iter->getProjectedY()-bound < 0) || (iter->getProjectedY()+bound>iViewer->height())) { - result = 0.0; - return 0; + if ((iter->getProjectedX()-bound < 0) || (iter->getProjectedX()+bound>iViewer->width()) || + (iter->getProjectedY()-bound < 0) || (iter->getProjectedY()+bound>iViewer->height())) { + result = 0.0; + return 0; } - GrayImage image ; - iViewer->readDepthPixels((int)iter->getProjectedX()-bound,(int)iter->getProjectedY()-bound,_filter.maskSize(),_filter.maskSize(),image); - result = _filter.getSmoothedPixel(&image, (int)iter->getProjectedX(), (int)iter->getProjectedY()); + + GrayImage image; + iViewer->readDepthPixels((int)iter->getProjectedX() - bound, (int)iter->getProjectedY()-bound, + _filter.maskSize(), _filter.maskSize(), image); + result = _filter.getSmoothedPixel(&image, (int)iter->getProjectedX(), (int)iter->getProjectedY()); + return 0; - } +} - int ReadMapPixelF0D::operator()(Interface0DIterator& iter) { - Canvas * canvas = Canvas::getInstance(); - result = canvas->readMapPixel(_mapName, _level, (int)iter->getProjectedX(), (int)iter->getProjectedY()); +int ReadMapPixelF0D::operator()(Interface0DIterator& iter) +{ + Canvas * canvas = Canvas::getInstance(); + result = canvas->readMapPixel(_mapName, _level, (int)iter->getProjectedX(), (int)iter->getProjectedY()); return 0; - } - - int ReadSteerableViewMapPixelF0D::operator()(Interface0DIterator& iter) { - SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap(); - result = svm->readSteerableViewMapPixel(_orientation, _level,(int)iter->getProjectedX(), (int)iter->getProjectedY()); - return 0; - } - - int ReadCompleteViewMapPixelF0D::operator()(Interface0DIterator& iter) { - SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap(); - result = svm->readCompleteViewMapPixel(_level,(int)iter->getProjectedX(), (int)iter->getProjectedY()); - return 0; - } - - int GetViewMapGradientNormF0D::operator()(Interface0DIterator& iter){ - SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap(); - float pxy = svm->readCompleteViewMapPixel(_level,(int)iter->getProjectedX(), (int)iter->getProjectedY()); - float gx = svm->readCompleteViewMapPixel(_level,(int)iter->getProjectedX()+_step, (int)iter->getProjectedY()) - - pxy; - float gy = svm->readCompleteViewMapPixel(_level,(int)iter->getProjectedX(), (int)iter->getProjectedY()+_step) - - pxy; - result = Vec2f(gx,gy).norm(); - return 0; - } +} + +int ReadSteerableViewMapPixelF0D::operator()(Interface0DIterator& iter) +{ + SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap(); + result = svm->readSteerableViewMapPixel(_orientation, _level, (int)iter->getProjectedX(), + (int)iter->getProjectedY()); + return 0; +} + +int ReadCompleteViewMapPixelF0D::operator()(Interface0DIterator& iter) +{ + SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap(); + result = svm->readCompleteViewMapPixel(_level,(int)iter->getProjectedX(), (int)iter->getProjectedY()); + return 0; +} + +int GetViewMapGradientNormF0D::operator()(Interface0DIterator& iter) +{ + SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap(); + float pxy = svm->readCompleteViewMapPixel(_level, (int)iter->getProjectedX(), (int)iter->getProjectedY()); + float gx = svm->readCompleteViewMapPixel(_level, (int)iter->getProjectedX() + _step, (int)iter->getProjectedY()) + - pxy; + float gy = svm->readCompleteViewMapPixel(_level, (int)iter->getProjectedX(), (int)iter->getProjectedY() + _step) + - pxy; + result = Vec2f(gx, gy).norm(); + return 0; +} + } // end of namespace Functions0D diff --git a/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.h b/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.h index 5d62ea8d9eb..2875402700b 100644 --- a/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.h +++ b/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.h @@ -1,40 +1,45 @@ -// -// Filename : AdvancedFunctions0D.h -// Author(s) : Stephane Grabli -// Emmanuel Turquin -// Purpose : Functions taking 0D input -// Date of creation : 01/07/2003 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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_ADVANCED_FUNCTIONS_0D_H__ +#define __FREESTYLE_ADVANCED_FUNCTIONS_0D_H__ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef ADVANCED_FUNCTIONS0D_HPP -# define ADVANCED_FUNCTIONS0D_HPP +/** \file blender/freestyle/intern/stroke/AdvancedFunctions0D.h + * \ingroup freestyle + * \brief Functions taking 0D input + * \author Stephane Grabli + * \author Emmanuel Turquin + * \date 01/07/2003 + */ +#include "../image/GaussianFilter.h" +#include "../image/Image.h" -# include "../image/Image.h" -# include "../image/GaussianFilter.h" -# include "../view_map/Functions0D.h" +#include "../view_map/Functions0D.h" // // Functions definitions @@ -43,167 +48,182 @@ namespace Functions0D { - // DensityF0D - /*! Returns the density of the (result) image evaluated at an Interface0D. - * This density is evaluated using a pixels square window around the - * evaluation point and integrating these values using - * a gaussian. - */ - class LIB_STROKE_EXPORT DensityF0D : public UnaryFunction0D - { - public: - /*! Builds the functor from the gaussian sigma value. - * \param sigma - * sigma indicates the x value for which the gaussian - * function is 0.5. It leads to the window size - * value. (the larger, the smoother) - */ - DensityF0D(double sigma = 2) : UnaryFunction0D() { - _filter.setSigma((float)sigma); - } - /*! Returns the string "DensityF0D"*/ - string getName() const { - return "DensityF0D"; - } - /*! The () operator. */ - int operator()(Interface0DIterator& iter); - - private: - - GaussianFilter _filter; - }; - - // LocalAverageDepthF0D - /*! Returns the average depth around a point. - * The result is obtained by querying the - * depth buffer on a window around that point. - */ - class LIB_STROKE_EXPORT LocalAverageDepthF0D : public UnaryFunction0D - { - private: - GaussianFilter _filter; - public: - /*! Builds the functor from the size of the mask that - * will be used. - */ - LocalAverageDepthF0D(real maskSize=5.f) : UnaryFunction0D() { - _filter.setSigma((float)maskSize/2.f); - } - /*! Returns the string "LocalAverageDepthF0D"*/ - string getName() const { - return "LocalAverageDepthF0D"; - } - /*! the () operator.*/ - int operator()(Interface0DIterator& iter); - }; - - // ReadMapPixel - /*! Reads a pixel in a map. - */ - class LIB_STROKE_EXPORT ReadMapPixelF0D : public UnaryFunction0D - { - private: - const char * _mapName; - int _level; - public: - /*! Builds the functor from name of the - * Map that must be read. - * \param iMapName - * The name of the map. - * \param level - * The level of the pyramid from which - * the pixel must be read. - */ - ReadMapPixelF0D(const char *iMapName, int level) : UnaryFunction0D() { - _mapName = iMapName; - _level = level; - } - /*! Returns the string "ReadMapPixelF0D"*/ - string getName() const { - return "ReadMapPixelF0D"; - } - /*! the () operator.*/ - int operator()(Interface0DIterator& iter); - }; - - // ReadSteerableViewMapPixel - /*! Reads a pixel in one of the level of one of the steerable viewmaps. - */ - class LIB_STROKE_EXPORT ReadSteerableViewMapPixelF0D : public UnaryFunction0D - { - private: - unsigned _orientation; - int _level; - public: - /*! Builds the functor - * \param nOrientation - * The integer belonging to [0,4] indicating the orientation (E,NE,N,NW) - * we are interested in. - * \param level - * The level of the pyramid from which - * the pixel must be read. - */ - ReadSteerableViewMapPixelF0D(unsigned nOrientation, int level) : UnaryFunction0D() { - _orientation = nOrientation; - _level = level; - } - /*! Returns the string "ReadSteerableViewMapPixelF0D"*/ - string getName() const { - return "ReadSteerableViewMapPixelF0D"; - } - /*! the () operator.*/ - int operator()(Interface0DIterator& iter); - }; - - // ReadCompleteViewMapPixel - /*! Reads a pixel in one of the level of the complete viewmap. - */ - class LIB_STROKE_EXPORT ReadCompleteViewMapPixelF0D : public UnaryFunction0D - { - private: - int _level; - public: - /*! Builds the functor - * \param level - * The level of the pyramid from which - * the pixel must be read. - */ - ReadCompleteViewMapPixelF0D(int level) : UnaryFunction0D() { - _level = level; - } - /*! Returns the string "ReadCompleteViewMapPixelF0D"*/ - string getName() const { - return "ReadCompleteViewMapPixelF0D"; - } - /*! the () operator.*/ - int operator()(Interface0DIterator& iter); - }; - - // GetViewMapGradientNormF0D - /*! Returns the norm of the gradient of the global viewmap density image. - */ - class LIB_STROKE_EXPORT GetViewMapGradientNormF0D: public UnaryFunction0D< float> - { - private: - int _level; - float _step; - public: - /*! Builds the functor - * \param level - * The level of the pyramid from which - * the pixel must be read. - */ - GetViewMapGradientNormF0D(int level) : UnaryFunction0D() { - _level = level; - _step = (float)pow(2.0,_level); - } - /*! Returns the string "GetOccludeeF0D"*/ - string getName() const { - return "GetViewMapGradientNormF0D"; - } - /*! the () operator.*/ - int operator()(Interface0DIterator& iter); - }; +// DensityF0D +/*! Returns the density of the (result) image evaluated at an Interface0D. + * This density is evaluated using a pixels square window around the evaluation point and integrating + * these values using a gaussian. + */ +class LIB_STROKE_EXPORT DensityF0D : public UnaryFunction0D +{ +public: + /*! Builds the functor from the gaussian sigma value. + * \param sigma + * sigma indicates the x value for which the gaussian function is 0.5. It leads to the window size value. + * (the larger, the smoother) + */ + DensityF0D(double sigma = 2) : UnaryFunction0D() + { + _filter.setSigma((float)sigma); + } + + /*! Returns the string "DensityF0D" */ + string getName() const + { + return "DensityF0D"; + } + + /*! The () operator. */ + int operator()(Interface0DIterator& iter); + +private: + GaussianFilter _filter; +}; + +// LocalAverageDepthF0D +/*! Returns the average depth around a point. + * The result is obtained by querying the depth buffer on a window around that point. + */ +class LIB_STROKE_EXPORT LocalAverageDepthF0D : public UnaryFunction0D +{ +private: + GaussianFilter _filter; + +public: + /*! Builds the functor from the size of the mask that will be used. */ + LocalAverageDepthF0D(real maskSize = 5.0f) : UnaryFunction0D() + { + _filter.setSigma((float)maskSize / 2.0f); + } + + /*! Returns the string "LocalAverageDepthF0D" */ + string getName() const + { + return "LocalAverageDepthF0D"; + } + + /*! the () operator. */ + int operator()(Interface0DIterator& iter); +}; + +// ReadMapPixel +/*! Reads a pixel in a map. */ +class LIB_STROKE_EXPORT ReadMapPixelF0D : public UnaryFunction0D +{ +private: + const char * _mapName; + int _level; + +public: + /*! Builds the functor from name of the + * Map that must be read. + * \param iMapName + * The name of the map. + * \param level + * The level of the pyramid from which the pixel must be read. + */ + ReadMapPixelF0D(const char *iMapName, int level) : UnaryFunction0D() + { + _mapName = iMapName; + _level = level; + } + + /*! Returns the string "ReadMapPixelF0D" */ + string getName() const + { + return "ReadMapPixelF0D"; + } + + /*! the () operator. */ + int operator()(Interface0DIterator& iter); +}; + +// ReadSteerableViewMapPixel +/*! Reads a pixel in one of the level of one of the steerable viewmaps. */ +class LIB_STROKE_EXPORT ReadSteerableViewMapPixelF0D : public UnaryFunction0D +{ +private: + unsigned _orientation; + int _level; + +public: + /*! Builds the functor + * \param nOrientation + * The integer belonging to [0,4] indicating the orientation (E,NE,N,NW) we are interested in. + * \param level + * The level of the pyramid from which the pixel must be read. + */ + ReadSteerableViewMapPixelF0D(unsigned nOrientation, int level) : UnaryFunction0D() + { + _orientation = nOrientation; + _level = level; + } + + /*! Returns the string "ReadSteerableViewMapPixelF0D" */ + string getName() const + { + return "ReadSteerableViewMapPixelF0D"; + } + + /*! the () operator. */ + int operator()(Interface0DIterator& iter); +}; + +// ReadCompleteViewMapPixel +/*! Reads a pixel in one of the level of the complete viewmap. */ +class LIB_STROKE_EXPORT ReadCompleteViewMapPixelF0D : public UnaryFunction0D +{ +private: + int _level; + +public: + /*! Builds the functor + * \param level + * The level of the pyramid from which the pixel must be read. + */ + ReadCompleteViewMapPixelF0D(int level) : UnaryFunction0D() + { + _level = level; + } + + /*! Returns the string "ReadCompleteViewMapPixelF0D" */ + string getName() const + { + return "ReadCompleteViewMapPixelF0D"; + } + + /*! the () operator. */ + int operator()(Interface0DIterator& iter); +}; + +// GetViewMapGradientNormF0D +/*! Returns the norm of the gradient of the global viewmap density image. */ +class LIB_STROKE_EXPORT GetViewMapGradientNormF0D: public UnaryFunction0D< float> +{ +private: + int _level; + float _step; + +public: + /*! Builds the functor + * \param level + * The level of the pyramid from which the pixel must be read. + */ + GetViewMapGradientNormF0D(int level) : UnaryFunction0D() + { + _level = level; + _step = (float)pow(2.0, _level); + } + + /*! Returns the string "GetOccludeeF0D" */ + string getName() const + { + return "GetViewMapGradientNormF0D"; + } + + /*! the () operator. */ + int operator()(Interface0DIterator& iter); +}; + } // end of namespace Functions0D -#endif // ADVANCED_FUNCTIONS0D_HPP +#endif // __FREESTYLE_ADVANCED_FUNCTIONS_0D_H__ diff --git a/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.cpp b/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.cpp index 2548ce38659..f757f6ced82 100644 --- a/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.cpp +++ b/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.cpp @@ -1,110 +1,138 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/stroke/AdvancedFunctions1D.cpp + * \ingroup freestyle + * \brief Functions taking 1D input + * \author Stephane Grabli + * \author Emmanuel Turquin + * \date 01/07/2003 + */ -# include "AdvancedFunctions1D.h" -# include "../view_map/SteerableViewMap.h" -# include "Canvas.h" +#include "AdvancedFunctions1D.h" +#include "Canvas.h" + +#include "../view_map/SteerableViewMap.h" // FIXME namespace Functions1D { - int GetSteerableViewMapDensityF1D::operator()(Interface1D& inter) { - SteerableViewMap * svm = Canvas::getInstance()->getSteerableViewMap(); - Interface0DIterator it = inter.pointsBegin(_sampling); - Interface0DIterator itnext = it;++itnext; - FEdge *fe; - unsigned nSVM; - vector values; - while(!itnext.isEnd()){ - Interface0D& i0D = (*it); - Interface0D& i0Dnext = (*itnext); - fe = i0D.getFEdge(i0Dnext); - if(fe == 0){ - cerr << "GetSteerableViewMapDensityF1D warning: no FEdge between " << i0D.getId() << " and " << i0Dnext.getId() << endl; - // compute the direction between these two ??? - Vec2f dir = i0Dnext.getPoint2D()-i0D.getPoint2D(); - nSVM = svm->getSVMNumber(dir); - }else{ - nSVM = svm->getSVMNumber(fe->getId().getFirst()); - } - Vec2r m((i0D.getProjectedX()+i0Dnext.getProjectedX())/2.0, - (i0D.getProjectedY()+i0Dnext.getProjectedY())/2.0); - values.push_back(svm->readSteerableViewMapPixel(nSVM,_level,(int)m[0],(int)m[1])); - ++it;++itnext; - } - float res, res_tmp; - vector::iterator v = values.begin(), vend=values.end(); - unsigned size = 1; - switch(_integration) { - case MIN: - res = *v;++v; - for (; v!=vend; ++v) { - res_tmp = *v; - if (res_tmp < res) - res = res_tmp; - } - break; - case MAX: - res = *v;++v; - for (; v!=vend; ++v) { - res_tmp = *v; - if (res_tmp > res) - res = res_tmp; - } - break; - case FIRST: - res = *v; - break; - case LAST: - --vend; - res = *vend; - break; - case MEAN: - default: - res = *v;++v; - for (; v!=vend; ++v, ++size) - res += *v; - res /= (size ? size : 1); - break; - } +int GetSteerableViewMapDensityF1D::operator()(Interface1D& inter) +{ + SteerableViewMap * svm = Canvas::getInstance()->getSteerableViewMap(); + Interface0DIterator it = inter.pointsBegin(_sampling); + Interface0DIterator itnext = it; + ++itnext; + FEdge *fe; + unsigned nSVM; + vector values; + + while (!itnext.isEnd()) { + Interface0D& i0D = (*it); + Interface0D& i0Dnext = (*itnext); + fe = i0D.getFEdge(i0Dnext); + if (fe == 0) { + cerr << "GetSteerableViewMapDensityF1D warning: no FEdge between " << i0D.getId() << " and " + << i0Dnext.getId() << endl; + // compute the direction between these two ??? + Vec2f dir = i0Dnext.getPoint2D() - i0D.getPoint2D(); + nSVM = svm->getSVMNumber(dir); + } + else { + nSVM = svm->getSVMNumber(fe->getId().getFirst()); + } + Vec2r m((i0D.getProjectedX() + i0Dnext.getProjectedX()) / 2.0, + (i0D.getProjectedY() + i0Dnext.getProjectedY()) / 2.0); + values.push_back(svm->readSteerableViewMapPixel(nSVM, _level, (int)m[0], (int)m[1])); + ++it; + ++itnext; + } + + float res, res_tmp; + vector::iterator v = values.begin(), vend = values.end(); + unsigned size = 1; + switch (_integration) { + case MIN: + res = *v; + ++v; + for (; v != vend; ++v) { + res_tmp = *v; + if (res_tmp < res) + res = res_tmp; + } + break; + case MAX: + res = *v; + ++v; + for (; v != vend; ++v) { + res_tmp = *v; + if (res_tmp > res) + res = res_tmp; + } + break; + case FIRST: + res = *v; + break; + case LAST: + --vend; + res = *vend; + break; + case MEAN: + default: + res = *v; + ++v; + for (; v != vend; ++v, ++size) + res += *v; + res /= (size ? size : 1); + break; + } result = res; return 0; - } +} + +int GetDirectionalViewMapDensityF1D::operator()(Interface1D& inter) +{ + //soc unsigned size; + result = integrate(_fun, inter.pointsBegin(_sampling), inter.pointsEnd(_sampling), _integration); + return 0; +} - int GetDirectionalViewMapDensityF1D::operator()(Interface1D& inter) { - //soc unsigned size; - result = integrate(_fun, inter.pointsBegin(_sampling), inter.pointsEnd(_sampling), _integration); - return 0; - } - - int GetCompleteViewMapDensityF1D::operator()(Interface1D& inter) { - //soc unsigned size; - Id id = inter.getId(); - result = integrate(_fun, inter.pointsBegin(_sampling), inter.pointsEnd(_sampling), _integration); - return 0; - } +int GetCompleteViewMapDensityF1D::operator()(Interface1D& inter) +{ + //soc unsigned size; + Id id = inter.getId(); + result = integrate(_fun, inter.pointsBegin(_sampling), inter.pointsEnd(_sampling), _integration); + return 0; +} - int GetViewMapGradientNormF1D::operator()(Interface1D& inter){ +int GetViewMapGradientNormF1D::operator()(Interface1D& inter) +{ result = integrate(_func, inter.pointsBegin(_sampling), inter.pointsEnd(_sampling), _integration); return 0; - } } +} // Functions1D namespace diff --git a/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h b/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h index ab963c68034..35f516cd781 100644 --- a/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h +++ b/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h @@ -1,38 +1,44 @@ -// -// Filename : AdvancedFunctions1D.h -// Author(s) : Stephane Grabli, Emmanuel Turquin -// Purpose : Functions taking 1D input -// Date of creation : 01/07/2003 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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_ADVANCED_FUNCTIONS_1D_H__ +#define __FREESTYLE_ADVANCED_FUNCTIONS_1D_H__ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/stroke/AdvancedFunctions1D.h + * \ingroup freestyle + * \brief Functions taking 1D input + * \author Stephane Grabli + * \author Emmanuel Turquin + * \date 01/07/2003 + */ -#ifndef ADVANCED_FUNCTIONS1D_HPP -# define ADVANCED_FUNCTIONS1D_HPP +#include "AdvancedFunctions0D.h" - -# include "../view_map/Functions1D.h" -# include "AdvancedFunctions0D.h" +#include "../view_map/Functions1D.h" // // Functions definitions @@ -41,248 +47,248 @@ namespace Functions1D { - // DensityF1D - /*! Returns the density evaluated for an Interface1D. - * The density is evaluated for a set of points along - * the Interface1D (using the DensityF0D functor) - * with a user-defined sampling and - * then integrated into a single value using - * a user-defined integration method. - */ - class DensityF1D : public UnaryFunction1D - { - private: - float _sampling; - public: - /*! Builds the functor. - * \param sigma - * Thesigma used in DensityF0D and determining - * the window size used in each density query. - * \param iType - * The integration method used to compute - * a single value from a set of values. - * \param sampling - * The resolution used to sample the chain: the corresponding 0D function - * is evaluated at each sample point and the result is obtained by - * combining the resulting values into a single one, following the - * method specified by iType. - */ - DensityF1D(double sigma = 2, IntegrationType iType = MEAN, float sampling=2.f) : UnaryFunction1D(iType), _fun(sigma) { - _sampling = sampling; - } - /*! Destructor */ - virtual ~DensityF1D(){} - - /*! Returns the string "DensityF1D"*/ - string getName() const { - return "DensityF1D"; - } - /*! the () operator.*/ - int operator()(Interface1D& inter) { - result = integrate(_fun, inter.pointsBegin(_sampling), inter.pointsEnd(_sampling), _integration); - return 0; - } - private: - Functions0D::DensityF0D _fun; - }; - - // LocalAverageDepthF1D - /*! Returns the average depth evaluated for an Interface1D. - * The average depth is evaluated for a set of points along - * the Interface1D (using the LocalAverageDepthF0D functor) - * with a user-defined sampling and - * then integrated into a single value using - * a user-defined integration method. - */ - class LocalAverageDepthF1D : public UnaryFunction1D - { - public: - /*! Builds the functor. - * \param sigma - * The sigma used in DensityF0D and determining - * the window size used in each density query. - * \param iType - * The integration method used to compute - * a single value from a set of values. - */ - LocalAverageDepthF1D(real sigma, IntegrationType iType = MEAN) - : UnaryFunction1D(iType), _fun(sigma){ - } - /*! Returns the string "LocalAverageDepthF1D"*/ - string getName() const { - return "LocalAverageDepthF1D"; - } - /*! the () operator.*/ - int operator()(Interface1D& inter) { - result = integrate(_fun, inter.verticesBegin(), inter.verticesEnd(), _integration); - return 0; - } - private: - Functions0D::LocalAverageDepthF0D _fun; - }; - - // GetCompleteViewMapDensity - /*! Returns the density evaluated for an Interface1D in the - * complete viewmap image. - * The density is evaluated for a set of points along - * the Interface1D (using the ReadCompleteViewMapPixelF0D functor) - * and then integrated into a single value using - * a user-defined integration method. - */ - class LIB_STROKE_EXPORT GetCompleteViewMapDensityF1D : public UnaryFunction1D - { - public: - /*! Builds the functor. - * \param level - * The level of the pyramid from which - * the pixel must be read. - * \param iType - * The integration method used to compute - * a single value from a set of values. - * \param sampling - * The resolution used to sample the chain: the corresponding 0D function - * is evaluated at each sample point and the result is obtained by - * combining the resulting values into a single one, following the - * method specified by iType. - */ - GetCompleteViewMapDensityF1D(unsigned level, IntegrationType iType = MEAN, float sampling=2.f) - : UnaryFunction1D(iType), _fun(level){_sampling = sampling;} - /*! Returns the string "GetCompleteViewMapDensityF1D"*/ - string getName() const { - return "GetCompleteViewMapDensityF1D"; - } - /*! the () operator.*/ - int operator()(Interface1D& inter); - - private: - Functions0D::ReadCompleteViewMapPixelF0D _fun; - float _sampling; - }; - - // GetDirectionalViewMapDensity - /*! Returns the density evaluated for an Interface1D in of the - * steerable viewmaps image. - * The direction telling which Directional map to choose - * is explicitely specified by the user. - * The density is evaluated for a set of points along - * the Interface1D (using the ReadSteerableViewMapPixelF0D functor) - * and then integrated into a single value using - * a user-defined integration method. - */ - class LIB_STROKE_EXPORT GetDirectionalViewMapDensityF1D : public UnaryFunction1D - { - public: - /*! Builds the functor. - * \param iOrientation - * The number of the directional map - * we must work with. - * \param level - * The level of the pyramid from which - * the pixel must be read. - * \param iType - * The integration method used to compute - * a single value from a set of values. - * \param sampling - * The resolution used to sample the chain: the corresponding 0D function - * is evaluated at each sample point and the result is obtained by - * combining the resulting values into a single one, following the - * method specified by iType. - */ - GetDirectionalViewMapDensityF1D(unsigned iOrientation, unsigned level, IntegrationType iType = MEAN, float sampling=2.f) - : UnaryFunction1D(iType), _fun(iOrientation,level){_sampling = sampling;} - /*! Returns the string "GetDirectionalViewMapDensityF1D"*/ - string getName() const { - return "GetDirectionalViewMapDensityF1D"; - } - /*! the () operator.*/ - int operator()(Interface1D& inter); - - private: - Functions0D::ReadSteerableViewMapPixelF0D _fun; - float _sampling; - }; - - // GetSteerableViewMapDensityF1D - /*! Returns the density of the viewmap - * for a given Interface1D. The density of each - * FEdge is evaluated in the proper steerable - * ViewMap depending on its oorientation. - */ - class LIB_STROKE_EXPORT GetSteerableViewMapDensityF1D : public UnaryFunction1D - { - private: - int _level; - float _sampling; - public: - /*! Builds the functor from the level - * of the pyramid from which the pixel must be read. - * \param level - * The level of the pyramid from which - * the pixel must be read. - * \param iType - * The integration method used to compute - * a single value from a set of values. - * \param sampling - * The resolution used to sample the chain: the corresponding 0D function - * is evaluated at each sample point and the result is obtained by - * combining the resulting values into a single one, following the - * method specified by iType. - */ - GetSteerableViewMapDensityF1D(int level,IntegrationType iType = MEAN, float sampling=2.f) : UnaryFunction1D(iType) { - _level = level; - _sampling = sampling; - } - /*! Destructor */ - virtual ~GetSteerableViewMapDensityF1D(){} - - /*! Returns the string "GetSteerableViewMapDensityF1D"*/ - string getName() const { - return "GetSteerableViewMapDensityF1D"; - } - /*! the () operator.*/ - int operator()(Interface1D& inter); - }; - - // GetViewMapGradientNormF1D - /*! Returns the density of the viewmap - * for a given Interface1D. The density of each - * FEdge is evaluated in the proper steerable - * ViewMap depending on its oorientation. - */ - class LIB_STROKE_EXPORT GetViewMapGradientNormF1D : public UnaryFunction1D - { - private: - int _level; - float _sampling; - Functions0D::GetViewMapGradientNormF0D _func; - public: - /*! Builds the functor from the level - * of the pyramid from which the pixel must be read. - * \param level - * The level of the pyramid from which - * the pixel must be read. - * \param iType - * The integration method used to compute - * a single value from a set of values. - * \param sampling - * The resolution used to sample the chain: the corresponding 0D function - * is evaluated at each sample point and the result is obtained by - * combining the resulting values into a single one, following the - * method specified by iType. - */ - GetViewMapGradientNormF1D(int level,IntegrationType iType = MEAN, float sampling=2.f) - : UnaryFunction1D(iType), _func(level) { - _level = level; - _sampling = sampling; - } - - /*! Returns the string "GetSteerableViewMapDensityF1D"*/ - string getName() const { - return "GetViewMapGradientNormF1D"; - } - /*! the () operator.*/ - int operator()(Interface1D& inter); - }; +// DensityF1D +/*! Returns the density evaluated for an Interface1D. + * The density is evaluated for a set of points along the Interface1D (using the DensityF0D functor) with a + * user-defined sampling and then integrated into a single value using a user-defined integration method. + */ +class DensityF1D : public UnaryFunction1D +{ +private: + float _sampling; + +public: + /*! Builds the functor. + * \param sigma + * Thesigma used in DensityF0D and determining the window size used in each density query. + * \param iType + * The integration method used to compute a single value from a set of values. + * \param sampling + * The resolution used to sample the chain: the corresponding 0D function is evaluated at each sample point and the + * result is obtained by combining the resulting values into a single one, following the method specified by iType. + */ + DensityF1D(double sigma = 2, IntegrationType iType = MEAN, float sampling = 2.0f) + : UnaryFunction1D(iType), _fun(sigma) + { + _sampling = sampling; + } + + /*! Destructor */ + virtual ~DensityF1D() {} + + /*! Returns the string "DensityF1D"*/ + string getName() const + { + return "DensityF1D"; + } + + /*! the () operator.*/ + int operator()(Interface1D& inter) + { + result = integrate(_fun, inter.pointsBegin(_sampling), inter.pointsEnd(_sampling), _integration); + return 0; + } + +private: + Functions0D::DensityF0D _fun; +}; + +// LocalAverageDepthF1D +/*! Returns the average depth evaluated for an Interface1D. + * The average depth is evaluated for a set of points along the Interface1D (using the LocalAverageDepthF0D functor) + * with a user-defined sampling and then integrated into a single value using a user-defined integration method. + */ +class LocalAverageDepthF1D : public UnaryFunction1D +{ +public: + /*! Builds the functor. + * \param sigma + * The sigma used in DensityF0D and determining the window size used in each density query. + * \param iType + * The integration method used to compute a single value from a set of values. + */ + LocalAverageDepthF1D(real sigma, IntegrationType iType = MEAN) + : UnaryFunction1D(iType), _fun(sigma) + { + } + + /*! Returns the string "LocalAverageDepthF1D" */ + string getName() const + { + return "LocalAverageDepthF1D"; + } + + /*! the () operator. */ + int operator()(Interface1D& inter) + { + result = integrate(_fun, inter.verticesBegin(), inter.verticesEnd(), _integration); + return 0; + } + +private: + Functions0D::LocalAverageDepthF0D _fun; +}; + +// GetCompleteViewMapDensity +/*! Returns the density evaluated for an Interface1D in the complete viewmap image. + * The density is evaluated for a set of points along the Interface1D (using the ReadCompleteViewMapPixelF0D functor) + * and then integrated into a single value using a user-defined integration method. + */ +class LIB_STROKE_EXPORT GetCompleteViewMapDensityF1D : public UnaryFunction1D +{ +public: + /*! Builds the functor. + * \param level + * The level of the pyramid from which + * the pixel must be read. + * \param iType + * The integration method used to compute + * a single value from a set of values. + * \param sampling + * The resolution used to sample the chain: the corresponding 0D function + * is evaluated at each sample point and the result is obtained by + * combining the resulting values into a single one, following the + * method specified by iType. + */ + GetCompleteViewMapDensityF1D(unsigned level, IntegrationType iType = MEAN, float sampling = 2.0f) + : UnaryFunction1D(iType), _fun(level) + { + _sampling = sampling; + } + + /*! Returns the string "GetCompleteViewMapDensityF1D" */ + string getName() const + { + return "GetCompleteViewMapDensityF1D"; + } + + /*! the () operator. */ + int operator()(Interface1D& inter); + +private: + Functions0D::ReadCompleteViewMapPixelF0D _fun; + float _sampling; +}; + +// GetDirectionalViewMapDensity +/*! Returns the density evaluated for an Interface1D in of the steerable viewmaps image. + * The direction telling which Directional map to choose is explicitely specified by the user. + * The density is evaluated for a set of points along the Interface1D (using the ReadSteerableViewMapPixelF0D functor) + * and then integrated into a single value using a user-defined integration method. + */ +class LIB_STROKE_EXPORT GetDirectionalViewMapDensityF1D : public UnaryFunction1D +{ +public: + /*! Builds the functor. + * \param iOrientation + * The number of the directional map we must work with. + * \param level + * The level of the pyramid from which the pixel must be read. + * \param iType + * The integration method used to compute a single value from a set of values. + * \param sampling + * The resolution used to sample the chain: the corresponding 0D function is evaluated at each sample point and the + * result is obtained by combining the resulting values into a single one, following the method specified by iType. + */ + GetDirectionalViewMapDensityF1D(unsigned iOrientation, unsigned level, IntegrationType iType = MEAN, + float sampling = 2.0f) + : UnaryFunction1D(iType), _fun(iOrientation, level) + { + _sampling = sampling; + } + + /*! Returns the string "GetDirectionalViewMapDensityF1D" */ + string getName() const + { + return "GetDirectionalViewMapDensityF1D"; + } + + /*! the () operator. */ + int operator()(Interface1D& inter); + +private: + Functions0D::ReadSteerableViewMapPixelF0D _fun; + float _sampling; +}; + +// GetSteerableViewMapDensityF1D +/*! Returns the density of the viewmap for a given Interface1D. The density of each FEdge is evaluated + * in the proper steerable ViewMap depending on its oorientation. + */ +class LIB_STROKE_EXPORT GetSteerableViewMapDensityF1D : public UnaryFunction1D +{ +private: + int _level; + float _sampling; + +public: + /*! Builds the functor from the level of the pyramid from which the pixel must be read. + * \param level + * The level of the pyramid from which the pixel must be read. + * \param iType + * The integration method used to compute a single value from a set of values. + * \param sampling + * The resolution used to sample the chain: the corresponding 0D function is evaluated at each sample point and the + * result is obtained by combining the resulting values into a single one, following the method specified by iType. + */ + GetSteerableViewMapDensityF1D(int level,IntegrationType iType = MEAN, float sampling = 2.0f) + : UnaryFunction1D(iType) + { + _level = level; + _sampling = sampling; + } + + /*! Destructor */ + virtual ~GetSteerableViewMapDensityF1D() {} + + /*! Returns the string "GetSteerableViewMapDensityF1D" */ + string getName() const + { + return "GetSteerableViewMapDensityF1D"; + } + + /*! the () operator. */ + int operator()(Interface1D& inter); +}; + +// GetViewMapGradientNormF1D +/*! Returns the density of the viewmap for a given Interface1D. The density of each FEdge is evaluated in + * the proper steerable ViewMap depending on its oorientation. + */ +class LIB_STROKE_EXPORT GetViewMapGradientNormF1D : public UnaryFunction1D +{ +private: + int _level; + float _sampling; + Functions0D::GetViewMapGradientNormF0D _func; + +public: + /*! Builds the functor from the level of the pyramid from which the pixel must be read. + * \param level + * The level of the pyramid from which the pixel must be read. + * \param iType + * The integration method used to compute a single value from a set of values. + * \param sampling + * The resolution used to sample the chain: the corresponding 0D function is evaluated at each sample point and the + * result is obtained by combining the resulting values into a single one, following the method specified by iType. + */ + GetViewMapGradientNormF1D(int level,IntegrationType iType = MEAN, float sampling = 2.0f) + : UnaryFunction1D(iType), _func(level) + { + _level = level; + _sampling = sampling; + } + + /*! Returns the string "GetSteerableViewMapDensityF1D" */ + string getName() const + { + return "GetViewMapGradientNormF1D"; + } + + /*! the () operator. */ + int operator()(Interface1D& inter); +}; + } // end of namespace Functions1D -#endif // ADVANCED_FUNCTIONS1D_HPP +#endif // __FREESTYLE_ADVANCED_FUNCTIONS_1D_H__ diff --git a/source/blender/freestyle/intern/stroke/AdvancedPredicates1D.h b/source/blender/freestyle/intern/stroke/AdvancedPredicates1D.h index 91b63168aa9..9235598da78 100644 --- a/source/blender/freestyle/intern/stroke/AdvancedPredicates1D.h +++ b/source/blender/freestyle/intern/stroke/AdvancedPredicates1D.h @@ -1,39 +1,46 @@ -// -// Filename : AdvancedPredicates1D.h -// Author(s) : Stephane Grabli -// Purpose : Class gathering stroke creation algorithms -// Date of creation : 01/07/2003 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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_ADVANCED_PREDICATES_1D_H__ +#define __FREESTYLE_ADVANCED_PREDICATES_1D_H__ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/stroke/AdvancedPredicates1D.h + * \ingroup freestyle + * \brief Class gathering stroke creation algorithms + * \author Stephane Grabli + * \date 01/07/2003 + */ + +#include -#ifndef ADVANCED_PREDICATES1D_H -# define ADVANCED_PREDICATES1D_H +#include "AdvancedFunctions1D.h" +#include "Predicates1D.h" -# include -# include "../view_map/Interface1D.h" -# include "AdvancedFunctions1D.h" -# include "Predicates1D.h" +#include "../view_map/Interface1D.h" // // Predicates definitions @@ -42,43 +49,47 @@ namespace Predicates1D { - // DensityLowerThanUP1D - /*! Returns true if the density evaluated for the - * Interface1D is less than a user-defined density value. - */ - class DensityLowerThanUP1D : public UnaryPredicate1D - { - public: - /*! Builds the functor. - * \param threshold - * The value of the threshold density. - * Any Interface1D having a density lower than - * this threshold will match. - * \param sigma - * The sigma value defining the density evaluation window size - * used in the DensityF0D functor. - */ - DensityLowerThanUP1D(double threshold, double sigma = 2) { - _threshold = threshold; - _sigma = sigma; - } - /*! Returns the string "DensityLowerThanUP1D"*/ - string getName() const { - return "DensityLowerThanUP1D"; - } - /*! The () operator. */ - int operator()(Interface1D& inter) { - Functions1D::DensityF1D fun(_sigma); - if (fun(inter) < 0) - return -1; - result = (fun.result < _threshold); - return 0; - } - private: - double _sigma; - double _threshold; - }; +// DensityLowerThanUP1D +/*! Returns true if the density evaluated for the +* Interface1D is less than a user-defined density value. +*/ +class DensityLowerThanUP1D : public UnaryPredicate1D +{ +public: + /*! Builds the functor. + * \param threshold + * The value of the threshold density. + * Any Interface1D having a density lower than this threshold will match. + * \param sigma + * The sigma value defining the density evaluation window size used in the DensityF0D functor. + */ + DensityLowerThanUP1D(double threshold, double sigma = 2) + { + _threshold = threshold; + _sigma = sigma; + } + + /*! Returns the string "DensityLowerThanUP1D" */ + string getName() const + { + return "DensityLowerThanUP1D"; + } + + /*! The () operator. */ + int operator()(Interface1D& inter) + { + Functions1D::DensityF1D fun(_sigma); + if (fun(inter) < 0) + return -1; + result = (fun.result < _threshold); + return 0; + } + +private: + double _sigma; + double _threshold; +}; } // end of namespace Predicates1D -#endif // ADVANCED_PREDICATES1D_H +#endif // __FREESTYLE_ADVANCED_PREDICATES_1D_H__ diff --git a/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp index 7ee5762a70f..e631b9f4471 100644 --- a/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp +++ b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp @@ -1,28 +1,42 @@ - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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 ***** + */ + +/** \file blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp + * \ingroup freestyle + * \brief Fredo's stroke shaders + * \author Fredo Durand + * \date 17/12/2002 + */ #include "AdvancedStrokeShaders.h" +#include "StrokeIterators.h" + #include "../system/PseudoNoise.h" #include "../system/RandGen.h" -#include "StrokeIterators.h" ///////////////////////////////////////// // @@ -30,75 +44,63 @@ // ///////////////////////////////////////// - -CalligraphicShader::CalligraphicShader (real iMinThickness, real iMaxThickness, - const Vec2f &iOrientation, bool clamp) - : StrokeShader() +CalligraphicShader::CalligraphicShader(real iMinThickness, real iMaxThickness, const Vec2f &iOrientation, bool clamp) +: StrokeShader() { - _minThickness=iMinThickness; - _maxThickness=iMaxThickness; - _orientation = iOrientation; - _orientation.normalize(); - _clamp = clamp; + _minThickness = iMinThickness; + _maxThickness = iMaxThickness; + _orientation = iOrientation; + _orientation.normalize(); + _clamp = clamp; } -float ksinToto=0; +float ksinToto = 0.0f; -int -CalligraphicShader::shade(Stroke &ioStroke) const +int CalligraphicShader::shade(Stroke &ioStroke) const { - Interface0DIterator v; - Functions0D::VertexOrientation2DF0D fun; - StrokeVertex* sv; - for(v=ioStroke.verticesBegin(); - !v.isEnd(); - ++v) - { - real thickness; - if (fun(v) < 0) - return -1; - Vec2f vertexOri(fun.result); - Vec2r ori2d(-vertexOri[1], vertexOri[0]); - ori2d.normalizeSafe(); - real scal = ori2d * _orientation; - sv = dynamic_cast(&(*v)); - if (_clamp && (scal<0)) { - scal=0.0; - sv->attribute().setColor(1,1,1); - } - else { - scal=fabs(scal); - sv->attribute().setColor(0,0,0); - } - thickness=_minThickness+scal*(_maxThickness-_minThickness); - if (thickness<0.0) - thickness=0.0; - sv->attribute().setThickness(thickness/2.0,thickness/2.0); - } - - return 0; -} - -//void -//TipRemoverShader::shade(Stroke &ioStroke) const -//{ -// -// StrokeInternal::StrokeVertexIterator v, vend; -// for(v=ioStroke.strokeVerticesBegin(), vend=ioStroke.strokeVerticesEnd(); -// v!=vend; -// ++v) -// { -// if (((*v)->curvilinearAbscissa()<_tipLength) || -// ((*v)->strokeLength()-(*v)->curvilinearAbscissa()<_tipLength)) -// { -// (*v)->attribute().setThickness(0.0, 0.0); -// (*v)->attribute().setColor(1,1,1); -// } -// } -// -//} + Interface0DIterator v; + Functions0D::VertexOrientation2DF0D fun; + StrokeVertex *sv; + for (v = ioStroke.verticesBegin(); !v.isEnd(); ++v) { + real thickness; + if (fun(v) < 0) + return -1; + + Vec2f vertexOri(fun.result); + Vec2r ori2d(-vertexOri[1], vertexOri[0]); + ori2d.normalizeSafe(); + real scal = ori2d * _orientation; + sv = dynamic_cast(&(*v)); + if (_clamp && (scal<0)) { + scal = 0.0; + sv->attribute().setColor(1, 1, 1); + } + else { + scal = fabs(scal); + sv->attribute().setColor(0, 0, 0); + } + thickness = _minThickness + scal * (_maxThickness - _minThickness); + if (thickness < 0.0) + thickness = 0.0; + sv->attribute().setThickness(thickness / 2.0, thickness / 2.0); + } + return 0; +} +#if 0 +void TipRemoverShader::shade(Stroke &ioStroke) const +{ + StrokeInternal::StrokeVertexIterator v, vend; + for (v = ioStroke.strokeVerticesBegin(), vend = ioStroke.strokeVerticesEnd(); v != vend; ++v) { + if (((*v)->curvilinearAbscissa() < _tipLength) || + (((*v)->strokeLength() - (*v)->curvilinearAbscissa()) < _tipLength)) { + (*v)->attribute().setThickness(0.0, 0.0); + (*v)->attribute().setColor(1, 1, 1); + } + } +} +#endif ///////////////////////////////////////// // @@ -108,99 +110,93 @@ CalligraphicShader::shade(Stroke &ioStroke) const static const unsigned NB_VALUE_NOISE = 512; -SpatialNoiseShader::SpatialNoiseShader (float ioamount, float ixScale, int nbOctave, - bool smooth, bool pureRandom) - : StrokeShader() +SpatialNoiseShader::SpatialNoiseShader(float ioamount, float ixScale, int nbOctave, bool smooth, bool pureRandom) +: StrokeShader() { - _amount = ioamount; - if (ixScale==0) _xScale=0; - else _xScale=1.0/ixScale/real(NB_VALUE_NOISE); - _nbOctave=nbOctave; - _smooth=smooth; - _pureRandom=pureRandom; + _amount = ioamount; + if (ixScale == 0) + _xScale = 0; + else + _xScale = 1.0 / ixScale / real(NB_VALUE_NOISE); + _nbOctave = nbOctave; + _smooth = smooth; + _pureRandom = pureRandom; } -int -SpatialNoiseShader::shade(Stroke &ioStroke) const + +int SpatialNoiseShader::shade(Stroke &ioStroke) const { - Interface0DIterator v, v2; - v=ioStroke.verticesBegin(); - Vec2r p(v->getProjectedX(), v->getProjectedY()); - v2=v; ++v2; - Vec2r p0(v2->getProjectedX(), v2->getProjectedY()); - p0=p+2*(p-p0); - StrokeVertex* sv; - sv = dynamic_cast(&(*v)); - real initU = sv->strokeLength()*real(NB_VALUE_NOISE); - if (_pureRandom) initU+=RandGen::drand48()*real(NB_VALUE_NOISE); - - Functions0D::VertexOrientation2DF0D fun; - while (!v.isEnd()) - { - sv = dynamic_cast(&(*v)); - Vec2r p(sv->getPoint()); - if (fun(v) < 0) - return -1; - Vec2r vertexOri(fun.result); - Vec2r ori2d(vertexOri[0], vertexOri[1]); - ori2d = Vec2r(p-p0); - ori2d.normalizeSafe(); - - PseudoNoise mynoise; - real bruit; - - if (_smooth) - bruit=mynoise.turbulenceSmooth(_xScale*sv->curvilinearAbscissa()+initU, - _nbOctave); - else - bruit=mynoise.turbulenceLinear(_xScale*sv->curvilinearAbscissa()+initU, - _nbOctave); - - Vec2r noise(-ori2d[1]*_amount*bruit, - ori2d[0]*_amount*bruit); - - sv->setPoint(p[0]+noise[0], p[1]+noise[1]); - p0=p; - - ++v; - } - - return 0; -} + Interface0DIterator v, v2; + v = ioStroke.verticesBegin(); + Vec2r p(v->getProjectedX(), v->getProjectedY()); + v2 = v; + ++v2; + Vec2r p0(v2->getProjectedX(), v2->getProjectedY()); + p0 = p + 2 * (p - p0); + StrokeVertex *sv; + sv = dynamic_cast(&(*v)); + real initU = sv->strokeLength() * real(NB_VALUE_NOISE); + if (_pureRandom) + initU += RandGen::drand48() * real(NB_VALUE_NOISE); + + Functions0D::VertexOrientation2DF0D fun; + while (!v.isEnd()) { + sv = dynamic_cast(&(*v)); + Vec2r p(sv->getPoint()); + if (fun(v) < 0) + return -1; + Vec2r vertexOri(fun.result); + Vec2r ori2d(vertexOri[0], vertexOri[1]); + ori2d = Vec2r(p - p0); + ori2d.normalizeSafe(); + + PseudoNoise mynoise; + real bruit; + + if (_smooth) + bruit = mynoise.turbulenceSmooth(_xScale * sv->curvilinearAbscissa() + initU, _nbOctave); + else + bruit = mynoise.turbulenceLinear(_xScale * sv->curvilinearAbscissa() + initU, _nbOctave); + + Vec2r noise(-ori2d[1] * _amount * bruit, ori2d[0] * _amount * bruit); + + sv->setPoint(p[0] + noise[0], p[1] + noise[1]); + p0 = p; + + ++v; + } + return 0; +} - ///////////////////////////////////////// // // SMOOTHING SHADER // ///////////////////////////////////////// - -SmoothingShader::SmoothingShader (int ionbIteration, real iFactorPoint, real ifactorCurvature, real iFactorCurvatureDifference, - real iAnisoPoint, real iAnisoNormal, real iAnisoCurvature, real iCarricatureFactor) - : StrokeShader() +SmoothingShader::SmoothingShader(int ionbIteration, real iFactorPoint, real ifactorCurvature, + real iFactorCurvatureDifference, real iAnisoPoint, real iAnisoNormal, + real iAnisoCurvature, real iCarricatureFactor) +: StrokeShader() { - _nbIterations=ionbIteration; - _factorCurvature=ifactorCurvature; - _factorCurvatureDifference=iFactorCurvatureDifference; - _anisoNormal=iAnisoNormal; - _anisoCurvature=iAnisoCurvature; - _carricatureFactor=iCarricatureFactor; - _factorPoint=iFactorPoint; - _anisoPoint=iAnisoPoint; + _nbIterations = ionbIteration; + _factorCurvature = ifactorCurvature; + _factorCurvatureDifference = iFactorCurvatureDifference; + _anisoNormal = iAnisoNormal; + _anisoCurvature = iAnisoCurvature; + _carricatureFactor = iCarricatureFactor; + _factorPoint = iFactorPoint; + _anisoPoint = iAnisoPoint; } - - -int -SmoothingShader::shade(Stroke &ioStroke) const +int SmoothingShader::shade(Stroke &ioStroke) const { - //cerr<<" Smoothing a stroke "<getPoint(); - i++; - } - Vec2r vec_tmp(_vertex[0]-_vertex[_nbVertices-1]); - _isClosedCurve = (vec_tmp.norm() < M_EPSILON); - - _safeTest=(_nbVertices>4); + _stroke = &ioStroke; + + _nbVertices = ioStroke.vertices_size(); + _vertex = new Vec2r[_nbVertices]; + _curvature = new real[_nbVertices]; + _normal = new Vec2r[_nbVertices]; + StrokeInternal::StrokeVertexIterator v, vend; + int i = 0; + for (v = ioStroke.strokeVerticesBegin(), vend = ioStroke.strokeVerticesEnd(); v != vend; ++v, ++i) { + _vertex[i] = (v)->getPoint(); + } + Vec2r vec_tmp(_vertex[0] - _vertex[_nbVertices - 1]); + _isClosedCurve = (vec_tmp.norm() < M_EPSILON); + + _safeTest = (_nbVertices > 4); } void Smoother::smooth(int nbIteration, real iFactorPoint, real ifactorCurvature, real iFactorCurvatureDifference, - real iAnisoPoint, real iAnisoNormal, real iAnisoCurvature, real iCarricatureFactor) + real iAnisoPoint, real iAnisoNormal, real iAnisoCurvature, real iCarricatureFactor) { - _factorCurvature=ifactorCurvature; - _factorCurvatureDifference=iFactorCurvatureDifference; - _anisoNormal=iAnisoNormal; - _anisoCurvature=iAnisoCurvature; - _carricatureFactor=iCarricatureFactor; - _factorPoint=iFactorPoint; - _anisoPoint=iAnisoPoint; - - for (int i=0; i M_EPSILON) - _curvature[i]/=(0.5*lba+lbc); - } - _curvature[0]=_curvature[1]; - _curvature[_nbVertices-1]=_curvature[_nbVertices-2]; - Vec2r di(_vertex[1]-_vertex[0]); - _normal[0] = Vec2r(-di[1], di[0]); - _normal[0].normalizeSafe(); - di=_vertex[_nbVertices-1]-_vertex[_nbVertices-2]; - _normal[_nbVertices-1]=Vec2r(-di[1], di[0]); - _normal[_nbVertices-1].normalizeSafe(); - - if (_isClosedCurve) - { - BA=_vertex[_nbVertices-2]-_vertex[0]; - BC=_vertex[1]-_vertex[0]; - real lba=BA.norm(), lbc=BC.norm(); - BA.normalizeSafe(); - BC.normalizeSafe(); - normalCurvature = BA + BC; - - _normal[i]=Vec2r(-(BC-BA)[1], (BC-BA)[0]); - _normal[i].normalizeSafe(); - - _curvature[i] = normalCurvature * _normal[i]; - if (lba+lbc > M_EPSILON) - _curvature[i]/=(0.5*lba+lbc); - - _normal[_nbVertices-1]=_normal[0]; - _curvature[_nbVertices-1]=_curvature[0]; - } + int i; + Vec2r BA, BC, normalCurvature; + for (i = 1; i < (_nbVertices - 1); ++i) { + BA = _vertex[i - 1] - _vertex[i]; + BC = _vertex[i + 1] - _vertex[i]; + real lba = BA.norm(), lbc = BC.norm(); + BA.normalizeSafe(); + BC.normalizeSafe(); + normalCurvature = BA + BC; + + _normal[i] = Vec2r(-(BC - BA)[1], (BC - BA)[0]); + _normal[i].normalizeSafe(); + + _curvature[i] = normalCurvature * _normal[i]; + if (lba + lbc > M_EPSILON) + _curvature[i] /= (0.5 * lba + lbc); + } + _curvature[0] = _curvature[1]; + _curvature[_nbVertices - 1] = _curvature[_nbVertices - 2]; + Vec2r di(_vertex[1] - _vertex[0]); + _normal[0] = Vec2r(-di[1], di[0]); + _normal[0].normalizeSafe(); + di = _vertex[_nbVertices - 1] - _vertex[_nbVertices - 2]; + _normal[_nbVertices - 1] = Vec2r(-di[1], di[0]); + _normal[_nbVertices - 1].normalizeSafe(); + + if (_isClosedCurve) { + BA = _vertex[_nbVertices - 2] - _vertex[0]; + BC = _vertex[1] - _vertex[0]; + real lba = BA.norm(), lbc = BC.norm(); + BA.normalizeSafe(); + BC.normalizeSafe(); + normalCurvature = BA + BC; + + _normal[i] = Vec2r(-(BC - BA)[1], (BC - BA)[0]); + _normal[i].normalizeSafe(); + + _curvature[i] = normalCurvature * _normal[i]; + if (lba + lbc > M_EPSILON) + _curvature[i] /= (0.5 * lba + lbc); + + _normal[_nbVertices - 1] = _normal[0]; + _curvature[_nbVertices - 1] = _curvature[0]; + } } -void -Smoother::copyVertices () +void Smoother::copyVertices() { - int i=0; - StrokeInternal::StrokeVertexIterator v, vend; - for(v=_stroke->strokeVerticesBegin(), vend=_stroke->strokeVerticesEnd(); - v!=vend; - ++v) - { - const Vec2r p0((v)->getPoint()); - const Vec2r p1(_vertex[i]); - Vec2r p(p0 + _carricatureFactor * (p1 - p0)); - - (v)->setPoint(p[0], p[1]); - i++; - } - + int i = 0; + StrokeInternal::StrokeVertexIterator v, vend; + for (v = _stroke->strokeVerticesBegin(), vend = _stroke->strokeVerticesEnd(); v != vend; ++v) { + const Vec2r p0((v)->getPoint()); + const Vec2r p1(_vertex[i]); + Vec2r p(p0 + _carricatureFactor * (p1 - p0)); + + (v)->setPoint(p[0], p[1]); + ++i; + } } - #if 0 // FIXME ///////////////////////////////////////// @@ -373,63 +352,53 @@ Smoother::copyVertices () // ///////////////////////////////////////// -OmissionShader::OmissionShader (real sizeWindow, real thrVari, real thrFlat, real lFlat) +OmissionShader::OmissionShader(real sizeWindow, real thrVari, real thrFlat, real lFlat) { - _sizeWindow=sizeWindow; - _thresholdVariation=thrVari; - _thresholdFlat=thrFlat; - _lengthFlat=lFlat; + _sizeWindow = sizeWindow; + _thresholdVariation = thrVari; + _thresholdFlat = thrFlat; + _lengthFlat = lFlat; } -int -OmissionShader::shade(Stroke &ioStroke) const +int OmissionShader::shade(Stroke &ioStroke) const { - Omitter omi(ioStroke); - omi.omit(_sizeWindow, _thresholdVariation, _thresholdFlat, _lengthFlat); + Omitter omi(ioStroke); + omi.omit(_sizeWindow, _thresholdVariation, _thresholdFlat, _lengthFlat); - return 0; + return 0; } // OMITTER /////////////////////////// -Omitter::Omitter (Stroke &ioStroke) - :Smoother (ioStroke) +Omitter::Omitter(Stroke &ioStroke) : Smoother(ioStroke) { - StrokeInternal::StrokeVertexIterator v, vend; - int i=0; - for(v=ioStroke.strokeVerticesBegin(), vend=ioStroke.strokeVerticesEnd(); - v!=vend; - ++v) - { - _u[i]=(v)->curvilinearAbscissa(); - i++; - } - + StrokeInternal::StrokeVertexIterator v, vend; + int i = 0; + for (v = ioStroke.strokeVerticesBegin(), vend = ioStroke.strokeVerticesEnd(); v != vend; ++v, ++i) { + _u[i] = (v)->curvilinearAbscissa(); + } } -void -Omitter::omit (real sizeWindow, real thrVari, real thrFlat, real lFlat) +void Omitter::omit(real sizeWindow, real thrVari, real thrFlat, real lFlat) { - _sizeWindow=sizeWindow; - _thresholdVariation=thrVari; - _thresholdFlat=thrFlat; - _lengthFlat=lFlat; - - for (int i=1; i<_nbVertices-1; i++) - { - if (_u[i]<_lengthFlat) continue; - // is the previous segment flat? - int j=i-1; - while ((j>=0) && (_u[i]-_u[j]<_lengthFlat)) - { - if ((_normal[j] * _normal[i]) < _thresholdFlat) - ; // FIXME - j--; + _sizeWindow=sizeWindow; + _thresholdVariation=thrVari; + _thresholdFlat=thrFlat; + _lengthFlat=lFlat; + + for (int i = 1; i < _nbVertices-1; ++i) { + if (_u[i] < _lengthFlat) + continue; + // is the previous segment flat? + int j = i - 1; + while ((j >= 0) && (_u[i] - _u[j] < _lengthFlat)) { + if ((_normal[j] * _normal[i]) < _thresholdFlat) + ; // FIXME + --j; + } } - - } } #endif diff --git a/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.h b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.h index f2e56222cc0..a957a3f7155 100644 --- a/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.h +++ b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.h @@ -1,70 +1,73 @@ -// -// Filename : AdvancedStrokeShaders.h -// Author : Fredo Durand -// Purpose : Fredo's stroke shaders -// Date of creation : 17/12/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef ADVANCEDSTROKESHADERS_H -# define ADVANCEDSTROKESHADERS_H - -# include "BasicStrokeShaders.h" +/* + * ***** 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_ADVANCED_STROKE_SHADERS_H__ +#define __FREESTYLE_ADVANCED_STROKE_SHADERS_H__ + +/** \file blender/freestyle/intern/stroke/AdvancedStrokeShaders.h + * \ingroup freestyle + * \brief Fredo's stroke shaders + * \author Fredo Durand + * \date 17/12/2002 + */ + +#include "BasicStrokeShaders.h" /*! [ Thickness Shader ]. - * Assigns thicknesses to the stroke vertices - * so that the stroke looks like made with a calligraphic tool. - * i.e. The stroke will be the thickest in a main direction, - * the thinest in the direction perpendicular to this one, + * Assigns thicknesses to the stroke vertices so that the stroke looks like made with a calligraphic tool. + * i.e. The stroke will be the thickest in a main direction, the thinest in the direction perpendicular to this one, * and an interpolation inbetween. */ -class LIB_STROKE_EXPORT CalligraphicShader : public StrokeShader +class LIB_STROKE_EXPORT CalligraphicShader : public StrokeShader { - public: - /*! Builds the shader. - * \param iMinThickness - * The minimum thickness in the direction perpandicular - * to the main direction. - * \param iMaxThickness - * The maximum thickness in the main direction. - * \param iOrientation - * The 2D vector giving the main direction. - * \param clamp - * Tells ??? - */ - CalligraphicShader (real iMinThickness, real iMaxThickness, - const Vec2f &iOrientation, bool clamp); - /*! Destructor. */ - virtual ~CalligraphicShader () {} - /*! The shading method */ - virtual int shade(Stroke &ioStroke) const; + /*! Builds the shader. + * \param iMinThickness + * The minimum thickness in the direction perpandicular to the main direction. + * \param iMaxThickness + * The maximum thickness in the main direction. + * \param iOrientation + * The 2D vector giving the main direction. + * \param clamp + * Tells ??? + */ + CalligraphicShader(real iMinThickness, real iMaxThickness, const Vec2f &iOrientation, bool clamp); + + /*! Destructor. */ + virtual ~CalligraphicShader() {} + + /*! The shading method */ + virtual int shade(Stroke &ioStroke) const; + protected: - real _maxThickness; - real _minThickness; - Vec2f _orientation; - bool _clamp; + real _maxThickness; + real _minThickness; + Vec2f _orientation; + bool _clamp; }; /*! [ Geometry Shader ]. @@ -72,151 +75,152 @@ protected: * Moves the vertices to make the stroke more noisy. * @see \htmlonly noise/noise.html \endhtmlonly */ -class LIB_STROKE_EXPORT SpatialNoiseShader : public StrokeShader +class LIB_STROKE_EXPORT SpatialNoiseShader : public StrokeShader { public: - /*! Builds the shader. - * \param iAmount - * The amplitude of the noise. - * \param ixScale - * The noise frequency - * \param nbOctave - * The number of octaves - * \param smooth - * If you want the noise to be smooth - * \param pureRandom - * If you don't want any coherence - */ - SpatialNoiseShader (float iAmount, float ixScale, int nbOctave, bool smooth, bool pureRandom); - /*! Destructor. */ - virtual ~SpatialNoiseShader () {} - /*! The shading method. */ - virtual int shade(Stroke &ioStroke) const; + /*! Builds the shader. + * \param iAmount + * The amplitude of the noise. + * \param ixScale + * The noise frequency + * \param nbOctave + * The number of octaves + * \param smooth + * If you want the noise to be smooth + * \param pureRandom + * If you don't want any coherence + */ + SpatialNoiseShader(float iAmount, float ixScale, int nbOctave, bool smooth, bool pureRandom); + + /*! Destructor. */ + virtual ~SpatialNoiseShader() {} + + /*! The shading method. */ + virtual int shade(Stroke &ioStroke) const; protected: - - float _amount; - float _xScale; - int _nbOctave; - bool _smooth; - bool _pureRandom; + float _amount; + float _xScale; + int _nbOctave; + bool _smooth; + bool _pureRandom; }; /*! [ Geometry Shader ]. * Smoothes the stroke. * (Moves the vertices to make the stroke smoother). - * Uses curvature flow to converge towards a curve of constant - * curvature. The diffusion method we use is anisotropic + * Uses curvature flow to converge towards a curve of constant curvature. The diffusion method we use is anisotropic * to prevent the diffusion accross corners. * @see \htmlonly smoothing/smoothing.html endhtmlonly */ -class LIB_STROKE_EXPORT SmoothingShader : public StrokeShader +class LIB_STROKE_EXPORT SmoothingShader : public StrokeShader { public: - /*! Builds the shader. - * \param iNbIteration - * The number of iterations. (400) - * \param iFactorPoint - * 0 - * \param ifactorCurvature - * 0 - * \param iFactorCurvatureDifference - * 0.2 - * \param iAnisoPoint - * 0 - * \param iAnisNormal - * 0 - * \param iAnisoCurvature - * 0 - * \param icarricatureFactor - * 1 - */ - SmoothingShader (int iNbIteration, real iFactorPoint, real ifactorCurvature, real iFactorCurvatureDifference, - real iAnisoPoint, real iAnisoNormal, real iAnisoCurvature, real icarricatureFactor); - /*! Destructor. */ - virtual ~SmoothingShader () {} - - /*! The shading method. */ - virtual int shade(Stroke &ioStroke) const; + /*! Builds the shader. + * \param iNbIteration + * The number of iterations. (400) + * \param iFactorPoint + * 0 + * \param ifactorCurvature + * 0 + * \param iFactorCurvatureDifference + * 0.2 + * \param iAnisoPoint + * 0 + * \param iAnisNormal + * 0 + * \param iAnisoCurvature + * 0 + * \param icarricatureFactor + * 1 + */ + SmoothingShader(int iNbIteration, real iFactorPoint, real ifactorCurvature, real iFactorCurvatureDifference, + real iAnisoPoint, real iAnisoNormal, real iAnisoCurvature, real icarricatureFactor); + + /*! Destructor. */ + virtual ~SmoothingShader() {} + + /*! The shading method. */ + virtual int shade(Stroke &ioStroke) const; protected: - - int _nbIterations; - real _factorPoint; - real _factorCurvature; - real _factorCurvatureDifference; - real _anisoPoint; - real _anisoNormal; - real _anisoCurvature; - real _carricatureFactor; + int _nbIterations; + real _factorPoint; + real _factorCurvature; + real _factorCurvatureDifference; + real _anisoPoint; + real _anisoNormal; + real _anisoCurvature; + real _carricatureFactor; }; class LIB_STROKE_EXPORT Smoother { public: - Smoother (Stroke &ioStroke); - - virtual ~Smoother () {} + Smoother(Stroke &ioStroke); + + virtual ~Smoother() {} - void smooth (int nbIterations, real iFactorPoint, real ifactorCurvature, real iFactorCurvatureDifference, - real iAnisoPoint, real iAnisoNormal, real iAnisoCurvature, real icarricatureFactor); - void computeCurvature (); + void smooth(int nbIterations, real iFactorPoint, real ifactorCurvature, real iFactorCurvatureDifference, + real iAnisoPoint, real iAnisoNormal, real iAnisoCurvature, real icarricatureFactor); + + void computeCurvature(); protected: - real _factorPoint; - real _factorCurvature; - real _factorCurvatureDifference; - real _anisoPoint; - real _anisoNormal; - real _anisoCurvature; - real _carricatureFactor; - - void iteration(); - void copyVertices (); - - Stroke *_stroke; - int _nbVertices; - Vec2r *_vertex; - Vec2r *_normal; - real *_curvature; - bool *_isFixedVertex; - - bool _isClosedCurve; - bool _safeTest; + real _factorPoint; + real _factorCurvature; + real _factorCurvatureDifference; + real _anisoPoint; + real _anisoNormal; + real _anisoCurvature; + real _carricatureFactor; + + void iteration(); + void copyVertices (); + + Stroke *_stroke; + int _nbVertices; + Vec2r *_vertex; + Vec2r *_normal; + real *_curvature; + bool *_isFixedVertex; + + bool _isClosedCurve; + bool _safeTest; }; -class LIB_STROKE_EXPORT Omitter : public Smoother +class LIB_STROKE_EXPORT Omitter : public Smoother { public: - Omitter (Stroke &ioStroke); - virtual ~Omitter () {} + Omitter(Stroke &ioStroke); + + virtual ~Omitter() {} + + void omit(real sizeWindow, real thrVari, real thrFlat, real lFlat); - void omit (real sizeWindow, real thrVari, real thrFlat, real lFlat); protected: - real *_u; + real *_u; - real _sizeWindow; - real _thresholdVariation; - real _thresholdFlat; - real _lengthFlat; + real _sizeWindow; + real _thresholdVariation; + real _thresholdFlat; + real _lengthFlat; }; -/*! Omission shader - */ -class LIB_STROKE_EXPORT OmissionShader : public StrokeShader +/*! Omission shader */ +class LIB_STROKE_EXPORT OmissionShader : public StrokeShader { public: - OmissionShader (real sizeWindow, real thrVari, real thrFlat, real lFlat); - virtual ~OmissionShader () {} + OmissionShader(real sizeWindow, real thrVari, real thrFlat, real lFlat); + virtual ~OmissionShader() {} - virtual int shade(Stroke &ioStroke) const; + virtual int shade(Stroke &ioStroke) const; protected: - - real _sizeWindow; - real _thresholdVariation; - real _thresholdFlat; - real _lengthFlat; + real _sizeWindow; + real _thresholdVariation; + real _thresholdFlat; + real _lengthFlat; }; -#endif // ADVANCEDSTROKESHADERS_H +#endif // __FREESTYLE_ADVANCED_STROKE_SHADERS_H__ diff --git a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp index eea6da40c9f..852a36571d4 100644 --- a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp +++ b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp @@ -1,1170 +1,1108 @@ +/* + * ***** 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 ***** + */ + +/** \file blender/freestyle/intern/stroke/BasicStrokeShaders.cpp + * \ingroup freestyle + * \brief Class gathering basic stroke shaders + * \author Stephane Grabli + * \date 17/12/2002 + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#include "StrokeRenderer.h" #include + +#include "AdvancedFunctions0D.h" +#include "AdvancedFunctions1D.h" #include "BasicStrokeShaders.h" +#include "StrokeIO.h" +#include "StrokeIterators.h" +#include "StrokeRenderer.h" + #include "../system/PseudoNoise.h" #include "../system/RandGen.h" +#include "../system/StringUtils.h" + #include "../view_map/Functions0D.h" #include "../view_map/Functions1D.h" -#include "AdvancedFunctions0D.h" -#include "AdvancedFunctions1D.h" -#include "StrokeIterators.h" -#include "../system/StringUtils.h" -#include "StrokeIO.h" //soc #include //soc #include + extern "C" { -#include "IMB_imbuf.h" -#include "IMB_imbuf_types.h" +# include "IMB_imbuf.h" +# include "IMB_imbuf_types.h" } // Internal function -// soc -// void convert(const QImage& iImage, float **oArray, unsigned &oSize) { -// oSize = iImage.width(); -// *oArray = new float[oSize]; -// for(unsigned i=0; ix; - *oArray = new float[oSize]; + *oArray = new float[oSize]; char *pix; - for(unsigned i=0; i < oSize; ++i) { - pix = (char*) imBuf->rect + i*4; - (*oArray)[i] = ((float) pix[2] )/255.f; - } + for (unsigned int i = 0; i < oSize; ++i) { + pix = (char*) imBuf->rect + i * 4; + (*oArray)[i] = ((float) pix[2]) / 255.0f; + } } namespace StrokeShaders { - // - // Thickness modifiers - // - ////////////////////////////////////////////////////////// - - int ConstantThicknessShader::shade(Stroke& stroke) const - { - StrokeInternal::StrokeVertexIterator v, vend; - int i=0; - int size = stroke.strokeVerticesSize(); - for(v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); - v!=vend; - ++v) - { - if((1 == i) || (size-2 == i)) - v->attribute().setThickness(_thickness/4.0,_thickness/4.0); - if((0 == i) || (size-1 == i)) - v->attribute().setThickness(0,0); - - v->attribute().setThickness(_thickness/2.0, _thickness/2.0); - } +// +// Thickness modifiers +// +////////////////////////////////////////////////////////// + +int ConstantThicknessShader::shade(Stroke& stroke) const +{ + StrokeInternal::StrokeVertexIterator v, vend; + int i = 0; + int size = stroke.strokeVerticesSize(); + for (v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); v != vend; ++v) { + // XXX What's the use of i here? And is not the thickness always overriden by the last line of the loop? + if ((1 == i) || (size - 2 == i)) + v->attribute().setThickness(_thickness / 4.0, _thickness / 4.0); + if ((0 == i) || (size - 1 == i)) + v->attribute().setThickness(0, 0); + + v->attribute().setThickness(_thickness / 2.0, _thickness / 2.0); + } return 0; - } - - int ConstantExternThicknessShader::shade(Stroke& stroke) const - { - StrokeInternal::StrokeVertexIterator v, vend; - int i=0; - int size = stroke.strokeVerticesSize(); - for(v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); - v!=vend; - ++v) - { - if((1 == i) || (size-2 == i)) - v->attribute().setThickness(_thickness/2.0,0); - if((0 == i) || (size-1 == i)) - v->attribute().setThickness(0,0); - - v->attribute().setThickness(_thickness, 0); - } +} + +int ConstantExternThicknessShader::shade(Stroke& stroke) const +{ + StrokeInternal::StrokeVertexIterator v, vend; + int i = 0; + int size = stroke.strokeVerticesSize(); + for (v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); v != vend; ++v) { + // XXX What's the use of i here? And is not the thickness always overriden by the last line of the loop? + if ((1 == i) || (size - 2 == i)) + v->attribute().setThickness(_thickness / 2.0, 0); + if ((0 == i) || (size - 1 == i)) + v->attribute().setThickness(0, 0); + + v->attribute().setThickness(_thickness, 0); + } return 0; - } - - int IncreasingThicknessShader::shade(Stroke& stroke) const - { - - int n=stroke.strokeVerticesSize()-1; - StrokeInternal::StrokeVertexIterator v, vend; - int i=0; - for(v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); - v!=vend; - - ++v) - { - float t; - if(i < (float)n/2.f) - t = (1.0-(float)i/(float)n)*_ThicknessMin + (float)i/(float)n*_ThicknessMax; - else - t = (1.0-(float)i/(float)n)*_ThicknessMax + (float)i/(float)n*_ThicknessMin; - v->attribute().setThickness(t/2.0, t/2.0); - ++i; - } +} + +int IncreasingThicknessShader::shade(Stroke& stroke) const +{ + int n = stroke.strokeVerticesSize() - 1, i; + StrokeInternal::StrokeVertexIterator v, vend; + for (i = 0, v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); + v != vend; + ++v, ++i) + { + float t; + if (i < (float)n / 2.0f) + t = (1.0 - (float)i / (float)n) * _ThicknessMin + (float)i / (float)n * _ThicknessMax; + else + t = (1.0 - (float)i / (float)n) * _ThicknessMax + (float)i / (float)n * _ThicknessMin; + v->attribute().setThickness(t / 2.0, t / 2.0); + } return 0; - } - - int ConstrainedIncreasingThicknessShader::shade(Stroke& stroke) const - { - float slength = stroke.getLength2D(); - float maxT = min(_ratio*slength,_ThicknessMax); - int n=stroke.strokeVerticesSize()-1; - StrokeInternal::StrokeVertexIterator v, vend; - int i=0; - for(v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); - v!=vend; - - ++v) - { - float t; - if(i < (float)n/2.f) - t = (1.0-(float)i/(float)n)*_ThicknessMin + (float)i/(float)n*maxT; - else - t = (1.0-(float)i/(float)n)*maxT + (float)i/(float)n*_ThicknessMin; - v->attribute().setThickness(t/2.0, t/2.0); - if(i == n-1) - v->attribute().setThickness(_ThicknessMin/2.0, _ThicknessMin/2.0); - ++i; - } +} + +int ConstrainedIncreasingThicknessShader::shade(Stroke& stroke) const +{ + float slength = stroke.getLength2D(); + float maxT = min(_ratio*slength,_ThicknessMax); + int n = stroke.strokeVerticesSize() - 1, i; + StrokeInternal::StrokeVertexIterator v, vend; + for (i = 0, v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); + v != vend; + ++v, ++i) + { + // XXX Why not using an if/else here? Else, if last condition is true, everything else is computed for nothing! + float t; + if (i < (float)n / 2.0f) + t = (1.0 - (float)i / (float)n) * _ThicknessMin + (float)i / (float)n * maxT; + else + t = (1.0 - (float)i / (float)n) * maxT + (float)i / (float)n * _ThicknessMin; + v->attribute().setThickness(t / 2.0, t / 2.0); + if (i == n - 1) + v->attribute().setThickness(_ThicknessMin / 2.0, _ThicknessMin / 2.0); + } return 0; - } - - - int LengthDependingThicknessShader::shade(Stroke& stroke) const - { - float step = (_maxThickness-_minThickness)/3.f; - float l = stroke.getLength2D(); - float thickness = 0.0; - if(l>300.f) - thickness = _minThickness+3.f*step; - else if((l< 300.f) && (l>100.f)) - thickness = _minThickness+2.f*step; - else if((l<100.f) && (l>50.f)) - thickness = _minThickness+1.f*step; - else if(l< 50.f) - thickness = _minThickness; - - StrokeInternal::StrokeVertexIterator v, vend; - int i=0; - int size = stroke.strokeVerticesSize(); - for(v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); - v!=vend; - ++v) - { - if((1 == i) || (size-2 == i)) - v->attribute().setThickness(thickness/4.0,thickness/4.0); - if((0 == i) || (size-1 == i)) - v->attribute().setThickness(0,0); - - v->attribute().setThickness(thickness/2.0, thickness/2.0); - } +} + + +int LengthDependingThicknessShader::shade(Stroke& stroke) const +{ + float step = (_maxThickness - _minThickness) / 3.0f; + float l = stroke.getLength2D(); + float thickness = 0.0f; + if (l > 300.0f) + thickness = _minThickness + 3.0f * step; + else if ((l < 300.0f) && (l > 100.0f)) + thickness = _minThickness + 2.0f * step; + else if ((l < 100.0f) && (l > 50.0f)) + thickness = _minThickness + 1.0f * step; + else // else if (l < 50.0f), tsst... + thickness = _minThickness; + + StrokeInternal::StrokeVertexIterator v, vend; + int i = 0; + int size = stroke.strokeVerticesSize(); + for (v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); v != vend; ++v) { + // XXX What's the use of i here? And is not the thickness always overriden by the last line of the loop? + if ((1 == i) || (size - 2 == i)) + v->attribute().setThickness(thickness / 4.0, thickness / 4.0); + if ((0 == i) || (size - 1 == i)) + v->attribute().setThickness(0, 0); + + v->attribute().setThickness(thickness / 2.0, thickness / 2.0); + } return 0; - } - - - ThicknessVariationPatternShader::ThicknessVariationPatternShader(const string pattern_name, - float iMinThickness, - float iMaxThickness, - bool stretch) - : StrokeShader() { - _stretch = stretch; - _minThickness = iMinThickness; - _maxThickness = iMaxThickness; - ImBuf *image = 0; //soc - vector pathnames; - StringUtils::getPathName(TextureManager::Options::getPatternsPath(), - pattern_name, - pathnames); - for (vector::const_iterator j = pathnames.begin(); j != pathnames.end(); j++) { - ifstream ifs(j->c_str()); - if (ifs.is_open()) { - //soc image.load(j->c_str()); - /* OCIO_TODO: support different input color space */ - image = IMB_loadiffname(j->c_str(), 0, NULL); - break; - } - } - if (image == 0) //soc - cerr << "Error: cannot find pattern \"" << pattern_name - << "\" - check the path in the Options" << endl; - else - convert(image, &_aThickness, _size); - } - - int ThicknessVariationPatternShader::shade(Stroke& stroke) const - { - StrokeInternal::StrokeVertexIterator v, vend; - float *array = 0; - int size; - array = _aThickness; - size = _size; - // } - int vert_size = stroke.strokeVerticesSize(); - int sig = 0; - unsigned index; - const float* originalThickness; - for(v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); - v!=vend; - ++v) - { - originalThickness = v->attribute().getThickness(); - if (_stretch) { - float tmp = v->u()*(_size-1); - index = (unsigned)floor(tmp); - if((tmp-index) > (index+1-tmp)) - ++index; +} + + +ThicknessVariationPatternShader::ThicknessVariationPatternShader(const string pattern_name, float iMinThickness, + float iMaxThickness, bool stretch) +: StrokeShader() +{ + _stretch = stretch; + _minThickness = iMinThickness; + _maxThickness = iMaxThickness; + ImBuf *image = NULL; //soc + vector pathnames; + StringUtils::getPathName(TextureManager::Options::getPatternsPath(), pattern_name, pathnames); + for (vector::const_iterator j = pathnames.begin(); j != pathnames.end(); ++j) { + ifstream ifs(j->c_str()); + if (ifs.is_open()) { + //soc image.load(j->c_str()); + /* OCIO_TODO: support different input color space */ + image = IMB_loadiffname(j->c_str(), 0, NULL); + break; + } } + if (image == NULL) //soc + cerr << "Error: cannot find pattern \"" << pattern_name << "\" - check the path in the Options" << endl; else - index = (unsigned)floor(v->curvilinearAbscissa()); - index %= _size; - float thicknessR = array[index]*originalThickness[0]; - float thicknessL = array[index]*originalThickness[1]; - if(thicknessR+thicknessL < _minThickness) - { - thicknessL = _minThickness/2.f; - thicknessR = _minThickness/2.f; - } - if(thicknessR+thicknessL > _maxThickness) - { - thicknessL = _maxThickness/2.f; - thicknessR = _maxThickness/2.f; - } - if((sig==0) || (sig==vert_size-1)) - v->attribute().setThickness(1, 1); - else - v->attribute().setThickness(thicknessR, thicknessL); - ++sig; - } + convert(image, &_aThickness, _size); +} + + +int ThicknessVariationPatternShader::shade(Stroke& stroke) const +{ + StrokeInternal::StrokeVertexIterator v, vend; + float *array = 0; + int size; + array = _aThickness; + size = _size; + int vert_size = stroke.strokeVerticesSize(); + int sig = 0; + unsigned index; + const float* originalThickness; + for (v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); v != vend; ++v) { + originalThickness = v->attribute().getThickness(); + if (_stretch) { + float tmp = v->u() * (_size - 1); + index = (unsigned)floor(tmp); + if ((tmp - index) > (index + 1 - tmp)) + ++index; + } + else { + index = (unsigned)floor(v->curvilinearAbscissa()); + } + index %= _size; + float thicknessR = array[index] * originalThickness[0]; + float thicknessL = array[index] * originalThickness[1]; + if (thicknessR+thicknessL < _minThickness) { + thicknessL = _minThickness/2.0f; + thicknessR = _minThickness/2.0f; + } + if (thicknessR+thicknessL > _maxThickness) { + thicknessL = _maxThickness/2.0f; + thicknessR = _maxThickness/2.0f; + } + if ((sig == 0) || (sig == vert_size - 1)) + v->attribute().setThickness(1, 1); + else + v->attribute().setThickness(thicknessR, thicknessL); + ++sig; + } return 0; - } - - - static const unsigned NB_VALUE_NOISE = 512; - ThicknessNoiseShader::ThicknessNoiseShader() - :StrokeShader() - {_amplitude=1.f;_scale=1.f/2.f/(float)NB_VALUE_NOISE;} - - ThicknessNoiseShader::ThicknessNoiseShader(float iAmplitude, float iPeriod) - :StrokeShader() - {_amplitude=iAmplitude;_scale=1.f/iPeriod/(float)NB_VALUE_NOISE;} - - - int ThicknessNoiseShader::shade(Stroke& stroke) const - { - StrokeInternal::StrokeVertexIterator v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); - real initU1=v->strokeLength()*real(NB_VALUE_NOISE)+RandGen::drand48()*real(NB_VALUE_NOISE); - real initU2=v->strokeLength()*real(NB_VALUE_NOISE)+RandGen::drand48()*real(NB_VALUE_NOISE); - - real bruit, bruit2; - PseudoNoise mynoise, mynoise2; - for(; - v!=vend; - ++v) - { - - bruit=mynoise.turbulenceSmooth(_scale*v->curvilinearAbscissa()+initU1, - 2); //2 : nbOctaves - bruit2=mynoise2.turbulenceSmooth(_scale*v->curvilinearAbscissa()+initU2, - 2); //2 : nbOctaves - const float *originalThickness = v->attribute().getThickness(); - float r = bruit*_amplitude+originalThickness[0]; - float l = bruit2*_amplitude+originalThickness[1]; - v->attribute().setThickness(r,l); - } - +} + + +static const unsigned NB_VALUE_NOISE = 512; + +ThicknessNoiseShader::ThicknessNoiseShader() : StrokeShader() +{ + _amplitude = 1.0f; + _scale = 1.0f / 2.0f / (float)NB_VALUE_NOISE; +} + +ThicknessNoiseShader::ThicknessNoiseShader(float iAmplitude, float iPeriod) : StrokeShader() +{ + _amplitude = iAmplitude; + _scale = 1.0f / iPeriod / (float)NB_VALUE_NOISE; +} + +int ThicknessNoiseShader::shade(Stroke& stroke) const +{ + StrokeInternal::StrokeVertexIterator v = stroke.strokeVerticesBegin(), vend; + real initU1 = v->strokeLength() * real(NB_VALUE_NOISE) + RandGen::drand48() * real(NB_VALUE_NOISE); + real initU2 = v->strokeLength() * real(NB_VALUE_NOISE) + RandGen::drand48() * real(NB_VALUE_NOISE); + + real bruit, bruit2; + PseudoNoise mynoise, mynoise2; + for (vend = stroke.strokeVerticesEnd(); v != vend; ++v) { + bruit = mynoise.turbulenceSmooth(_scale * v->curvilinearAbscissa() + initU1, 2); // 2 : nbOctaves + bruit2 = mynoise2.turbulenceSmooth(_scale * v->curvilinearAbscissa() + initU2, 2); // 2 : nbOctaves + const float *originalThickness = v->attribute().getThickness(); + float r = bruit * _amplitude + originalThickness[0]; + float l = bruit2 * _amplitude + originalThickness[1]; + v->attribute().setThickness(r, l); + } + return 0; - } - - // - // Color shaders - // - /////////////////////////////////////////////////////////////////////////////// - - int ConstantColorShader::shade(Stroke& stroke) const - { - StrokeInternal::StrokeVertexIterator v, vend; - for(v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); - v!=vend; - ++v) - { - v->attribute().setColor(_color[0], _color[1], _color[2]); - v->attribute().setAlpha(_color[3]); - } +} + +// +// Color shaders +// +/////////////////////////////////////////////////////////////////////////////// + +int ConstantColorShader::shade(Stroke& stroke) const +{ + StrokeInternal::StrokeVertexIterator v, vend; + for (v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); v != vend; ++v) { + v->attribute().setColor(_color[0], _color[1], _color[2]); + v->attribute().setAlpha(_color[3]); + } return 0; - } - - int IncreasingColorShader::shade(Stroke& stroke) const - { - StrokeInternal::StrokeVertexIterator v, vend; - int n=stroke.strokeVerticesSize()-1; - int yo=0; - float newcolor[4]; - for(v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); - v!=vend; - - ++v) - { - for(int i=0; i<4; ++i) - { - newcolor[i] = (1.0-(float)yo/(float)n)*_colorMin[i] + (float)yo/(float)n*_colorMax[i]; - } - v->attribute().setColor(newcolor[0], newcolor[1], newcolor[2]); - v->attribute().setAlpha(newcolor[3]); - ++yo; - } +} + +int IncreasingColorShader::shade(Stroke& stroke) const +{ + StrokeInternal::StrokeVertexIterator v, vend; + int n = stroke.strokeVerticesSize() - 1, yo; + float newcolor[4]; + for (yo = 0, v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); + v != vend; + ++v, ++yo) + { + for (int i = 0; i < 4; ++i) { + newcolor[i] = (1.0 - (float) yo / (float)n) * _colorMin[i] + (float)yo / (float)n * _colorMax[i]; + } + v->attribute().setColor(newcolor[0], newcolor[1], newcolor[2]); + v->attribute().setAlpha(newcolor[3]); + } return 0; - } - - ColorVariationPatternShader::ColorVariationPatternShader(const string pattern_name, - bool stretch) - : StrokeShader() { - _stretch = stretch; - ImBuf *image = 0; //soc - vector pathnames; - StringUtils::getPathName(TextureManager::Options::getPatternsPath(), - pattern_name, - pathnames); - for (vector::const_iterator j = pathnames.begin(); j != pathnames.end(); j++) { - ifstream ifs(j->c_str()); - if (ifs.is_open()) { - /* OCIO_TODO: support different input color space */ - image = IMB_loadiffname(j->c_str(), 0, NULL); //soc - break; - } - } - if (image == 0) //soc - cerr << "Error: cannot find pattern \"" << pattern_name - << "\" - check the path in the Options" << endl; - else - convert(image, &_aVariation, _size); - } - - int ColorVariationPatternShader::shade(Stroke& stroke) const - { - StrokeInternal::StrokeVertexIterator v, vend; - unsigned index; - for(v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); - v!=vend; - ++v) - { - const float *originalColor = v->attribute().getColor(); - if (_stretch) { - float tmp = v->u()*(_size-1); - index = (unsigned)floor(tmp); - if((tmp-index) > (index+1-tmp)) - ++index; +} + +ColorVariationPatternShader::ColorVariationPatternShader(const string pattern_name, bool stretch) : StrokeShader() +{ + _stretch = stretch; + ImBuf *image = NULL; //soc + vector pathnames; + StringUtils::getPathName(TextureManager::Options::getPatternsPath(), pattern_name, pathnames); + for (vector::const_iterator j = pathnames.begin(); j != pathnames.end(); ++j) { + ifstream ifs(j->c_str()); + if (ifs.is_open()) { + /* OCIO_TODO: support different input color space */ + image = IMB_loadiffname(j->c_str(), 0, NULL); //soc + break; + } } + if (image == NULL) //soc + cerr << "Error: cannot find pattern \"" << pattern_name << "\" - check the path in the Options" << endl; else - index = (unsigned)floor(v->curvilinearAbscissa()); - index %= _size; - float r = _aVariation[index]*originalColor[0]; - float g = _aVariation[index]*originalColor[1]; - float b = _aVariation[index]*originalColor[2]; - v->attribute().setColor(r,g,b); - } + convert(image, &_aVariation, _size); +} + +int ColorVariationPatternShader::shade(Stroke& stroke) const +{ + StrokeInternal::StrokeVertexIterator v, vend; + unsigned index; + for (v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); v != vend; ++v) { + const float *originalColor = v->attribute().getColor(); + if (_stretch) { + float tmp = v->u() * (_size - 1); + index = (unsigned)floor(tmp); + if ((tmp - index) > (index + 1 - tmp)) + ++index; + } + else { + index = (unsigned)floor(v->curvilinearAbscissa()); + } + index %= _size; + float r = _aVariation[index] * originalColor[0]; + float g = _aVariation[index] * originalColor[1]; + float b = _aVariation[index] * originalColor[2]; + v->attribute().setColor(r, g, b); + } return 0; - } - - int MaterialColorShader::shade(Stroke& stroke) const - { - Interface0DIterator v, vend; - Functions0D::MaterialF0D fun; - StrokeVertex *sv; - for(v=stroke.verticesBegin(), vend=stroke.verticesEnd(); - v!=vend; - ++v) - { - if (fun(v) < 0) - return -1; - const float *diffuse = fun.result.diffuse(); - sv = dynamic_cast(&(*v)); - sv->attribute().setColor(diffuse[0]*_coefficient, diffuse[1]*_coefficient, diffuse[2]*_coefficient); - sv->attribute().setAlpha(diffuse[3]); - } +} + +int MaterialColorShader::shade(Stroke& stroke) const +{ + Interface0DIterator v, vend; + Functions0D::MaterialF0D fun; + StrokeVertex *sv; + for (v = stroke.verticesBegin(), vend = stroke.verticesEnd(); v != vend; ++v) { + if (fun(v) < 0) + return -1; + const float *diffuse = fun.result.diffuse(); + sv = dynamic_cast(&(*v)); + sv->attribute().setColor(diffuse[0] * _coefficient, diffuse[1] * _coefficient, diffuse[2] * _coefficient); + sv->attribute().setAlpha(diffuse[3]); + } return 0; - } - - - int CalligraphicColorShader::shade(Stroke& stroke) const - { - Interface0DIterator v; - Functions0D::VertexOrientation2DF0D fun; - StrokeVertex* sv; - for(v=stroke.verticesBegin(); - !v.isEnd(); - ++v) - { - if (fun(v) < 0) - return -1; - Vec2f vertexOri(fun.result); - Vec2d ori2d(-vertexOri[1], vertexOri[0]); - ori2d.normalizeSafe(); - real scal = ori2d * _orientation; - sv = dynamic_cast(&(*v)); - if ((scal<0)) - sv->attribute().setColor(0,0,0); - else - sv->attribute().setColor(1,1,1); - } +} + + +int CalligraphicColorShader::shade(Stroke& stroke) const +{ + Interface0DIterator v; + Functions0D::VertexOrientation2DF0D fun; + StrokeVertex *sv; + for (v = stroke.verticesBegin(); !v.isEnd(); ++v) { + if (fun(v) < 0) + return -1; + Vec2f vertexOri(fun.result); + Vec2d ori2d(-vertexOri[1], vertexOri[0]); + ori2d.normalizeSafe(); + real scal = ori2d * _orientation; + sv = dynamic_cast(&(*v)); + if ((scal < 0)) + sv->attribute().setColor(0, 0, 0); + else + sv->attribute().setColor(1, 1, 1); + } return 0; - } - - - ColorNoiseShader::ColorNoiseShader() - :StrokeShader() - {_amplitude=1.f;_scale=1.f/2.f/(float)NB_VALUE_NOISE;} - - ColorNoiseShader::ColorNoiseShader(float iAmplitude, float iPeriod) - :StrokeShader() - {_amplitude=iAmplitude;_scale=1.f/iPeriod/(float)NB_VALUE_NOISE;} - - - int ColorNoiseShader::shade(Stroke& stroke) const - { - StrokeInternal::StrokeVertexIterator v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); - real initU=v->strokeLength()*real(NB_VALUE_NOISE)+RandGen::drand48()*real(NB_VALUE_NOISE); - - real bruit; - PseudoNoise mynoise; - for(; - v!=vend; - ++v) - { - - bruit=mynoise.turbulenceSmooth(_scale*v->curvilinearAbscissa()+initU, - 2); //2 : nbOctaves - const float *originalColor = v->attribute().getColor(); - float r = bruit*_amplitude+originalColor[0]; - float g = bruit*_amplitude+originalColor[1]; - float b = bruit*_amplitude+originalColor[2]; - v->attribute().setColor(r,g,b); - } - +} + + +ColorNoiseShader::ColorNoiseShader() : StrokeShader() +{ + _amplitude = 1.0f; + _scale = 1.0f / 2.0f / (float)NB_VALUE_NOISE; +} + +ColorNoiseShader::ColorNoiseShader(float iAmplitude, float iPeriod) : StrokeShader() +{ + _amplitude = iAmplitude; + _scale = 1.0f / iPeriod / (float)NB_VALUE_NOISE; +} + +int ColorNoiseShader::shade(Stroke& stroke) const +{ + StrokeInternal::StrokeVertexIterator v = stroke.strokeVerticesBegin(), vend; + real initU = v->strokeLength() * real(NB_VALUE_NOISE) + RandGen::drand48() * real(NB_VALUE_NOISE); + + real bruit; + PseudoNoise mynoise; + for (vend = stroke.strokeVerticesEnd(); v != vend; ++v) { + bruit = mynoise.turbulenceSmooth(_scale * v->curvilinearAbscissa() + initU, 2); // 2 : nbOctaves + const float *originalColor = v->attribute().getColor(); + float r = bruit * _amplitude + originalColor[0]; + float g = bruit * _amplitude + originalColor[1]; + float b = bruit * _amplitude + originalColor[2]; + v->attribute().setColor(r, g, b); + } + return 0; - } - - - // - // Texture Shaders - // - /////////////////////////////////////////////////////////////////////////////// - - int TextureAssignerShader::shade(Stroke& stroke) const - { - // getBrushTextureIndex(TEXTURES_DIR "/brushes/charcoalAlpha.bmp", Stroke::HUMID_MEDIUM); - // getBrushTextureIndex(TEXTURES_DIR "/brushes/washbrushAlpha.bmp", Stroke::HUMID_MEDIUM); - // getBrushTextureIndex(TEXTURES_DIR "/brushes/oil.bmp", Stroke::HUMID_MEDIUM); - // getBrushTextureIndex(TEXTURES_DIR "/brushes/oilnoblend.bmp", Stroke::HUMID_MEDIUM); - // getBrushTextureIndex(TEXTURES_DIR "/brushes/charcoalAlpha.bmp", Stroke::DRY_MEDIUM); - // getBrushTextureIndex(TEXTURES_DIR "/brushes/washbrushAlpha.bmp", Stroke::DRY_MEDIUM); - // getBrushTextureIndex(TEXTURES_DIR "/brushes/opaqueDryBrushAlpha.bmp", Stroke::OPAQUE_MEDIUM); - // getBrushTextureIndex(TEXTURES_DIR "/brushes/opaqueBrushAlpha.bmp", Stroke::OPAQUE_MEDIUM); - - TextureManager * instance = TextureManager::getInstance(); - if(!instance) - return 0; - string pathname; - Stroke::MediumType mediumType; - bool hasTips = false; - switch(_textureId) - { - case 0: - //pathname = TextureManager::Options::getBrushesPath() + "/charcoalAlpha.bmp"; +} + + +// +// Texture Shaders +// +/////////////////////////////////////////////////////////////////////////////// + +int TextureAssignerShader::shade(Stroke& stroke) const +{ +#if 0 + getBrushTextureIndex(TEXTURES_DIR "/brushes/charcoalAlpha.bmp", Stroke::HUMID_MEDIUM); + getBrushTextureIndex(TEXTURES_DIR "/brushes/washbrushAlpha.bmp", Stroke::HUMID_MEDIUM); + getBrushTextureIndex(TEXTURES_DIR "/brushes/oil.bmp", Stroke::HUMID_MEDIUM); + getBrushTextureIndex(TEXTURES_DIR "/brushes/oilnoblend.bmp", Stroke::HUMID_MEDIUM); + getBrushTextureIndex(TEXTURES_DIR "/brushes/charcoalAlpha.bmp", Stroke::DRY_MEDIUM); + getBrushTextureIndex(TEXTURES_DIR "/brushes/washbrushAlpha.bmp", Stroke::DRY_MEDIUM); + getBrushTextureIndex(TEXTURES_DIR "/brushes/opaqueDryBrushAlpha.bmp", Stroke::OPAQUE_MEDIUM); + getBrushTextureIndex(TEXTURES_DIR "/brushes/opaqueBrushAlpha.bmp", Stroke::OPAQUE_MEDIUM); +#endif + + TextureManager *instance = TextureManager::getInstance(); + if (!instance) + return 0; + string pathname; + Stroke::MediumType mediumType; + bool hasTips = false; + switch (_textureId) { + case 0: + //pathname = TextureManager::Options::getBrushesPath() + "/charcoalAlpha.bmp"; pathname = "/charcoalAlpha.bmp"; - mediumType = Stroke::HUMID_MEDIUM; - hasTips = false; - break; - case 1: - pathname = "/washbrushAlpha.bmp"; - mediumType = Stroke::HUMID_MEDIUM; - hasTips = true; - break; - case 2: - pathname = "/oil.bmp"; - mediumType = Stroke::HUMID_MEDIUM; - hasTips = true; - break; - case 3: - pathname = "/oilnoblend.bmp"; - mediumType = Stroke::HUMID_MEDIUM; - hasTips = true; - break; - case 4: - pathname = "/charcoalAlpha.bmp"; - mediumType = Stroke::DRY_MEDIUM; - hasTips = false; - break; - case 5: - mediumType = Stroke::DRY_MEDIUM; - hasTips = true; - break; - case 6: - pathname = "/opaqueDryBrushAlpha.bmp"; - mediumType = Stroke::OPAQUE_MEDIUM; - hasTips = true; - break; - case 7: - pathname = "/opaqueBrushAlpha.bmp"; - mediumType = Stroke::OPAQUE_MEDIUM; - hasTips = true; - break; - default: - pathname = "/smoothAlpha.bmp"; - mediumType = Stroke::OPAQUE_MEDIUM; - hasTips = false; - break; - } - unsigned int texId = instance->getBrushTextureIndex(pathname, mediumType); - stroke.setMediumType(mediumType); - stroke.setTips(hasTips); - stroke.setTextureId(texId); + mediumType = Stroke::HUMID_MEDIUM; + hasTips = false; + break; + case 1: + pathname = "/washbrushAlpha.bmp"; + mediumType = Stroke::HUMID_MEDIUM; + hasTips = true; + break; + case 2: + pathname = "/oil.bmp"; + mediumType = Stroke::HUMID_MEDIUM; + hasTips = true; + break; + case 3: + pathname = "/oilnoblend.bmp"; + mediumType = Stroke::HUMID_MEDIUM; + hasTips = true; + break; + case 4: + pathname = "/charcoalAlpha.bmp"; + mediumType = Stroke::DRY_MEDIUM; + hasTips = false; + break; + case 5: + mediumType = Stroke::DRY_MEDIUM; + hasTips = true; + break; + case 6: + pathname = "/opaqueDryBrushAlpha.bmp"; + mediumType = Stroke::OPAQUE_MEDIUM; + hasTips = true; + break; + case 7: + pathname = "/opaqueBrushAlpha.bmp"; + mediumType = Stroke::OPAQUE_MEDIUM; + hasTips = true; + break; + default: + pathname = "/smoothAlpha.bmp"; + mediumType = Stroke::OPAQUE_MEDIUM; + hasTips = false; + break; + } + unsigned int texId = instance->getBrushTextureIndex(pathname, mediumType); + stroke.setMediumType(mediumType); + stroke.setTips(hasTips); + stroke.setTextureId(texId); return 0; - } - - // FIXME - int StrokeTextureShader::shade(Stroke& stroke) const - { - TextureManager * instance = TextureManager::getInstance(); - if(!instance) - return 0; - string pathname = TextureManager::Options::getBrushesPath() + "/" + _texturePath; - unsigned int texId = instance->getBrushTextureIndex(pathname, _mediumType); - stroke.setMediumType(_mediumType); - stroke.setTips(_tips); - stroke.setTextureId(texId); +} + +// FIXME +int StrokeTextureShader::shade(Stroke& stroke) const +{ + TextureManager *instance = TextureManager::getInstance(); + if (!instance) + return 0; + string pathname = TextureManager::Options::getBrushesPath() + "/" + _texturePath; + unsigned int texId = instance->getBrushTextureIndex(pathname, _mediumType); + stroke.setMediumType(_mediumType); + stroke.setTips(_tips); + stroke.setTextureId(texId); return 0; - } - - // - // Geometry Shaders - // - /////////////////////////////////////////////////////////////////////////////// - - int BackboneStretcherShader::shade(Stroke& stroke) const - { - float l=stroke.getLength2D(); - if(l <= 1e-6) - return 0; - - StrokeInternal::StrokeVertexIterator v0=stroke.strokeVerticesBegin(); - StrokeInternal::StrokeVertexIterator v1=v0;++v1; - StrokeInternal::StrokeVertexIterator vn=stroke.strokeVerticesEnd();--vn; - StrokeInternal::StrokeVertexIterator vn_1=vn;--vn_1; - - - Vec2d first((v0)->x(), (v0)->y()); - Vec2d last((vn)->x(), (vn)->y()); - - Vec2d d1(first-Vec2d((v1)->x(), (v1)->y())); - d1.normalize(); - Vec2d dn(last-Vec2d((vn_1)->x(), (vn_1)->y())); - dn.normalize(); - - Vec2d newFirst(first+_amount*d1); - (v0)->setPoint(newFirst[0], newFirst[1]); - Vec2d newLast(last+_amount*dn); - (vn)->setPoint(newLast[0], newLast[1]); +} + +// +// Geometry Shaders +// +/////////////////////////////////////////////////////////////////////////////// + +int BackboneStretcherShader::shade(Stroke& stroke) const +{ + float l = stroke.getLength2D(); + if (l <= 1.0e-6) + return 0; + + StrokeInternal::StrokeVertexIterator v0 = stroke.strokeVerticesBegin(); + StrokeInternal::StrokeVertexIterator v1 = v0; + ++v1; + StrokeInternal::StrokeVertexIterator vn = stroke.strokeVerticesEnd(); + --vn; + StrokeInternal::StrokeVertexIterator vn_1 = vn; + --vn_1; + + + Vec2d first((v0)->x(), (v0)->y()); + Vec2d last((vn)->x(), (vn)->y()); + + Vec2d d1(first-Vec2d((v1)->x(), (v1)->y())); + d1.normalize(); + Vec2d dn(last-Vec2d((vn_1)->x(), (vn_1)->y())); + dn.normalize(); + + Vec2d newFirst(first + _amount * d1); + (v0)->setPoint(newFirst[0], newFirst[1]); + Vec2d newLast(last + _amount * dn); + (vn)->setPoint(newLast[0], newLast[1]); stroke.UpdateLength(); return 0; - } +} - int SamplingShader::shade(Stroke& stroke) const - { - stroke.Resample(_sampling); +int SamplingShader::shade(Stroke& stroke) const +{ + stroke.Resample(_sampling); return 0; - } - - int ExternalContourStretcherShader::shade(Stroke& stroke) const - { - //float l=stroke.getLength2D(); - Interface0DIterator it=stroke.verticesBegin(); - Functions0D::Normal2DF0D fun; - StrokeVertex* sv; - while (!it.isEnd()) - { - if (fun(it) < 0) - return -1; - Vec2f n(fun.result); - sv = dynamic_cast(&(*it)); - Vec2d newPoint(sv->x()+_amount*n.x(), sv->y()+_amount*n.y()); - sv->setPoint(newPoint[0], newPoint[1]); - ++it; - } +} + +int ExternalContourStretcherShader::shade(Stroke& stroke) const +{ + //float l = stroke.getLength2D(); + Interface0DIterator it; + Functions0D::Normal2DF0D fun; + StrokeVertex* sv; + for (it = stroke.verticesBegin(); !it.isEnd(); ++it) { + if (fun(it) < 0) + return -1; + Vec2f n(fun.result); + sv = dynamic_cast(&(*it)); + Vec2d newPoint(sv->x() + _amount * n.x(), sv->y() + _amount * n.y()); + sv->setPoint(newPoint[0], newPoint[1]); + } stroke.UpdateLength(); return 0; - } - - int BSplineShader::shade(Stroke& stroke) const - { - if(stroke.strokeVerticesSize() < 4) - return 0; - - // Find the new vertices - vector newVertices; - double t=0.f; - float _sampling = 5.f; - - StrokeInternal::StrokeVertexIterator p0,p1,p2,p3, end; - p0 = stroke.strokeVerticesBegin(); - p1 = p0; - p2 = p1; - p3 = p2; - end = stroke.strokeVerticesEnd(); - double a[4],b[4]; - int n=0; - while(p1 != end) - { - // if(p1 == end) - // p1 = p0; - if(p2 == end) - p2 = p1; - if(p3 == end) - p3 = p2; - // compute new matrix - a[0] = (-(p0)->x()+3*(p1)->x()-3*(p2)->x()+(p3)->x())/6.0; - a[1] = (3*(p0)->x()-6*(p1)->x()+3*(p2)->x())/6.0; - a[2] = (-3*(p0)->x()+3*(p2)->x())/6.0; - a[3] = ((p0)->x()+4*(p1)->x()+(p2)->x())/6.0; - - b[0] = (-(p0)->y()+3*(p1)->y()-3*(p2)->y()+(p3)->y())/6.0; - b[1] = (3*(p0)->y()-6*(p1)->y()+3*(p2)->y())/6.0; - b[2] = (-3*(p0)->y()+3*(p2)->y())/6.0; - b[3] = ((p0)->y()+4*(p1)->y()+(p2)->y())/6.0; - - - // draw the spline depending on resolution: - Vec2d p1p2((p2)->x()-(p1)->x(), (p2)->y()-(p1)->y()); - double norm = p1p2.norm(); - //t = _sampling/norm; - t=0; - while(t<1) - { - newVertices.push_back(Vec2d((a[3] + t*(a[2] + t*(a[1] + t*a[0]))), - (b[3] + t*(b[2] + t*(b[1] + t*b[0]))))); - t = t + _sampling/norm; - } - if(n > 2) - { - ++p0; - ++p1; - ++p2; - ++p3; - } - else - { - if(n==0) - ++p3; - if(n==1) - {++p2;++p3;} - if(n==2) - {++p1;++p2;++p3;} - ++n; - } - } - //last point: - newVertices.push_back(Vec2d((p0)->x(), (p0)->y())); - - int originalSize = newVertices.size(); - _sampling = stroke.ComputeSampling(originalSize); - - // Resample and set x,y coordinates - stroke.Resample(_sampling); - int newsize = stroke.strokeVerticesSize(); - - int nExtraVertex=0; - if(newsize < originalSize) - cerr << "Warning: unsufficient resampling" << endl; - else - { - nExtraVertex = newsize - originalSize; - } - - // assigns the new coordinates: - vector::iterator p,pend; - p=newVertices.begin();pend=newVertices.end(); - vector::iterator last = p; - n=0; - StrokeInternal::StrokeVertexIterator it=stroke.strokeVerticesBegin(), itend=stroke.strokeVerticesEnd(); - it=stroke.strokeVerticesBegin(); - for(; - ((it!=itend) && (p!=pend)); - ++it) - { - it->setX(p->x()); - it->setY(p->y()); - last = p; - ++p; - ++n; - } - // nExtraVertex should stay unassigned - for(int i=0; i< nExtraVertex; ++i) - { - it->setX(last->x()); - it->setY(last->y()); - if(it.isEnd()) - cerr << "Warning: Problem encountered while creating B-spline" << endl; - ++it; - ++n; - } +} + +int BSplineShader::shade(Stroke& stroke) const +{ + if (stroke.strokeVerticesSize() < 4) + return 0; + + // Find the new vertices + vector newVertices; + double t = 0.0; + float _sampling = 5.0f; + + StrokeInternal::StrokeVertexIterator p0, p1, p2, p3, end; + p0 = stroke.strokeVerticesBegin(); + p1 = p0; + p2 = p1; + p3 = p2; + end = stroke.strokeVerticesEnd(); + double a[4], b[4]; + int n = 0; + while (p1 != end) { +#if 0 + if (p1 == end) + p1 = p0; +#endif + if (p2 == end) + p2 = p1; + if (p3 == end) + p3 = p2; + // compute new matrix + a[0] = (-(p0)->x() + 3 * (p1)->x() - 3 * (p2)->x() + (p3)->x()) / 6.0; + a[1] = (3 * (p0)->x() - 6 * (p1)->x() + 3 * (p2)->x()) / 6.0; + a[2] = (-3 * (p0)->x() + 3 * (p2)->x()) / 6.0; + a[3] = ((p0)->x() + 4 * (p1)->x() + (p2)->x()) / 6.0; + + b[0] = (-(p0)->y() + 3 * (p1)->y() - 3 * (p2)->y() + (p3)->y()) / 6.0; + b[1] = (3 * (p0)->y() - 6 * (p1)->y() + 3 * (p2)->y()) / 6.0; + b[2] = (-3 * (p0)->y() + 3 * (p2)->y()) / 6.0; + b[3] = ((p0)->y() + 4 * (p1)->y() + (p2)->y()) / 6.0; + + // draw the spline depending on resolution: + Vec2d p1p2((p2)->x() - (p1)->x(), (p2)->y() - (p1)->y()); + double norm = p1p2.norm(); + //t = _sampling / norm; + t = 0; + while (t < 1) { + newVertices.push_back(Vec2d((a[3] + t * (a[2] + t * (a[1] + t * a[0]))), + (b[3] + t * (b[2] + t * (b[1] + t * b[0]))))); + t = t + _sampling / norm; + } + if (n > 2) { + ++p0; + ++p1; + ++p2; + ++p3; + } + else { + if (n == 0) + ++p3; + if (n == 1) { + ++p2; + ++p3; + } + if (n == 2) { + ++p1; + ++p2; + ++p3; + } + ++n; + } + } + //last point: + newVertices.push_back(Vec2d((p0)->x(), (p0)->y())); + + int originalSize = newVertices.size(); + _sampling = stroke.ComputeSampling(originalSize); + + // Resample and set x,y coordinates + stroke.Resample(_sampling); + int newsize = stroke.strokeVerticesSize(); + + int nExtraVertex = 0; + if (newsize < originalSize) { + cerr << "Warning: unsufficient resampling" << endl; + } + else { + nExtraVertex = newsize - originalSize; + } + + // assigns the new coordinates: + vector::iterator p = newVertices.begin(), pend = newVertices.end(); + vector::iterator last = p; + n = 0; + StrokeInternal::StrokeVertexIterator it, itend; + for (it = stroke.strokeVerticesBegin(), itend = stroke.strokeVerticesEnd(); + (it != itend) && (p != pend); + ++it, ++p, ++n) + { + it->setX(p->x()); + it->setY(p->y()); + last = p; + } + + // nExtraVertex should stay unassigned + for (int i = 0; i < nExtraVertex; ++i, ++it, ++n) { + it->setX(last->x()); + it->setY(last->y()); + if (it.isEnd()) { + // XXX Shouldn't we break in this case??? + cerr << "Warning: Problem encountered while creating B-spline" << endl; + } + } stroke.UpdateLength(); return 0; - } - - //!! Bezier curve stroke shader - int BezierCurveShader::shade(Stroke& stroke) const - { - if(stroke.strokeVerticesSize() < 4) - return 0; - - // Build the Bezier curve from this set of data points: - vector data; - StrokeInternal::StrokeVertexIterator v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); - data.push_back(Vec2d(v->x(), v->y()));//first one - StrokeInternal::StrokeVertexIterator previous = v;++v; - for(; - v!=vend; - ++v) - { - if(!((fabs(v->x() -(previous)->x())y() - (previous)->y())x(), v->y())); - previous = v; - } - - // Vec2d tmp;bool equal=false; - // if(data.front() == data.back()) - // { - // tmp = data.back(); - // data.pop_back(); - // equal=true; - // } - // here we build the bezier curve - BezierCurve bcurve(data, _error); - - // bad performances are here !!! // FIXME - vector CurveVertices; - vector& bsegments = bcurve.segments(); - vector::iterator s=bsegments.begin(),send=bsegments.end(); - vector& segmentsVertices = (*s)->vertices(); - vector::iterator p,pend; - // first point - CurveVertices.push_back(segmentsVertices[0]); - for(; - s!=send; - ++s) - { - segmentsVertices = (*s)->vertices(); - p=segmentsVertices.begin(); pend=segmentsVertices.end(); - ++p; - for(; - p!=pend; - ++p) - { - CurveVertices.push_back((*p)); - } - } - - //if(equal) - // if(data.back() == data.front()) - // { - // vector::iterator d=data.begin(), dend=data.end(); - // cout << "ending point = starting point" << endl; - // cout << "---------------DATA----------" << endl; - // for(; - // d!=dend; - // ++d) - // { - // cout << d->x() << "-" << d->y() << endl; - // } - // cout << "--------------BEZIER RESULT----------" << endl; - // d=CurveVertices.begin(), dend=CurveVertices.end(); - // for(;d!=dend;++d) - // { - // cout << d->x() << "-" << d->y() << endl; - // } - // } - - // Resample the Stroke depending on the number of - // vertices of the bezier curve: - int originalSize = CurveVertices.size(); - //float sampling = stroke.ComputeSampling(originalSize); - //stroke.Resample(sampling); - stroke.Resample(originalSize); - int newsize = stroke.strokeVerticesSize(); - int nExtraVertex=0; - if(newsize < originalSize) - cerr << "Warning: unsufficient resampling" << endl; - else - { - //cout << "Oversampling" << endl; - nExtraVertex = newsize - originalSize; - if(nExtraVertex != 0) - cout << "Bezier Shader : Stroke " << stroke.getId() << " have not been resampled" << endl; - } - - // assigns the new coordinates: - p=CurveVertices.begin();pend=CurveVertices.end(); - vector::iterator last = p; - int n=0; - StrokeInternal::StrokeVertexIterator it=stroke.strokeVerticesBegin(), itend=stroke.strokeVerticesEnd(); - // while(p!=pend) - // { - // ++n; - // ++p; - // } - it=stroke.strokeVerticesBegin(); - for(; - ((it!=itend) && (p!=pend)); - ++it) - { - it->setX(p->x()); - it->setY(p->y()); - // double x = p->x(); - // double y = p->y(); - // cout << "x = " << x << "-" << "y = " << y << endl; - last = p; - ++p; - ++n; - } +} + +//!! Bezier curve stroke shader +int BezierCurveShader::shade(Stroke& stroke) const +{ + if (stroke.strokeVerticesSize() < 4) + return 0; + + // Build the Bezier curve from this set of data points: + vector data; + StrokeInternal::StrokeVertexIterator v = stroke.strokeVerticesBegin(), vend; + data.push_back(Vec2d(v->x(), v->y())); //first one + StrokeInternal::StrokeVertexIterator previous = v; + ++v; + for (vend = stroke.strokeVerticesEnd(); v != vend; ++v) { + if (!((fabs(v->x() - (previous)->x()) < M_EPSILON) && ((fabs(v->y() - (previous)->y()) < M_EPSILON)))) + data.push_back(Vec2d(v->x(), v->y())); + previous = v; + } + +#if 0 + Vec2d tmp; + bool equal = false; + if (data.front() == data.back()) { + tmp = data.back(); + data.pop_back(); + equal = true; + } +#endif + // here we build the bezier curve + BezierCurve bcurve(data, _error); + + // bad performances are here !!! // FIXME + vector CurveVertices; + vector& bsegments = bcurve.segments(); + vector::iterator s = bsegments.begin(), send; + vector& segmentsVertices = (*s)->vertices(); + vector::iterator p, pend; + // first point + CurveVertices.push_back(segmentsVertices[0]); + for (send = bsegments.end(); s != send; ++s) { + segmentsVertices = (*s)->vertices(); + p = segmentsVertices.begin(); + ++p; + for (pend = segmentsVertices.end(); p != pend; ++p) { + CurveVertices.push_back((*p)); + } + } + +#if 0 + if (equal) { + if (data.back() == data.front()) { + vector::iterator d = data.begin(), dend; + cout << "ending point = starting point" << endl; + cout << "---------------DATA----------" << endl; + for (dend = data.end(); d != dend; ++d) { + cout << d->x() << "-" << d->y() << endl; + } + cout << "--------------BEZIER RESULT----------" << endl; + for (d = CurveVertices.begin(), dend = CurveVertices.end(); d != dend; ++d) { + cout << d->x() << "-" << d->y() << endl; + } + } + } +#endif + + // Resample the Stroke depending on the number of vertices of the bezier curve: + int originalSize = CurveVertices.size(); +#if 0 + float sampling = stroke.ComputeSampling(originalSize); + stroke.Resample(sampling); +#endif + stroke.Resample(originalSize); + int newsize = stroke.strokeVerticesSize(); + int nExtraVertex = 0; + if (newsize < originalSize) { + cerr << "Warning: unsufficient resampling" << endl; + } + else { + //cout << "Oversampling" << endl; + nExtraVertex = newsize - originalSize; + if (nExtraVertex != 0) + cout << "Bezier Shader : Stroke " << stroke.getId() << " have not been resampled" << endl; + } + + // assigns the new coordinates: + p = CurveVertices.begin(); + vector::iterator last = p; + int n; + StrokeInternal::StrokeVertexIterator it, itend; +#if 0 + for (; p != pend; ++n, ++p); +#endif + for (n = 0, it = stroke.strokeVerticesBegin(), itend = stroke.strokeVerticesEnd(), pend = CurveVertices.end(); + (it != itend) && (p != pend); + ++it, ++p, ++n) + { + it->setX(p->x()); + it->setY(p->y()); +#if 0 + double x = p->x(); + double y = p->y(); + cout << "x = " << x << "-" << "y = " << y << endl; +#endif + last = p; + } stroke.UpdateLength(); - // Deal with extra vertices: - if(nExtraVertex == 0) - return 0; - - // nExtraVertex should stay unassigned - vector attributes; - vector verticesToRemove; - for(int i=0; i< nExtraVertex; ++i) - { - verticesToRemove.push_back(&(*it)); - if(it.isEnd()) - cout << "fucked up" << endl; - ++it; - ++n; - } - it=stroke.strokeVerticesBegin(); - for(; - it!=itend; - ++it) - { - attributes.push_back(it->attribute()); - } - - for(vector::iterator vr=verticesToRemove.begin(), vrend=verticesToRemove.end(); - vr!=vrend; - ++vr) - { - stroke.RemoveVertex(*vr); - } - it=stroke.strokeVerticesBegin(); - itend=stroke.strokeVerticesEnd(); - vector::iterator a=attributes.begin(), aend=attributes.end(); - int index = 0; - int index1 = (int)floor((float)originalSize/2.0); - int index2 = index1+nExtraVertex; - for(; - (it!=itend) && (a!=aend); - ++it) - { - (it)->setAttribute(*a); - if((index <= index1)||(index>index2)) - ++a; - ++index; - } + // Deal with extra vertices: + if (nExtraVertex == 0) + return 0; + + // nExtraVertex should stay unassigned + vector attributes; + vector verticesToRemove; + for (int i = 0; i < nExtraVertex; ++i, ++it, ++n) { + verticesToRemove.push_back(&(*it)); + if (it.isEnd()) { + // XXX Shocking! :P Shouldn't we break in this case??? + cout << "fucked up" << endl; + } + } + for (it = stroke.strokeVerticesBegin(); it != itend; ++it) { + attributes.push_back(it->attribute()); + } + + for (vector::iterator vr = verticesToRemove.begin(), vrend = verticesToRemove.end(); + vr != vrend; + ++vr) + { + stroke.RemoveVertex(*vr); + } + + vector::iterator a = attributes.begin(), aend = attributes.end(); + int index = 0; + int index1 = (int)floor((float)originalSize / 2.0); + int index2 = index1 + nExtraVertex; + for (it = stroke.strokeVerticesBegin(), itend = stroke.strokeVerticesEnd(); + (it != itend) && (a != aend); + ++it) + { + (it)->setAttribute(*a); + if ((index <= index1) || (index > index2)) + ++a; + ++index; + } return 0; - } +} - int InflateShader::shade(Stroke& stroke) const - { - // we're computing the curvature variance of the stroke.(Combo 5) - // If it's too high, forget about it - Functions1D::Curvature2DAngleF1D fun; +int InflateShader::shade(Stroke& stroke) const +{ + // we're computing the curvature variance of the stroke. (Combo 5) + // If it's too high, forget about it + Functions1D::Curvature2DAngleF1D fun; if (fun(stroke) < 0) - return -1; + return -1; if (fun.result > _curvatureThreshold) - return 0; - - Functions0D::VertexOrientation2DF0D ori_fun; - Functions0D::Curvature2DAngleF0D curv_fun; - Functions1D::Normal2DF1D norm_fun; - Interface0DIterator it=stroke.verticesBegin(); - StrokeVertex* sv; - while (!it.isEnd()) - { - if (ori_fun(it) < 0) - return -1; - Vec2f ntmp(ori_fun.result); - Vec2f n(ntmp.y(), -ntmp.x()); - if (norm_fun(stroke) < 0) - return -1; - Vec2f strokeN(norm_fun.result); - if(n*strokeN < 0) - { - n[0] = -n[0]; - n[1] = -n[1]; - } - sv = dynamic_cast(&(*it)); - float u=sv->u(); - float t = 4.f*(0.25f - (u-0.5)*(u-0.5)); - if (curv_fun(it) < 0) - return -1; - float curvature_coeff = (M_PI-curv_fun.result)/M_PI; - Vec2d newPoint(sv->x()+curvature_coeff*t*_amount*n.x(), sv->y()+curvature_coeff*t*_amount*n.y()); - sv->setPoint(newPoint[0], newPoint[1]); - ++it; - } + return 0; + + Functions0D::VertexOrientation2DF0D ori_fun; + Functions0D::Curvature2DAngleF0D curv_fun; + Functions1D::Normal2DF1D norm_fun; + Interface0DIterator it; + StrokeVertex *sv; + for (it = stroke.verticesBegin(); !it.isEnd(); ++it) { + if (ori_fun(it) < 0) + return -1; + Vec2f ntmp(ori_fun.result); + Vec2f n(ntmp.y(), -ntmp.x()); + if (norm_fun(stroke) < 0) + return -1; + Vec2f strokeN(norm_fun.result); + if (n*strokeN < 0) { + n[0] = -n[0]; + n[1] = -n[1]; + } + sv = dynamic_cast(&(*it)); + float u = sv->u(); + float t = 4.0f * (0.25f - (u - 0.5) * (u - 0.5)); + if (curv_fun(it) < 0) + return -1; + float curvature_coeff = (M_PI - curv_fun.result) / M_PI; + Vec2d newPoint(sv->x() + curvature_coeff * t * _amount * n.x(), + sv->y() + curvature_coeff * t * _amount * n.y()); + sv->setPoint(newPoint[0], newPoint[1]); + } stroke.UpdateLength(); return 0; - } - - class CurvePiece - { - public: - StrokeInternal::StrokeVertexIterator _begin; - StrokeInternal::StrokeVertexIterator _last; - Vec2d A; - Vec2d B; - int size; - float _error; - - CurvePiece(StrokeInternal::StrokeVertexIterator b, StrokeInternal::StrokeVertexIterator l, int iSize) - { - _begin = b; - _last = l; - A = Vec2d((_begin)->x(),(_begin)->y()); - B = Vec2d((_last)->x(),(_last)->y()); - size = iSize; - } - - float error() - { - float maxE = 0.f; - for(StrokeInternal::StrokeVertexIterator it=_begin; - it!=_last; - ++it) +} + +class CurvePiece +{ +public: + StrokeInternal::StrokeVertexIterator _begin; + StrokeInternal::StrokeVertexIterator _last; + Vec2d A; + Vec2d B; + int size; + float _error; + + CurvePiece(StrokeInternal::StrokeVertexIterator b, StrokeInternal::StrokeVertexIterator l, int iSize) { - Vec2d P(it->x(), it->y()); - float d = GeomUtils::distPointSegment(P,A,B); - if(d > maxE) - maxE = d; + _begin = b; + _last = l; + A = Vec2d((_begin)->x(), (_begin)->y()); + B = Vec2d((_last)->x(), (_last)->y()); + size = iSize; } - _error = maxE; - return maxE; - } - //! Subdivides the curve into two pieces. - // The first piece is this same object (modified) - // the second piece is returned by the method - CurvePiece * subdivide() - { - StrokeInternal::StrokeVertexIterator it=_begin; - int actualSize = 1; - for(int i=0; ix(), it->y()); + float d = GeomUtils::distPointSegment(P, A, B); + if (d > maxE) + maxE = d; + } + _error = maxE; + return maxE; + } + + //! Subdivides the curve into two pieces. + // The first piece is this same object (modified) + // The second piece is returned by the method + CurvePiece *subdivide() + { + StrokeInternal::StrokeVertexIterator it = _begin; + int actualSize = (size > 1) ? size / 2 : 1; + for (int i = 0; i <= actualSize; ++it, ++i); + + CurvePiece *second = new CurvePiece(it, _last, size - actualSize + 1); + size = actualSize; + _last = it; + B = Vec2d((_last)->x(), (_last)->y()); + return second; + } +}; + +int PolygonalizationShader::shade(Stroke& stroke) const +{ + vector _pieces; + vector _results; + vector::iterator cp, cpend; + + // Compute first approx: + StrokeInternal::StrokeVertexIterator a = stroke.strokeVerticesBegin(); + StrokeInternal::StrokeVertexIterator b = stroke.strokeVerticesEnd(); + --b; + int size = stroke.strokeVerticesSize(); + + CurvePiece *piece = new CurvePiece(a, b, size); + _pieces.push_back(piece); + + while (!_pieces.empty()) { + piece = _pieces.back(); + _pieces.pop_back(); + if (piece->error() > _error) { + CurvePiece *second = piece->subdivide(); + _pieces.push_back(second); + _pieces.push_back(piece); + } + else { + _results.push_back(piece); + } + } + + // actually modify the geometry for each piece: + for (cp = _results.begin(), cpend = _results.end(); cp != cpend; ++cp) { + a = (*cp)->_begin; + b = (*cp)->_last; + Vec2d u = (*cp)->B - (*cp)->A; + Vec2d n(u[1], -u[0]); + n.normalize(); + //Vec2d n(0, 0); + float offset = ((*cp)->_error); + StrokeInternal::StrokeVertexIterator v; + for (v = a; v != b; ++v) { + v->setPoint((*cp)->A.x() + v->u() * u.x() + n.x() * offset, + (*cp)->A.y() + v->u() * u.y() + n.y() * offset); + } +#if 0 + u.normalize(); + (*a)->setPoint((*a)->x() - u.x() * 10, (*a)->y() - u.y() * 10); +#endif } - CurvePiece * second = new CurvePiece(it, _last, size-actualSize+1); - size = actualSize; - _last = it; - B = Vec2d((_last)->x(), (_last)->y()); - return second; - } - }; - - int PolygonalizationShader::shade(Stroke& stroke) const - { - vector _pieces; - vector _results; - vector::iterator cp,cpend; - - // Compute first approx: - StrokeInternal::StrokeVertexIterator a=stroke.strokeVerticesBegin(); - StrokeInternal::StrokeVertexIterator b=stroke.strokeVerticesEnd();--b; - int size = stroke.strokeVerticesSize(); - - CurvePiece * piece = new CurvePiece(a,b,size); - _pieces.push_back(piece); - - while(!_pieces.empty()) - { - piece = _pieces.back();_pieces.pop_back(); - if(piece->error() > _error) - { - CurvePiece * second = piece->subdivide(); - _pieces.push_back(second); - _pieces.push_back(piece); - } - else - { - _results.push_back(piece); - } - } - - // actually modify the geometry for each piece: - for(cp=_results.begin(), cpend=_results.end(); - cp!=cpend; - ++cp) - { - a = (*cp)->_begin; - b = (*cp)->_last; - Vec2d u = (*cp)->B-(*cp)->A; - Vec2d n(u[1], -u[0]);n.normalize(); - //Vec2d n(0,0); - float offset = ((*cp)->_error); - StrokeInternal::StrokeVertexIterator v,vlast; - for(v=a; - v!=b; - ++v) - { - v->setPoint((*cp)->A.x()+v->u()*u.x()+n.x()*offset, (*cp)->A.y()+v->u()*u.y()+n.y()*offset); - } - // u.normalize(); - // (*a)->setPoint((*a)->x()-u.x()*10, (*a)->y()-u.y()*10); - } stroke.UpdateLength(); - // delete stuff - for(cp=_results.begin(), cpend=_results.end(); - cp!=cpend; - ++cp) - { - delete (*cp); - } - _results.clear(); + // delete stuff + for (cp = _results.begin(), cpend = _results.end(); cp != cpend; ++cp) { + delete (*cp); + } + _results.clear(); return 0; - } - - int GuidingLinesShader::shade(Stroke& stroke) const - { - Functions1D::Normal2DF1D norm_fun; - StrokeInternal::StrokeVertexIterator a=stroke.strokeVerticesBegin(); - StrokeInternal::StrokeVertexIterator b=stroke.strokeVerticesEnd();--b; - int size = stroke.strokeVerticesSize(); - CurvePiece piece(a,b,size); - - Vec2d u = piece.B-piece.A; - Vec2f n(u[1], -u[0]);n.normalize(); +} + +int GuidingLinesShader::shade(Stroke& stroke) const +{ + Functions1D::Normal2DF1D norm_fun; + StrokeInternal::StrokeVertexIterator a = stroke.strokeVerticesBegin(); + StrokeInternal::StrokeVertexIterator b = stroke.strokeVerticesEnd(); + --b; + int size = stroke.strokeVerticesSize(); + CurvePiece piece(a, b, size); + + Vec2d u = piece.B - piece.A; + Vec2f n(u[1], -u[0]); + n.normalize(); if (norm_fun(stroke) < 0) - return -1; - Vec2f strokeN(norm_fun.result); - if(n*strokeN < 0) - { - n[0] = -n[0]; - n[1] = -n[1]; - } - float offset = (piece.error())/2.f*_offset; - StrokeInternal::StrokeVertexIterator v=a,vend=stroke.strokeVerticesEnd(); - for(; - v!=vend; - ++v) - { - v->setPoint(piece.A.x()+v->u()*u.x()+n.x()*offset, piece.A.y()+v->u()*u.y()+n.y()*offset); - } + return -1; + Vec2f strokeN(norm_fun.result); + if (n * strokeN < 0) { + n[0] = -n[0]; + n[1] = -n[1]; + } + float offset = (piece.error()) / 2.0f * _offset; + StrokeInternal::StrokeVertexIterator v, vend; + for (v = a, vend = stroke.strokeVerticesEnd(); v != vend; ++v) { + v->setPoint(piece.A.x() + v->u() * u.x() + n.x() * offset, + piece.A.y() + v->u() * u.y() + n.y() * offset); + } stroke.UpdateLength(); return 0; - } - - ///////////////////////////////////////// - // - // Tip Remover - // - ///////////////////////////////////////// - - - TipRemoverShader::TipRemoverShader(real tipLength) - : StrokeShader() - { - _tipLength = tipLength; - } - - int - TipRemoverShader::shade(Stroke& stroke) const - { - int originalSize = stroke.strokeVerticesSize(); - - if(originalSize<4) - return 0; - - StrokeInternal::StrokeVertexIterator v, vend; - vector verticesToRemove; - vector oldAttributes; - v=stroke.strokeVerticesBegin(); vend=stroke.strokeVerticesEnd(); - for(; - v!=vend; - ++v) - { - if ((v->curvilinearAbscissa()<_tipLength) || - (v->strokeLength()-v->curvilinearAbscissa()<_tipLength)) - { - verticesToRemove.push_back(&(*v)); - } - oldAttributes.push_back(v->attribute()); - } - - if(originalSize-verticesToRemove.size() < 2) - return 0; - - vector::iterator sv=verticesToRemove.begin(), svend=verticesToRemove.end(); - for(; - sv!=svend; - ++sv) - { - stroke.RemoveVertex((*sv)); - } - - // Resample so that our new stroke have the same - // number of vertices than before - stroke.Resample(originalSize); - - if((int)stroke.strokeVerticesSize() != originalSize) //soc - cerr << "Warning: resampling problem" << endl; - - // assign old attributes to new stroke vertices: - v=stroke.strokeVerticesBegin(); vend=stroke.strokeVerticesEnd(); - vector::iterator a=oldAttributes.begin(), aend=oldAttributes.end(); - //cout << "-----------------------------------------------" << endl; - for(;(v!=vend)&&(a!=aend);++v,++a) - { - v->setAttribute(*a); - //cout << "thickness = " << (*a).getThickness()[0] << "-" << (*a).getThickness()[1] << endl; - } - // we're done! +} + +///////////////////////////////////////// +// +// Tip Remover +// +///////////////////////////////////////// + + +TipRemoverShader::TipRemoverShader(real tipLength) : StrokeShader() +{ + _tipLength = tipLength; +} + +int TipRemoverShader::shade(Stroke& stroke) const +{ + int originalSize = stroke.strokeVerticesSize(); + + if (originalSize < 4) + return 0; + + StrokeInternal::StrokeVertexIterator v, vend; + vector verticesToRemove; + vector oldAttributes; + for (v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); v != vend; ++v) { + if ((v->curvilinearAbscissa() < _tipLength) || (v->strokeLength() - v->curvilinearAbscissa() < _tipLength)) { + verticesToRemove.push_back(&(*v)); + } + oldAttributes.push_back(v->attribute()); + } + + if (originalSize - verticesToRemove.size() < 2) + return 0; + + vector::iterator sv, svend; + for (sv = verticesToRemove.begin(), svend = verticesToRemove.end(); sv != svend; ++sv) { + stroke.RemoveVertex((*sv)); + } + + // Resample so that our new stroke have the same number of vertices than before + stroke.Resample(originalSize); + + if ((int)stroke.strokeVerticesSize() != originalSize) //soc + cerr << "Warning: resampling problem" << endl; + + // assign old attributes to new stroke vertices: + vector::iterator a = oldAttributes.begin(), aend = oldAttributes.end(); + //cout << "-----------------------------------------------" << endl; + for (v = stroke.strokeVerticesBegin(), vend = stroke.strokeVerticesEnd(); + (v != vend) && (a != aend); + ++v, ++a) + { + v->setAttribute(*a); + //cout << "thickness = " << (*a).getThickness()[0] << "-" << (*a).getThickness()[1] << endl; + } + // we're done! return 0; - } +} - int streamShader::shade(Stroke& stroke) const{ - cout << stroke << endl; +int streamShader::shade(Stroke& stroke) const +{ + cout << stroke << endl; return 0; - } - int fstreamShader::shade(Stroke& stroke) const{ - _stream << stroke << endl; +} + +int fstreamShader::shade(Stroke& stroke) const +{ + _stream << stroke << endl; return 0; - } +} } // end of namespace StrokeShaders - diff --git a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h index a0c0a44c9b6..33919b65f21 100644 --- a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h +++ b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h @@ -1,890 +1,902 @@ +/* + * ***** 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_BASIC_STROKE_SHADERS_H__ +#define __FREESTYLE_BASIC_STROKE_SHADERS_H__ + +/** \file blender/freestyle/intern/stroke/BasicStrokeShaders.h + * \ingroup freestyle + * \brief Class gathering basic stroke shaders + * \author Stephane Grabli + * \date 17/12/2002 + */ + +#include + +#include "Stroke.h" +#include "StrokeShader.h" + +#include "../geometry/Bezier.h" +#include "../geometry/Geom.h" + +using namespace std; +using namespace Geometry; + +namespace StrokeShaders { + // -// Filename : BasicStrokeShaders.h -// Author : Stephane Grabli -// Purpose : Class gathering basic stroke shaders -// Date of creation : 17/12/2002 +// Thickness modifiers // -/////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////// + +/*! [ Thickness Shader ]. + * Assigns an absolute constant thickness to every vertices of the Stroke. + */ +class LIB_STROKE_EXPORT ConstantThicknessShader : public StrokeShader +{ +public: + /*! Builds the shader. + * \param thickness + * The thickness that must be assigned to the stroke. + */ + ConstantThicknessShader(float thickness) : StrokeShader() + { + _thickness = thickness; + } + + /*! Destructor. */ + virtual ~ConstantThicknessShader() {} + + /*! Returns the string "ConstantThicknessShader".*/ + virtual string getName() const + { + return "ConstantThicknessShader"; + } + + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; + +private: + float _thickness; +}; + +/* [ Thickness Shader ]. + * Assigns an absolute constant external thickness to every vertices of the Stroke. The external thickness of a point + * is its thickness from the point to the strip border in the direction pointing outside the object the + * Stroke delimitates. + */ +class LIB_STROKE_EXPORT ConstantExternThicknessShader : public StrokeShader +{ +public: + ConstantExternThicknessShader(float thickness) : StrokeShader() + { + _thickness = thickness; + } + + virtual ~ConstantExternThicknessShader() {} + virtual string getName() const + { + return "ConstantExternThicknessShader"; + } + + virtual int shade(Stroke& stroke) const; + +private: + float _thickness; +}; + +/*! [ Thickness Shader ]. + * Assigns thicknesses values such as the thickness increases from a thickness value A to a thickness value B between + * the first vertex to the midpoint vertex and then decreases from B to a A between this midpoint vertex + * and the last vertex. + * The thickness is linearly interpolated from A to B. + */ +class LIB_STROKE_EXPORT IncreasingThicknessShader : public StrokeShader +{ +public: + /*! Builds the shader. + * \param iThicknessMin + * The first thickness value. + * \param iThicknessMax + * The second thickness value. + */ + IncreasingThicknessShader(float iThicknessMin, float iThicknessMax) : StrokeShader() + { + _ThicknessMin = iThicknessMin; + _ThicknessMax = iThicknessMax; + } + + /*! Destructor.*/ + virtual ~IncreasingThicknessShader() {} + + virtual string getName() const + { + return "IncreasingThicknessShader"; + } + + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; + +private: + float _ThicknessMin; + float _ThicknessMax; +}; + +/*! [ Thickness shader ]. + * Same as previous but here we allow the user to control the ratio thickness/length so that we don't get + * fat short lines + */ +class LIB_STROKE_EXPORT ConstrainedIncreasingThicknessShader : public StrokeShader +{ +private: + float _ThicknessMin; + float _ThicknessMax; + float _ratio; + +public: + /*! Builds the shader. + * \param iThicknessMin + * The first thickness value. + * \param iThicknessMax + * The second thickness value. + * \param iRatio + * The ration thickness/length we don't want to exceed. + */ + ConstrainedIncreasingThicknessShader(float iThicknessMin, float iThicknessMax, float iRatio) : StrokeShader() + { + _ThicknessMin = iThicknessMin; + _ThicknessMax = iThicknessMax; + _ratio = iRatio; + } + + /*! Destructor.*/ + virtual ~ConstrainedIncreasingThicknessShader() {} + + virtual string getName() const + { + return "ConstrainedIncreasingThicknessShader"; + } + + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; +}; + +/* [ Thickness Shader ]. + * Modifys the thickness in a relative way depending on its length. + */ +class LIB_STROKE_EXPORT LengthDependingThicknessShader : public StrokeShader +{ +private: + float _minThickness; + float _maxThickness; + // We divide the strokes in 4 categories: + // l > 300 + // 100 < l < 300 + // 50 < l < 100 + // l < 50 + +public: + LengthDependingThicknessShader(float iMinThickness, float iMaxThickness) : StrokeShader() + { + _minThickness = iMinThickness; + _maxThickness = iMaxThickness; + } + + virtual ~LengthDependingThicknessShader() {} + + virtual string getName() const + { + return "LengthDependingThicknessShader"; + } + + virtual int shade(Stroke& stroke) const; +}; + +/*! [ Thickness Shader ]. +* Applys a pattern (texture) to vary thickness. +* The new thicknesses are the result of the multiplication +* of the pattern and the original thickness +*/ +class LIB_STROKE_EXPORT ThicknessVariationPatternShader : public StrokeShader +{ +public: + /*! Builds the shader. + * \param pattern_name + * The texture file name. + * \param iMinThickness + * The minimum thickness we don't want to exceed. + * \param iMaxThickness + * The maximum thickness we don't want to exceed. + * \param stretch + * Tells whether the pattern texture must be stretched or repeted to fit the stroke. + */ + ThicknessVariationPatternShader(const string pattern_name, float iMinThickness = 1.0f, float iMaxThickness = 5.0f, + bool stretch = true); + + /*! Destructor.*/ + virtual ~ThicknessVariationPatternShader() + { + if (0 != _aThickness) { + delete[] _aThickness; + _aThickness = 0; + } + } + virtual string getName() const + { + return "ThicknessVariationPatternShader"; + } + + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; + +private: + float *_aThickness; // array of thickness values, in % of the max (i.e comprised between 0 and 1) + unsigned _size; + float _minThickness; + float _maxThickness; + bool _stretch; +}; + +/*! [ Thickness Shader ]. + * Adds some noise to the stroke thickness. + * \see \htmlonly noise/noise.html\endhtmlonly + */ +class LIB_STROKE_EXPORT ThicknessNoiseShader : public StrokeShader +{ +private: + float _amplitude; + float _scale; + +public: + ThicknessNoiseShader(); + + /*! Builds a Thickness Noise Shader + * \param iAmplitude + * The amplitude of the noise signal + * \param iPeriod + * The period of the noise signal + */ + ThicknessNoiseShader(float iAmplitude, float iPeriod); + + virtual string getName() const + { + return "ThicknessNoiseShader"; + } + + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; +}; + + +// +// Color shaders // -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. +///////////////////////////////////////////////////////// +/*! [ Color Shader ]. + * Assigns a constant color to every vertices of the Stroke. + */ +class LIB_STROKE_EXPORT ConstantColorShader : public StrokeShader +{ +public: + /*! Builds the shader from a user-specified color. + * \param iR + * The red component + * \param iG + * The green component + * \param iB + * The blue component + * \param iAlpha + * The alpha value + */ + ConstantColorShader(float iR, float iG, float iB, float iAlpha = 1.0f) : StrokeShader() + { + _color[0] = iR; + _color[1] = iG; + _color[2] = iB; + _color[3] = iAlpha; + } + + virtual string getName() const + { + return "ConstantColorShader"; + } + + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; + +private: + float _color[4]; +}; + +/*! [ Color Shader ]. + * Assigns a varying color to the stroke. + * The user specifies 2 colors A and B. The stroke color will change linearly from A to B between the + * first and the last vertex. + */ +class LIB_STROKE_EXPORT IncreasingColorShader : public StrokeShader +{ +private: + float _colorMin[4]; + float _colorMax[4]; + +public: + /*! Builds the shader from 2 user-specified colors. + * \param iRm + * The first color red component + * \param iGm + * The first color green component + * \param iBm + * The first color blue component + * \param iAlpham + * The first color alpha value + * \param iRM + * The second color red component + * \param iGM + * The second color green component + * \param iBM + * The second color blue component + * \param iAlphaM + * The second color alpha value + */ + IncreasingColorShader(float iRm, float iGm, float iBm, float iAlpham, + float iRM, float iGM, float iBM, float iAlphaM) + : StrokeShader() + { + _colorMin[0] = iRm; + _colorMin[1] = iGm; + _colorMin[2] = iBm; + _colorMin[3] = iAlpham; + + _colorMax[0] = iRM; + _colorMax[1] = iGM; + _colorMax[2] = iBM; + _colorMax[3] = iAlphaM; + } + + virtual string getName() const + { + return "IncreasingColorShader"; + } + + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; +}; + +/*! [ Color Shader ]. + * Applys a pattern to vary original color. + * The new color is the result of the multiplication of the pattern and the original color + */ +class LIB_STROKE_EXPORT ColorVariationPatternShader : public StrokeShader +{ +public: + /*! Builds the shader from the pattern texture file name. + * \param pattern_name + * The file name of the texture file to use as pattern + * \param stretch + * Tells whether the texture must be strecthed or repeted to fit the stroke. + */ + ColorVariationPatternShader(const string pattern_name, bool stretch = true); + + /*! Destructor */ + virtual ~ColorVariationPatternShader() + { + if (0 != _aVariation) { + delete[] _aVariation; + _aVariation = 0; + } + } + + virtual string getName() const + { + return "ColorVariationPatternShader"; + } + + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; + +private: + float *_aVariation; // array of coef values, in % of the max (i.e comprised between 0 and 1) + unsigned _size; + bool _stretch; +}; + +/* [ Color Shader ]. + * Assigns a color to the stroke depending on the material of the shape to which ot belongs to. (Disney shader) + */ +class LIB_STROKE_EXPORT MaterialColorShader : public StrokeShader +{ +private: + float _coefficient; + +public: + MaterialColorShader(float coeff = 1.0f) : StrokeShader() + { + _coefficient = coeff; + } + + virtual string getName() const + { + return "MaterialColorShader"; + } + + virtual int shade(Stroke& stroke) const; +}; + +class LIB_STROKE_EXPORT CalligraphicColorShader : public StrokeShader +{ +private: + int _textureId; + Vec2d _orientation; + +public: + CalligraphicColorShader(const Vec2d &iOrientation) : StrokeShader() + { + _orientation = iOrientation; + _orientation.normalize(); + } + + virtual string getName() const + { + return "CalligraphicColorShader"; + } + + virtual int shade(Stroke& stroke) const; +}; + +/*! [ Color Shader ]. + * Shader to add noise to the stroke colors. + */ +class LIB_STROKE_EXPORT ColorNoiseShader : public StrokeShader +{ +private: + float _amplitude; + float _scale; + +public: + ColorNoiseShader(); + + /*! Builds a Color Noise Shader + * \param iAmplitude + * The amplitude of the noise signal + * \param iPeriod + * The period of the noise signal + */ + ColorNoiseShader(float iAmplitude, float iPeriod); + + virtual string getName() const + { + return "ColorNoiseShader"; + } + + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; +}; + // -// 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. +// Texture Shaders // -// 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. +/////////////////////////////////////////////////////////////////////////////// +/*! [ Texture Shader ]. +* Assigns a texture to the stroke in order to simulate +* its marks system. This shader takes as input an integer value +* telling which texture and blending mode to use among a set of +* predefined textures. +* Here are the different presets: +* 0) -> /brushes/charcoalAlpha.bmp, HUMID_MEDIUM +* 1) -> /brushes/washbrushAlpha.bmp, HUMID_MEDIUM +* 2) -> /brushes/oil.bmp, HUMID_MEDIUM +* 3) -> /brushes/oilnoblend.bmp, HUMID_MEDIUM +* 4) -> /brushes/charcoalAlpha.bmp, DRY_MEDIUM +* 5) -> /brushes/washbrushAlpha.bmp, DRY_MEDIUM +* 6) -> /brushes/opaqueDryBrushAlpha.bmp, OPAQUE_MEDIUM +* 7) -> /brushes/opaqueBrushAlpha.bmp, Stroke::OPAQUE_MEDIUM +* Any other value will lead to the following preset: +* default) -> /brushes/smoothAlpha.bmp, OPAQUE_MEDIUM. +*/ +class LIB_STROKE_EXPORT TextureAssignerShader : public StrokeShader // FIXME +{ +private: + int _textureId; + +public: + /*! Builds the shader. + * \param id + * The number of the preset to use. + */ + TextureAssignerShader(int id) : StrokeShader() + { + _textureId = id; + } + + virtual string getName() const + { + return "TextureAssignerShader"; + } + + /*! The shading method */ + virtual int shade(Stroke& stroke) const; +}; + +/*! [ Texture Shader ]. +* Assigns a texture and a blending mode to the stroke +* in order to simulate its marks system. +*/ +class LIB_STROKE_EXPORT StrokeTextureShader : public StrokeShader +{ +private: + string _texturePath; + Stroke::MediumType _mediumType; + bool _tips; // 0 or 1 + +public: + /*! Builds the shader from the texture file name and the blending mode to use. + * \param textureFile + * The the texture file name. + * \attention The textures must be placed in the $FREESTYLE_DIR/data/textures/brushes directory. + * \param mediumType + * The medium type and therefore, the blending mode that must be used for the rendering of this stroke. + * \param iTips + * Tells whether the texture includes tips or not. + * If it is the case, the texture image must respect the following format: + * \verbatim + * __________ + * | | + * | A | + * |__________| + * | | | + * | B | C | + * |_____|____| + * + * \endverbatim + * - A : The stroke's corpus texture + * - B : The stroke's left extremity texture + * - C : The stroke's right extremity texture + */ + StrokeTextureShader(const string textureFile, Stroke::MediumType mediumType = Stroke::OPAQUE_MEDIUM, + bool iTips = false) + : StrokeShader() + { + _texturePath = textureFile; + _mediumType = mediumType; + _tips = iTips; + } + + virtual string getName() const + { + return "StrokeTextureShader"; + } + + /*! The shading method */ + virtual int shade(Stroke& stroke) const; +}; + + // -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// Geometry Shaders // /////////////////////////////////////////////////////////////////////////////// +/*! [ Geometry Shader ]. + * Stretches the stroke at its two extremities and following the respective directions: v(1)v(0) and v(n-1)v(n). + */ +class LIB_STROKE_EXPORT BackboneStretcherShader : public StrokeShader +{ +private: + float _amount; + +public: + /*! Builds the shader. + * \param iAmount + * The stretching amount value. + */ + BackboneStretcherShader(float iAmount = 2.0f) : StrokeShader() + { + _amount = iAmount; + } -#ifndef BASIC_STROKE_SHADERS_H -# define BASIC_STROKE_SHADERS_H + virtual string getName() const + { + return "BackboneStretcherShader"; + } -# include "Stroke.h" -# include "../geometry/Geom.h" -# include "../geometry/Bezier.h" -# include "StrokeShader.h" -# include + /*! The shading method */ + virtual int shade(Stroke& stroke) const; +}; + +/*! [ Geometry Shader. ] + * Resamples the stroke. + * @see Stroke::Resample(float). + */ +class LIB_STROKE_EXPORT SamplingShader: public StrokeShader +{ +private: + float _sampling; + +public: + /*! Builds the shader. + * \param sampling + * The sampling to use for the stroke resampling + */ + SamplingShader(float sampling) : StrokeShader() + { + _sampling = sampling; + } -using namespace std; -using namespace Geometry; + virtual string getName() const + { + return "SamplingShader"; + } -namespace StrokeShaders { + /*! The shading method */ + virtual int shade(Stroke& stroke) const; +}; + + +class LIB_STROKE_EXPORT ExternalContourStretcherShader : public StrokeShader +{ +private: + float _amount; + +public: + ExternalContourStretcherShader(float iAmount = 2.0f) : StrokeShader() + { + _amount = iAmount; + } + + virtual string getName() const + { + return "ExternalContourStretcherShader"; + } + + virtual int shade(Stroke& stroke) const; +}; + +// B-Spline stroke shader +class LIB_STROKE_EXPORT BSplineShader: public StrokeShader +{ +public: + BSplineShader() : StrokeShader() {} + + virtual string getName() const + { + return "BSplineShader"; + } + + virtual int shade(Stroke& stroke) const; +}; + + +// Bezier curve stroke shader +/*! [ Geometry Shader ]. + * Transforms the stroke backbone geometry so that it corresponds to a Bezier Curve approximation of the + * original backbone geometry. + * @see \htmlonly bezier/bezier.html \endhtmlonly + */ +class LIB_STROKE_EXPORT BezierCurveShader : public StrokeShader +{ +private: + float _error; + +public: + /*! Builds the shader. + * \param error + * The error we're allowing for the approximation. + * This error is the max distance allowed between the new curve and the original geometry. + */ + BezierCurveShader(float error = 4.0) : StrokeShader() + { + _error = error; + } + + virtual string getName() const + { + return "BezierCurveShader"; + } + + /*! The shading method */ + virtual int shade(Stroke& stroke) const; +}; + +/* Shader to inflate the curves. It keeps the extreme points positions and moves the other ones along the 2D normal. + * The displacement value is proportional to the 2d curvature at the considered point (the higher the curvature, + * the smaller the displacement) and to a value specified by the user. + */ +class LIB_STROKE_EXPORT InflateShader : public StrokeShader +{ +private: + float _amount; + float _curvatureThreshold; + +public: + /*! Builds an inflate shader + * \param iAmount + * A multiplicative coefficient that acts on the amount and direction of displacement + * \param iThreshold + * The curves having a 2d curvature > iThreshold at one of their points is not inflated + */ + InflateShader(float iAmount, float iThreshold) : StrokeShader() + { + _amount = iAmount; + _curvatureThreshold = iThreshold; + } + + virtual string getName() const + { + return "InflateShader"; + } + + /*! The shading method */ + virtual int shade(Stroke& stroke) const; +}; + +/*! [ Geometry Shader ]. + * Shader to modify the Stroke geometry so that it looks more "polygonal". + * The basic idea is to start from the minimal stroke approximation consisting in a line joining the first vertex + * to the last one and to subdivide using the original stroke vertices until a certain error is reached. + */ +class LIB_STROKE_EXPORT PolygonalizationShader : public StrokeShader +{ +private: + float _error; + +public: + /*! Builds the shader. + * \param iError + * The error we want our polygonal approximation to have with respect to the original geometry. + * The smaller, the closer the new stroke to the orinal one. + * This error corresponds to the maximum distance between the new stroke and the old one. + */ + PolygonalizationShader(float iError) : StrokeShader() + { + _error = iError; + } + + virtual string getName() const + { + return "PolygonalizationShader"; + } + + /*! The shading method */ + virtual int shade(Stroke& stroke) const; +}; + + +/*! [ Geometry Shader ]. + * Shader to modify the Stroke geometry so that it corresponds to its main direction line. + * This shader must be used together with the splitting operator using the curvature criterion. + * Indeed, the precision of the approximation will depend on the size of the stroke's pieces. + * The bigger the pieces, the rougher the approximation. + */ +class LIB_STROKE_EXPORT GuidingLinesShader : public StrokeShader +{ +private: + float _offset; + +public: + /*! Builds a Guiding Lines shader + * \param iOffset + * The line that replaces the stroke is initially in the middle of the initial stroke "bbox". + * iOffset is the value of the displacement which is applied to this line along its normal. + */ + GuidingLinesShader(float iOffset) : StrokeShader() + { + _offset = iOffset; + } + + virtual string getName() const + { + return "GuidingLinesShader"; + } + + /*! The shading method */ + virtual int shade(Stroke& stroke) const; +}; + +/*! [ Geometry Shader ]. + * Removes the stroke's extremities. + */ +class LIB_STROKE_EXPORT TipRemoverShader : public StrokeShader +{ +public: + /*! Builds the shader. + * \param tipLength + * The length of the piece of stroke we want to remove at each extremity. + */ + TipRemoverShader (real tipLength); + + /*! Destructor. */ + virtual ~TipRemoverShader () {} + + /*! The shading method */ + virtual string getName() const + { + return "TipRemoverShader"; + } + + virtual int shade(Stroke &stroke) const; + +protected: + real _tipLength; +}; + +/*! [ output Shader ]. + * streams the Stroke + */ +class LIB_STROKE_EXPORT streamShader : public StrokeShader +{ +public: + /*! Destructor. */ + virtual ~streamShader() {} + + /*! Returns the string "streamShader".*/ + virtual string getName() const + { + return "streamShader"; + } + + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; +}; + +/*! [ output Shader ]. + * streams the Stroke in a file + */ +class LIB_STROKE_EXPORT fstreamShader : public StrokeShader +{ +protected: + mutable ofstream _stream; + +public: + /*! Builds the shader from the output file name */ + fstreamShader(const char *iFileName) : StrokeShader() + { + _stream .open(iFileName); + if (!_stream.is_open()) { + cout << "couldn't open file " << iFileName << endl; + } + } + + /*! Destructor. */ + virtual ~fstreamShader() + { + _stream.close(); + } + + /*! Returns the string "fstreamShader".*/ + virtual string getName() const + { + return "fstreamShader"; + } + + /*! The shading method. */ + virtual int shade(Stroke& stroke) const; +}; - // - // Thickness modifiers - // - ////////////////////////////////////////////////////// - /*! [ Thickness Shader ]. - * Assigns an absolute constant thickness to every - * vertices of the Stroke. - */ - class LIB_STROKE_EXPORT ConstantThicknessShader : public StrokeShader - { - public: - /*! Builds the shader. - * \param thickness - * The thickness that must be assigned - * to the stroke. - */ - ConstantThicknessShader(float thickness) : StrokeShader() { - _thickness = thickness; - } - /*! Destructor. */ - virtual ~ConstantThicknessShader() {} - /*! Returns the string "ConstantThicknessShader".*/ - virtual string getName() const { - return "ConstantThicknessShader"; - } - /*! The shading method. */ - virtual int shade(Stroke& stroke) const; - - private: - float _thickness; - }; - - /* [ Thickness Shader ]. - * Assigns an absolute constant external thickness to every - * vertices of the Stroke. The external thickness of a point - * is its thickness from the point to the strip border - * in the direction pointing outside the object the - * Stroke delimitates. - */ - class LIB_STROKE_EXPORT ConstantExternThicknessShader : public StrokeShader - { - public: - - ConstantExternThicknessShader(float thickness) : StrokeShader() { - _thickness = thickness; - } - - virtual ~ConstantExternThicknessShader() {} - - virtual string getName() const { - return "ConstantExternThicknessShader"; - } - - virtual int shade(Stroke& stroke) const; - - private: - - float _thickness; - }; - - /*! [ Thickness Shader ]. - * Assigns thicknesses values such as the thickness - * increases from a thickness value A to a thickness value B - * between the first vertex to the midpoint vertex and - * then decreases from B to a A between this midpoint vertex - * and the last vertex. - * The thickness is linearly interpolated from A to B. - */ - class LIB_STROKE_EXPORT IncreasingThicknessShader : public StrokeShader - { - public: - /*! Builds the shader. - * \param iThicknessMin - * The first thickness value. - * \param iThicknessMax - * The second thickness value. - */ - IncreasingThicknessShader(float iThicknessMin, float iThicknessMax) - : StrokeShader() - { - _ThicknessMin = iThicknessMin; - _ThicknessMax = iThicknessMax; - } - /*! Destructor.*/ - virtual ~IncreasingThicknessShader() {} - - virtual string getName() const { - return "IncreasingThicknessShader"; - } - - /*! The shading method. */ - virtual int shade(Stroke& stroke) const; - - private: - - float _ThicknessMin; - float _ThicknessMax; - }; - - /*! [ Thickness shader ]. - * Same as previous but - * here we allow the user to control the ratio thickness/length so that - * we don't get fat short lines - */ - class LIB_STROKE_EXPORT ConstrainedIncreasingThicknessShader : public StrokeShader - { - private: - float _ThicknessMin; - float _ThicknessMax; - float _ratio; - public: - /*! Builds the shader. - * \param iThicknessMin - * The first thickness value. - * \param iThicknessMax - * The second thickness value. - * \param iRatio - * The ration thickness/length we don't want to - * exceed. - */ - ConstrainedIncreasingThicknessShader(float iThicknessMin, float iThicknessMax, float iRatio) - : StrokeShader() - { - _ThicknessMin = iThicknessMin; - _ThicknessMax = iThicknessMax; - _ratio = iRatio; - } - /*! Destructor.*/ - virtual ~ConstrainedIncreasingThicknessShader() {} - - virtual string getName() const { - return "ConstrainedIncreasingThicknessShader"; - } - - /*! The shading method. */ - virtual int shade(Stroke& stroke) const; - }; - - /* [ Thickness Shader ]. - * Modifys the thickness in a relative way - * depending on its length. - */ - class LIB_STROKE_EXPORT LengthDependingThicknessShader : public StrokeShader - { - private: - float _minThickness; - float _maxThickness; - // We divide the strokes in 4 categories: - // l > 300 - // 100 < l < 300 - // 50 < l < 100 - // l < 50 - public: - LengthDependingThicknessShader(float iMinThickness, float iMaxThickness) - : StrokeShader() - { - _minThickness = iMinThickness; - _maxThickness = iMaxThickness; - } - virtual ~LengthDependingThicknessShader() {} - - virtual string getName() const { - return "LengthDependingThicknessShader"; - } - - virtual int shade(Stroke& stroke) const; - }; - - /*! [ Thickness Shader ]. - * Applys a pattern (texture) to vary thickness. - * The new thicknesses are the result of the multiplication - * of the pattern and the original thickness - */ - class LIB_STROKE_EXPORT ThicknessVariationPatternShader : public StrokeShader - { - public: - - /*! Builds the shader. - * \param pattern_name - * The texture file name. - * \param iMinThickness - * The minimum thickness we don't want to exceed. - * \param iMaxThickness - * The maximum thickness we don't want to exceed. - * \param stretch - * Tells whether the pattern texture must - * be stretched or repeted to fit the stroke. - */ - ThicknessVariationPatternShader(const string pattern_name, - float iMinThickness = 1.f, - float iMaxThickness = 5.f, - bool stretch = true); - /*! Destructor.*/ - virtual ~ThicknessVariationPatternShader() - { - if(0 != _aThickness) - { - delete [] _aThickness; - _aThickness = 0; - } - } - - virtual string getName() const { - return "ThicknessVariationPatternShader"; - } - - /*! The shading method. */ - virtual int shade(Stroke& stroke) const; - - private: - - float* _aThickness; // array of thickness values, in % of the max (i.e comprised between 0 and 1) - unsigned _size; - float _minThickness; - float _maxThickness; - bool _stretch; - }; - - /*! [ Thickness Shader ]. - * Adds some noise to the stroke thickness. - * \see \htmlonly noise/noise.html\endhtmlonly - */ - class LIB_STROKE_EXPORT ThicknessNoiseShader : public StrokeShader - { - private: - float _amplitude; - float _scale; - public: - ThicknessNoiseShader(); - /*! Builds a Thickness Noise Shader - * \param iAmplitude - * The amplitude of the noise signal - * \param iPeriod - * The period of the noise signal - */ - ThicknessNoiseShader(float iAmplitude, float iPeriod); - - virtual string getName() const { - return "ThicknessNoiseShader"; - } - - /*! The shading method. */ - virtual int shade(Stroke& stroke) const; - }; - - - // - // Color shaders - // - ///////////////////////////////////////////////////////// - /*! [ Color Shader ]. - * Assigns a constant color to every vertices of the Stroke. - */ - class LIB_STROKE_EXPORT ConstantColorShader : public StrokeShader - { - public: - /*! Builds the shader from a user-specified color. - * \param iR - * The red component - * \param iG - * The green component - * \param iB - * The blue component - * \param iAlpha - * The alpha value - */ - ConstantColorShader(float iR, float iG, float iB, float iAlpha=1.f) - : StrokeShader() - { - _color[0] = iR; - _color[1] = iG; - _color[2] = iB; - _color[3] = iAlpha; - } - - virtual string getName() const { - return "ConstantColorShader"; - } - /*! The shading method. */ - virtual int shade(Stroke& stroke) const; - - private: - - float _color[4]; - }; - - /*! [ Color Shader ]. - * Assigns a varying color to the stroke. - * The user specifies 2 colors A and B. The stroke - * color will change linearly from A to B between the - * first and the last vertex. - */ - class LIB_STROKE_EXPORT IncreasingColorShader : public StrokeShader - { - private: - float _colorMin[4]; - float _colorMax[4]; - public: - /*! Builds the shader from 2 user-specified colors. - * \param iRm - * The first color red component - * \param iGm - * The first color green component - * \param iBm - * The first color blue component - * \param iAlpham - * The first color alpha value - * \param iRM - * The second color red component - * \param iGM - * The second color green component - * \param iBM - * The second color blue component - * \param iAlphaM - * The second color alpha value - */ - IncreasingColorShader(float iRm, float iGm, float iBm, float iAlpham, - float iRM, float iGM, float iBM, float iAlphaM) - : StrokeShader() - { - _colorMin[0] = iRm; - _colorMin[1] = iGm; - _colorMin[2] = iBm; - _colorMin[3] = iAlpham; - - _colorMax[0] = iRM; - _colorMax[1] = iGM; - _colorMax[2] = iBM; - _colorMax[3] = iAlphaM; - } - - virtual string getName() const { - return "IncreasingColorShader"; - } - - /*! The shading method. */ - virtual int shade(Stroke& stroke) const; - }; - - /*! [ Color Shader ]. - * Applys a pattern to vary original color. - * The new color is the result of the multiplication - * of the pattern and the original color - */ - class LIB_STROKE_EXPORT ColorVariationPatternShader : public StrokeShader - { - public: - /*! Builds the shader from the pattern texture file name. - * \param pattern_name - * The file name of the texture file to use as pattern - * \param stretch - * Tells whether the texture must be strecthed or repeted - * to fit the stroke. - */ - ColorVariationPatternShader(const string pattern_name, bool stretch = true); - /*! Destructor */ - virtual ~ColorVariationPatternShader() - { - if(0 != _aVariation) - { - delete [] _aVariation; - _aVariation = 0; - } - } - - virtual string getName() const { - return "ColorVariationPatternShader"; - } - - /*! The shading method. */ - virtual int shade(Stroke& stroke) const; - - private: - - float* _aVariation; // array of coef values, in % of the max (i.e comprised between 0 and 1) - unsigned _size; - bool _stretch; - }; - - /* [ Color Shader ]. - * Assigns a color to the stroke depending - * on the material of the shape to which ot belongs - * to. (Disney shader) - */ - class LIB_STROKE_EXPORT MaterialColorShader : public StrokeShader - { - private: - float _coefficient; - public: - MaterialColorShader(float coeff=1.f) - : StrokeShader() - {_coefficient=coeff;} - - virtual string getName() const { - return "MaterialColorShader"; - } - - virtual int shade(Stroke& stroke) const; - }; - - class LIB_STROKE_EXPORT CalligraphicColorShader : public StrokeShader - { - private: - int _textureId; - Vec2d _orientation; - public: - CalligraphicColorShader( - const Vec2d &iOrientation) - : StrokeShader() - { - _orientation=iOrientation; - _orientation.normalize(); - } - - virtual string getName() const { - return "CalligraphicColorShader"; - } - - virtual int shade(Stroke& stroke) const; - - }; - - /*! [ Color Shader ]. - * Shader to add noise to the stroke colors. - */ - class LIB_STROKE_EXPORT ColorNoiseShader : public StrokeShader - { - private: - float _amplitude; - float _scale; - - public: - ColorNoiseShader(); - /*! Builds a Color Noise Shader - * \param iAmplitude - * The amplitude of the noise signal - * \param iPeriod - * The period of the noise signal - */ - ColorNoiseShader(float iAmplitude, float iPeriod); - - virtual string getName() const { - return "ColorNoiseShader"; - } - - /*! The shading method. */ - virtual int shade(Stroke& stroke) const; - }; - - // - // Texture Shaders - // - /////////////////////////////////////////////////////////////////////////////// - /*! [ Texture Shader ]. - * Assigns a texture to the stroke in order to simulate - * its marks system. This shader takes as input an integer value - * telling which texture and blending mode to use among a set of - * predefined textures. - * Here are the different presets: - * 0) -> /brushes/charcoalAlpha.bmp, HUMID_MEDIUM - * 1) -> /brushes/washbrushAlpha.bmp, HUMID_MEDIUM - * 2) -> /brushes/oil.bmp, HUMID_MEDIUM - * 3) -> /brushes/oilnoblend.bmp, HUMID_MEDIUM - * 4) -> /brushes/charcoalAlpha.bmp, DRY_MEDIUM - * 5) -> /brushes/washbrushAlpha.bmp, DRY_MEDIUM - * 6) -> /brushes/opaqueDryBrushAlpha.bmp, OPAQUE_MEDIUM - * 7) -> /brushes/opaqueBrushAlpha.bmp, Stroke::OPAQUE_MEDIUM - * Any other value will lead to the following preset: - * default) -> /brushes/smoothAlpha.bmp, OPAQUE_MEDIUM. - */ - class LIB_STROKE_EXPORT TextureAssignerShader : public StrokeShader // FIXME - { - private: - int _textureId; - public: - /*! Builds the shader. - * \param id - * The number of the preset to use. - */ - TextureAssignerShader(int id) - : StrokeShader() - { - _textureId = id; - } - - virtual string getName() const { - return "TextureAssignerShader"; - } - - /*! The shading method */ - virtual int shade(Stroke& stroke) const; - - }; - /*! [ Texture Shader ]. - * Assigns a texture and a blending mode to the stroke - * in order to simulate its marks system. - */ - class LIB_STROKE_EXPORT StrokeTextureShader : public StrokeShader - { - private: - string _texturePath; - Stroke::MediumType _mediumType; - bool _tips; // 0 or 1 - - public: - /*! Builds the shader from the texture file name and the blending mode to use. - * \param textureFile - * The the texture file name. - * \attention The textures must be placed in the $FREESTYLE_DIR/data/textures/brushes - * directory. - * \param mediumType - * The medium type and therefore, the blending mode that must - * be used for the rendering of this stroke. - * \param iTips - * Tells whether the texture includes tips or not. - * If it is the case, the texture image must respect the following - * format: - * \verbatim - * __________ - * | | - * | A | - * |__________| - * | | | - * | B | C | - * |_____|____| - * - * \endverbatim - * - A : The stroke's corpus texture - * - B : The stroke's left extremity texture - * - C : The stroke's right extremity texture - */ - StrokeTextureShader(const string textureFile, Stroke::MediumType mediumType = Stroke::OPAQUE_MEDIUM, bool iTips = false) - : StrokeShader() - { - _texturePath = textureFile; - _mediumType = mediumType; - _tips = iTips; - } - - virtual string getName() const { - return "StrokeTextureShader"; - } - - /*! The shading method */ - virtual int shade(Stroke& stroke) const; - - }; - - - // - // Geometry Shaders - // - /////////////////////////////////////////////////////////////////////////////// - /*! [ Geometry Shader ]. - * Stretches the stroke at its two extremities and following the - * respective directions: v(1)v(0) and v(n-1)v(n). - */ - class LIB_STROKE_EXPORT BackboneStretcherShader : public StrokeShader - { - private: - float _amount; - public: - /*! Builds the shader. - * \param iAmount - * The stretching amount value. - */ - BackboneStretcherShader(float iAmount=2.f) - : StrokeShader() - { - _amount = iAmount; - } - - virtual string getName() const { - return "BackboneStretcherShader"; - } - - /*! The shading method */ - virtual int shade(Stroke& stroke) const; - }; - - /*! [ Geometry Shader. ] - * Resamples the stroke. - * @see Stroke::Resample(float). - */ - class LIB_STROKE_EXPORT SamplingShader: public StrokeShader - { - private: - float _sampling; - public: - /*! Builds the shader. - * \param sampling - * The sampling to use for the - * stroke resampling - */ - SamplingShader(float sampling) - : StrokeShader() - { - _sampling = sampling; - } - - virtual string getName() const { - return "SamplingShader"; - } - - /*! The shading method */ - virtual int shade(Stroke& stroke) const; - }; - - - class LIB_STROKE_EXPORT ExternalContourStretcherShader : public StrokeShader - { - private: - float _amount; - public: - ExternalContourStretcherShader(float iAmount=2.f) - : StrokeShader() - { - _amount = iAmount; - } - - virtual string getName() const { - return "ExternalContourStretcherShader"; - } - - virtual int shade(Stroke& stroke) const; - }; - - // B-Spline stroke shader - class LIB_STROKE_EXPORT BSplineShader: public StrokeShader - { - public: - BSplineShader() - : StrokeShader() - {} - - virtual string getName() const { - return "BSplineShader"; - } - - virtual int shade(Stroke& stroke) const; - }; - - - // Bezier curve stroke shader - /*! [ Geometry Shader ]. - * Transforms the stroke backbone geometry - * so that it corresponds to a Bezier Curve - * approximation of the original backbone geometry. - * @see \htmlonly bezier/bezier.html \endhtmlonly - */ - class LIB_STROKE_EXPORT BezierCurveShader : public StrokeShader - { - private: - float _error; - public: - /*! Builds the shader. - * \param error - * The error we're allowing for the approximation. - * This error is the max distance allowed between - * the new curve and the original geometry. - */ - BezierCurveShader(float error = 4.0) - : StrokeShader() - {_error=error;} - - virtual string getName() const { - return "BezierCurveShader"; - } - - /*! The shading method */ - virtual int shade(Stroke& stroke) const; - }; - - /* Shader to inflate the curves. It keeps the extreme - * points positions and moves the other ones along - * the 2D normal. The displacement value is proportional - * to the 2d curvature at the considered point (the higher - * the curvature, the smaller the displacement) and to a value - * specified by the user. - */ - class LIB_STROKE_EXPORT InflateShader : public StrokeShader - { - private: - float _amount; - float _curvatureThreshold; - public: - /*! Builds an inflate shader - * \param iAmount - * A multiplicative coefficient that - * acts on the amount and direction of displacement - * \param iThreshold - * The curves having a 2d curvature > iThreshold - * at one of their points is not inflated - */ - InflateShader(float iAmount,float iThreshold) - : StrokeShader() - { - _amount = iAmount; - _curvatureThreshold = iThreshold; - } - - virtual string getName() const { - return "InflateShader"; - } - - /*! The shading method */ - virtual int shade(Stroke& stroke) const; - }; - - /*! [ Geometry Shader ]. - * Shader to modify the Stroke geometry so that - * it looks more "polygonal". - * The basic idea is to start from the - * minimal stroke approximation consisting in - * a line joining the first vertex to the last one and - * to subdivide using the original stroke vertices - * until a certain error is reached. - */ - class LIB_STROKE_EXPORT PolygonalizationShader : public StrokeShader - { - private: - float _error; - public: - /*! Builds the shader. - * \param iError - * The error we want our polygonal approximation - * to have with respect to the original geometry. - * The smaller, the closer the new stroke to - * the orinal one. - * This error corresponds to the maximum distance - * between the new stroke and the old one. - */ - PolygonalizationShader(float iError) : StrokeShader() - {_error = iError;} - - virtual string getName() const { - return "PolygonalizationShader"; - } - - /*! The shading method */ - virtual int shade(Stroke& stroke) const; - }; - - - /*! [ Geometry Shader ]. - * Shader to modify the Stroke geometry so that - * it corresponds to its main direction line. - * This shader must be used together with the - * splitting operator using the curvature criterion. - * Indeed, the precision of the approximation - * will depend on the size of the stroke's pieces. - * The bigger the pieces, the rougher the approximation. - */ - class LIB_STROKE_EXPORT GuidingLinesShader : public StrokeShader - { - private: - float _offset; - public: - /*! Builds a Guiding Lines shader - * \param iOffset - * The line that replaces the stroke - * is initially in the middle - * of the initial stroke "bbox". - * iOffset is the value of the displacement - * which is applied to this line along its - * normal. - */ - GuidingLinesShader(float iOffset) : StrokeShader() - {_offset = iOffset;} - - virtual string getName() const { - return "GuidingLinesShader"; - } - - /*! The shading method */ - virtual int shade(Stroke& stroke) const; - }; - - /*! [ Geometry Shader ]. - * Removes the stroke's extremities. - */ - class LIB_STROKE_EXPORT TipRemoverShader : public StrokeShader - { - public: - /*! Builds the shader. - * \param tipLength - * The length of the piece of stroke - * we want to remove at each extremity. - */ - TipRemoverShader (real tipLength); - /*! Destructor. */ - virtual ~TipRemoverShader () {} - /*! The shading method */ - virtual string getName() const { - return "TipRemoverShader"; - } - - virtual int shade(Stroke &stroke) const; - - protected: - - real _tipLength; - }; - - /*! [ output Shader ]. - * streams the Stroke - */ - class LIB_STROKE_EXPORT streamShader : public StrokeShader - { - public: - /*! Destructor. */ - virtual ~streamShader() {} - /*! Returns the string "streamShader".*/ - virtual string getName() const { - return "streamShader"; - } - /*! The shading method. */ - virtual int shade(Stroke& stroke) const; - }; - - /*! [ output Shader ]. - * streams the Stroke in a file - */ - class LIB_STROKE_EXPORT fstreamShader : public StrokeShader - { - protected: - mutable ofstream _stream; - public: - /*! Builds the shader from the output file name */ - fstreamShader(const char *iFileName) : StrokeShader(){ - _stream .open(iFileName); - if(!_stream.is_open()){ - cout << "couldn't open file " << iFileName << endl; - } - } - /*! Destructor. */ - virtual ~fstreamShader() {_stream.close();} - /*! Returns the string "fstreamShader".*/ - virtual string getName() const { - return "fstreamShader"; - } - /*! The shading method. */ - virtual int shade(Stroke& stroke) const; - }; } // end of namespace StrokeShaders -#endif // BASIC_STROKE_SHADERS_H +#endif // __FREESTYLE_BASIC_STROKE_SHADERS_H__ diff --git a/source/blender/freestyle/intern/stroke/Canvas.cpp b/source/blender/freestyle/intern/stroke/Canvas.cpp index f2cfe6a855f..a51c138f64e 100644 --- a/source/blender/freestyle/intern/stroke/Canvas.cpp +++ b/source/blender/freestyle/intern/stroke/Canvas.cpp @@ -1,455 +1,471 @@ - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#include "StrokeRenderer.h" +/* + * ***** 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 ***** + */ + +/** \file blender/freestyle/intern/stroke/Canvas.cpp + * \ingroup freestyle + * \brief Class to define a canvas designed to draw style modules + * \author Stephane Grabli + * \date 20/10/2002 + */ + +#include #include -#include "../system/FreestyleConfig.h" -#include "../system/TimeStamp.h" -#include "../system/PseudoNoise.h" + #include "Canvas.h" +#include "StrokeRenderer.h" +#include "StyleModule.h" + #include "../image/Image.h" #include "../image/GaussianFilter.h" #include "../image/ImagePyramid.h" + +#include "../system/FreestyleConfig.h" +#include "../system/TimeStamp.h" +#include "../system/PseudoNoise.h" + #include "../view_map/SteerableViewMap.h" -#include "StyleModule.h" //soc #include //soc #include -#include extern "C" { -#include "IMB_imbuf.h" -#include "IMB_imbuf_types.h" +# include "IMB_imbuf.h" +# include "IMB_imbuf_types.h" } using namespace std; LIB_STROKE_EXPORT -Canvas * Canvas::_pInstance = 0; +Canvas *Canvas::_pInstance = 0; LIB_STROKE_EXPORT -const char * Canvas::_MapsPath = 0; - -using namespace std; +const char *Canvas::_MapsPath = 0; Canvas::Canvas() { - _SelectedFEdge = 0; - _pInstance = this; - PseudoNoise::init(42); - _Renderer = 0; - _current_sm = NULL; - _steerableViewMap = new SteerableViewMap(NB_STEERABLE_VIEWMAP-1); - _basic = false; + _SelectedFEdge = 0; + _pInstance = this; + PseudoNoise::init(42); + _Renderer = 0; + _current_sm = NULL; + _steerableViewMap = new SteerableViewMap(NB_STEERABLE_VIEWMAP - 1); + _basic = false; } Canvas::Canvas(const Canvas& iBrother) { - _SelectedFEdge = iBrother._SelectedFEdge; - _pInstance = this; - PseudoNoise::init(42); - _Renderer = iBrother._Renderer; - _current_sm = iBrother._current_sm; - _steerableViewMap = new SteerableViewMap(*(iBrother._steerableViewMap)); - _basic = iBrother._basic; + _SelectedFEdge = iBrother._SelectedFEdge; + _pInstance = this; + PseudoNoise::init(42); + _Renderer = iBrother._Renderer; + _current_sm = iBrother._current_sm; + _steerableViewMap = new SteerableViewMap(*(iBrother._steerableViewMap)); + _basic = iBrother._basic; } Canvas::~Canvas() { - _pInstance = 0; - - Clear(); - if(_Renderer) - { - delete _Renderer; - _Renderer = 0; - } - // FIXME: think about an easy control - // for the maps memory management... - if(!_maps.empty()){ - for(mapsMap::iterator m=_maps.begin(), mend=_maps.end(); - m!=mend; - ++m){ - delete ((*m).second); - } - _maps.clear(); - } - if(_steerableViewMap) - delete _steerableViewMap; + _pInstance = 0; + + Clear(); + if (_Renderer) { + delete _Renderer; + _Renderer = 0; + } + // FIXME: think about an easy control for the maps memory management... + if (!_maps.empty()) { + for (mapsMap::iterator m = _maps.begin(), mend = _maps.end(); m != mend; ++m) { + delete ((*m).second); + } + _maps.clear(); + } + if (_steerableViewMap) + delete _steerableViewMap; } void Canvas::preDraw() {} void Canvas::Draw() { - if(_StyleModules.empty()) - return; - preDraw(); - TimeStamp *timestamp = TimeStamp::instance(); + if (_StyleModules.empty()) + return; + preDraw(); + TimeStamp *timestamp = TimeStamp::instance(); - for(unsigned i = 0; i < _StyleModules.size(); i++) { - _current_sm = _StyleModules[i]; + for (unsigned int i = 0; i < _StyleModules.size(); ++i) { + _current_sm = _StyleModules[i]; - if (i < _Layers.size() && _Layers[i]) - delete _Layers[i]; + if (i < _Layers.size() && _Layers[i]) + delete _Layers[i]; - _Layers[i] = _StyleModules[i]->execute(); - if (!_Layers[i]) - continue; + _Layers[i] = _StyleModules[i]->execute(); + if (!_Layers[i]) + continue; - stroke_count += _Layers[i]->strokes_size(); + stroke_count += _Layers[i]->strokes_size(); - timestamp->increment(); - } - postDraw(); + timestamp->increment(); + } + postDraw(); } void Canvas::postDraw() { - update(); + update(); } void Canvas::Clear() { - if(!_Layers.empty()) { - for (deque::iterator sl=_Layers.begin(), slend=_Layers.end(); - sl != slend; - ++sl) - if (*sl) - delete (*sl); - _Layers.clear(); - } - - if(!_StyleModules.empty()) { - for (deque::iterator s=_StyleModules.begin(), send=_StyleModules.end(); - s != send; - ++s) - if (*s) - delete (*s); - _StyleModules.clear(); - } - if(_steerableViewMap) - _steerableViewMap->Reset(); + if (!_Layers.empty()) { + for (deque::iterator sl = _Layers.begin(), slend = _Layers.end(); sl != slend; ++sl) { + if (*sl) + delete (*sl); + } + _Layers.clear(); + } + + if (!_StyleModules.empty()) { + for (deque::iterator s = _StyleModules.begin(), send = _StyleModules.end(); s != send; ++s) { + if (*s) + delete (*s); + } + _StyleModules.clear(); + } + if (_steerableViewMap) + _steerableViewMap->Reset(); stroke_count = 0; } void Canvas::Erase() { - if(!_Layers.empty()) - { - for (deque::iterator sl=_Layers.begin(), slend=_Layers.end(); - sl != slend; - ++sl) - if (*sl) - (*sl)->clear(); - } - if(_steerableViewMap) - _steerableViewMap->Reset(); - update(); - -stroke_count = 0; + if (!_Layers.empty()) { + for (deque::iterator sl = _Layers.begin(), slend = _Layers.end(); sl != slend; ++sl) { + if (*sl) + (*sl)->clear(); + } + } + if (_steerableViewMap) + _steerableViewMap->Reset(); + update(); + + stroke_count = 0; } -void Canvas::PushBackStyleModule(StyleModule *iStyleModule) { - StrokeLayer* layer = new StrokeLayer(); - _StyleModules.push_back(iStyleModule); - _Layers.push_back(layer); +void Canvas::PushBackStyleModule(StyleModule *iStyleModule) +{ + StrokeLayer* layer = new StrokeLayer(); + _StyleModules.push_back(iStyleModule); + _Layers.push_back(layer); } -void Canvas::InsertStyleModule(unsigned index, StyleModule *iStyleModule) { - unsigned size = _StyleModules.size(); - StrokeLayer* layer = new StrokeLayer(); - if((_StyleModules.empty()) || (index == size)) { - _StyleModules.push_back(iStyleModule); - _Layers.push_back(layer); - return; - } +void Canvas::InsertStyleModule(unsigned index, StyleModule *iStyleModule) +{ + unsigned size = _StyleModules.size(); + StrokeLayer *layer = new StrokeLayer(); + if ((_StyleModules.empty()) || (index == size)) { + _StyleModules.push_back(iStyleModule); + _Layers.push_back(layer); + return; + } _StyleModules.insert(_StyleModules.begin() + index, iStyleModule); - _Layers.insert(_Layers.begin()+index, layer); + _Layers.insert(_Layers.begin() + index, layer); } void Canvas::RemoveStyleModule(unsigned index) { - unsigned i=0; - if (!_StyleModules.empty()) - { - for(deque::iterator s=_StyleModules.begin(), send=_StyleModules.end(); - s!=send; - ++s) - { - if(i == index) - { - // remove shader - if (*s) - delete *s; - _StyleModules.erase(s); - break; - } - ++i; + unsigned int i = 0; + if (!_StyleModules.empty()) { + for (deque::iterator s = _StyleModules.begin(), send = _StyleModules.end(); + s != send; + ++s, ++i) + { + if (i == index) { + // remove shader + if (*s) + delete *s; + _StyleModules.erase(s); + break; + } + } + } + + if (!_Layers.empty()) { + i = 0; + for (deque::iterator sl = _Layers.begin(), slend = _Layers.end(); + sl != slend; + ++sl, ++i) + { + if (i == index) { + // remove layer + if (*sl) + delete *sl; + _Layers.erase(sl); + break; + } + } } - } - i=0; - if(!_Layers.empty()) - { - for(deque::iterator sl=_Layers.begin(), slend=_Layers.end(); - sl!=slend; - ++sl) - { - if(i == index) - { - // remove layer - if (*sl) - delete *sl; - _Layers.erase(sl); - break; - } - ++i; - } - } } void Canvas::SwapStyleModules(unsigned i1, unsigned i2) { - StyleModule* tmp; - tmp = _StyleModules[i1]; - _StyleModules[i1] = _StyleModules[i2]; - _StyleModules[i2] = tmp; - - StrokeLayer* tmp2; - tmp2 = _Layers[i1]; - _Layers[i1] = _Layers[i2]; - _Layers[i2] = tmp2; + StyleModule *tmp; + tmp = _StyleModules[i1]; + _StyleModules[i1] = _StyleModules[i2]; + _StyleModules[i2] = tmp; + + StrokeLayer *tmp2; + tmp2 = _Layers[i1]; + _Layers[i1] = _Layers[i2]; + _Layers[i2] = tmp2; } void Canvas::ReplaceStyleModule(unsigned index, StyleModule *iStyleModule) { - unsigned i=0; - for(deque::iterator s=_StyleModules.begin(), send=_StyleModules.end(); - s != send; - ++s) - { - if(i == index) - { - if (*s) - delete *s; - *s = iStyleModule; - break; + unsigned i = 0; + for (deque::iterator s = _StyleModules.begin(), send = _StyleModules.end(); s != send; ++s, ++i) { + if (i == index) { + if (*s) + delete *s; + *s = iStyleModule; + break; + } } - ++i; - } } -void Canvas::setVisible(unsigned index, bool iVisible) { - _StyleModules[index]->setDisplayed(iVisible); +void Canvas::setVisible(unsigned index, bool iVisible) +{ + _StyleModules[index]->setDisplayed(iVisible); } - + void Canvas::setModified(unsigned index, bool iMod) { - _StyleModules[index]->setModified(iMod); + _StyleModules[index]->setModified(iMod); } -void Canvas::resetModified(bool iMod/* =false */) +void Canvas::resetModified(bool iMod/* = false */) { - unsigned size = _StyleModules.size(); - for(unsigned i = 0; i < size; ++i) - setModified(i,iMod); + unsigned int size = _StyleModules.size(); + for (unsigned int i = 0; i < size; ++i) + setModified(i, iMod); } -void Canvas::causalStyleModules(vector& vec, unsigned index) { - unsigned size = _StyleModules.size(); +void Canvas::causalStyleModules(vector& vec, unsigned index) +{ + unsigned int size = _StyleModules.size(); - for(unsigned i = index; i < size; ++i) - if (_StyleModules[i]->getCausal()) - vec.push_back(i); + for (unsigned int i = index; i < size; ++i) { + if (_StyleModules[i]->getCausal()) + vec.push_back(i); + } } void Canvas::Render(const StrokeRenderer *iRenderer) { - for (unsigned i = 0; i < _StyleModules.size(); i++) { - if(!_StyleModules[i]->getDisplayed() || !_Layers[i]) - continue; - _Layers[i]->Render(iRenderer); - } + for (unsigned int i = 0; i < _StyleModules.size(); ++i) { + if (!_StyleModules[i]->getDisplayed() || !_Layers[i]) + continue; + _Layers[i]->Render(iRenderer); + } } void Canvas::RenderBasic(const StrokeRenderer *iRenderer) - { - for (unsigned i = 0; i < _StyleModules.size(); i++) { - if(!_StyleModules[i]->getDisplayed() || !_Layers[i]) - continue; - _Layers[i]->RenderBasic(iRenderer); - } + for (unsigned int i = 0; i < _StyleModules.size(); ++i) { + if (!_StyleModules[i]->getDisplayed() || !_Layers[i]) + continue; + _Layers[i]->RenderBasic(iRenderer); + } } -void Canvas::loadMap(const char *iFileName, const char *iMapName, unsigned int iNbLevels, float iSigma){ - // check whether this map was already loaded: - if(!_maps.empty()){ - mapsMap::iterator m = _maps.find(iMapName); - if(m!=_maps.end()){ - // lazy check for size changes - ImagePyramid * pyramid = (*m).second; - if((pyramid->width() != width()) || (pyramid->height() != height())){ - delete pyramid; - }else{ - return; - } - } - } - string filePath; - if(_MapsPath){ - filePath = _MapsPath; - filePath += iFileName; - }else{ - filePath = iFileName; - } - - //soc - // QImage *qimg; - // QImage newMap(filePath.c_str()); - // if(newMap.isNull()){ - // cout << "Could not load image file " << filePath << endl; - // return; - // } - // qimg = &newMap; +void Canvas::loadMap(const char *iFileName, const char *iMapName, unsigned int iNbLevels, float iSigma) +{ + // check whether this map was already loaded: + if (!_maps.empty()) { + mapsMap::iterator m = _maps.find(iMapName); + if (m != _maps.end()) { + // lazy check for size changes + ImagePyramid * pyramid = (*m).second; + if ((pyramid->width() != width()) || (pyramid->height() != height())) { + delete pyramid; + } + else { + return; + } + } + } + + string filePath; + if (_MapsPath) { + filePath = _MapsPath; + filePath += iFileName; + } + else { + filePath = iFileName; + } + +#if 0 //soc + QImage *qimg; + QImage newMap(filePath.c_str()); + if (newMap.isNull()) { + cout << "Could not load image file " << filePath << endl; + return; + } + qimg = &newMap; +#endif /* OCIO_TODO: support different input color space */ - ImBuf *qimg = IMB_loadiffname(filePath.c_str(), 0, NULL); - if( qimg == 0 ){ + ImBuf *qimg = IMB_loadiffname(filePath.c_str(), 0, NULL); + if (qimg == 0) { cout << "Could not load image file " << filePath << endl; - return; + return; } - // soc - //resize - // QImage scaledImg; - // if((newMap.width()!=width()) || (newMap.height()!=height())){ - // scaledImg = newMap.scaled(width(), height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - // qimg = &scaledImg; - // } +#if 0 // soc + // resize + QImage scaledImg; + if ((newMap.width() != width()) || (newMap.height() != height())) { + scaledImg = newMap.scaled(width(), height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + qimg = &scaledImg; + } +#endif ImBuf *scaledImg; - if( ( qimg->x != width() ) || ( qimg->y != height() ) ){ - scaledImg = IMB_dupImBuf(qimg); - IMB_scaleImBuf(scaledImg, width(), height()); - } - - - // deal with color image - // if(newMap->depth() != 8){ - // int w = newMap->width(); - // int h = newMap->height(); - // QImage *tmp = new QImage(w, h, 8); - // for(unsigned y=0;ypixel(x,y)); - // tmp->setPixel(x,y,c); - // } - // } - // delete newMap; - // newMap = tmp; - // } - - int x,y; - int w = qimg->x; - int h = qimg->y; -int rowbytes = w*4; - GrayImage tmp(w,h); - char *pix; - - for(y=0; yrect + y*rowbytes + x*4; - float c = (pix[0]*11 + pix[1]*16 + pix[2]*5)/32; - tmp.setPixel(x,y,c); - } - } - - // GrayImage blur(w,h); - // GaussianFilter gf(4.f); - // //int bound = gf.getBound(); - // for(y=0; y(&tmp, x,y); - // blur.setPixel(x,y,c); - // } - // } - - GaussianPyramid *pyramid = new GaussianPyramid(tmp, iNbLevels, iSigma); - int ow = pyramid->width(0); - int oh = pyramid->height(0); - string base(iMapName); //soc - for(int i=0; igetNumberOfLevels(); ++i){ - // save each image: - // w = pyramid.width(i); - // h = pyramid.height(i); - - //soc QImage qtmp(ow, oh, QImage::Format_RGB32); - ImBuf *qtmp = IMB_allocImBuf(ow, oh, 32, IB_rect); - -//int k = (1<pixel(x,y,i);//255*pyramid->pixel(x,y,i); - //soc qtmp.setPixel(x,y,qRgb(c,c,c)); - pix = (char*)qtmp->rect + y*rowbytes + x*4; - pix[0] = pix [1] = pix[2] = c; - } - } - //soc qtmp.save(base+QString::number(i)+".bmp", "BMP"); - stringstream filename; - filename << base; - filename << i << ".bmp"; - qtmp->ftype= BMP; - IMB_saveiff(qtmp, const_cast(filename.str().c_str()), 0); - - } - // QImage *qtmp = new QImage(w, h, 32); - // for(y=0;ysetPixel(x,y,qRgb(c,c,c)); - // } - // } - // delete newMap; - // newMap = qtmp; - // - _maps[iMapName] = pyramid; - // newMap->save("toto.bmp", "BMP"); + if ((qimg->x != width()) || (qimg->y != height())) { + scaledImg = IMB_dupImBuf(qimg); + IMB_scaleImBuf(scaledImg, width(), height()); + } + + + // deal with color image +#if 0 + if (newMap->depth() != 8) { + int w = newMap->width(); + int h = newMap->height(); + QImage *tmp = new QImage(w, h, 8); + for (unsigned int y = 0; y < h; ++y) { + for (unsigned int x = 0; x < w; ++x) { + int c = qGray(newMap->pixel(x, y)); + tmp->setPixel(x, y, c); + } + } + delete newMap; + newMap = tmp; + } +#endif + + int x, y; + int w = qimg->x; + int h = qimg->y; + int rowbytes = w * 4; + GrayImage tmp(w, h); + char *pix; + + for (y = 0; y < h; ++y) { + for (x = 0; x < w; ++x) { + pix = (char*)qimg->rect + y * rowbytes + x * 4; + float c = (pix[0] * 11 + pix[1] * 16 + pix[2] * 5) / 32; + tmp.setPixel(x, y, c); + } + } + +#if 0 + GrayImage blur(w, h); + GaussianFilter gf(4.0f); + //int bound = gf.getBound(); + for (y = 0; y < h; ++y) { + for (x = 0; x < w; ++x) { + int c = gf.getSmoothedPixel(&tmp, x, y); + blur.setPixel(x, y, c); + } + } +#endif + + GaussianPyramid *pyramid = new GaussianPyramid(tmp, iNbLevels, iSigma); + int ow = pyramid->width(0); + int oh = pyramid->height(0); + string base(iMapName); //soc + for (int i = 0; i < pyramid->getNumberOfLevels(); ++i) { + // save each image: +#if 0 + w = pyramid.width(i); + h = pyramid.height(i); +#endif + + //soc QImage qtmp(ow, oh, QImage::Format_RGB32); + ImBuf *qtmp = IMB_allocImBuf(ow, oh, 32, IB_rect); + + //int k = (1 << i); + for (y = 0; y < oh; ++y) { + for (x = 0; x < ow; ++x) { + int c = pyramid->pixel(x, y, i); // 255 * pyramid->pixel(x, y, i); + //soc qtmp.setPixel(x, y, qRgb(c, c, c)); + pix = (char*)qtmp->rect + y * rowbytes + x * 4; + pix[0] = pix [1] = pix[2] = c; + } + } + //soc qtmp.save(base + QString::number(i) + ".bmp", "BMP"); + stringstream filename; + filename << base; + filename << i << ".bmp"; + qtmp->ftype = BMP; + IMB_saveiff(qtmp, const_cast(filename.str().c_str()), 0); + } + +#if 0 + QImage *qtmp = new QImage(w, h, 32); + for (y = 0; y < h; ++y) { + for (x = 0; x < w; ++x) { + int c = (int)blur.pixel(x, y); + qtmp->setPixel(x, y, qRgb(c, c, c)); + } + } + delete newMap; + newMap = qtmp; +#endif + + _maps[iMapName] = pyramid; + //newMap->save("toto.bmp", "BMP"); } -float Canvas::readMapPixel(const char *iMapName, int level, int x, int y){ - if(_maps.empty()){ - cout << "readMapPixel warning: no map was loaded "<< endl; - return -1; - } - mapsMap::iterator m = _maps.find(iMapName); - if(m==_maps.end()){ - cout << "readMapPixel warning: no map was loaded with the name " << iMapName << endl; - return -1; - } - ImagePyramid *pyramid = (*m).second; - if((x<0) || (x>=pyramid->width()) || (y<0) || (y>=pyramid->height())) - return 0; - - return pyramid->pixel(x,height()-1-y,level); +float Canvas::readMapPixel(const char *iMapName, int level, int x, int y) +{ + if (_maps.empty()) { + cout << "readMapPixel warning: no map was loaded "<< endl; + return -1; + } + mapsMap::iterator m = _maps.find(iMapName); + if (m == _maps.end()) { + cout << "readMapPixel warning: no map was loaded with the name " << iMapName << endl; + return -1; + } + ImagePyramid *pyramid = (*m).second; + if ((x < 0) || (x >= pyramid->width()) || (y < 0) || (y >= pyramid->height())) + return 0; + + return pyramid->pixel(x, height() - 1 - y, level); } diff --git a/source/blender/freestyle/intern/stroke/Canvas.h b/source/blender/freestyle/intern/stroke/Canvas.h index 707455c87f6..9931bf3c97e 100644 --- a/source/blender/freestyle/intern/stroke/Canvas.h +++ b/source/blender/freestyle/intern/stroke/Canvas.h @@ -1,52 +1,60 @@ -// -// Filename : Canvas.h -// Author(s) : Stephane Grabli -// Purpose : Class to define a canvas designed to draw style modules -// Date of creation : 20/10/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef CANVAS_H -# define CANVAS_H - -# include -# include -# include -# include -# include "../system/FreestyleConfig.h" -# include "StrokeLayer.h" -# include "../geometry/BBox.h" -# include "../geometry/Geom.h" +/* + * ***** 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_CANVAS_H__ +#define __FREESTYLE_CANVAS_H__ + +/** \file blender/freestyle/intern/stroke/Canvas.h + * \ingroup freestyle + * \brief Class to define a canvas designed to draw style modules + * \author Stephane Grabli + * \date 20/10/2002 + */ + +#include +#include +#include +#include + +#include "StrokeLayer.h" + +#include "../geometry/BBox.h" +#include "../geometry/Geom.h" + +#include "../system/FreestyleConfig.h" using namespace Geometry; struct ltstr { - bool operator()(const char* s1, const char* s2) const - { - return strcmp(s1, s2) < 0; - } + bool operator()(const char* s1, const char* s2) const + { + return strcmp(s1, s2) < 0; + } }; class InformationMap; @@ -64,133 +72,178 @@ class StyleModule; /*! Class to define the canvas on which strokes are drawn. * It's used to store state information about the drawing. */ -class LIB_STROKE_EXPORT Canvas +class LIB_STROKE_EXPORT Canvas { public: - /*! Returns a pointer on the Canvas instance */ - static Canvas * getInstance() {return _pInstance;} - typedef std::map mapsMap ; - static const int NB_STEERABLE_VIEWMAP = 5; + /*! Returns a pointer on the Canvas instance */ + static Canvas *getInstance() + { + return _pInstance; + } + + typedef std::map mapsMap; + static const int NB_STEERABLE_VIEWMAP = 5; + protected: - static Canvas *_pInstance; - std::deque _Layers; - std::deque _StyleModules; - FEdge *_SelectedFEdge; - - StrokeRenderer *_Renderer; - StyleModule* _current_sm; - mapsMap _maps; - static const char * _MapsPath; - SteerableViewMap *_steerableViewMap; - bool _basic; + static Canvas *_pInstance; + std::deque _Layers; + std::deque _StyleModules; + FEdge *_SelectedFEdge; + + StrokeRenderer *_Renderer; + StyleModule *_current_sm; + mapsMap _maps; + static const char *_MapsPath; + SteerableViewMap *_steerableViewMap; + bool _basic; public: - /* Builds the Canvas */ - Canvas(); - /* Copy constructor */ - Canvas(const Canvas& iBrother); - /* Destructor */ - virtual ~Canvas(); - - /* operations that need to be done before a draw */ - virtual void preDraw(); - - /* Draw the canvas using the current shader */ - virtual void Draw(); - - /* operations that need to be done after a draw */ - virtual void postDraw(); - - /* Renders the created strokes */ - virtual void Render(const StrokeRenderer *iRenderer); - /* Basic Renders the created strokes */ - virtual void RenderBasic(const StrokeRenderer *iRenderer); - /* Renders a stroke */ - virtual void RenderStroke(Stroke *iStroke) = 0; - - /* init the canvas */ - virtual void init() = 0; - - /* Clears the Canvas (shaders stack, layers stack...)*/ - void Clear(); - - /* Erases the layers */ - virtual void Erase(); - - /* Reads a pixel area from the canvas */ - virtual void readColorPixels(int x, int y,int w, int h, RGBImage& oImage) const = 0; - /* Reads a depth pixel area from the canvas */ - virtual void readDepthPixels(int x, int y,int w, int h, GrayImage& oImage) const = 0; - - /* update the canvas (display) */ - virtual void update() = 0; - - /* checks whether the canvas is empty or not */ - bool isEmpty() const {return (_Layers.empty());} - - /* Maps management */ - /*! Loads an image map. The map will be scaled - * (without preserving the ratio in order - * to fit the actual canvas size.) - * The image must be a gray values image... - * \param iFileName - * The name of the image file - * \param iMapName - * The name that will be used to access - * this image - * \param iNbLevels - * The number of levels in the map pyramid. (default = 4). - * If iNbLevels == 0, the complete pyramid is built. - */ - void loadMap(const char *iFileName, const char *iMapName, unsigned iNbLevels=4, float iSigma = 1.f); - - /*! Reads a pixel value in a map. - * Returns a value between 0 and 1. - * \param iMapName - * The name of the map - * \param level - * The level of the pyramid from which the pixel must - * be read. - * \param x - * The abscissa of the desired pixel specified in level0 coordinate - * system. The origin is the lower left corner. - * \param y - * The ordinate of the desired pixel specified in level0 coordinate - * system. The origin is the lower left corner. - */ - float readMapPixel(const char *iMapName, int level, int x, int y); - - /*! Sets the steerable viewmap */ - void loadSteerableViewMap(SteerableViewMap * iSVM) {_steerableViewMap = iSVM;} - - /*! Returns the steerable VM */ - SteerableViewMap * getSteerableViewMap() {return _steerableViewMap;} - - /*! accessors */ - inline const FEdge * selectedFEdge() const {return _SelectedFEdge;} - inline FEdge * selectedFEdge() {return _SelectedFEdge;} - virtual int width() const = 0; - virtual int height() const = 0; - virtual BBox scene3DBBox() const = 0; - inline const StrokeRenderer * renderer() const {return _Renderer;} - inline StyleModule* getCurrentStyleModule() { return _current_sm; } - virtual bool getRecordFlag() const {return false;} + /* Builds the Canvas */ + Canvas(); + /* Copy constructor */ + Canvas(const Canvas& iBrother); + /* Destructor */ + virtual ~Canvas(); + + /* operations that need to be done before a draw */ + virtual void preDraw(); + + /* Draw the canvas using the current shader */ + virtual void Draw(); + + /* operations that need to be done after a draw */ + virtual void postDraw(); + + /* Renders the created strokes */ + virtual void Render(const StrokeRenderer *iRenderer); + /* Basic Renders the created strokes */ + virtual void RenderBasic(const StrokeRenderer *iRenderer); + /* Renders a stroke */ + virtual void RenderStroke(Stroke *iStroke) = 0; + + /* init the canvas */ + virtual void init() = 0; + + /* Clears the Canvas (shaders stack, layers stack...) */ + void Clear(); + + /* Erases the layers */ + virtual void Erase(); + + /* Reads a pixel area from the canvas */ + virtual void readColorPixels(int x, int y,int w, int h, RGBImage& oImage) const = 0; + /* Reads a depth pixel area from the canvas */ + virtual void readDepthPixels(int x, int y,int w, int h, GrayImage& oImage) const = 0; + + /* update the canvas (display) */ + virtual void update() = 0; + + /* checks whether the canvas is empty or not */ + bool isEmpty() const + { + return (_Layers.empty()); + } + + /* Maps management */ + /*! Loads an image map. The map will be scaled (without preserving the ratio in order to fit the actual + * canvas size.). + * The image must be a gray values image... + * \param iFileName + * The name of the image file + * \param iMapName + * The name that will be used to access this image + * \param iNbLevels + * The number of levels in the map pyramid. (default = 4). + * If iNbLevels == 0, the complete pyramid is built. + */ + void loadMap(const char *iFileName, const char *iMapName, unsigned iNbLevels = 4, float iSigma = 1.0f); + + /*! Reads a pixel value in a map. + * Returns a value between 0 and 1. + * \param iMapName + * The name of the map + * \param level + * The level of the pyramid from which the pixel must be read. + * \param x + * The abscissa of the desired pixel specified in level0 coordinate system. The origin is the lower left corner. + * \param y + * The ordinate of the desired pixel specified in level0 coordinate system. The origin is the lower left corner. + */ + float readMapPixel(const char *iMapName, int level, int x, int y); + + /*! Sets the steerable viewmap */ + void loadSteerableViewMap(SteerableViewMap * iSVM) + { + _steerableViewMap = iSVM; + } + + /*! Returns the steerable VM */ + SteerableViewMap * getSteerableViewMap() + { + return _steerableViewMap; + } + + /*! accessors */ + inline const FEdge *selectedFEdge() const + { + return _SelectedFEdge; + } + + inline FEdge *selectedFEdge() + { + return _SelectedFEdge; + } + + virtual int width() const = 0; + virtual int height() const = 0; + virtual BBox scene3DBBox() const = 0; + + inline const StrokeRenderer *renderer() const + { + return _Renderer; + } + + inline StyleModule *getCurrentStyleModule() + { + return _current_sm; + } + + virtual bool getRecordFlag() const + { + return false; + } + int stroke_count; - /*! modifiers */ - inline void setSelectedFEdge(FEdge *iFEdge) {_SelectedFEdge = iFEdge;} - /*! inserts a shader at pos index+1 */ - void PushBackStyleModule(StyleModule *iStyleModule); - void InsertStyleModule(unsigned index, StyleModule *iStyleModule); - void RemoveStyleModule(unsigned index); - void SwapStyleModules(unsigned i1, unsigned i2); - void ReplaceStyleModule(unsigned index, StyleModule *iStyleModule); - void setVisible(unsigned index, bool iVisible) ; - //inline void setDensityMap(InformationMap* iMap) {_DensityMap = iMap;} - inline void AddLayer(StrokeLayer *iLayer) {_Layers.push_back(iLayer);} - void resetModified(bool iMod=false); - void causalStyleModules(std::vector& vec, unsigned index = 0); - void setModified(unsigned index, bool b); + /*! modifiers */ + inline void setSelectedFEdge(FEdge *iFEdge) + { + _SelectedFEdge = iFEdge; + } + + /*! inserts a shader at pos index+1 */ + void PushBackStyleModule(StyleModule *iStyleModule); + void InsertStyleModule(unsigned index, StyleModule *iStyleModule); + void RemoveStyleModule(unsigned index); + void SwapStyleModules(unsigned i1, unsigned i2); + void ReplaceStyleModule(unsigned index, StyleModule *iStyleModule); + void setVisible(unsigned index, bool iVisible) ; + +#if 0 + inline void setDensityMap(InformationMap *iMap) + { + _DensityMap = iMap; + } +#endif + + inline void AddLayer(StrokeLayer *iLayer) + { + _Layers.push_back(iLayer); + } + + void resetModified(bool iMod = false); + void causalStyleModules(std::vector& vec, unsigned index = 0); + void setModified(unsigned index, bool b); }; -#endif // CANVAS_H +#endif // __FREESTYLE_CANVAS_H__ diff --git a/source/blender/freestyle/intern/stroke/Chain.cpp b/source/blender/freestyle/intern/stroke/Chain.cpp index bf61a3b32cb..59cebbd5da0 100644 --- a/source/blender/freestyle/intern/stroke/Chain.cpp +++ b/source/blender/freestyle/intern/stroke/Chain.cpp @@ -1,151 +1,156 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/stroke/Chain.h + * \ingroup freestyle + * \brief Class to define a chain of viewedges. + * \author Stephane Grabli + * \date 09/01/2003 + */ #include "Chain.h" -#include "../view_map/ViewMapIterators.h" + #include "../view_map/ViewMapAdvancedIterators.h" +#include "../view_map/ViewMapIterators.h" void Chain::push_viewedge_back(ViewEdge *iViewEdge, bool orientation) { - ViewEdge::vertex_iterator v; - ViewEdge::vertex_iterator vend; - ViewEdge::vertex_iterator vfirst; - Vec3r previous, current; - if(true == orientation) - { - v=iViewEdge->vertices_begin(); - vfirst = v; - vend=iViewEdge->vertices_end(); - } - else - { - v=iViewEdge->vertices_last(); - vfirst = v; - vend=iViewEdge->vertices_end(); - } + ViewEdge::vertex_iterator v; + ViewEdge::vertex_iterator vend; + ViewEdge::vertex_iterator vfirst; + Vec3r previous, current; + if (true == orientation) { + v = iViewEdge->vertices_begin(); + vfirst = v; + vend = iViewEdge->vertices_end(); + } + else { + v = iViewEdge->vertices_last(); + vfirst = v; + vend = iViewEdge->vertices_end(); + } - if(!_Vertices.empty()) - { - previous = _Vertices.back()->point2d(); - if(orientation) - ++v; - else - --v; - // Ensure the continuity of underlying FEdges - CurvePoint *cp = _Vertices.back(); // assumed to be instantiated as new CurvePoint(iSVertex, 0, 0.f); - SVertex *sv_first = (*vfirst); - FEdge *fe = _fedgeB->duplicate(); - fe->setVertexB(sv_first); - fe->vertexA()->shape()->AddEdge(fe); - fe->vertexA()->AddFEdge(fe); - fe->vertexB()->AddFEdge(fe); - cp->setA(sv_first); - } - else - previous = (*v)->point2d(); - do{ - current = (*v)->point2d(); - Curve::push_vertex_back(*v); - //_Length += (current-previous).norm(); - previous = current; - if(orientation) - ++v; - else - --v; - }while((v!=vend) && (v!=vfirst)); + if (!_Vertices.empty()) { + previous = _Vertices.back()->point2d(); + if (orientation) + ++v; + else + --v; + // Ensure the continuity of underlying FEdges + CurvePoint *cp = _Vertices.back(); // assumed to be instantiated as new CurvePoint(iSVertex, 0, 0.f); + SVertex *sv_first = (*vfirst); + FEdge *fe = _fedgeB->duplicate(); + fe->setVertexB(sv_first); + fe->vertexA()->shape()->AddEdge(fe); + fe->vertexA()->AddFEdge(fe); + fe->vertexB()->AddFEdge(fe); + cp->setA(sv_first); + } + else { + previous = (*v)->point2d(); + } + do { + current = (*v)->point2d(); + Curve::push_vertex_back(*v); + //_Length += (current - previous).norm(); + previous = current; + if (orientation) + ++v; + else + --v; + } while ((v != vend) && (v != vfirst)); - if(v==vfirst) - { - //Add last one: - current = (*v)->point2d(); - Curve::push_vertex_back(*v); - //_Length += (current-previous).norm(); - } + if (v == vfirst) { + //Add last one: + current = (*v)->point2d(); + Curve::push_vertex_back(*v); + //_Length += (current - previous).norm(); + } - _fedgeB = (orientation) ? iViewEdge->fedgeB() : iViewEdge->fedgeA(); -} + _fedgeB = (orientation) ? iViewEdge->fedgeB() : iViewEdge->fedgeA(); +} void Chain::push_viewedge_front(ViewEdge *iViewEdge, bool orientation) { - orientation = !orientation; - ViewEdge::vertex_iterator v; - ViewEdge::vertex_iterator vend; - ViewEdge::vertex_iterator vfirst; - Vec3r previous, current; - if(true == orientation) - { - v=iViewEdge->vertices_begin(); - vfirst = v; - vend=iViewEdge->vertices_end(); - } - else - { - v=iViewEdge->vertices_last(); - vfirst = v; - vend=iViewEdge->vertices_end(); - } - - if(!_Vertices.empty()) - { - previous = _Vertices.front()->point2d(); - if(orientation) - ++v; - else - --v; - // Ensure the continuity of underlying FEdges - CurvePoint *cp = _Vertices.front(); // assumed to be instantiated as new CurvePoint(iSVertex, 0, 0.f); - SVertex *sv_last = cp->A(); - SVertex *sv_curr = (*v); - FEdge *fe = (orientation) ? iViewEdge->fedgeA() : iViewEdge->fedgeB(); - FEdge *fe2 = fe->duplicate(); - fe2->setVertexA(sv_curr); - fe2->setVertexB(sv_last); - sv_last->AddFEdge(fe2); - sv_curr->AddFEdge(fe2); - sv_curr->shape()->AddEdge(fe2); - } - else - previous = (*v)->point2d(); - do{ - current = (*v)->point2d(); - Curve::push_vertex_front((*v)); - //_Length += (current-previous).norm(); - previous = current; - if(orientation) - ++v; - else - --v; - }while((v!=vend) && (v!=vfirst)); - - if(v==vfirst) - { - //Add last one: - current = (*v)->point2d(); - Curve::push_vertex_front(*v); - //_Length += (current-previous).norm(); - } - - if (!_fedgeB) - _fedgeB = (orientation) ? iViewEdge->fedgeB() : iViewEdge->fedgeA(); -} + orientation = !orientation; + ViewEdge::vertex_iterator v; + ViewEdge::vertex_iterator vend; + ViewEdge::vertex_iterator vfirst; + Vec3r previous, current; + if (true == orientation) { + v = iViewEdge->vertices_begin(); + vfirst = v; + vend = iViewEdge->vertices_end(); + } + else { + v = iViewEdge->vertices_last(); + vfirst = v; + vend = iViewEdge->vertices_end(); + } + if (!_Vertices.empty()) { + previous = _Vertices.front()->point2d(); + if (orientation) + ++v; + else + --v; + // Ensure the continuity of underlying FEdges + CurvePoint *cp = _Vertices.front(); // assumed to be instantiated as new CurvePoint(iSVertex, 0, 0.f); + SVertex *sv_last = cp->A(); + SVertex *sv_curr = (*v); + FEdge *fe = (orientation) ? iViewEdge->fedgeA() : iViewEdge->fedgeB(); + FEdge *fe2 = fe->duplicate(); + fe2->setVertexA(sv_curr); + fe2->setVertexB(sv_last); + sv_last->AddFEdge(fe2); + sv_curr->AddFEdge(fe2); + sv_curr->shape()->AddEdge(fe2); + } + else { + previous = (*v)->point2d(); + } + do { + current = (*v)->point2d(); + Curve::push_vertex_front((*v)); + //_Length += (current - previous).norm(); + previous = current; + if (orientation) + ++v; + else + --v; + } while ((v != vend) && (v != vfirst)); + if (v == vfirst) { + //Add last one: + current = (*v)->point2d(); + Curve::push_vertex_front(*v); + //_Length += (current - previous).norm(); + } + if (!_fedgeB) + _fedgeB = (orientation) ? iViewEdge->fedgeB() : iViewEdge->fedgeA(); +} diff --git a/source/blender/freestyle/intern/stroke/Chain.h b/source/blender/freestyle/intern/stroke/Chain.h index 0dc3dd21a28..425761d28ef 100644 --- a/source/blender/freestyle/intern/stroke/Chain.h +++ b/source/blender/freestyle/intern/stroke/Chain.h @@ -1,87 +1,116 @@ -// -// Filename : Chain.h -// Author(s) : Stephane Grabli -// Purpose : Class to define a chain of viewedges. -// Date of creation : 09/01/2003 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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_CHAIN_H__ +#define __FREESTYLE_CHAIN_H__ +/** \file blender/freestyle/intern/stroke/Chain.h + * \ingroup freestyle + * \brief Class to define a chain of viewedges. + * \author Stephane Grabli + * \date 09/01/2003 + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +#include "Curve.h" -#ifndef CHAIN_H -# define CHAIN_H +#include "../view_map/ViewMap.h" -# include "../view_map/ViewMap.h" -# include "Curve.h" -/*! Class to represent a 1D elements issued - * from the chaining process. - * A Chain is the last step before the Stroke and - * is used in the Splitting and Creation processes. +/*! Class to represent a 1D elements issued from the chaining process. + * A Chain is the last step before the Stroke and is used in the Splitting and Creation processes. */ class Chain : public Curve { protected: - // tmp - Id * _splittingId; - FEdge *_fedgeB; // the last FEdge of the ViewEdge passed to the last call for push_viewedge_back(). + // tmp + Id * _splittingId; + FEdge *_fedgeB; // the last FEdge of the ViewEdge passed to the last call for push_viewedge_back(). + public: - /*! Defult constructor. */ - Chain() : Curve() {_splittingId=0;_fedgeB=0;} - /*! Builds a chain from its Id. */ - Chain(const Id& id) : Curve(id) {_splittingId=0;_fedgeB=0;} - /*! Copy Constructor */ - Chain(const Chain& iBrother) : Curve(iBrother) {_splittingId=iBrother._splittingId;_fedgeB=iBrother._fedgeB;} - /*! Destructor. */ - virtual ~Chain() { - // only the last splitted deletes this id - if(_splittingId){ - if(*_splittingId == _Id) - delete _splittingId; - } - } - /*! Returns the string "Chain" */ - virtual string getExactTypeName() const { - return "Chain"; - } + /*! Defult constructor. */ + Chain() : Curve() + { + _splittingId = 0; + _fedgeB = 0; + } + + /*! Builds a chain from its Id. */ + Chain(const Id& id) : Curve(id) + { + _splittingId = 0; + _fedgeB = 0; + } + + /*! Copy Constructor */ + Chain(const Chain& iBrother) : Curve(iBrother) + { + _splittingId = iBrother._splittingId; + _fedgeB = iBrother._fedgeB; + } + + /*! Destructor. */ + virtual ~Chain() { + // only the last splitted deletes this id + if (_splittingId) { + if (*_splittingId == _Id) + delete _splittingId; + } + } + + /*! Returns the string "Chain" */ + virtual string getExactTypeName() const + { + return "Chain"; + } + + /*! Adds a ViewEdge at the end of the chain + * \param iViewEdge + * The ViewEdge that must be added. + * \param orientation + * The orientation with which this ViewEdge must be processed. + */ + void push_viewedge_back(ViewEdge *iViewEdge, bool orientation); + + /*! Adds a ViewEdge at the beginning of the chain + * \param iViewEdge + * The ViewEdge that must be added. + * \param orientation + * The orientation with which this ViewEdge must be processed. + */ + void push_viewedge_front(ViewEdge *iViewEdge, bool orientation); - /*! Adds a ViewEdge at the end of the chain - * \param iViewEdge - * The ViewEdge that must be added. - * \param orientation - * The orientation with which this ViewEdge - * must be processed. - */ - void push_viewedge_back(ViewEdge *iViewEdge, bool orientation) ; - /*! Adds a ViewEdge at the beginning of the chain - * \param iViewEdge - * The ViewEdge that must be added. - * \param orientation - * The orientation with which this ViewEdge - * must be processed. - */ - void push_viewedge_front(ViewEdge *iViewEdge, bool orientation) ; + inline void setSplittingId(Id *sid) + { + _splittingId = sid; + } - inline void setSplittingId(Id * sid){_splittingId = sid;} - inline Id* getSplittingId() {return _splittingId;} + inline Id* getSplittingId() + { + return _splittingId; + } }; -#endif // CHAIN_H +#endif // __FREESTYLE_CHAIN_H__ diff --git a/source/blender/freestyle/intern/stroke/ChainingIterators.cpp b/source/blender/freestyle/intern/stroke/ChainingIterators.cpp index c54ee6ea1ee..1883e494eab 100644 --- a/source/blender/freestyle/intern/stroke/ChainingIterators.cpp +++ b/source/blender/freestyle/intern/stroke/ChainingIterators.cpp @@ -1,96 +1,120 @@ +/* + * ***** 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 ***** + */ + +/** \file blender/freestyle/intern/stroke/ChainingIterators.cpp + * \ingroup freestyle + * \brief Chaining iterators + * \author Stephane Grabli + * \date 01/07/2003 + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// #include "ChainingIterators.h" + #include "../system/TimeStamp.h" -ViewEdge* AdjacencyIterator::operator*() { - return (*_internalIterator).first; +ViewEdge* AdjacencyIterator::operator*() +{ + return (*_internalIterator).first; } -bool AdjacencyIterator::isIncoming() const{ - return (*_internalIterator).second; + +bool AdjacencyIterator::isIncoming() const +{ + return (*_internalIterator).second; } -int AdjacencyIterator::increment(){ - ++_internalIterator; - while((!_internalIterator.isEnd()) && (!isValid((*_internalIterator).first))) - ++_internalIterator; - return 0; +int AdjacencyIterator::increment() +{ + ++_internalIterator; + while((!_internalIterator.isEnd()) && (!isValid((*_internalIterator).first))) + ++_internalIterator; + return 0; } -bool AdjacencyIterator::isValid(ViewEdge* edge){ - if(_restrictToSelection) - if(edge->getTimeStamp() != TimeStamp::instance()->getTimeStamp()) - return false; - if(_restrictToUnvisited) - if(edge->getChainingTimeStamp() > TimeStamp::instance()->getTimeStamp()) - return false; - return true; +bool AdjacencyIterator::isValid(ViewEdge* edge) +{ + if (_restrictToSelection) { + if (edge->getTimeStamp() != TimeStamp::instance()->getTimeStamp()) + return false; + } + if (_restrictToUnvisited) { + if (edge->getChainingTimeStamp() > TimeStamp::instance()->getTimeStamp()) + return false; + } + return true; } -int ChainingIterator::increment() { - _increment = true; - ViewVertex * vertex = getVertex(); - if(!vertex){ - _edge = 0; - return 0; - } - AdjacencyIterator it = AdjacencyIterator(vertex, _restrictToSelection, _restrictToUnvisited); - if(it.isEnd()) { - _edge = 0; +int ChainingIterator::increment() +{ + _increment = true; + ViewVertex * vertex = getVertex(); + if (!vertex) { + _edge = 0; + return 0; + } + AdjacencyIterator it = AdjacencyIterator(vertex, _restrictToSelection, _restrictToUnvisited); + if (it.isEnd()) { + _edge = 0; + return 0; + } + if (traverse(it) < 0) + return -1; + _edge = result; + if(_edge == 0) + return 0; + if(_edge->A() == vertex) + _orientation = true; + else + _orientation = false; return 0; - } - if (traverse(it) < 0) - return -1; - _edge = result; - if(_edge == 0) - return 0; - if(_edge->A() == vertex) - _orientation = true; - else - _orientation = false; - return 0; } -int ChainingIterator::decrement() { - _increment = false; - ViewVertex * vertex = getVertex(); - if(!vertex){ - _edge = 0; - return 0; - } - AdjacencyIterator it = AdjacencyIterator(vertex, _restrictToSelection, _restrictToUnvisited); - if(it.isEnd()) { - _edge = 0; +int ChainingIterator::decrement() +{ + _increment = false; + ViewVertex * vertex = getVertex(); + if (!vertex) { + _edge = 0; + return 0; + } + AdjacencyIterator it = AdjacencyIterator(vertex, _restrictToSelection, _restrictToUnvisited); + if (it.isEnd()) { + _edge = 0; + return 0; + } + if (traverse(it) < 0) + return -1; + _edge = result; + if(_edge == 0) + return 0; + if(_edge->B() == vertex) + _orientation = true; + else + _orientation = false; return 0; - } - if (traverse(it) < 0) - return -1; - _edge = result; - if(_edge == 0) - return 0; - if(_edge->B() == vertex) - _orientation = true; - else - _orientation = false; - return 0; } // @@ -98,73 +122,81 @@ int ChainingIterator::decrement() { // /////////////////////////////////////////////////////////// -int ChainSilhouetteIterator::traverse(const AdjacencyIterator& ait){ - AdjacencyIterator it(ait); - ViewVertex* nextVertex = getVertex(); - // we can't get a NULL nextVertex here, it was intercepted - // before - if(nextVertex->getNature() & Nature::T_VERTEX){ - TVertex * tvertex = (TVertex*)nextVertex; - ViewEdge *mate = (tvertex)->mate(getCurrentEdge()); - while(!it.isEnd()){ - ViewEdge *ve = *it; - if(ve == mate) { - result = ve; - return 0; - } - ++it; - } - result = 0; - return 0; - } - if(nextVertex->getNature() & Nature::NON_T_VERTEX){ - //soc NonTVertex * nontvertex = (NonTVertex*)nextVertex; - ViewEdge * newEdge(0); - // we'll try to chain the edges by keeping the same nature... - // the preseance order is : SILHOUETTE, BORDER, CREASE, SUGGESTIVE, VALLEY, RIDGE - Nature::EdgeNature natures[6] = {Nature::SILHOUETTE, Nature::BORDER, Nature::CREASE, Nature::SUGGESTIVE_CONTOUR, Nature::VALLEY, Nature::RIDGE}; - for(unsigned i=0; i<6; ++i){ - if(getCurrentEdge()->getNature() & natures[i]){ - int n = 0; - while(!it.isEnd()){ - ViewEdge *ve = *it; - if(ve->getNature() & natures[i]){ - ++n; - newEdge = ve; - } - ++it; - } - if(n == 1){ - result = newEdge; - }else{ - result = 0; - } +int ChainSilhouetteIterator::traverse(const AdjacencyIterator& ait) +{ + AdjacencyIterator it(ait); + ViewVertex* nextVertex = getVertex(); + // we can't get a NULL nextVertex here, it was intercepted before + if (nextVertex->getNature() & Nature::T_VERTEX) { + TVertex * tvertex = (TVertex*)nextVertex; + ViewEdge *mate = (tvertex)->mate(getCurrentEdge()); + while (!it.isEnd()) { + ViewEdge *ve = *it; + if (ve == mate) { + result = ve; + return 0; + } + ++it; + } + result = 0; return 0; - } - } - } - result = 0; - return 0; + } + if (nextVertex->getNature() & Nature::NON_T_VERTEX) { + //soc NonTVertex * nontvertex = (NonTVertex*)nextVertex; + ViewEdge * newEdge(0); + // we'll try to chain the edges by keeping the same nature... + // the preseance order is : SILHOUETTE, BORDER, CREASE, SUGGESTIVE, VALLEY, RIDGE + Nature::EdgeNature natures[6] = { + Nature::SILHOUETTE, + Nature::BORDER, + Nature::CREASE, + Nature::SUGGESTIVE_CONTOUR, + Nature::VALLEY, + Nature::RIDGE + }; + for (unsigned int i = 0; i < 6; ++i) { + if (getCurrentEdge()->getNature() & natures[i]) { + int n = 0; + while (!it.isEnd()) { + ViewEdge *ve = *it; + if(ve->getNature() & natures[i]) { + ++n; + newEdge = ve; + } + ++it; + } + if (n == 1) { + result = newEdge; + } + else { + result = 0; + } + return 0; + } + } + } + result = 0; + return 0; } -int ChainPredicateIterator::traverse(const AdjacencyIterator& ait){ - AdjacencyIterator it(ait); - // Iterates over next edges to see if one of them - // respects the predicate: - while(!it.isEnd()) { - ViewEdge *ve = *it; - if (_unary_predicate->operator()(*ve) < 0) - return -1; - if (_unary_predicate->result) { - if (_binary_predicate->operator()(*(getCurrentEdge()), *(ve)) < 0) - return -1; - if (_binary_predicate->result) { - result = ve; - return 0; - } +int ChainPredicateIterator::traverse(const AdjacencyIterator& ait) +{ + AdjacencyIterator it(ait); + // Iterates over next edges to see if one of them respects the predicate: + while (!it.isEnd()) { + ViewEdge *ve = *it; + if (_unary_predicate->operator()(*ve) < 0) + return -1; + if (_unary_predicate->result) { + if (_binary_predicate->operator()(*(getCurrentEdge()), *(ve)) < 0) + return -1; + if (_binary_predicate->result) { + result = ve; + return 0; + } + } + ++it; } - ++it; - } - result = 0; - return 0; -} + result = 0; + return 0; +} diff --git a/source/blender/freestyle/intern/stroke/ChainingIterators.h b/source/blender/freestyle/intern/stroke/ChainingIterators.h index fec8d5ab6dc..66a57061ec9 100644 --- a/source/blender/freestyle/intern/stroke/ChainingIterators.h +++ b/source/blender/freestyle/intern/stroke/ChainingIterators.h @@ -1,42 +1,51 @@ -// -// Filename : ChainingIterators -// Author : Stephane Grabli -// Purpose : Chaining iterators -// Date of creation : 01/07/2003 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// -#ifndef CHAININGITERATORS_H -# define CHAININGITERATORS_H +#ifndef __FREESTYLE_CHAINING_ITERATORS_H__ +#define __FREESTYLE_CHAINING_ITERATORS_H__ + +/** \file blender/freestyle/intern/stroke/ChainingIterators.h + * \ingroup freestyle + * \brief Chaining iterators + * \author Stephane Grabli + * \date 01/07/2003 + */ + +#include -# include "../view_map/ViewMap.h" -# include "../view_map/ViewMapIterators.h" -# include "../view_map/ViewMapAdvancedIterators.h" -# include -# include "Predicates1D.h" +#include "Predicates1D.h" + +#include "../python/Director.h" #include "../system/Iterator.h" //soc -# include "../python/Director.h" +#include "../view_map/ViewMap.h" +#include "../view_map/ViewMapIterators.h" +#include "../view_map/ViewMapAdvancedIterators.h" //using namespace ViewEdgeInternal; @@ -44,73 +53,95 @@ // Adjacency iterator used in the chaining process // /////////////////////////////////////////////////////////// -class LIB_STROKE_EXPORT AdjacencyIterator : public Iterator { +class LIB_STROKE_EXPORT AdjacencyIterator : public Iterator +{ protected: - ViewVertexInternal::orientedViewEdgeIterator _internalIterator; - bool _restrictToSelection; - bool _restrictToUnvisited; + ViewVertexInternal::orientedViewEdgeIterator _internalIterator; + bool _restrictToSelection; + bool _restrictToUnvisited; + public: - AdjacencyIterator(){ - _restrictToSelection = true; - _restrictToUnvisited = true; - } - AdjacencyIterator(ViewVertex *iVertex, bool iRestrictToSelection = true, bool iRestrictToUnvisited = true){ - _restrictToSelection = iRestrictToSelection; - _restrictToUnvisited = iRestrictToUnvisited; - _internalIterator = iVertex->edgesBegin(); - while((!_internalIterator.isEnd()) && (!isValid((*_internalIterator).first))) - ++_internalIterator; - } - AdjacencyIterator(const AdjacencyIterator& iBrother){ - _internalIterator = iBrother._internalIterator; - _restrictToSelection = iBrother._restrictToSelection; - _restrictToUnvisited = iBrother._restrictToUnvisited; - } - AdjacencyIterator& operator=(const AdjacencyIterator& iBrother) { - _internalIterator = iBrother._internalIterator; - _restrictToSelection = iBrother._restrictToSelection; - _restrictToUnvisited = iBrother._restrictToUnvisited; - return *this; - } - virtual ~AdjacencyIterator(){ - } - - virtual string getExactTypeName() const { - return "AdjacencyIterator"; - } - - virtual inline bool isEnd() const { - return _internalIterator.isEnd(); - } - virtual inline bool isBegin() const { - return _internalIterator.isBegin(); - } - /*! Returns true if the current ViewEdge is is coming - * towards the iteration vertex. False otherwise. - */ - bool isIncoming() const ; - - /*! Returns a *pointer* to the pointed ViewEdge. */ - virtual ViewEdge* operator*() ; - virtual ViewEdge* operator->() {return operator*();} - virtual AdjacencyIterator& operator++() { - increment(); - return *this; - } - virtual AdjacencyIterator operator++(int) { - AdjacencyIterator tmp(*this); - increment(); - return tmp; - } - virtual int increment(); - - virtual int decrement(){ - cerr << "Warning: method decrement() not implemented" << endl; - return 0; - } + AdjacencyIterator() + { + _restrictToSelection = true; + _restrictToUnvisited = true; + } + + AdjacencyIterator(ViewVertex *iVertex, bool iRestrictToSelection = true, bool iRestrictToUnvisited = true) + { + _restrictToSelection = iRestrictToSelection; + _restrictToUnvisited = iRestrictToUnvisited; + _internalIterator = iVertex->edgesBegin(); + while ((!_internalIterator.isEnd()) && (!isValid((*_internalIterator).first))) + ++_internalIterator; + } + + AdjacencyIterator(const AdjacencyIterator& iBrother) + { + _internalIterator = iBrother._internalIterator; + _restrictToSelection = iBrother._restrictToSelection; + _restrictToUnvisited = iBrother._restrictToUnvisited; + } + + AdjacencyIterator& operator=(const AdjacencyIterator& iBrother) + { + _internalIterator = iBrother._internalIterator; + _restrictToSelection = iBrother._restrictToSelection; + _restrictToUnvisited = iBrother._restrictToUnvisited; + return *this; + } + + virtual ~AdjacencyIterator() {} + + virtual string getExactTypeName() const + { + return "AdjacencyIterator"; + } + + virtual inline bool isEnd() const + { + return _internalIterator.isEnd(); + } + + virtual inline bool isBegin() const + { + return _internalIterator.isBegin(); + } + + /*! Returns true if the current ViewEdge is is coming towards the iteration vertex. False otherwise. */ + bool isIncoming() const; + + /*! Returns a *pointer* to the pointed ViewEdge. */ + virtual ViewEdge* operator*(); + + virtual ViewEdge* operator->() + { + return operator*(); + } + + virtual AdjacencyIterator& operator++() + { + increment(); + return *this; + } + + virtual AdjacencyIterator operator++(int) + { + AdjacencyIterator tmp(*this); + increment(); + return tmp; + } + + virtual int increment(); + + virtual int decrement() + { + cerr << "Warning: method decrement() not implemented" << endl; + return 0; + } protected: - bool isValid(ViewEdge* edge); + bool isValid(ViewEdge* edge); }; // @@ -119,121 +150,114 @@ protected: /////////////////////////////////////////////////////////// /*! Base class for chaining iterators. - * This class is designed to be overloaded - * in order to describe chaining rules. - * It makes the works of chaining rules description - * easier. - * The two main methods that need to overloaded are - * traverse() and init(). + * This class is designed to be overloaded in order to describe chaining rules. + * It makes the works of chaining rules description easier. + * The two main methods that need to overloaded are traverse() and init(). * traverse() tells which ViewEdge to follow, among the adjacent ones. - * If you specify restriction rules (such as "Chain only - * ViewEdges of the selection"), they will be included - * in the adjacency iterator. (i.e, the adjacent iterator - * will only stop on "valid" edges). + * If you specify restriction rules (such as "Chain only ViewEdges of the selection"), they will be included + * in the adjacency iterator. (i.e, the adjacent iterator will only stop on "valid" edges). */ -class LIB_STROKE_EXPORT ChainingIterator : public ViewEdgeInternal::ViewEdgeIterator{ +class LIB_STROKE_EXPORT ChainingIterator : public ViewEdgeInternal::ViewEdgeIterator +{ protected: - bool _restrictToSelection; - bool _restrictToUnvisited; - bool _increment; //true if we're currently incrementing, false when decrementing - + bool _restrictToSelection; + bool _restrictToUnvisited; + bool _increment; //true if we're currently incrementing, false when decrementing + public: - ViewEdge *result; PyObject *py_c_it; - - /*! Builds a Chaining Iterator from the first ViewEdge used for iteration - * and its orientation. - * \param iRestrictToSelection - * Indicates whether to force the chaining to stay within - * the set of selected ViewEdges or not. - * \param iRestrictToUnvisited - * Indicates whether a ViewEdge that has already been chained - * must be ignored ot not. - * \param begin - * The ViewEdge from which to start the chain. - * \param orientation - * The direction to follow to explore the graph. If true, - * the direction indicated by the first ViewEdge is used. - */ - ChainingIterator(bool iRestrictToSelection = true, bool iRestrictToUnvisited = true, ViewEdge* begin = 0, bool orientation = true) - : ViewEdgeIterator(begin, orientation) { - _restrictToSelection = iRestrictToSelection; - _restrictToUnvisited = iRestrictToUnvisited; - _increment = true; - py_c_it = 0; - } - - /*! Copy constructor */ - ChainingIterator(const ChainingIterator& brother) - : ViewEdgeIterator(brother) { - _restrictToSelection = brother._restrictToSelection; - _restrictToUnvisited = brother._restrictToUnvisited; - _increment = brother._increment; - py_c_it = brother.py_c_it; - } - - /*! Returns the string "ChainingIterator" */ - virtual string getExactTypeName() const { - return "ChainingIterator"; - } - - /*! Inits the iterator context. - * This method is called each time - * a new chain is started. - * It can be used to reset some - * history information that you - * might want to keep. - */ - virtual int init() { - return Director_BPy_ChainingIterator_init( this ); - } - - /*! This method iterates over the potential next - * ViewEdges and returns the one that will be - * followed next. - * returns the next ViewEdge to follow or - * 0 when the end of the chain is reached. - * \param it - * The iterator over the ViewEdges adjacent to - * the end vertex of the current ViewEdge. - * The Adjacency iterator reflects the restriction - * rules by only iterating over the valid ViewEdges. - */ - virtual int traverse(const AdjacencyIterator &it){ - return Director_BPy_ChainingIterator_traverse( this, const_cast(it) ); - } - - /* accessors */ - /*! Returns true if the orientation of the current ViewEdge - * corresponds to its natural orientation - */ - //inline bool getOrientation() const {} - /*! Returns the vertex which is the next crossing */ - inline ViewVertex * getVertex() { - if(_increment){ - if(_orientation){ - return _edge->B(); - }else{ - return _edge->A(); - } - }else{ - if(_orientation){ - return _edge->A(); - }else{ - return _edge->B(); - } - } - } - - /*! Returns true if the current iteration is an incrementation */ - inline bool isIncrementing() const{ - return _increment; - } - - /* increments.*/ - virtual int increment() ; - virtual int decrement() ; + + /*! Builds a Chaining Iterator from the first ViewEdge used for iteration and its orientation. + * \param iRestrictToSelection + * Indicates whether to force the chaining to stay within the set of selected ViewEdges or not. + * \param iRestrictToUnvisited + * Indicates whether a ViewEdge that has already been chained must be ignored ot not. + * \param begin + * The ViewEdge from which to start the chain. + * \param orientation + * The direction to follow to explore the graph. If true, the direction indicated by the first ViewEdge is used. + */ + ChainingIterator(bool iRestrictToSelection = true, bool iRestrictToUnvisited = true, ViewEdge* begin = 0, + bool orientation = true) + : ViewEdgeIterator(begin, orientation) + { + _restrictToSelection = iRestrictToSelection; + _restrictToUnvisited = iRestrictToUnvisited; + _increment = true; + py_c_it = 0; + } + + /*! Copy constructor */ + ChainingIterator(const ChainingIterator& brother) + : ViewEdgeIterator(brother) + { + _restrictToSelection = brother._restrictToSelection; + _restrictToUnvisited = brother._restrictToUnvisited; + _increment = brother._increment; + py_c_it = brother.py_c_it; + } + + /*! Returns the string "ChainingIterator" */ + virtual string getExactTypeName() const + { + return "ChainingIterator"; + } + + /*! Inits the iterator context. + * This method is called each time a new chain is started. + * It can be used to reset some history information that you might want to keep. + */ + virtual int init() + { + return Director_BPy_ChainingIterator_init(this); + } + + /*! This method iterates over the potential next ViewEdges and returns the one that will be followed next. + * returns the next ViewEdge to follow or 0 when the end of the chain is reached. + * \param it + * The iterator over the ViewEdges adjacent to the end vertex of the current ViewEdge. + * The Adjacency iterator reflects the restriction rules by only iterating over the valid ViewEdges. + */ + virtual int traverse(const AdjacencyIterator &it) + { + return Director_BPy_ChainingIterator_traverse(this, const_cast(it)); + } + + /* accessors */ + /*! Returns true if the orientation of the current ViewEdge corresponds to its natural orientation */ + //inline bool getOrientation() const {} + + /*! Returns the vertex which is the next crossing */ + inline ViewVertex * getVertex() + { + if (_increment) { + if (_orientation) { + return _edge->B(); + } + else { + return _edge->A(); + } + } + else { + if (_orientation) { + return _edge->A(); + } + else { + return _edge->B(); + } + } + } + + /*! Returns true if the current iteration is an incrementation */ + inline bool isIncrementing() const + { + return _increment; + } + + /* increments.*/ + virtual int increment(); + virtual int decrement(); }; // @@ -243,51 +267,46 @@ public: /*! A ViewEdge Iterator used to follow ViewEdges the most naturally. * For example, it will follow visible ViewEdges of same nature. - * As soon, as the nature or the visibility changes, the iteration - * stops (by setting the pointed ViewEdge to 0). - * In the case of an iteration over a set of ViewEdge that are both - * Silhouette and Crease, there will be a precedence of the silhouette - * over the crease criterion. + * As soon, as the nature or the visibility changes, the iteration stops (by setting the pointed ViewEdge to 0). + * In the case of an iteration over a set of ViewEdge that are both Silhouette and Crease, there will be a precedence + * of the silhouette over the crease criterion. */ class LIB_STROKE_EXPORT ChainSilhouetteIterator : public ChainingIterator { public: - /*! Builds a ChainSilhouetteIterator from the first ViewEdge used for iteration - * and its orientation. - * \param iRestrictToSelection - * Indicates whether to force the chaining to stay within - * the set of selected ViewEdges or not. - * \param begin - * The ViewEdge from where to start the iteration. - * \param orientation - * If true, we'll look for the next ViewEdge among the - * ViewEdges that surround the ending ViewVertex of begin. - * If false, we'll search over the ViewEdges surrounding - * the ending ViewVertex of begin. - */ - ChainSilhouetteIterator(bool iRestrictToSelection = true, ViewEdge* begin = NULL, bool orientation = true) - : ChainingIterator(iRestrictToSelection, true, begin, orientation) {} - - /*! Copy constructor */ - ChainSilhouetteIterator(const ChainSilhouetteIterator& brother) - : ChainingIterator(brother) {} - - /*! Returns the string "ChainSilhouetteIterator" */ - virtual string getExactTypeName() const { - return "ChainSilhouetteIterator"; - } - - /*! This method iterates over the potential next - * ViewEdges and returns the one that will be - * followed next. - * When reaching the end of a chain, 0 is returned. - */ - virtual int traverse(const AdjacencyIterator& it); + /*! Builds a ChainSilhouetteIterator from the first ViewEdge used for iteration and its orientation. + * \param iRestrictToSelection + * Indicates whether to force the chaining to stay within the set of selected ViewEdges or not. + * \param begin + * The ViewEdge from where to start the iteration. + * \param orientation + * If true, we'll look for the next ViewEdge among the ViewEdges that surround the ending ViewVertex of begin. + * If false, we'll search over the ViewEdges surrounding the ending ViewVertex of begin. + */ + ChainSilhouetteIterator(bool iRestrictToSelection = true, ViewEdge* begin = NULL, bool orientation = true) + : ChainingIterator(iRestrictToSelection, true, begin, orientation) + { + } + + /*! Copy constructor */ + ChainSilhouetteIterator(const ChainSilhouetteIterator& brother) : ChainingIterator(brother) {} + + /*! Returns the string "ChainSilhouetteIterator" */ + virtual string getExactTypeName() const + { + return "ChainSilhouetteIterator"; + } + + /*! This method iterates over the potential next ViewEdges and returns the one that will be followed next. + * When reaching the end of a chain, 0 is returned. + */ + virtual int traverse(const AdjacencyIterator& it); /*! Inits the iterator context */ - virtual int init() { - return 0; - } + virtual int init() + { + return 0; + } }; // @@ -295,100 +314,94 @@ public: // /////////////////////////////////////////////////////////// -/*! A "generic" user-controlled ViewEdge iterator. This iterator - * is in particular built from a unary predicate and a binary predicate. - * First, the unary predicate is evaluated for all potential next ViewEdges - * in order to only keep the ones respecting a certain constraint. - * Then, the binary predicate is evaluated on the current ViewEdge - * together with each ViewEdge of the previous selection. The first - * ViewEdge respecting both the unary predicate and the binary predicate - * is kept as the next one. If none of the potential next ViewEdge respects - * these 2 predicates, 0 is returned. +/*! A "generic" user-controlled ViewEdge iterator. This iterator is in particular built from a unary predicate and + * a binary predicate. + * First, the unary predicate is evaluated for all potential next ViewEdges in order to only keep the ones respecting + * a certain constraint. + * Then, the binary predicate is evaluated on the current ViewEdge together with each ViewEdge of the previous + * selection. The first ViewEdge respecting both the unary predicate and the binary predicate is kept as the next one. + * If none of the potential next ViewEdge respects these 2 predicates, 0 is returned. */ class LIB_STROKE_EXPORT ChainPredicateIterator : public ChainingIterator { protected: - BinaryPredicate1D *_binary_predicate; // the caller is responsible for the deletion of this object - UnaryPredicate1D *_unary_predicate; // the caller is responsible for the deletion of this object -public: - - /*! Builds a ChainPredicateIterator from a starting ViewEdge and its orientation. - * \param iRestrictToSelection - * Indicates whether to force the chaining to stay within - * the set of selected ViewEdges or not. - * \param iRestrictToUnvisited - * Indicates whether a ViewEdge that has already been chained - * must be ignored ot not. - * \param begin - * The ViewEdge from where to start the iteration. - * \param orientation - * If true, we'll look for the next ViewEdge among the - * ViewEdges that surround the ending ViewVertex of begin. - * If false, we'll search over the ViewEdges surrounding - * the ending ViewVertex of begin. - */ - ChainPredicateIterator(bool iRestrictToSelection = true, bool iRestrictToUnvisited = true, ViewEdge* begin = NULL, bool orientation = true) - : ChainingIterator(iRestrictToSelection, iRestrictToUnvisited, begin, orientation) { - _binary_predicate = 0; - _unary_predicate = 0; - } - - /*! Builds a ChainPredicateIterator from a unary predicate, a binary predicate, a starting ViewEdge and its orientation. - * \param iRestrictToSelection - * Indicates whether to force the chaining to stay within - * the set of selected ViewEdges or not. - * \param iRestrictToUnvisited - * Indicates whether a ViewEdge that has already been chained - * must be ignored ot not. - * \param upred - * The unary predicate that the next ViewEdge must satisfy. - * \param bpred - * The binary predicate that the next ViewEdge must satisfy - * together with the actual pointed ViewEdge. - * \param begin - * The ViewEdge from where to start the iteration. - * \param orientation - * If true, we'll look for the next ViewEdge among the - * ViewEdges that surround the ending ViewVertex of begin. - * If false, we'll search over the ViewEdges surrounding - * the ending ViewVertex of begin. - */ - ChainPredicateIterator(UnaryPredicate1D& upred, BinaryPredicate1D& bpred, bool iRestrictToSelection = true, bool iRestrictToUnvisited = true, ViewEdge* begin = NULL, bool orientation = true) - : ChainingIterator(iRestrictToSelection, iRestrictToUnvisited, begin, orientation) { - _unary_predicate = &upred; - _binary_predicate = &bpred; - } - - /*! Copy constructor */ - ChainPredicateIterator(const ChainPredicateIterator& brother) - : ChainingIterator(brother){ - _unary_predicate = brother._unary_predicate; - _binary_predicate = brother._binary_predicate; - } - - /*! Destructor. */ - virtual ~ChainPredicateIterator(){ - _unary_predicate = 0; - _binary_predicate = 0; - } - - /*! Returns the string "ChainPredicateIterator" */ - virtual string getExactTypeName() const { - return "ChainPredicateIterator"; - } - - /*! This method iterates over the potential next - * ViewEdges and returns the one that will be - * followed next. - * When reaching the end of a chain, 0 is returned. - */ - virtual int traverse(const AdjacencyIterator &it); + BinaryPredicate1D *_binary_predicate; // the caller is responsible for the deletion of this object + UnaryPredicate1D *_unary_predicate; // the caller is responsible for the deletion of this object - /*! Inits the iterator context */ - virtual int init() { - return 0; - } - +public: + /*! Builds a ChainPredicateIterator from a starting ViewEdge and its orientation. + * \param iRestrictToSelection + * Indicates whether to force the chaining to stay within the set of selected ViewEdges or not. + * \param iRestrictToUnvisited + * Indicates whether a ViewEdge that has already been chained must be ignored ot not. + * \param begin + * The ViewEdge from where to start the iteration. + * \param orientation + * If true, we'll look for the next ViewEdge among the ViewEdges that surround the ending ViewVertex of begin. + * If false, we'll search over the ViewEdges surrounding the ending ViewVertex of begin. + */ + ChainPredicateIterator(bool iRestrictToSelection = true, bool iRestrictToUnvisited = true, ViewEdge* begin = NULL, + bool orientation = true) + : ChainingIterator(iRestrictToSelection, iRestrictToUnvisited, begin, orientation) + { + _binary_predicate = 0; + _unary_predicate = 0; + } + + /*! Builds a ChainPredicateIterator from a unary predicate, a binary predicate, a starting ViewEdge and + * its orientation. + * \param iRestrictToSelection + * Indicates whether to force the chaining to stay within the set of selected ViewEdges or not. + * \param iRestrictToUnvisited + * Indicates whether a ViewEdge that has already been chained must be ignored ot not. + * \param upred + * The unary predicate that the next ViewEdge must satisfy. + * \param bpred + * The binary predicate that the next ViewEdge must satisfy together with the actual pointed ViewEdge. + * \param begin + * The ViewEdge from where to start the iteration. + * \param orientation + * If true, we'll look for the next ViewEdge among the ViewEdges that surround the ending ViewVertex of begin. + * If false, we'll search over the ViewEdges surrounding the ending ViewVertex of begin. + */ + ChainPredicateIterator(UnaryPredicate1D& upred, BinaryPredicate1D& bpred, bool iRestrictToSelection = true, + bool iRestrictToUnvisited = true, ViewEdge* begin = NULL, bool orientation = true) + : ChainingIterator(iRestrictToSelection, iRestrictToUnvisited, begin, orientation) + { + _unary_predicate = &upred; + _binary_predicate = &bpred; + } + + /*! Copy constructor */ + ChainPredicateIterator(const ChainPredicateIterator& brother) : ChainingIterator(brother) + { + _unary_predicate = brother._unary_predicate; + _binary_predicate = brother._binary_predicate; + } + + /*! Destructor. */ + virtual ~ChainPredicateIterator() + { + _unary_predicate = 0; + _binary_predicate = 0; + } + + /*! Returns the string "ChainPredicateIterator" */ + virtual string getExactTypeName() const + { + return "ChainPredicateIterator"; + } + + /*! This method iterates over the potential next ViewEdges and returns the one that will be followed next. + * When reaching the end of a chain, 0 is returned. + */ + virtual int traverse(const AdjacencyIterator &it); + + /*! Inits the iterator context */ + virtual int init() + { + return 0; + } }; -#endif // CHAININGITERATORS_H +#endif // __FREESTYLE_CHAINING_ITERATORS_H__ diff --git a/source/blender/freestyle/intern/stroke/ContextFunctions.cpp b/source/blender/freestyle/intern/stroke/ContextFunctions.cpp index b55da1fb0f8..7723c57921d 100644 --- a/source/blender/freestyle/intern/stroke/ContextFunctions.cpp +++ b/source/blender/freestyle/intern/stroke/ContextFunctions.cpp @@ -1,60 +1,87 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/stroke/ContextFunctions.cpp + * \ingroup freestyle + * \brief Functions related to context queries + * \brief Interface to access the context related information. + * \author Stephane Grabli + * \date 20/12/2003 + */ #include "ContextFunctions.h" + #include "../view_map/SteerableViewMap.h" + #include "../system/TimeStamp.h" + namespace ContextFunctions { - - unsigned GetTimeStampCF(){ - return TimeStamp::instance()->getTimeStamp(); - } - - unsigned GetCanvasWidthCF(){ - return Canvas::getInstance()->width(); - } - - unsigned GetCanvasHeightCF(){ - return Canvas::getInstance()->height(); - } - void LoadMapCF(const char *iFileName, const char *iMapName, unsigned iNbLevels, float iSigma ){ - return Canvas::getInstance()->loadMap(iFileName, iMapName, iNbLevels,iSigma); - } - - float ReadMapPixelCF(const char *iMapName, int level, unsigned x, unsigned y){ - Canvas * canvas = Canvas::getInstance(); - return canvas->readMapPixel(iMapName, level, x,y); - } - - float ReadCompleteViewMapPixelCF(int level, unsigned x, unsigned y){ - SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap(); - return svm->readCompleteViewMapPixel(level,x,y); - } - - float ReadDirectionalViewMapPixelCF(int iOrientation, int level, unsigned x, unsigned y){ - SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap(); - return svm->readSteerableViewMapPixel(iOrientation, level,x,y); - } - - FEdge * GetSelectedFEdgeCF(){ - return Canvas::getInstance()->selectedFEdge(); - } + +unsigned GetTimeStampCF() +{ + return TimeStamp::instance()->getTimeStamp(); +} + +unsigned GetCanvasWidthCF() +{ + return Canvas::getInstance()->width(); +} + +unsigned GetCanvasHeightCF() +{ + return Canvas::getInstance()->height(); +} + +void LoadMapCF(const char *iFileName, const char *iMapName, unsigned iNbLevels, float iSigma) +{ + return Canvas::getInstance()->loadMap(iFileName, iMapName, iNbLevels,iSigma); } + +float ReadMapPixelCF(const char *iMapName, int level, unsigned x, unsigned y) +{ + Canvas *canvas = Canvas::getInstance(); + return canvas->readMapPixel(iMapName, level, x, y); +} + +float ReadCompleteViewMapPixelCF(int level, unsigned x, unsigned y) +{ + SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap(); + return svm->readCompleteViewMapPixel(level, x, y); +} + +float ReadDirectionalViewMapPixelCF(int iOrientation, int level, unsigned x, unsigned y) +{ + SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap(); + return svm->readSteerableViewMapPixel(iOrientation, level, x, y); +} + +FEdge * GetSelectedFEdgeCF() +{ + return Canvas::getInstance()->selectedFEdge(); +} + +} // ContextFunctions namespace diff --git a/source/blender/freestyle/intern/stroke/ContextFunctions.h b/source/blender/freestyle/intern/stroke/ContextFunctions.h index 37c98656fa7..0718ebb1d6a 100644 --- a/source/blender/freestyle/intern/stroke/ContextFunctions.h +++ b/source/blender/freestyle/intern/stroke/ContextFunctions.h @@ -1,43 +1,46 @@ -// -// Filename : AdvancedFunctions0D.h -// Author(s) : Stephane Grabli -// Purpose : Functions related to context queries -// Date of creation : 20/12/2003 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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_CONTEXT_FUNCTIONS_H__ +#define __FREESTYLE_CONTEXT_FUNCTIONS_H__ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/stroke/ContextFunctions.h + * \ingroup freestyle + * \brief Functions related to context queries + * \brief Interface to access the context related information. + * \author Stephane Grabli + * \date 20/12/2003 + */ -#ifndef CONTEXT_FUNCTIONS_HPP -# define CONTEXT_FUNCTIONS_HPP +#include "Canvas.h" -# include "Canvas.h" -# include "../image/Image.h" -# include "../image/GaussianFilter.h" +#include "../image/GaussianFilter.h" +#include "../image/Image.h" -/*! \file ContextFunctions.h - * Interface to access the context related - * information. - */ // // Context Functions definitions // @@ -45,80 +48,73 @@ /*! namespace containing all the Context related functions */ namespace ContextFunctions { - // GetTimeStamp - LIB_STROKE_EXPORT - /*! Returns the system time stamp */ - unsigned GetTimeStampCF(); +// GetTimeStamp +/*! Returns the system time stamp */ +LIB_STROKE_EXPORT +unsigned GetTimeStampCF(); + +// GetCanvasWidth +/*! Returns the canvas width */ +LIB_STROKE_EXPORT +unsigned GetCanvasWidthCF(); + +// GetCanvasHeight +/*! Returns the canvas width */ +LIB_STROKE_EXPORT +unsigned GetCanvasHeightCF(); - // GetCanvasWidth - /*! Returns the canvas width */ - LIB_STROKE_EXPORT - unsigned GetCanvasWidthCF(); - - // GetCanvasHeight - /*! Returns the canvas width */ - LIB_STROKE_EXPORT - unsigned GetCanvasHeightCF(); - - // Load map - /*! Loads an image map for further reading */ - LIB_STROKE_EXPORT - void LoadMapCF(const char *iFileName, const char *iMapName, unsigned iNbLevels=4, float iSigma=1.f); +// Load map +/*! Loads an image map for further reading */ +LIB_STROKE_EXPORT +void LoadMapCF(const char *iFileName, const char *iMapName, unsigned iNbLevels = 4, float iSigma = 1.0f); - // ReadMapPixel - /*! Reads a pixel in a user-defined map - * \return the floating value stored for that pixel - * \param iMapName - * The name of the map - * \param level - * The level of the pyramid in which we wish to read the pixel - * \param x - * The x-coordinate of the pixel we wish to read. The origin is - * in the lower-left corner. - * \param y - * The y-coordinate of the pixel we wish to read. The origin is - * in the lower-left corner. - */ - LIB_STROKE_EXPORT - float ReadMapPixelCF(const char *iMapName, int level, unsigned x, unsigned y); +// ReadMapPixel +/*! Reads a pixel in a user-defined map + * \return the floating value stored for that pixel + * \param iMapName + * The name of the map + * \param level + * The level of the pyramid in which we wish to read the pixel + * \param x + * The x-coordinate of the pixel we wish to read. The origin is in the lower-left corner. + * \param y + * The y-coordinate of the pixel we wish to read. The origin is in the lower-left corner. + */ +LIB_STROKE_EXPORT +float ReadMapPixelCF(const char *iMapName, int level, unsigned x, unsigned y); - // ReadCompleteViewMapPixel - /*! Reads a pixel in the complete view map - * \return the floating value stored for that pixel - * \param level - * The level of the pyramid in which we wish to read the pixel - * \param x - * The x-coordinate of the pixel we wish to read. The origin is - * in the lower-left corner. - * \param y - * The y-coordinate of the pixel we wish to read. The origin is - * in the lower-left corner. - */ - LIB_STROKE_EXPORT - float ReadCompleteViewMapPixelCF(int level, unsigned x, unsigned y); +// ReadCompleteViewMapPixel +/*! Reads a pixel in the complete view map + * \return the floating value stored for that pixel + * \param level + * The level of the pyramid in which we wish to read the pixel + * \param x + * The x-coordinate of the pixel we wish to read. The origin is in the lower-left corner. + * \param y + * The y-coordinate of the pixel we wish to read. The origin is in the lower-left corner. + */ +LIB_STROKE_EXPORT +float ReadCompleteViewMapPixelCF(int level, unsigned x, unsigned y); - // ReadOrientedViewMapPixel - /*! Reads a pixel in one of the oriented view map images - * \return the floating value stored for that pixel - * \param iOrientation - * The number telling which orientation we want to check - * \param level - * The level of the pyramid in which we wish to read the pixel - * \param x - * The x-coordinate of the pixel we wish to read. The origin is - * in the lower-left corner. - * \param y - * The y-coordinate of the pixel we wish to read. The origin is - * in the lower-left corner. - */ - LIB_STROKE_EXPORT - float ReadDirectionalViewMapPixelCF(int iOrientation, int level, unsigned x, unsigned y); +// ReadOrientedViewMapPixel +/*! Reads a pixel in one of the oriented view map images + * \return the floating value stored for that pixel + * \param iOrientation + * The number telling which orientation we want to check + * \param level + * The level of the pyramid in which we wish to read the pixel + * \param x + * The x-coordinate of the pixel we wish to read. The origin is in the lower-left corner. + * \param y + * The y-coordinate of the pixel we wish to read. The origin is in the lower-left corner. + */ +LIB_STROKE_EXPORT +float ReadDirectionalViewMapPixelCF(int iOrientation, int level, unsigned x, unsigned y); - // DEBUG - LIB_STROKE_EXPORT - FEdge * GetSelectedFEdgeCF(); +// DEBUG +LIB_STROKE_EXPORT +FEdge *GetSelectedFEdgeCF(); } // end of namespace ContextFunctions -#endif // CONTEXT_FUNCTIONS_HPP - +#endif // __FREESTYLE_CONTEXT_FUNCTIONS_H__ diff --git a/source/blender/freestyle/intern/stroke/Curve.cpp b/source/blender/freestyle/intern/stroke/Curve.cpp index 4cca210161e..54b8eeaef36 100644 --- a/source/blender/freestyle/intern/stroke/Curve.cpp +++ b/source/blender/freestyle/intern/stroke/Curve.cpp @@ -1,863 +1,925 @@ - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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 ***** + */ + +/** \file blender/freestyle/intern/stroke/Curve.cpp + * \ingroup freestyle + * \brief Class to define a container for curves + * \author Stephane Grabli + * \date 11/01/2003 + */ #include "Curve.h" -#include "CurveIterators.h" #include "CurveAdvancedIterators.h" +#include "CurveIterators.h" - /**********************************/ - /* */ - /* */ - /* CurvePoint */ - /* */ - /* */ - /**********************************/ +/**********************************/ +/* */ +/* */ +/* CurvePoint */ +/* */ +/* */ +/**********************************/ CurvePoint::CurvePoint() { - __A=0; - __B=0; - _t2d=0; -} - -CurvePoint::CurvePoint(SVertex *iA, SVertex *iB, float t) -{ - __A=iA; - __B=iB; - _t2d=t; - if((iA == 0) && (t == 1.f)) - { - _Point2d=__B->point2d(); - _Point3d=__B->point3d(); - } - else if((iB == 0) && (t == 0.f)) - { - _Point2d=__A->point2d(); - _Point3d=__A->point3d(); - } - else - { - _Point2d=__A->point2d()+_t2d*(__B->point2d()-__A->point2d()); - _Point3d=__A->point3d()+_t2d*(__B->point3d()-__A->point3d()); - } -} - -CurvePoint::CurvePoint(CurvePoint *iA, CurvePoint *iB, float t3) -{ - __A = 0; - __B = 0; - float t1=iA->t2d(); - float t2=iB->t2d(); - if((iA->A() == iB->A()) && (iA->B() == iB->B()) && (iA->A() != 0) && (iA->B() != 0) && (iB->A() != 0) && (iB->B() != 0)) - { - __A=iA->A(); - __B=iB->B(); - _t2d=t1+t2*t3-t1*t3; - } - else if((iA->B() == 0) && (iB->B() == 0)) - { - __A = iA->A(); - __B = iB->A(); - _t2d = t3; - } - else if((iA->t2d() == 0) && (iB->t2d() == 0)) - { - __A = iA->A(); - __B = iB->A(); - _t2d = t3; - } - else if(iA->A() == iB->A()) - { + __A = 0; + __B = 0; + _t2d = 0; +} + +CurvePoint::CurvePoint(SVertex *iA, SVertex *iB, float t) +{ + __A = iA; + __B = iB; + _t2d = t; + if ((iA == 0) && (t == 1.0f)) { + _Point2d = __B->point2d(); + _Point3d = __B->point3d(); + } + else if ((iB == 0) && (t == 0.0f)) { + _Point2d = __A->point2d(); + _Point3d = __A->point3d(); + } + else { + _Point2d = __A->point2d() + _t2d * (__B->point2d() - __A->point2d()); + _Point3d = __A->point3d() + _t2d * (__B->point3d() - __A->point3d()); + } +} + +CurvePoint::CurvePoint(CurvePoint *iA, CurvePoint *iB, float t3) +{ + __A = 0; + __B = 0; + float t1 = iA->t2d(); + float t2 = iB->t2d(); + if ((iA->A() == iB->A()) && (iA->B() == iB->B()) && + (iA->A() != 0) && (iA->B() != 0) && (iB->A() != 0) && (iB->B() != 0)) + { + __A = iA->A(); + __B = iB->B(); + _t2d = t1 + t2 * t3 - t1 * t3; + } + else if ((iA->B() == 0) && (iB->B() == 0)) { + __A = iA->A(); + __B = iB->A(); + _t2d = t3; + } + else if ((iA->t2d() == 0) && (iB->t2d() == 0)) { + __A = iA->A(); + __B = iB->A(); + _t2d = t3; + } + else if (iA->A() == iB->A()) { iA_A_eq_iB_A: - if(iA->t2d() == 0){ - __A = iB->A(); - __B = iB->B(); - _t2d = t3; - }else if(iB->t2d() == 0){ - __A = iA->A(); - __B = iA->B(); - _t2d = t3; - } - } - else if(iA->B() == iB->B()) - { + if (iA->t2d() == 0) { + __A = iB->A(); + __B = iB->B(); + _t2d = t3; + } + else if (iB->t2d() == 0) { + __A = iA->A(); + __B = iA->B(); + _t2d = t3; + } + } + else if (iA->B() == iB->B()) { iA_B_eq_iB_B: - if(iA->t2d() == 1){ - __A = iB->A(); - __B = iB->B(); - _t2d = t3; - }else if(iB->t2d() == 1){ - __A = iA->A(); - __B = iA->B(); - _t2d = t3; - } - } - else if(iA->B() == iB->A()) - { + if (iA->t2d() == 1) { + __A = iB->A(); + __B = iB->B(); + _t2d = t3; + } + else if (iB->t2d() == 1) { + __A = iA->A(); + __B = iA->B(); + _t2d = t3; + } + } + else if (iA->B() == iB->A()) { iA_B_eq_iB_A: - if((iA->t2d() != 1.f) && (iB->t2d() == 0.f)) - { - __A = iA->A(); - __B = iA->B(); - _t2d=t1+t3-t1*t3; - //_t2d = t3; - } - else if((iA->t2d() == 1.f) && (iB->t2d() != 0.f)) - { - __A = iB->A(); - __B = iB->B(); - //_t2d = t3; - _t2d=t2*t3; - } - else if((iA->getPoint2D() - iA->getPoint2D()).norm() < 1e-6) { - __A = iB->A(); - __B = iB->B(); - //_t2d = t3; - _t2d=t2*t3; - } - } - else if(iA->A() != 0 && iB->A() != 0 && (iA->A()->point3d() - iB->A()->point3d()).norm() < 1e-6) - { - goto iA_A_eq_iB_A; - } - else if(iA->B() != 0 && iB->B() != 0 && (iA->B()->point3d() - iB->B()->point3d()).norm() < 1e-6) - { - goto iA_B_eq_iB_B; - } - else if(iA->B() != 0 && iB->A() != 0 && (iA->B()->point3d() - iB->A()->point3d()).norm() < 1e-6) - { - goto iA_B_eq_iB_A; - } - if (!__A || !__B) { - printf("iA A 0x%p p (%f, %f)\n", iA->A(), iA->A()->getPoint2D().x(), iA->A()->getPoint2D().y()); - printf("iA B 0x%p p (%f, %f)\n", iA->B(), iA->B()->getPoint2D().x(), iA->B()->getPoint2D().y()); - printf("iB A 0x%p p (%f, %f)\n", iB->A(), iB->A()->getPoint2D().x(), iB->A()->getPoint2D().y()); - printf("iB B 0x%p p (%f, %f)\n", iB->B(), iB->B()->getPoint2D().x(), iB->B()->getPoint2D().y()); - printf("iA t2d %f p (%f, %f)\n", iA->t2d(), iA->getPoint2D().x(), iA->getPoint2D().y()); - printf("iB t2d %f p (%f, %f)\n", iB->t2d(), iB->getPoint2D().x(), iB->getPoint2D().y()); - cerr << "Fatal error in CurvePoint::CurvePoint(CurvePoint *iA, CurvePoint *iB, float t3)" << endl; - } - assert(__A != 0 && __B != 0); - - //_Point2d=__A->point2d()+_t2d*(__B->point2d()-__A->point2d()); - //_Point3d=__A->point3d()+_t2d*(__B->point3d()-__A->point3d()); - - _Point2d= iA->point2d()+t3*(iB->point2d()-iA->point2d()); - _Point3d=__A->point3d()+_t2d*(__B->point3d()-__A->point3d()); -} - -CurvePoint::CurvePoint(const CurvePoint& iBrother) -{ - __A=iBrother.__A; - __B=iBrother.__B; - _t2d=iBrother._t2d; - _Point2d=iBrother._Point2d; - _Point3d=iBrother._Point3d; + if ((iA->t2d() != 1.0f) && (iB->t2d() == 0.0f)) { + __A = iA->A(); + __B = iA->B(); + _t2d = t1 + t3 - t1 * t3; + //_t2d = t3; + } + else if ((iA->t2d() == 1.0f) && (iB->t2d() != 0.0f)) { + __A = iB->A(); + __B = iB->B(); + //_t2d = t3; + _t2d = t2 * t3; + } + else if ((iA->getPoint2D() - iA->getPoint2D()).norm() < 1.0e-6) { + __A = iB->A(); + __B = iB->B(); + //_t2d = t3; + _t2d = t2 * t3; + } + } + else if (iA->A() != 0 && iB->A() != 0 && (iA->A()->point3d() - iB->A()->point3d()).norm() < 1.0e-6) { + goto iA_A_eq_iB_A; + } + else if (iA->B() != 0 && iB->B() != 0 && (iA->B()->point3d() - iB->B()->point3d()).norm() < 1.0e-6) { + goto iA_B_eq_iB_B; + } + else if (iA->B() != 0 && iB->A() != 0 && (iA->B()->point3d() - iB->A()->point3d()).norm() < 1.0e-6) { + goto iA_B_eq_iB_A; + } + + if (!__A || !__B) { + printf("iA A 0x%p p (%f, %f)\n", iA->A(), iA->A()->getPoint2D().x(), iA->A()->getPoint2D().y()); + printf("iA B 0x%p p (%f, %f)\n", iA->B(), iA->B()->getPoint2D().x(), iA->B()->getPoint2D().y()); + printf("iB A 0x%p p (%f, %f)\n", iB->A(), iB->A()->getPoint2D().x(), iB->A()->getPoint2D().y()); + printf("iB B 0x%p p (%f, %f)\n", iB->B(), iB->B()->getPoint2D().x(), iB->B()->getPoint2D().y()); + printf("iA t2d %f p (%f, %f)\n", iA->t2d(), iA->getPoint2D().x(), iA->getPoint2D().y()); + printf("iB t2d %f p (%f, %f)\n", iB->t2d(), iB->getPoint2D().x(), iB->getPoint2D().y()); + cerr << "Fatal error in CurvePoint::CurvePoint(CurvePoint *iA, CurvePoint *iB, float t3)" << endl; + } + assert(__A != 0 && __B != 0); + +#if 0 + _Point2d = __A->point2d() + _t2d * (__B->point2d() - __A->point2d()); + _Point3d = __A->point3d() + _t2d * (__B->point3d() - __A->point3d()); +#endif + + _Point2d = iA->point2d() + t3 * (iB->point2d() - iA->point2d()); + _Point3d = __A->point3d() + _t2d * (__B->point3d() - __A->point3d()); +} + +CurvePoint::CurvePoint(const CurvePoint& iBrother) +{ + __A = iBrother.__A; + __B = iBrother.__B; + _t2d = iBrother._t2d; + _Point2d = iBrother._Point2d; + _Point3d = iBrother._Point3d; } CurvePoint& CurvePoint::operator=(const CurvePoint& iBrother) { - __A=iBrother.__A; - __B=iBrother.__B; - _t2d=iBrother._t2d; - _Point2d=iBrother._Point2d; - _Point3d=iBrother._Point3d; - return *this; -} - - -FEdge *CurvePoint::fedge() -{ - if(getNature() & Nature::T_VERTEX) - return 0; - return __A->fedge(); -} - - -FEdge* CurvePoint::getFEdge(Interface0D& inter) -{ - CurvePoint* iVertexB = dynamic_cast(&inter); - if (!iVertexB) { - cerr << "Warning: CurvePoint::getFEdge() failed to cast the given 0D element to CurvePoint." << endl; - return 0; - } - if(((__A == iVertexB->__A) && (__B == iVertexB->__B)) - || - ((__A == iVertexB->__B) && (__B == iVertexB->__A))) - return __A->getFEdge(*__B); - if(__B == 0) - { - if(iVertexB->__B == 0) - return __A->getFEdge(*(iVertexB->__A)); - else if(iVertexB->__A == __A) - return __A->getFEdge(*(iVertexB->__B)); - else if(iVertexB->__B == __A) - return __A->getFEdge(*(iVertexB->__A)); - } - if(iVertexB->__B == 0) - { - if(iVertexB->__A == __A) - return __B->getFEdge(*(iVertexB->__A)); - else if(iVertexB->__A == __B) - return __A->getFEdge(*(iVertexB->__A)); - } - if(__B == iVertexB->__A) - { - if((_t2d != 1) && (iVertexB->_t2d == 0)) - return __A->getFEdge(*__B); - if((_t2d == 1) && (iVertexB->_t2d != 0)) - return iVertexB->__A->getFEdge(*(iVertexB->__B)); - } - if(__B == iVertexB->__B) - { - if((_t2d != 1) && (iVertexB->_t2d == 1)) - return __A->getFEdge(*__B); - if((_t2d == 1) && (iVertexB->_t2d != 1)) - return iVertexB->__A->getFEdge(*(iVertexB->__B)); - } - if(__A == iVertexB->__A) - { - if((_t2d == 0) && (iVertexB->_t2d != 0)) - return iVertexB->__A->getFEdge(*(iVertexB->__B)); - if((_t2d != 0) && (iVertexB->_t2d == 0)) - return __A->getFEdge(*__B); - } - if(__A == iVertexB->__B) - { - if((_t2d == 0) && (iVertexB->_t2d != 1)) - return iVertexB->__A->getFEdge(*(iVertexB->__B)); - if((_t2d != 0) && (iVertexB->_t2d == 1)) - return __A->getFEdge(*__B); - } + __A = iBrother.__A; + __B = iBrother.__B; + _t2d = iBrother._t2d; + _Point2d = iBrother._Point2d; + _Point3d = iBrother._Point3d; + return *this; +} + + +FEdge *CurvePoint::fedge() +{ + if (getNature() & Nature::T_VERTEX) + return 0; + return __A->fedge(); +} + + +FEdge *CurvePoint::getFEdge(Interface0D& inter) +{ + CurvePoint* iVertexB = dynamic_cast(&inter); + if (!iVertexB) { + cerr << "Warning: CurvePoint::getFEdge() failed to cast the given 0D element to CurvePoint." << endl; + return 0; + } + if (((__A == iVertexB->__A) && (__B == iVertexB->__B)) || + ((__A == iVertexB->__B) && (__B == iVertexB->__A))) + { + return __A->getFEdge(*__B); + } + if (__B == 0) { + if (iVertexB->__B == 0) + return __A->getFEdge(*(iVertexB->__A)); + else if (iVertexB->__A == __A) + return __A->getFEdge(*(iVertexB->__B)); + else if (iVertexB->__B == __A) + return __A->getFEdge(*(iVertexB->__A)); + } + if (iVertexB->__B == 0) { + if (iVertexB->__A == __A) + return __B->getFEdge(*(iVertexB->__A)); + else if (iVertexB->__A == __B) + return __A->getFEdge(*(iVertexB->__A)); + } + if (__B == iVertexB->__A) { + if ((_t2d != 1) && (iVertexB->_t2d == 0)) + return __A->getFEdge(*__B); + if ((_t2d == 1) && (iVertexB->_t2d != 0)) + return iVertexB->__A->getFEdge(*(iVertexB->__B)); + } + if (__B == iVertexB->__B) { + if ((_t2d != 1) && (iVertexB->_t2d == 1)) + return __A->getFEdge(*__B); + if ((_t2d == 1) && (iVertexB->_t2d != 1)) + return iVertexB->__A->getFEdge(*(iVertexB->__B)); + } + if (__A == iVertexB->__A) { + if ((_t2d == 0) && (iVertexB->_t2d != 0)) + return iVertexB->__A->getFEdge(*(iVertexB->__B)); + if ((_t2d != 0) && (iVertexB->_t2d == 0)) + return __A->getFEdge(*__B); + } + if (__A == iVertexB->__B) { + if ((_t2d == 0) && (iVertexB->_t2d != 1)) + return iVertexB->__A->getFEdge(*(iVertexB->__B)); + if ((_t2d != 0) && (iVertexB->_t2d == 1)) + return __A->getFEdge(*__B); + } #if 0 - printf("__A 0x%p p (%f, %f)\n", __A, __A->getPoint2D().x(), __A->getPoint2D().y()); - printf("__B 0x%p p (%f, %f)\n", __B, __B->getPoint2D().x(), __B->getPoint2D().y()); - printf("iVertexB->A() 0x%p p (%f, %f)\n", iVertexB->A(), iVertexB->A()->getPoint2D().x(), iVertexB->A()->getPoint2D().y()); - printf("iVertexB->B() 0x%p p (%f, %f)\n", iVertexB->B(), iVertexB->B()->getPoint2D().x(), iVertexB->B()->getPoint2D().y()); - printf("_t2d %f p (%f, %f)\n", _t2d, getPoint2D().x(), getPoint2D().y()); - printf("iVertexB->t2d() %f p (%f, %f)\n", iVertexB->t2d(), iVertexB->getPoint2D().x(), iVertexB->getPoint2D().y()); + printf("__A 0x%p p (%f, %f)\n", __A, __A->getPoint2D().x(), __A->getPoint2D().y()); + printf("__B 0x%p p (%f, %f)\n", __B, __B->getPoint2D().x(), __B->getPoint2D().y()); + printf("iVertexB->A() 0x%p p (%f, %f)\n", iVertexB->A(), iVertexB->A()->getPoint2D().x(), + iVertexB->A()->getPoint2D().y()); + printf("iVertexB->B() 0x%p p (%f, %f)\n", iVertexB->B(), iVertexB->B()->getPoint2D().x(), + iVertexB->B()->getPoint2D().y()); + printf("_t2d %f p (%f, %f)\n", _t2d, getPoint2D().x(), getPoint2D().y()); + printf("iVertexB->t2d() %f p (%f, %f)\n", iVertexB->t2d(), iVertexB->getPoint2D().x(), iVertexB->getPoint2D().y()); #endif - cerr << "Warning: CurvePoint::getFEdge() failed." << endl; + cerr << "Warning: CurvePoint::getFEdge() failed." << endl; + + return 0; +} + - return 0; +Vec3r CurvePoint::normal() const +{ + if (__B == 0) + return __A->normal(); + if (__A == 0) + return __B->normal(); + Vec3r Na = __A->normal(); + if (Exception::getException()) + Na = Vec3r(0, 0, 0); + Vec3r Nb = __B->normal(); + if (Exception::getException()) + Nb = Vec3r(0, 0, 0); + // compute t3d: + real t3d = SilhouetteGeomEngine::ImageToWorldParameter(__A->getFEdge(*__B), _t2d); + return ((1 - t3d) * Na + t3d * Nb); } - Vec3r CurvePoint::normal() const +#if 0 +Material CurvePoint::material() const { - if(__B == 0) - return __A->normal(); - if(__A == 0) - return __B->normal(); - Vec3r Na = __A->normal(); - if(Exception::getException()) - Na = Vec3r(0,0,0); - Vec3r Nb = __B->normal(); - if(Exception::getException()) - Nb = Vec3r(0,0,0); - // compute t3d: - real t3d = SilhouetteGeomEngine::ImageToWorldParameter(__A->getFEdge(*__B),_t2d); - return ((1-t3d)*Na+t3d*Nb); + if (__A == 0) + return __B->material(); + return __A->material(); } +Id CurvePoint::shape_id() const +{ + if (__A == 0) + return __B->shape_id(); + return __A->shape_id(); +} +#endif - // Material CurvePoint::material() const - //{ - // if(__A == 0) - // return __B->material(); - // return __A->material(); - //} +const SShape *CurvePoint::shape() const +{ + if (__A == 0) + return __B->shape(); + return __A->shape(); +} -// Id CurvePoint::shape_id() const -// { -// if(__A == 0) -// return __B->shape_id(); -// return __A->shape_id(); -// } +#if 0 +float CurvePoint::shape_importance() const +{ + if (__A == 0) + return __B->shape_importance(); + return __A->shape_importance(); +} - const SShape * CurvePoint::shape() const +const unsigned CurvePoint::qi() const { - if(__A == 0) - return __B->shape(); - return __A->shape(); + if (__A == 0) + return __B->qi(); + if (__B == 0) + return __A->qi(); + return __A->getFEdge(*__B)->qi(); } +#endif +occluder_container::const_iterator CurvePoint::occluders_begin() const +{ + if (__A == 0) + return __B->occluders_begin(); + if (__B == 0) + return __A->occluders_begin(); + return __A->getFEdge(*__B)->occluders_begin(); +} - -// float CurvePoint::shape_importance() const -// { - -// if(__A == 0) - -// return __B->shape_importance(); -// return __A->shape_importance(); -// } - - - // const unsigned CurvePoint::qi() const - //{ - // if(__A == 0) - // return __B->qi(); - // if(__B == 0) - // return __A->qi(); - // return __A->getFEdge(*__B)->qi(); - //} - - - occluder_container::const_iterator CurvePoint::occluders_begin() const -{ - if(__A == 0) - return __B->occluders_begin(); - if(__B == 0) - return __A->occluders_begin(); - return __A->getFEdge(*__B)->occluders_begin(); -} - - occluder_container::const_iterator CurvePoint::occluders_end() const -{ - if(__A == 0) - return __B->occluders_end(); - if(__B == 0) - return __A->occluders_end(); - return __A->getFEdge(*__B)->occluders_end(); -} - - bool CurvePoint::occluders_empty() const -{ - if(__A == 0) - return __B->occluders_empty(); - if(__B == 0) - return __A->occluders_empty(); - return __A->getFEdge(*__B)->occluders_empty(); -} - - int CurvePoint::occluders_size() const -{ - if(__A == 0) - return __B->occluders_size(); - if(__B == 0) - return __A->occluders_size(); - return __A->getFEdge(*__B)->occluders_size(); -} - - const SShape * CurvePoint::occluded_shape() const -{ - if(__A == 0) - return __B->occluded_shape(); - if(__B == 0) - return __A->occluded_shape(); - return __A->getFEdge(*__B)->occluded_shape(); -} - - const Polygon3r& CurvePoint::occludee() const -{ - if(__A == 0) - return __B->occludee(); - if(__B == 0) - return __A->occludee(); - return __A->getFEdge(*__B)->occludee(); -} - - const bool CurvePoint::occludee_empty() const -{ - if(__A == 0) - return __B->occludee_empty(); - if(__B == 0) - return __A->occludee_empty(); - return __A->getFEdge(*__B)->occludee_empty(); -} - - real CurvePoint::z_discontinuity() const -{ - if(__A == 0) - return __B->z_discontinuity(); - if(__B == 0) - return __A->z_discontinuity(); - if(__A->getFEdge(*__B) == 0) - return 0.0; - - return __A->getFEdge(*__B)->z_discontinuity(); -} -// -// float CurvePoint::local_average_depth() const -//{ -// return local_average_depth_function(this); -//} -// -// float CurvePoint::local_depth_variance() const -//{ -// return local_depth_variance_function(this); -//} -// -// real CurvePoint::local_average_density(float sigma) const -//{ -// //return local_average_density(this); -// -// return density_function(this); -//} -// Vec3r shaded_color() const ; -// -// Vec3r CurvePoint::orientation2d() const -// { -// if(__A == 0) -// return __B->orientation2d(); -// if(__B == 0) -// return __A->orientation2d(); -// return __B->point2d()-__A->point2d(); -// } -// -// Vec3r CurvePoint::orientation3d() const -// { -// if(__A == 0) -// return __B->orientation3d(); -// if(__B == 0) -// return __A->orientation3d(); -// return __B->point3d()-__A->point3d(); -// } - -// real curvature2d() const {return viewedge()->curvature2d((_VertexA->point2d()+_VertexB->point2d())/2.0);} -// -// Vec3r CurvePoint::curvature2d_as_vector() const -//{ -// // Vec3r edgeA = (_FEdges[0])->orientation2d().normalize(); -// // Vec3r edgeB = (_FEdges[1])->orientation2d().normalize(); -// // return edgeA+edgeB; -// // -// if(__A == 0) -// return __B->curvature2d_as_vector(); -// if(__B == 0) -// return __A->curvature2d_as_vector(); -// return ((1-_t2d)*__A->curvature2d_as_vector()+_t2d*__B->curvature2d_as_vector()); -//} -// -// real CurvePoint::curvature2d_as_angle() const -//{ -// // Vec3r edgeA = (_FEdges[0])->orientation2d(); -// // Vec3r edgeB = (_FEdges[1])->orientation2d(); -// // Vec2d N1(-edgeA.y(), edgeA.x());N1.normalize(); -// // Vec2d N2(-edgeB.y(), edgeB.x());N2.normalize(); -// // return acos((N1*N2)); -// -// if(__A == 0) -// return __B->curvature2d_as_angle(); -// if(__B == 0) -// return __A->curvature2d_as_angle(); -// return ((1-_t2d)*__A->curvature2d_as_angle()+_t2d*__B->curvature2d_as_angle()); -//} - - -real CurvePoint::curvatureFredo() const -{ - if(__A == 0) - return __B->curvatureFredo(); - if(__B == 0) - return __A->curvatureFredo(); - return ((1-_t2d)*__A->curvatureFredo()+_t2d*__B->curvatureFredo()); -} - -Vec2d CurvePoint::directionFredo () const -{ - if(__A == 0) - return __B->directionFredo(); - if(__B == 0) - return __A->directionFredo(); - return ((1-_t2d)*__A->directionFredo()+_t2d*__B->directionFredo()); -} - - /**********************************/ - /* */ - /* */ - /* Curve */ - /* */ - /* */ - /**********************************/ +occluder_container::const_iterator CurvePoint::occluders_end() const +{ + if (__A == 0) + return __B->occluders_end(); + if (__B == 0) + return __A->occluders_end(); + return __A->getFEdge(*__B)->occluders_end(); +} -/* for functions */ +bool CurvePoint::occluders_empty() const +{ + if (__A == 0) + return __B->occluders_empty(); + if (__B == 0) + return __A->occluders_empty(); + return __A->getFEdge(*__B)->occluders_empty(); +} + +int CurvePoint::occluders_size() const +{ + if (__A == 0) + return __B->occluders_size(); + if (__B == 0) + return __A->occluders_size(); + return __A->getFEdge(*__B)->occluders_size(); +} + +const SShape *CurvePoint::occluded_shape() const +{ + if (__A == 0) + return __B->occluded_shape(); + if (__B == 0) + return __A->occluded_shape(); + return __A->getFEdge(*__B)->occluded_shape(); +} + +const Polygon3r& CurvePoint::occludee() const +{ + if (__A == 0) + return __B->occludee(); + if (__B == 0) + return __A->occludee(); + return __A->getFEdge(*__B)->occludee(); +} + +const bool CurvePoint::occludee_empty() const +{ + if (__A == 0) + return __B->occludee_empty(); + if (__B == 0) + return __A->occludee_empty(); + return __A->getFEdge(*__B)->occludee_empty(); +} + +real CurvePoint::z_discontinuity() const +{ + if (__A == 0) + return __B->z_discontinuity(); + if (__B == 0) + return __A->z_discontinuity(); + if (__A->getFEdge(*__B) == 0) + return 0.0; + + return __A->getFEdge(*__B)->z_discontinuity(); +} + +#if 0 +float CurvePoint::local_average_depth() const +{ + return local_average_depth_function(this); +} + +float CurvePoint::local_depth_variance() const +{ + return local_depth_variance_function(this); +} + +real CurvePoint::local_average_density(float sigma) const +{ + //return local_average_density(this); + return density_function(this); +} + +Vec3r shaded_color() const; + +Vec3r CurvePoint::orientation2d() const +{ + if (__A == 0) + return __B->orientation2d(); + if (__B == 0) + return __A->orientation2d(); + return __B->point2d() - __A->point2d(); +} + +Vec3r CurvePoint::orientation3d() const +{ + if (__A == 0) + return __B->orientation3d(); + if (__B == 0) + return __A->orientation3d(); + return __B->point3d() - __A->point3d(); +} + +real curvature2d() const +{ + return viewedge()->curvature2d((_VertexA->point2d() + _VertexB->point2d()) / 2.0); +} + +Vec3r CurvePoint::curvature2d_as_vector() const +{ +#if 0 + Vec3r edgeA = (_FEdges[0])->orientation2d().normalize(); + Vec3r edgeB = (_FEdges[1])->orientation2d().normalize(); + return edgeA + edgeB; +#endif + if (__A == 0) + return __B->curvature2d_as_vector(); + if (__B == 0) + return __A->curvature2d_as_vector(); + return ((1 - _t2d) * __A->curvature2d_as_vector() + _t2d * __B->curvature2d_as_vector()); +} + +real CurvePoint::curvature2d_as_angle() const +{ +#if 0 + Vec3r edgeA = (_FEdges[0])->orientation2d(); + Vec3r edgeB = (_FEdges[1])->orientation2d(); + Vec2d N1(-edgeA.y(), edgeA.x()); + N1.normalize(); + Vec2d N2(-edgeB.y(), edgeB.x()); + N2.normalize(); + return acos((N1 * N2)); +#endif + if (__A == 0) + return __B->curvature2d_as_angle(); + if (__B == 0) + return __A->curvature2d_as_angle(); + return ((1 - _t2d) * __A->curvature2d_as_angle() + _t2d * __B->curvature2d_as_angle()); +} +#endif +real CurvePoint::curvatureFredo() const +{ + if (__A == 0) + return __B->curvatureFredo(); + if (__B == 0) + return __A->curvatureFredo(); + return ((1 - _t2d) * __A->curvatureFredo() + _t2d * __B->curvatureFredo()); +} + +Vec2d CurvePoint::directionFredo () const +{ + if (__A == 0) + return __B->directionFredo(); + if (__B == 0) + return __A->directionFredo(); + return ((1 - _t2d) * __A->directionFredo() + _t2d * __B->directionFredo()); +} + +/**********************************/ +/* */ +/* */ +/* Curve */ +/* */ +/* */ +/**********************************/ + +/* for functions */ Curve::~Curve() { - if(!_Vertices.empty()) - { - for(vertex_container::iterator it=_Vertices.begin(), itend =_Vertices.end(); - it!=itend; - ++it) - { - delete (*it); - } - _Vertices.clear(); - } + if (!_Vertices.empty()) { + for (vertex_container::iterator it = _Vertices.begin(), itend = _Vertices.end(); it != itend; ++it) { + delete (*it); + } + _Vertices.clear(); + } } /*! iterators access */ -Curve::point_iterator Curve::points_begin(float step) +Curve::point_iterator Curve::points_begin(float step) { - vertex_container::iterator second = _Vertices.begin();++second; - return point_iterator(_Vertices.begin(), second, _Vertices.begin(), _Vertices.end(), _nSegments, step, 0.f, 0.f); - //return point_iterator(_Vertices.begin(), second, _nSegments, step, 0.f, 0.f); + vertex_container::iterator second = _Vertices.begin(); + ++second; + return point_iterator(_Vertices.begin(), second, _Vertices.begin(), _Vertices.end(), _nSegments, step, 0.0f, 0.0f); + //return point_iterator(_Vertices.begin(), second, _nSegments, step, 0.0f, 0.0f); } -Curve::const_point_iterator Curve::points_begin(float step) const + +Curve::const_point_iterator Curve::points_begin(float step) const { - vertex_container::const_iterator second = _Vertices.begin();++second; - return const_point_iterator(_Vertices.begin(), second, _Vertices.begin(), _Vertices.end(), _nSegments, step, 0.f, 0.f); - //return const_point_iterator(_Vertices.begin(), second, _nSegments, step, 0.f, 0.f); + vertex_container::const_iterator second = _Vertices.begin(); + ++second; + return const_point_iterator(_Vertices.begin(), second, _Vertices.begin(), _Vertices.end(), + _nSegments, step, 0.0f, 0.0f); + //return const_point_iterator(_Vertices.begin(), second, _nSegments, step, 0.0f, 0.0f); } -Curve::point_iterator Curve::points_end(float step) + +Curve::point_iterator Curve::points_end(float step) { - return point_iterator(_Vertices.end(), _Vertices.end(), _Vertices.begin(), _Vertices.end(), _nSegments, step, 1.f, _Length); - //return point_iterator(_Vertices.end(), _Vertices.end(), _nSegments, step, 1.f, _Length); + return point_iterator(_Vertices.end(), _Vertices.end(), _Vertices.begin(), _Vertices.end(), + _nSegments, step, 1.0f, _Length); + //return point_iterator(_Vertices.end(), _Vertices.end(), _nSegments, step, 1.0f, _Length); } -Curve::const_point_iterator Curve::points_end(float step) const + +Curve::const_point_iterator Curve::points_end(float step) const { - return const_point_iterator(_Vertices.end(), _Vertices.end(), _Vertices.begin(), _Vertices.end(), _nSegments, step, 1.f, _Length); - //return const_point_iterator(_Vertices.end(), _Vertices.end(), _nSegments, step, 1.f, _Length); + return const_point_iterator(_Vertices.end(), _Vertices.end(), _Vertices.begin(), _Vertices.end(), + _nSegments, step, 1.0f, _Length); + //return const_point_iterator(_Vertices.end(), _Vertices.end(), _nSegments, step, 1.0f, _Length); } // Adavnced Iterators access -Curve::point_iterator Curve::vertices_begin(){return points_begin(0);} -Curve::const_point_iterator Curve::vertices_begin() const {return points_begin(0);} -Curve::point_iterator Curve::vertices_end(){return points_end(0);} -Curve::const_point_iterator Curve::vertices_end() const {return points_end(0);} +Curve::point_iterator Curve::vertices_begin() +{ + return points_begin(0); +} + +Curve::const_point_iterator Curve::vertices_begin() const +{ + return points_begin(0); +} + +Curve::point_iterator Curve::vertices_end() +{ + return points_end(0); +} + +Curve::const_point_iterator Curve::vertices_end() const +{ + return points_end(0); +} // specialized iterators access -CurveInternal::CurvePointIterator Curve::curvePointsBegin(float t){ - vertex_container::iterator second = _Vertices.begin();++second; - return CurveInternal::CurvePointIterator(_Vertices.begin(), second, _Vertices.begin(), _Vertices.end(), 0, _nSegments, _Length, t, 0.f, 0.f); -} - -CurveInternal::CurvePointIterator Curve::curvePointsEnd(float t){ - vertex_container::iterator last = _Vertices.end();--last; - return CurveInternal::CurvePointIterator(last, _Vertices.end(), _Vertices.begin(), _Vertices.end(), _nSegments, _nSegments, _Length, t, 0.f, _Length); -} - -CurveInternal::CurvePointIterator Curve::curveVerticesBegin(){ - return curvePointsBegin(0); -} - -CurveInternal::CurvePointIterator Curve::curveVerticesEnd(){ - return curvePointsEnd(0); -} - -Interface0DIterator Curve::pointsBegin(float t){ - vertex_container::iterator second = _Vertices.begin();++second; - Interface0DIterator ret(new CurveInternal::CurvePointIterator(_Vertices.begin(), second, _Vertices.begin(), _Vertices.end(), 0, _nSegments, _Length, t, 0.f, 0.f)); - return ret; -} - -Interface0DIterator Curve::pointsEnd(float t){ - vertex_container::iterator last = _Vertices.end();--last; - Interface0DIterator ret(new CurveInternal::CurvePointIterator(last, _Vertices.end(), _Vertices.begin(), _Vertices.end(), _nSegments, _nSegments, _Length, t, 0.f, _Length)); - return ret; -} - -Interface0DIterator Curve::verticesBegin(){ - return pointsBegin(0); -} - -Interface0DIterator Curve::verticesEnd(){ - return pointsEnd(0); -} - - -// Vec3r shaded_color(int iCombination = 0) const ; -// -// Vec3r Curve::orientation2d(point_iterator it) const -//{ -// return (*it)->orientation2d(); -//} -/* template */ -/* Vec3r Curve::orientation2d(int iCombination) const */ -/* { */ -/* return edge_orientation2d_function(this, iCombination); */ -/* } */ -// -// Vec3r Curve::orientation3d(point_iterator it) const -//{ -// return (*it)->orientation3d(); -//} -/* */ -/* Vec3r Curve::orientation3d(int iCombination) const */ -/* { */ -/* return edge_orientation3d_function(this, iCombination); */ -/* } */ -// real curvature2d(point_iterator it) const {return (*it)->curvature2d();} -// real curvature2d(int iCombination = 0) const ; - -// Material Curve::material() const -//{ -// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); -// const Material& mat = (*v)->material(); -// for(;v!=vend;++v) -// { -// if((*v)->material() != mat) -// Exception::raiseException(); -// } -// return mat; -//} - -// int Curve::qi() const -//{ -// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); -// int qi_= (*v)->qi(); -// for(;v!=vend;++v) -// { -// if((*v)->qi() != qi_) -// Exception::raiseException(); -// } -// return qi_; -//} -// occluder_container::const_iterator occluders_begin() const {return _FEdgeA->occluders().begin();} -// occluder_container::const_iterator occluders_end() const {return _FEdgeA->occluders().end();} - -//int Curve::occluders_size() const -//{ -// return qi(); -//} - -// bool Curve::occluders_empty() const -//{ -// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); -// bool empty = (*v)->occluders_empty(); -// for(;v!=vend;++v) -// { -// if((*v)->occluders_empty() != empty) -// Exception::raiseException(); -// } -// return empty; -//} -// const Polygon3r& occludee() const {return *(_FEdgeA->aFace());} - -// const SShape * Curve::occluded_shape() const -//{ -// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); -// const SShape *sshape = (*v)->occluded_shape(); -// for(;v!=vend;++v) -// { -// if((*v)->occluded_shape() != sshape) -// Exception::raiseException(); -// } -// return sshape; -//} - - -// const bool Curve::occludee_empty() const -//{ -// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); -// bool empty = (*v)->occludee_empty(); -// for(;v!=vend;++v) -// { -// if((*v)->occludee_empty() != empty) -// Exception::raiseException(); -// } -// return empty; -//} -/* */ -/* real Curve::z_discontinuity(int iCombination) const */ -/* { */ -/* return z_discontinuity_edge_function(this, iCombination); */ -/* } */ - -// int Curve::shape_id() const -// { -// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); -// Id id = (*v)->shape_id(); -// for(;v!=vend;++v) -// { -// if((*v)->shape_id() != id) -// Exception::raiseException(); -// } -// return id.first; -// } - - -// const SShape * Curve::shape() const -//{ -// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); -// const SShape *sshape = (*v)->shape(); -// for(;v!=vend;++v) -// { -// if((*v)->shape() != sshape) -// Exception::raiseException(); -// } -// return sshape; -//} - - -// occluder_container::const_iterator Curve::occluders_begin() const -//{ -// const_vertex_iterator v=vertices_begin(); -// return (*v)->occluders_begin(); -//} -// -// -// occluder_container::const_iterator Curve::occluders_end() const -//{ -// const_vertex_iterator v=vertices_end(); -// return (*v)->occluders_end(); -//} - -/* */ -/* Vec3r Curve::curvature2d_as_vector(int iCombination) const */ -/* { */ -/* return curvature2d_as_vector_edge_function(this, iCombination); */ -/* } */ -/* */ -/* real Curve::curvature2d_as_angle(int iCombination) const */ -/* { */ -/* return curvature2d_as_angle_edge_function(this, iCombination); */ -/* } */ - -/* */ -/* float Curve::shape_importance(int iCombination) const */ -/* { */ -/* return shape_importance_edge_function(this, iCombination); */ -/* } */ - -/* */ -/* float Curve::local_average_depth(int iCombination) const */ -/* { */ -/* return local_average_depth_edge_function(this, iCombination); */ -/* } */ -/* */ -/* float Curve::local_depth_variance(int iCombination ) const */ -/* { */ -/* return local_depth_variance_edge_function(this, iCombination); */ -/* // local_depth_variance_functor functor; */ -/* // float result; */ -/* // Evaluate >(&functor, iCombination, result); */ -/* // return result; */ -/* } */ - -/* */ -/* real Curve::local_average_density(float sigma, int iCombination ) const */ -/* { */ -/* return density_edge_function(this, iCombination); */ -/* // density_functor functor; */ -/* // real result; */ -/* // Evaluate >(&functor, iCombination, result); */ -/* // return result; */ -/* } */ +CurveInternal::CurvePointIterator Curve::curvePointsBegin(float t) +{ + vertex_container::iterator second = _Vertices.begin(); + ++second; + return CurveInternal::CurvePointIterator(_Vertices.begin(), second, _Vertices.begin(), _Vertices.end(), + 0, _nSegments, _Length, t, 0.0f, 0.0f); +} + +CurveInternal::CurvePointIterator Curve::curvePointsEnd(float t) +{ + vertex_container::iterator last = _Vertices.end(); + --last; + return CurveInternal::CurvePointIterator(last, _Vertices.end(), _Vertices.begin(), _Vertices.end(), + _nSegments, _nSegments, _Length, t, 0.0f, _Length); +} + +CurveInternal::CurvePointIterator Curve::curveVerticesBegin() +{ + return curvePointsBegin(0); +} + +CurveInternal::CurvePointIterator Curve::curveVerticesEnd() +{ + return curvePointsEnd(0); +} + +Interface0DIterator Curve::pointsBegin(float t) +{ + vertex_container::iterator second = _Vertices.begin(); + ++second; + Interface0DIterator ret(new CurveInternal::CurvePointIterator(_Vertices.begin(), second, _Vertices.begin(), + _Vertices.end(), 0, _nSegments, _Length, + t, 0.0f, 0.0f)); + return ret; +} + +Interface0DIterator Curve::pointsEnd(float t) +{ + vertex_container::iterator last = _Vertices.end(); + --last; + Interface0DIterator ret(new CurveInternal::CurvePointIterator(last, _Vertices.end(), _Vertices.begin(), + _Vertices.end(), _nSegments, _nSegments, + _Length, t, 0.0f, _Length)); + return ret; +} + +Interface0DIterator Curve::verticesBegin() +{ + return pointsBegin(0); +} + +Interface0DIterator Curve::verticesEnd() +{ + return pointsEnd(0); +} + +#if 0 +Vec3r shaded_color(int iCombination = 0) const; + +Vec3r Curve::orientation2d(point_iterator it) const +{ + return (*it)->orientation2d(); +} + +template +Vec3r Curve::orientation2d(int iCombination) const +{ + return edge_orientation2d_function(this, iCombination); +} + +Vec3r Curve::orientation3d(point_iterator it) const +{ + return (*it)->orientation3d(); +} + +Vec3r Curve::orientation3d(int iCombination) const +{ + return edge_orientation3d_function(this, iCombination); +} + +real curvature2d(point_iterator it) const +{ + return (*it)->curvature2d(); +} + +real curvature2d(int iCombination = 0) const; + +Material Curve::material() const +{ + const_vertex_iterator v = vertices_begin(), vend = vertices_end(); + const Material& mat = (*v)->material(); + for (; v != vend; ++v) { + if ((*v)->material() != mat) + Exception::raiseException(); + } + return mat; +} + +int Curve::qi() const +{ + const_vertex_iterator v = vertices_begin(), vend = vertices_end(); + int qi_ = (*v)->qi(); + for (; v != vend; ++v) { + if ((*v)->qi() != qi_) + Exception::raiseException(); + } + return qi_; +} + +occluder_container::const_iterator occluders_begin() const +{ + return _FEdgeA->occluders().begin(); +} + +occluder_container::const_iterator occluders_end() const +{ + return _FEdgeA->occluders().end(); +} + +int Curve::occluders_size() const +{ + return qi(); +} + +bool Curve::occluders_empty() const +{ + const_vertex_iterator v = vertices_begin(), vend = vertices_end(); + bool empty = (*v)->occluders_empty(); + for (; v != vend; ++v) { + if ((*v)->occluders_empty() != empty) + Exception::raiseException(); + } + return empty; +} + +const Polygon3r& occludee() const +{ + return *(_FEdgeA->aFace()); +} + +const SShape *Curve::occluded_shape() const +{ + const_vertex_iterator v = vertices_begin(), vend = vertices_end(); + const SShape *sshape = (*v)->occluded_shape(); + for (; v != vend; ++v) { + if ((*v)->occluded_shape() != sshape) + Exception::raiseException(); + } + return sshape; +} + +const bool Curve::occludee_empty() const +{ + const_vertex_iterator v = vertices_begin(), vend = vertices_end(); + bool empty = (*v)->occludee_empty(); + for (; v != vend; ++v) { + if ((*v)->occludee_empty() != empty) + Exception::raiseException(); + } + return empty; +} +real Curve::z_discontinuity(int iCombination) const +{ + return z_discontinuity_edge_function(this, iCombination); +} + +int Curve::shape_id() const +{ + const_vertex_iterator v = vertices_begin(), vend = vertices_end(); + Id id = (*v)->shape_id(); + for (; v != vend; ++v) { + if ((*v)->shape_id() != id) + Exception::raiseException(); + } + return id.first; +} + + +const SShape *Curve::shape() const +{ + const_vertex_iterator v = vertices_begin(), vend = vertices_end(); + const SShape *sshape = (*v)->shape(); + for (; v != vend; ++v) { + if ((*v)->shape() != sshape) + Exception::raiseException(); + } + return sshape; +} + + +occluder_container::const_iterator Curve::occluders_begin() const +{ + const_vertex_iterator v = vertices_begin(); + return (*v)->occluders_begin(); +} -#define EPS_CURVA_DIR 0.01 +occluder_container::const_iterator Curve::occluders_end() const +{ + const_vertex_iterator v = vertices_end(); + return (*v)->occluders_end(); +} + +Vec3r Curve::curvature2d_as_vector(int iCombination) const +{ + return curvature2d_as_vector_edge_function(this, iCombination); +} + +real Curve::curvature2d_as_angle(int iCombination) const +{ + return curvature2d_as_angle_edge_function(this, iCombination); +} + +float Curve::shape_importance(int iCombination) const +{ + return shape_importance_edge_function(this, iCombination); +} + +float Curve::local_average_depth(int iCombination) const +{ + return local_average_depth_edge_function(this, iCombination); +} + +float Curve::local_depth_variance(int iCombination ) const +{ + return local_depth_variance_edge_function(this, iCombination); +#if 0 + local_depth_variance_functor functor; + float result; + Evaluate >(&functor, iCombination, result); + return result; +#endif +} + +real Curve::local_average_density(float sigma, int iCombination ) const +{ + return density_edge_function(this, iCombination); +#if 0 + density_functor functor; + real result; + Evaluate >(&functor, iCombination, result); + return result; +#endif +} +#endif + +#define EPS_CURVA_DIR 0.01 void Curve::computeCurvatureAndOrientation () { -// const_vertex_iterator v=vertices_begin(), vend=vertices_end(), v2, prevV, v0; -// Vec2d p0, p1, p2; -// Vec3r p; - -// p=(*v)->point2d(); -// p0=Vec2d(p[0], p[1]); -// prevV=v; ++v; -// p=(*v)->point2d(); -// p1=Vec2d(p[0], p[1]); -// Vec2d prevDir(p1-p0); - -// for(;v!=vend;++v) -// { -// v2=v; ++v2; -// if (v2==vend) break; -// Vec3r p2=(*v2)->point2d(); - -// Vec2d BA=p0-p1; -// Vec2d BC=p2-p1; -// real lba=BA.norm(), lbc=BC.norm(); -// BA.normalizeSafe(); -// BC.normalizeSafe(); -// Vec2d normalCurvature=BA+BC; -// Vec2d dir=Vec2d(BC-BA); -// Vec2d normal=Vec2d(-dir[1], dir[0]); - -// normal.normalizeSafe(); -// real curvature=normalCurvature*normal; -// if (lba+lbc > MY_EPSILON) -// curvature/=(0.5*lba+lbc); -// if (dir.norm() < MY_EPSILON) -// dir=0.1*prevDir; -// (*v)->setCurvatureFredo(curvature); -// (*v)->setDirectionFredo(dir); - -// prevV=v; p0=p1; p1=p2; prevDir=dir; prevDir.normalize(); -// } -// (*v)->setCurvatureFredo((*prevV)->curvatureFredo()); -// (*v)->setDirectionFredo((*v)->point2d()-(*prevV)->point2d()); -// v0=vertices_begin(); v2=v0; ++v2; -// (*v0)->setCurvatureFredo((*v2)->curvatureFredo()); -// (*v0)->setDirectionFredo((*v2)->point2d()-(*v0)->point2d()); - -// //closed curve case one day... - -// // -// return; - -// //numerical degeneracy verification.. we'll see later -// const_vertex_iterator vLastReliable=vertices_begin(); - -// v=vertices_begin(); -// p=(*v)->point2d(); -// p0=Vec2d(p[0], p[1]); -// prevV=v; ++v; -// p=(*v)->point2d(); -// p1=Vec2d(p[0], p[1]); -// bool isReliable=false; -// if ((p1-p0).norm>EPS_CURVA) -// { -// vLastReliable=v; -// isReliable=true; -// } - -// for(;v!=vend;++v) -// { -// v2=v; ++v2; -// if (v2==vend) break; -// Vec3r p2=(*v2)->point2d(); - -// Vec2d BA=p0-p1; -// Vec2d BC=p2-p1; -// real lba=BA.norm(), lbc=BC.norm(); - -// if ((lba+lbc)setCurvatureFredo((*v)->curvatureFredo()); -// (*vfix)->setDirectionFredo((*v)->directionFredo()); -// } -// } -// isReliable=true; -// vLastReliable=v; -// } -// prevV=v; p0=p1; p1=p2; -// } +#if 0 + const_vertex_iterator v = vertices_begin(), vend = vertices_end(), v2, prevV, v0; + Vec2d p0, p1, p2; + Vec3r p; + + p = (*v)->point2d(); + p0 = Vec2d(p[0], p[1]); + prevV = v; + ++v; + p = (*v)->point2d(); + p1 = Vec2d(p[0], p[1]); + Vec2d prevDir(p1 - p0); + + for (; v! = vend; ++v) { + v2 = v; + ++v2; + if (v2 == vend) + break; + Vec3r p2 = (*v2)->point2d(); + + Vec2d BA = p0 - p1; + Vec2d BC = p2 - p1; + real lba = BA.norm(), lbc = BC.norm(); + BA.normalizeSafe(); + BC.normalizeSafe(); + Vec2d normalCurvature = BA + BC; + Vec2d dir = Vec2d(BC - BA); + Vec2d normal = Vec2d(-dir[1], dir[0]); + + normal.normalizeSafe(); + real curvature = normalCurvature * normal; + if (lba + lbc > MY_EPSILON) + curvature /= (0.5 * lba + lbc); + if (dir.norm() < MY_EPSILON) + dir = 0.1 * prevDir; + (*v)->setCurvatureFredo(curvature); + (*v)->setDirectionFredo(dir); + + prevV = v; + p0 = p1; + p1 = p2; + prevDir = dir; + prevDir.normalize(); + } + (*v)->setCurvatureFredo((*prevV)->curvatureFredo()); + (*v)->setDirectionFredo((*v)->point2d() - (*prevV)->point2d()); + v0 = vertices_begin(); + v2 = v0; + ++v2; + (*v0)->setCurvatureFredo((*v2)->curvatureFredo()); + (*v0)->setDirectionFredo((*v2)->point2d() - (*v0)->point2d()); + + //closed curve case one day... + + // + return; + + //numerical degeneracy verification... we'll see later + const_vertex_iterator vLastReliable = vertices_begin(); + + v = vertices_begin(); + p = (*v)->point2d(); + p0 = Vec2d(p[0], p[1]); + prevV = v; + ++v; + p = (*v)->point2d(); + p1 = Vec2d(p[0], p[1]); + bool isReliable = false; + if ((p1 - p0).norm > EPS_CURVA) { + vLastReliable = v; + isReliable = true; + } + for (; v != vend; ++v) { + v2 = v; + ++v2; + if (v2 == vend) + break; + Vec3r p2 = (*v2)->point2d(); + + Vec2d BA = p0 - p1; + Vec2d BC = p2 - p1; + real lba = BA.norm(), lbc = BC.norm(); + + if ((lba + lbc) < EPS_CURVA) { + isReliable = false; + cerr << "/"; + } + else { + if (!isReliable) { //previous points were not reliable + const_vertex_iterator vfix = vLastReliable; + ++vfix; + for (; vfix != v; ++vfix) { + (*vfix)->setCurvatureFredo((*v)->curvatureFredo()); + (*vfix)->setDirectionFredo((*v)->directionFredo()); + } + } + isReliable = true; + vLastReliable = v; + } + prevV = v; + p0 = p1; + p1 = p2; + } +#endif } diff --git a/source/blender/freestyle/intern/stroke/Curve.h b/source/blender/freestyle/intern/stroke/Curve.h index 60bc9815cb4..f451d83d65b 100644 --- a/source/blender/freestyle/intern/stroke/Curve.h +++ b/source/blender/freestyle/intern/stroke/Curve.h @@ -1,282 +1,364 @@ -// -// Filename : Curve.h -// Author(s) : Stephane Grabli -// Purpose : Class to define a container for curves -// Date of creation : 11/01/2003 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef CURVE_H -# define CURVE_H - -# include "../view_map/Silhouette.h" -# include -# include "../system/BaseIterator.h" -# include "../geometry/Geom.h" -//# include "../scene_graph/FrsMaterial.h" -# include "../view_map/SilhouetteGeomEngine.h" -# include "../view_map/Interface0D.h" -# include "../view_map/Interface1D.h" +/* + * ***** 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 + +#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 */ - /* */ - /* */ - /**********************************/ +/**********************************/ +/* */ +/* */ +/* 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 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. + * 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(); - } + /*! 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; + typedef SVertex vertex_type; + protected: - SVertex *__A; - SVertex *__B; - float _t2d; - //float _t3d; - Vec3r _Point2d; - Vec3r _Point3d; + 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;} - //inline const float t3d() const {return _t3d;} - - /* 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;} - //inline void SetT3d(float t) {_t3d = t;} - - /* 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 ; - // 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 ; - - real curvatureFredo () const; - Vec2d directionFredo () const; + /*! 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 */ - /* */ - /* */ - /**********************************/ +/**********************************/ +/* */ +/* */ +/* Curve */ +/* */ +/* */ +/**********************************/ namespace CurveInternal { - class CurvePoint_const_traits; - class CurvePoint_nonconst_traits; - template class __point_iterator; - class CurvePointIterator; + +class CurvePoint_const_traits; +class CurvePoint_nonconst_traits; +template class __point_iterator; +class CurvePointIterator; + } // end of namespace CurveInternal /*! Base class for curves made of CurvePoints. @@ -286,182 +368,222 @@ namespace CurveInternal { 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_container; - - /* Iterator to iterate over a vertex edges */ - - typedef CurveInternal::__point_iterator point_iterator; - typedef CurveInternal::__point_iterator const_point_iterator; - typedef point_iterator vertex_iterator ; - typedef const_point_iterator const_vertex_iterator ; - + typedef CurvePoint Vertex; + typedef CurvePoint Point; + typedef Point point_type; + typedef Vertex vertex_type; + typedef deque vertex_container; + + /* Iterator to iterate over a vertex edges */ + + typedef CurveInternal::__point_iterator point_iterator; + typedef CurveInternal::__point_iterator 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 + 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 - * oplyline constituing the Curve. - */ - inline unsigned int nSegments() const {return _nSegments;} - - inline void setId(const Id& id){_Id = id;} - /* Information access interface */ - - - //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 ; - - /* 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.f); - CurveInternal::CurvePointIterator curvePointsEnd(float t=0.f); - - 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.f); - /*! 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.f); -}; + /*! 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 +#endif // __FREESTYLE_CURVE_H__ diff --git a/source/blender/freestyle/intern/stroke/CurveAdvancedIterators.h b/source/blender/freestyle/intern/stroke/CurveAdvancedIterators.h index c1524d18fe1..0c053bf1845 100644 --- a/source/blender/freestyle/intern/stroke/CurveAdvancedIterators.h +++ b/source/blender/freestyle/intern/stroke/CurveAdvancedIterators.h @@ -1,378 +1,383 @@ -// -// Filename : CurveAdvancedIterators.h -// Author(s) : Stephane Grabli -// Purpose : Iterators used to iterate over the elements of the Curve -// Can't be used in python -// Date of creation : 01/08/2003 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef ADVANCEDCURVEITERATORS_H -# define ADVANCEDCURVEITERATORS_H - -# include "Stroke.h" +/* + * ***** 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_ADVANCED_ITERATORS_H__ +#define __FREESTYLE_CURVE_ADVANCED_ITERATORS_H__ + +/** \file blender/freestyle/intern/stroke/CurveAdvancedIterators.h + * \ingroup freestyle + * \brief Iterators used to iterate over the elements of the Curve. Can't be used in python + * \author Stephane Grabli + * \date 01/08/2003 + */ + +#include "Stroke.h" namespace CurveInternal { - class CurvePoint_const_traits : public Const_traits { - public: - typedef deque vertex_container; - typedef vertex_container::const_iterator vertex_container_iterator; - typedef SVertex vertex_type; - }; - - class CurvePoint_nonconst_traits : public Nonconst_traits { - public: - typedef deque vertex_container; - typedef vertex_container::iterator vertex_container_iterator ; - typedef SVertex vertex_type; - }; - - /**********************************/ - /* */ - /* */ - /* CurvePoint Iterator */ - /* */ - /* */ - /**********************************/ - - - /*! iterator on a curve. Allows an iterating outside - * initial vertices. A CurvePoint is instanciated an returned - * when the iterator is dereferenced. - */ - - template - class __point_iterator : public IteratorBase - { - public: - typedef __point_iterator Self; - typedef typename Traits::vertex_container_iterator vertex_container_iterator; - typedef typename Traits::vertex_type vertex_type; - typedef CurvePoint Point; - typedef Point point_type; - - typedef __point_iterator iterator; - typedef __point_iterator const_iterator; - - // public: - // typedef Vertex vertex_type ; - // typedef vertex_container_iterator vertex_iterator_type; - // typedef CurvePoint Point; - // typedef Point point_type; - typedef IteratorBase parent_class; - //# if defined(__GNUC__) && (__GNUC__ < 3) - // typedef bidirectional_iterator,ptrdiff_t> bidirectional_point_iterator; - //# else - // typedef iterator,ptrdiff_t> bidirectional_point_iterator; - //# endif - friend class Curve; - //friend class Curve::vertex_iterator; - //friend class __point_iterator; - //friend class iterator; - //protected: - public: - float _CurvilinearLength; - float _step; - vertex_container_iterator __A; - vertex_container_iterator __B; - vertex_container_iterator _begin; - vertex_container_iterator _end; - int _n; - int _currentn; - float _t; - mutable Point *_Point; - - public: - - public: - inline __point_iterator(float step = 0.f) - : parent_class() - { - _step = step; - _CurvilinearLength = 0.f; - _t = 0.f; - _Point = 0; - _n = 0; - _currentn = 0; - } - - inline __point_iterator(const iterator& iBrother) - : parent_class() - { - __A = iBrother.__A; - __B = iBrother.__B; - _begin = iBrother._begin; - _end = iBrother._end; - _CurvilinearLength = iBrother._CurvilinearLength; - _step = iBrother._step; - _t = iBrother._t; - if(iBrother._Point == 0) - _Point = 0; - else - _Point = new Point(*(iBrother._Point)); - _n = iBrother._n; - _currentn = iBrother._currentn; - } - inline __point_iterator(const const_iterator& iBrother) - : parent_class() - { - __A = iBrother.__A; - __B = iBrother.__B; - _begin = iBrother._begin; - _end = iBrother._end; - _CurvilinearLength = iBrother._CurvilinearLength; - _step = iBrother._step; - _t = iBrother._t; - if(iBrother._Point == 0) - _Point = 0; - else - _Point = new Point(*(iBrother._Point)); - _n = iBrother._n; - _currentn = iBrother._currentn; - } - inline Self& operator=(const Self& iBrother) - { - //((bidirectional_point_iterator*)this)->operator=(iBrother); - __A = iBrother.__A; - __B = iBrother.__B; - _begin = iBrother._begin; - _end = iBrother._end; - _CurvilinearLength = iBrother._CurvilinearLength; - _step = iBrother._step; - _t = iBrother._t; - if(iBrother._Point == 0) - _Point = 0; - else - _Point = new Point(*(iBrother._Point)); - _n = iBrother._n; - _currentn = iBrother._currentn; - return *this; - } - virtual ~__point_iterator() - { - if(_Point != 0) - delete _Point; - } - //protected://FIXME - public: - inline __point_iterator(vertex_container_iterator iA, - vertex_container_iterator iB, - vertex_container_iterator ibegin, - vertex_container_iterator iend, - int currentn, - int n, - float step, float t=0.f, float iCurvilinearLength = 0.f) - : parent_class() - { - __A = iA; - __B = iB; - _begin = ibegin; - _end = iend; - _CurvilinearLength = iCurvilinearLength; - _step = step; - _t = t; - _Point = 0; - _n = n; - _currentn = currentn; - } - - public: - - // operators - inline Self& operator++() // operator corresponding to ++i - { - increment(); - return *this; - } - inline Self operator++(int) // opérateur correspondant à i++ - { // c.a.d qui renvoie la valeur *puis* incrémente. - Self tmp = *this; // C'est pour cela qu'on stocke la valeur - increment(); // dans un temporaire. - return tmp; - } - inline Self& operator--() // operator corresponding to ++i - { - decrement(); - return *this; - } - inline Self operator--(int) // opérateur correspondant à i++ - { // c.a.d qui renvoie la valeur *puis* incrémente. - Self tmp = *this; // C'est pour cela qu'on stocke la valeur - decrement(); // dans un temporaire. - return tmp; - } - - // comparibility - virtual bool operator!=(const Self& b) const - { - return ((__A!=b.__A) || (__B!=b.__B) || (_t != b._t)); - } - virtual bool operator==(const Self& b) const - { - return !(*this != b); - } - - // dereferencing - virtual typename Traits::reference operator*() const - { - if(_Point != 0) - { - delete _Point; - _Point = 0; - } - if((_currentn < 0) || (_currentn >= _n)) - return _Point; // 0 in this case - return (_Point = new Point(*__A,*__B,_t)); - } - virtual typename Traits::pointer operator->() const { return &(operator*());} - - public: - virtual bool begin() const - { - if((__A == _begin) && (_t < (float)M_EPSILON)) - return true; - return false; - } - virtual bool end() const - { - if((__B == _end)) - return true; - return false; - } - protected: - virtual void increment() - { - if(_Point != 0) - { - delete _Point; - _Point = 0; - } - if((_currentn == _n-1) && (_t == 1.f)) - { - // we're setting the iterator to end - ++__A; - ++__B; - ++_currentn; - _t = 0.f; - return; - } - - if(0 == _step) // means we iterate over initial vertices - { - Vec3r vec_tmp((*__B)->point2d() - (*__A)->point2d()); - _CurvilinearLength += vec_tmp.norm(); - if(_currentn == _n-1) - { - _t = 1.f; - return; - } - ++__B; - ++__A; - ++_currentn; - return; - } - - // compute the new position: - Vec3r vec_tmp2((*__A)->point2d() - (*__B)->point2d()); - float normAB = vec_tmp2.norm(); - - if(normAB > M_EPSILON) - { - _CurvilinearLength += _step; - _t = _t + _step/normAB; - } - else - _t = 1.f; // AB is a null segment, we're directly at its end - //if normAB ~= 0, we don't change these values - if(_t >= 1) - { - _CurvilinearLength -= normAB*(_t-1); - if(_currentn == _n-1) - _t=1.f; - else - { - _t = 0.f; - ++_currentn; - ++__A;++__B; - } - } - } - virtual void decrement() - { - if(_Point != 0) - { - delete _Point; - _Point = 0; - } - - if(_t == 0.f) //we're at the beginning of the edge - { - _t = 1.f; - --_currentn; - --__A; --__B; - if(_currentn == _n-1) - return; - } - - if(0 == _step) // means we iterate over initial vertices - { - Vec3r vec_tmp((*__B)->point2d() - (*__A)->point2d()); - _CurvilinearLength -= vec_tmp.norm(); - _t = 0; - return; - } - - // compute the new position: - Vec3r vec_tmp2((*__A)->point2d() - (*__B)->point2d()); - float normAB = vec_tmp2.norm(); - - if(normAB >M_EPSILON) - { - _CurvilinearLength -= _step; - _t = _t - _step/normAB; - } - else - _t = -1.f; // We just need a negative value here - - // round value - if(fabs(_t) < (float)M_EPSILON) - _t = 0.0; - if(_t < 0) - { - if(_currentn == 0) - _CurvilinearLength = 0.f; - else - _CurvilinearLength += normAB*(-_t); - _t = 0.f; - } - } - }; - - - -} // end of namespace StrokeInternal - - -#endif // ADVANCEDCURVEITERATORS_H +class CurvePoint_const_traits : public Const_traits +{ +public: + typedef deque vertex_container; + typedef vertex_container::const_iterator vertex_container_iterator; + typedef SVertex vertex_type; +}; + +class CurvePoint_nonconst_traits : public Nonconst_traits +{ +public: + typedef deque vertex_container; + typedef vertex_container::iterator vertex_container_iterator; + typedef SVertex vertex_type; +}; + +/**********************************/ +/* */ +/* */ +/* CurvePoint Iterator */ +/* */ +/* */ +/**********************************/ + + +/*! iterator on a curve. Allows an iterating outside initial vertices. A CurvePoint is instanciated an returned + * when the iterator is dereferenced. + */ +template +class __point_iterator : public IteratorBase +{ +public: + typedef __point_iterator Self; + typedef typename Traits::vertex_container_iterator vertex_container_iterator; + typedef typename Traits::vertex_type vertex_type; + typedef CurvePoint Point; + typedef Point point_type; + + typedef __point_iterator iterator; + typedef __point_iterator const_iterator; + +#if 0 + typedef Vertex vertex_type ; + typedef vertex_container_iterator vertex_iterator_type; + typedef CurvePoint Point; + typedef Point point_type; +#endif + typedef IteratorBase parent_class; +#if 0 +#if defined(__GNUC__) && (__GNUC__ < 3) + typedef bidirectional_iterator, ptrdiff_t> bidirectional_point_iterator; +#else + typedef iterator, ptrdiff_t> bidirectional_point_iterator; +#endif +#endif + friend class Curve; +#if 0 + friend class Curve::vertex_iterator; + friend class __point_iterator; + friend class iterator; +#endif +//protected: +public: + float _CurvilinearLength; + float _step; + vertex_container_iterator __A; + vertex_container_iterator __B; + vertex_container_iterator _begin; + vertex_container_iterator _end; + int _n; + int _currentn; + float _t; + mutable Point *_Point; + +public: + inline __point_iterator(float step = 0.0f) : parent_class() + { + _step = step; + _CurvilinearLength = 0.0f; + _t = 0.0f; + _Point = 0; + _n = 0; + _currentn = 0; + } + + inline __point_iterator(const iterator& iBrother) : parent_class() + { + __A = iBrother.__A; + __B = iBrother.__B; + _begin = iBrother._begin; + _end = iBrother._end; + _CurvilinearLength = iBrother._CurvilinearLength; + _step = iBrother._step; + _t = iBrother._t; + if (iBrother._Point == 0) + _Point = 0; + else + _Point = new Point(*(iBrother._Point)); + _n = iBrother._n; + _currentn = iBrother._currentn; + } + + inline __point_iterator(const const_iterator& iBrother) : parent_class() + { + __A = iBrother.__A; + __B = iBrother.__B; + _begin = iBrother._begin; + _end = iBrother._end; + _CurvilinearLength = iBrother._CurvilinearLength; + _step = iBrother._step; + _t = iBrother._t; + if (iBrother._Point == 0) + _Point = 0; + else + _Point = new Point(*(iBrother._Point)); + _n = iBrother._n; + _currentn = iBrother._currentn; + } + + inline Self& operator=(const Self& iBrother) + { + //((bidirectional_point_iterator*)this)->operator=(iBrother); + __A = iBrother.__A; + __B = iBrother.__B; + _begin = iBrother._begin; + _end = iBrother._end; + _CurvilinearLength = iBrother._CurvilinearLength; + _step = iBrother._step; + _t = iBrother._t; + if (iBrother._Point == 0) + _Point = 0; + else + _Point = new Point(*(iBrother._Point)); + _n = iBrother._n; + _currentn = iBrother._currentn; + return *this; + } + + virtual ~__point_iterator() + { + if (_Point != 0) + delete _Point; + } + +//protected: //FIXME +public: + inline __point_iterator(vertex_container_iterator iA, vertex_container_iterator iB, + vertex_container_iterator ibegin, vertex_container_iterator iend, + int currentn, int n, float step, float t = 0.0f, float iCurvilinearLength = 0.0f) + : parent_class() + { + __A = iA; + __B = iB; + _begin = ibegin; + _end = iend; + _CurvilinearLength = iCurvilinearLength; + _step = step; + _t = t; + _Point = 0; + _n = n; + _currentn = currentn; + } + +public: + // operators + inline Self& operator++() // operator corresponding to ++i + { + increment(); + return *this; + } + + /* Operator corresponding to i++, i.e. it returns the value *and then* increments. + * That’s why we store the value in a temp. + */ + inline Self operator++(int) + { + Self tmp = *this; + increment(); + return tmp; + } + + inline Self& operator--() // operator corresponding to --i + { + decrement(); + return *this; + } + + inline Self operator--(int) // operator corresponding to i-- + { + Self tmp = *this; + decrement(); + return tmp; + } + + // comparibility + virtual bool operator!=(const Self& b) const + { + return ((__A != b.__A) || (__B != b.__B) || (_t != b._t)); + } + + virtual bool operator==(const Self& b) const + { + return !(*this != b); + } + + // dereferencing + virtual typename Traits::reference operator*() const + { + if (_Point != 0) { + delete _Point; + _Point = 0; + } + if ((_currentn < 0) || (_currentn >= _n)) + return _Point; // 0 in this case + return (_Point = new Point(*__A, *__B, _t)); + } + + virtual typename Traits::pointer operator->() const + { + return &(operator*()); + } + + virtual bool begin() const + { + if ((__A == _begin) && (_t < (float)M_EPSILON)) + return true; + return false; + } + + virtual bool end() const + { + if ((__B == _end)) + return true; + return false; + } + +protected: + virtual void increment() + { + if (_Point != 0) { + delete _Point; + _Point = 0; + } + if ((_currentn == _n - 1) && (_t == 1.0f)) { + // we're setting the iterator to end + ++__A; + ++__B; + ++_currentn; + _t = 0.0f; + return; + } + + if (0 == _step) { // means we iterate over initial vertices + Vec3r vec_tmp((*__B)->point2d() - (*__A)->point2d()); + _CurvilinearLength += vec_tmp.norm(); + if (_currentn == _n-1) { + _t = 1.0f; + return; + } + ++__B; + ++__A; + ++_currentn; + return; + } + + // compute the new position: + Vec3r vec_tmp2((*__A)->point2d() - (*__B)->point2d()); + float normAB = vec_tmp2.norm(); + + if (normAB > M_EPSILON) { + _CurvilinearLength += _step; + _t = _t + _step / normAB; + } + else { + _t = 1.0f; // AB is a null segment, we're directly at its end + } + //if normAB ~= 0, we don't change these values + if (_t >= 1) { + _CurvilinearLength -= normAB * (_t - 1); + if (_currentn == _n - 1) { + _t = 1.0f; + } + else { + _t = 0.0f; + ++_currentn; + ++__A; + ++__B; + } + } + } + + virtual void decrement() + { + if (_Point != 0) { + delete _Point; + _Point = 0; + } + + if (_t == 0.0f) { // we're at the beginning of the edge + _t = 1.0f; + --_currentn; + --__A; + --__B; + if (_currentn == _n - 1) + return; + } + + if (0 == _step) { // means we iterate over initial vertices + Vec3r vec_tmp((*__B)->point2d() - (*__A)->point2d()); + _CurvilinearLength -= vec_tmp.norm(); + _t = 0; + return; + } + + // compute the new position: + Vec3r vec_tmp2((*__A)->point2d() - (*__B)->point2d()); + float normAB = vec_tmp2.norm(); + + if (normAB >M_EPSILON) { + _CurvilinearLength -= _step; + _t = _t - _step / normAB; + } + else { + _t = -1.0f; // We just need a negative value here + } + + // round value + if (fabs(_t) < (float)M_EPSILON) + _t = 0.0f; + if (_t < 0) { + if (_currentn == 0) + _CurvilinearLength = 0.0f; + else + _CurvilinearLength += normAB * (-_t); + _t = 0.0f; + } + } +}; + +} // end of namespace CurveInternal + +#endif // __FREESTYLE_CURVE_ADVANCED_ITERATORS_H__ diff --git a/source/blender/freestyle/intern/stroke/CurveIterators.h b/source/blender/freestyle/intern/stroke/CurveIterators.h index a45ef4bfdaf..7d9e0e00ef1 100644 --- a/source/blender/freestyle/intern/stroke/CurveIterators.h +++ b/source/blender/freestyle/intern/stroke/CurveIterators.h @@ -1,299 +1,302 @@ -// -// Filename : CurveIterators.h -// Author(s) : Stephane Grabli -// Purpose : Iterators used to iterate over the elements of the Curve -// Date of creation : 01/08/2003 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef CURVEITERATORS_H -# define CURVEITERATORS_H +/* + * ***** 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_ITERATORS_H__ +#define __FREESTYLE_CURVE_ITERATORS_H__ + +/** \file blender/freestyle/intern/stroke/CurveIterators.h + * \ingroup freestyle + * \brief Iterators used to iterate over the elements of the Curve + * \author Stephane Grabli + * \date 01/08/2003 + */ -#include "Stroke.h" #include "Curve.h" +#include "Stroke.h" namespace CurveInternal { - /*! iterator on a curve. Allows an iterating outside - * initial vertices. A CurvePoint is instanciated an returned - * when the iterator is dereferenced. - */ - - class CurvePointIterator : public Interface0DIteratorNested - { - public: - friend class ::Curve; - public: - float _CurvilinearLength; - float _step; - ::Curve::vertex_container::iterator __A; - ::Curve::vertex_container::iterator __B; - ::Curve::vertex_container::iterator _begin; - ::Curve::vertex_container::iterator _end; - int _n; - int _currentn; - float _t; - mutable CurvePoint _Point; - float _CurveLength; - - public: - - public: - inline CurvePointIterator(float step = 0.f) - : Interface0DIteratorNested() - { - _step = step; - _CurvilinearLength = 0.f; - _t = 0.f; - //_Point = 0; - _n = 0; - _currentn = 0; - _CurveLength=0; - } - - inline CurvePointIterator(const CurvePointIterator& iBrother) - : Interface0DIteratorNested() - { - __A = iBrother.__A; - __B = iBrother.__B; - _begin = iBrother._begin; - _end = iBrother._end; - _CurvilinearLength = iBrother._CurvilinearLength; - _step = iBrother._step; - _t = iBrother._t; - _Point = iBrother._Point; - _n = iBrother._n; - _currentn = iBrother._currentn; - _CurveLength = iBrother._CurveLength; - } - inline CurvePointIterator& operator=(const CurvePointIterator& iBrother) - { - __A = iBrother.__A; - __B = iBrother.__B; - _begin = iBrother._begin; - _end = iBrother._end; - _CurvilinearLength = iBrother._CurvilinearLength; - _step = iBrother._step; - _t = iBrother._t; - _Point = iBrother._Point; - _n = iBrother._n; - _currentn = iBrother._currentn; - _CurveLength = iBrother._CurveLength; - return *this; - } - virtual ~CurvePointIterator() - { - } - protected: - inline CurvePointIterator(::Curve::vertex_container::iterator iA, - ::Curve::vertex_container::iterator iB, - ::Curve::vertex_container::iterator ibegin, - ::Curve::vertex_container::iterator iend, - int currentn, - int n, - float iCurveLength, - float step, float t=0.f, float iCurvilinearLength = 0.f) - : Interface0DIteratorNested() - { - __A = iA; - __B = iB; - _begin = ibegin; - _end = iend; - _CurvilinearLength = iCurvilinearLength; - _step = step; - _t = t; - _n = n; - _currentn = currentn; - _CurveLength = iCurveLength; - } - - public: - - virtual CurvePointIterator* copy() const { - return new CurvePointIterator(*this); - } - - inline Interface0DIterator castToInterface0DIterator() const{ - Interface0DIterator ret(new CurveInternal::CurvePointIterator(*this)); - return ret; - } - virtual string getExactTypeName() const { - return "CurvePointIterator"; - } - - // operators - inline CurvePointIterator& operator++() // operator corresponding to ++i - { - increment(); - return *this; - } - - inline CurvePointIterator& operator--() // operator corresponding to ++i - { - decrement(); - return *this; - } - - // comparibility - virtual bool operator==(const Interface0DIteratorNested& b) const - { - const CurvePointIterator* it_exact = dynamic_cast(&b); - if (!it_exact) - return false; - return ((__A==it_exact->__A) && (__B==it_exact->__B) && (_t == it_exact->_t)); - } - - // dereferencing - virtual CurvePoint& operator*() - { - return (_Point = CurvePoint(*__A,*__B,_t)); - } - virtual CurvePoint* operator->() { return &(operator*());} - public: - virtual bool isBegin() const - { - if((__A == _begin) && (_t < (float)M_EPSILON)) - return true; - return false; - } - virtual bool isEnd() const - { - if(__B == _end) - return true; - return false; - } - -// protected: - - virtual int increment() - { - if((_currentn == _n-1) && (_t == 1.f)) - { - // we're setting the iterator to end - ++__A; - ++__B; - ++_currentn; - _t = 0.f; - return 0; - } - - if(0 == _step) // means we iterate over initial vertices - { - Vec3r vec_tmp((*__B)->point2d() - (*__A)->point2d()); - _CurvilinearLength += (float)vec_tmp.norm(); - if(_currentn == _n-1) - { - _t = 1.f; - return 0; - } - ++__B; - ++__A; - ++_currentn; - return 0; - } - - // compute the new position: - Vec3r vec_tmp2((*__A)->point2d() - (*__B)->point2d()); - float normAB = (float)vec_tmp2.norm(); - - if(normAB > M_EPSILON) - { - _CurvilinearLength += _step; - _t = _t + _step/normAB; - } - else - _t = 1.f; // AB is a null segment, we're directly at its end - //if normAB ~= 0, we don't change these values - if(_t >= 1) - { - _CurvilinearLength -= normAB*(_t-1); - if(_currentn == _n-1) - _t=1.f; - else - { - _t = 0.f; - ++_currentn; - ++__A;++__B; - } - } - return 0; - } - virtual int decrement() - { - if(_t == 0.f) //we're at the beginning of the edge - { - _t = 1.f; - --_currentn; - --__A; --__B; - if(_currentn == _n-1) - return 0; - } - - if(0 == _step) // means we iterate over initial vertices - { - Vec3r vec_tmp((*__B)->point2d() - (*__A)->point2d()); - _CurvilinearLength -= (float)vec_tmp.norm(); - _t = 0; - return 0; - } - - // compute the new position: - Vec3r vec_tmp2((*__A)->point2d() - (*__B)->point2d()); - float normAB = (float)vec_tmp2.norm(); - - if(normAB >M_EPSILON) - { - _CurvilinearLength -= _step; - _t = _t - _step/normAB; - } - else - _t = -1.f; // We just need a negative value here - - // round value - if(fabs(_t) < (float)M_EPSILON) - _t = 0.0; - if(_t < 0) - { - if(_currentn == 0) - _CurvilinearLength = 0.f; - else - _CurvilinearLength += normAB*(-_t); - _t = 0.f; - } - return 0; - } - - virtual float t() const{ - return _CurvilinearLength; - } - virtual float u() const{ - return _CurvilinearLength/_CurveLength; - } - }; - - - -} // end of namespace StrokeInternal - -#endif // CURVEITERATORS_H +/*! iterator on a curve. Allows an iterating outside +* initial vertices. A CurvePoint is instanciated an returned +* when the iterator is dereferenced. +*/ + +class CurvePointIterator : public Interface0DIteratorNested +{ +public: + friend class ::Curve; + +public: + float _CurvilinearLength; + float _step; + ::Curve::vertex_container::iterator __A; + ::Curve::vertex_container::iterator __B; + ::Curve::vertex_container::iterator _begin; + ::Curve::vertex_container::iterator _end; + int _n; + int _currentn; + float _t; + mutable CurvePoint _Point; + float _CurveLength; + +public: + inline CurvePointIterator(float step = 0.0f) : Interface0DIteratorNested() + { + _step = step; + _CurvilinearLength = 0.0f; + _t = 0.0f; + //_Point = 0; + _n = 0; + _currentn = 0; + _CurveLength = 0; + } + + inline CurvePointIterator(const CurvePointIterator& iBrother) : Interface0DIteratorNested() + { + __A = iBrother.__A; + __B = iBrother.__B; + _begin = iBrother._begin; + _end = iBrother._end; + _CurvilinearLength = iBrother._CurvilinearLength; + _step = iBrother._step; + _t = iBrother._t; + _Point = iBrother._Point; + _n = iBrother._n; + _currentn = iBrother._currentn; + _CurveLength = iBrother._CurveLength; + } + + inline CurvePointIterator& operator=(const CurvePointIterator& iBrother) + { + __A = iBrother.__A; + __B = iBrother.__B; + _begin = iBrother._begin; + _end = iBrother._end; + _CurvilinearLength = iBrother._CurvilinearLength; + _step = iBrother._step; + _t = iBrother._t; + _Point = iBrother._Point; + _n = iBrother._n; + _currentn = iBrother._currentn; + _CurveLength = iBrother._CurveLength; + return *this; + } + + virtual ~CurvePointIterator() {} + +protected: + inline CurvePointIterator(::Curve::vertex_container::iterator iA, ::Curve::vertex_container::iterator iB, + ::Curve::vertex_container::iterator ibegin, ::Curve::vertex_container::iterator iend, + int currentn, int n, float iCurveLength, float step, float t = 0.0f, + float iCurvilinearLength = 0.0f) + : Interface0DIteratorNested() + { + __A = iA; + __B = iB; + _begin = ibegin; + _end = iend; + _CurvilinearLength = iCurvilinearLength; + _step = step; + _t = t; + _n = n; + _currentn = currentn; + _CurveLength = iCurveLength; + } + +public: + virtual CurvePointIterator* copy() const + { + return new CurvePointIterator(*this); + } + + inline Interface0DIterator castToInterface0DIterator() const + { + Interface0DIterator ret(new CurveInternal::CurvePointIterator(*this)); + return ret; + } + + virtual string getExactTypeName() const + { + return "CurvePointIterator"; + } + + // operators + inline CurvePointIterator& operator++() // operator corresponding to ++i + { + increment(); + return *this; + } + + inline CurvePointIterator& operator--() // operator corresponding to --i + { + decrement(); + return *this; + } + + // comparibility + virtual bool operator==(const Interface0DIteratorNested& b) const + { + const CurvePointIterator* it_exact = dynamic_cast(&b); + if (!it_exact) + return false; + return ((__A == it_exact->__A) && (__B == it_exact->__B) && (_t == it_exact->_t)); + } + + // dereferencing + virtual CurvePoint& operator*() + { + return (_Point = CurvePoint(*__A, *__B, _t)); + } + + virtual CurvePoint* operator->() + { + return &(operator*()); + } + + virtual bool isBegin() const + { + if ((__A == _begin) && (_t < (float)M_EPSILON)) + return true; + return false; + } + + virtual bool isEnd() const + { + if (__B == _end) + return true; + return false; + } + +//protected: + virtual int increment() + { + if ((_currentn == _n - 1) && (_t == 1.0f)) { + // we're setting the iterator to end + ++__A; + ++__B; + ++_currentn; + _t = 0.0f; + return 0; + } + + if (0 == _step) { // means we iterate over initial vertices + Vec3r vec_tmp((*__B)->point2d() - (*__A)->point2d()); + _CurvilinearLength += (float)vec_tmp.norm(); + if (_currentn == _n - 1) { + _t = 1.0f; + return 0; + } + ++__B; + ++__A; + ++_currentn; + return 0; + } + + // compute the new position: + Vec3r vec_tmp2((*__A)->point2d() - (*__B)->point2d()); + float normAB = (float)vec_tmp2.norm(); + + if (normAB > M_EPSILON) { + _CurvilinearLength += _step; + _t = _t + _step / normAB; + } + else { + _t = 1.0f; // AB is a null segment, we're directly at its end + } + //if normAB ~= 0, we don't change these values + if (_t >= 1) { + _CurvilinearLength -= normAB * (_t - 1); + if (_currentn == _n - 1) { + _t = 1.0f; + } + else { + _t = 0.0f; + ++_currentn; + ++__A; + ++__B; + } + } + return 0; + } + + virtual int decrement() + { + if (_t == 0.0f) { //we're at the beginning of the edge + _t = 1.0f; + --_currentn; + --__A; + --__B; + if (_currentn == _n - 1) + return 0; + } + + if (0 == _step) { // means we iterate over initial vertices + Vec3r vec_tmp((*__B)->point2d() - (*__A)->point2d()); + _CurvilinearLength -= (float)vec_tmp.norm(); + _t = 0; + return 0; + } + + // compute the new position: + Vec3r vec_tmp2((*__A)->point2d() - (*__B)->point2d()); + float normAB = (float)vec_tmp2.norm(); + + if (normAB > M_EPSILON) { + _CurvilinearLength -= _step; + _t = _t - _step / normAB; + } + else { + _t = -1.0f; // We just need a negative value here + } + + // round value + if (fabs(_t) < (float)M_EPSILON) + _t = 0.0f; + if (_t < 0) { + if (_currentn == 0) + _CurvilinearLength = 0.0f; + else + _CurvilinearLength += normAB * (-_t); + _t = 0.0f; + } + return 0; + } + + virtual float t() const + { + return _CurvilinearLength; + } + + virtual float u() const + { + return _CurvilinearLength / _CurveLength; + } +}; + +} // end of namespace CurveInternal + +#endif // __FREESTYLE_CURVE_ITERATORS_H__ diff --git a/source/blender/freestyle/intern/stroke/Modifiers.h b/source/blender/freestyle/intern/stroke/Modifiers.h index 21bebebc6f8..daa02002b7b 100644 --- a/source/blender/freestyle/intern/stroke/Modifiers.h +++ b/source/blender/freestyle/intern/stroke/Modifiers.h @@ -1,71 +1,74 @@ -// -// Filename : Modifiers.h -// Author : Stephane Grabli -// Purpose : modifiers... -// Date of creation : 05/01/2003 -// -/////////////////////////////////////////////////////////////////////////////// - +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +#ifndef __FREESTYLE_MODIFIERS_H__ +#define __FREESTYLE_MODIFIERS_H__ -#ifndef MODIFIERS_H -# define MODIFIERS_H +/** \file blender/freestyle/intern/stroke/Modifiers.h + * \ingroup freestyle + * \brief modifiers... + * \author Stephane Grabli + * \date 05/01/2003 + */ -# include "TimeStamp.h" +#include "TimeStamp.h" /* ----------------------------------------- * * * - * modifiers * + * modifiers * * * * ----------------------------------------- */ + /*! Base class for modifiers. - * Modifiers are used in the - * Operators in order to "mark" - * the processed Interface1D. + * Modifiers are used in the Operators in order to "mark" the processed Interface1D. */ template -struct EdgeModifier : public unary_function +struct EdgeModifier : public unary_function { - /*! Default construction */ - EdgeModifier() : unary_function() {} - /*! the () operator */ - virtual void operator()(Edge& iEdge) {} + /*! Default construction */ + EdgeModifier() : unary_function() {} + + /*! the () operator */ + virtual void operator()(Edge& iEdge) {} }; -/*! Modifier that sets the time stamp - * of an Interface1D to the time stamp - * of the system. - */ +/*! Modifier that sets the time stamp of an Interface1D to the time stamp of the system. */ template struct TimestampModifier : public EdgeModifier { - /*! Default constructor */ - TimestampModifier() : EdgeModifier() {} - /*! The () operator. */ - virtual void operator()(Edge& iEdge) - { - TimeStamp *timestamp = TimeStamp::instance(); - iEdge.setTimeStamp(timestamp->getTimeStamp()); - } + /*! Default constructor */ + TimestampModifier() : EdgeModifier() {} + + /*! The () operator. */ + virtual void operator()(Edge& iEdge) + { + TimeStamp *timestamp = TimeStamp::instance(); + iEdge.setTimeStamp(timestamp->getTimeStamp()); + } }; #endif // MODIFIERS_H diff --git a/source/blender/freestyle/intern/stroke/Module.h b/source/blender/freestyle/intern/stroke/Module.h index 591bb157392..da6708e6ea9 100644 --- a/source/blender/freestyle/intern/stroke/Module.h +++ b/source/blender/freestyle/intern/stroke/Module.h @@ -1,72 +1,82 @@ -// -// Filename : Module.h -// Author(s) : Emmanuel Turquin -// Purpose : Set the type of the module -// Date of creation : 01/07/2003 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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_MODULE_H__ +#define __FREESTYLE_MODULE_H__ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/stroke/Module.h + * \ingroup freestyle + * \brief Set the type of the module + * \author Emmanuel Turquin + * \date 01/07/2003 + */ -#ifndef MODULE_H -# define MODULE_H - -# include "Canvas.h" -# include "StyleModule.h" +#include "Canvas.h" +#include "StyleModule.h" class Module { public: + static void setAlwaysRefresh(bool b = true) + { + getCurrentStyleModule()->setAlwaysRefresh(b); + } - static void setAlwaysRefresh(bool b = true) { - getCurrentStyleModule()->setAlwaysRefresh(b); - } - - static void setCausal(bool b = true) { - getCurrentStyleModule()->setCausal(b); - } + static void setCausal(bool b = true) + { + getCurrentStyleModule()->setCausal(b); + } - static void setDrawable(bool b = true) { - getCurrentStyleModule()->setDrawable(b); - } + static void setDrawable(bool b = true) + { + getCurrentStyleModule()->setDrawable(b); + } - static bool getAlwaysRefresh() { - return getCurrentStyleModule()->getAlwaysRefresh(); - } + static bool getAlwaysRefresh() + { + return getCurrentStyleModule()->getAlwaysRefresh(); + } - static bool getCausal() { - return getCurrentStyleModule()->getCausal(); - } + static bool getCausal() + { + return getCurrentStyleModule()->getCausal(); + } - static bool getDrawable() { - return getCurrentStyleModule()->getDrawable(); - } + static bool getDrawable() + { + return getCurrentStyleModule()->getDrawable(); + } private: - - static StyleModule* getCurrentStyleModule() { - Canvas* canvas = Canvas::getInstance(); - return canvas->getCurrentStyleModule(); - } + static StyleModule* getCurrentStyleModule() + { + Canvas *canvas = Canvas::getInstance(); + return canvas->getCurrentStyleModule(); + } }; -#endif // MODULE_H +#endif // __FREESTYLE_MODULE_H__ diff --git a/source/blender/freestyle/intern/stroke/Operators.cpp b/source/blender/freestyle/intern/stroke/Operators.cpp index 80562e104d2..15aff89db45 100644 --- a/source/blender/freestyle/intern/stroke/Operators.cpp +++ b/source/blender/freestyle/intern/stroke/Operators.cpp @@ -1,643 +1,667 @@ +/* + * ***** 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 ***** + */ + +/** \file blender/freestyle/intern/stroke/Operators.cpp + * \ingroup freestyle + * \brief Class gathering stroke creation algorithms + * \author Stephane Grabli + * \author Emmanuel Turquin + * \date 01/07/2003 + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#include "Operators.h" #include #include + +#include "Operators.h" #include "Canvas.h" #include "Stroke.h" -LIB_STROKE_EXPORT Operators::I1DContainer Operators::_current_view_edges_set; -LIB_STROKE_EXPORT Operators::I1DContainer Operators::_current_chains_set; -LIB_STROKE_EXPORT Operators::I1DContainer* Operators::_current_set = NULL; -LIB_STROKE_EXPORT Operators::StrokesContainer Operators::_current_strokes_set; - -int Operators::select(UnaryPredicate1D& pred) { - if (!_current_set) - return 0; - if(_current_set->empty()) - return 0; - I1DContainer new_set; - I1DContainer rejected; - Functions1D::ChainingTimeStampF1D cts; - Functions1D::TimeStampF1D ts; - I1DContainer::iterator it = _current_set->begin(); - I1DContainer::iterator itbegin = it; - while (it != _current_set->end()) { - Interface1D * i1d = *it; - cts(*i1d); // mark everyone's chaining time stamp anyway - if(pred(*i1d) < 0){ - new_set.clear(); - rejected.clear(); - return -1; +LIB_STROKE_EXPORT Operators::I1DContainer Operators::_current_view_edges_set; +LIB_STROKE_EXPORT Operators::I1DContainer Operators::_current_chains_set; +LIB_STROKE_EXPORT Operators::I1DContainer *Operators::_current_set = NULL; +LIB_STROKE_EXPORT Operators::StrokesContainer Operators::_current_strokes_set; + +int Operators::select(UnaryPredicate1D& pred) +{ + if (!_current_set) + return 0; + if (_current_set->empty()) + return 0; + I1DContainer new_set; + I1DContainer rejected; + Functions1D::ChainingTimeStampF1D cts; + Functions1D::TimeStampF1D ts; + I1DContainer::iterator it = _current_set->begin(); + I1DContainer::iterator itbegin = it; + while (it != _current_set->end()) { + Interface1D *i1d = *it; + cts(*i1d); // mark everyone's chaining time stamp anyway + if (pred(*i1d) < 0) { + new_set.clear(); + rejected.clear(); + return -1; + } + if (pred.result) { + new_set.push_back(i1d); + ts(*i1d); + } + else { + rejected.push_back(i1d); + } + ++it; } - if(pred.result){ - new_set.push_back(i1d); - ts(*i1d); - }else{ - rejected.push_back(i1d); - } - ++it; - } - if((*itbegin)->getExactTypeName() != "ViewEdge"){ - for (it = rejected.begin(); - it != rejected.end(); - ++it) - delete *it; - } - rejected.clear(); - _current_set->clear(); - *_current_set = new_set; - return 0; + if ((*itbegin)->getExactTypeName() != "ViewEdge") { + for (it = rejected.begin(); it != rejected.end(); ++it) + delete *it; + } + rejected.clear(); + _current_set->clear(); + *_current_set = new_set; + return 0; } -int Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, - UnaryPredicate1D& pred, - UnaryFunction1D_void& modifier) { - if (_current_view_edges_set.empty()) - return 0; - - unsigned id = 0; - ViewEdge* edge; - I1DContainer new_chains_set; - - for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); - it_edge != _current_view_edges_set.end(); - ++it_edge) { - if (pred(**it_edge) < 0) - goto error; - if (pred.result) - continue; - - edge = dynamic_cast(*it_edge); - it.setBegin(edge); - it.setCurrentEdge(edge); - - Chain* new_chain = new Chain(id);++id; - for (;;) { - new_chain->push_viewedge_back(*it, it.getOrientation()); - if (modifier(**it) < 0) { - delete new_chain; - goto error; - } - ++it; - if (it.isEnd()) - break; - if (pred(**it) < 0) { - delete new_chain; - goto error; - } - if (pred.result) - break; +int Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, UnaryPredicate1D& pred, UnaryFunction1D_void& modifier) +{ + if (_current_view_edges_set.empty()) + return 0; + + unsigned id = 0; + ViewEdge *edge; + I1DContainer new_chains_set; + + for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); + it_edge != _current_view_edges_set.end(); + ++it_edge) + { + if (pred(**it_edge) < 0) + goto error; + if (pred.result) + continue; + + edge = dynamic_cast(*it_edge); + it.setBegin(edge); + it.setCurrentEdge(edge); + + Chain *new_chain = new Chain(id); + ++id; + while (TRUE) { + new_chain->push_viewedge_back(*it, it.getOrientation()); + if (modifier(**it) < 0) { + delete new_chain; + goto error; + } + ++it; + if (it.isEnd()) + break; + if (pred(**it) < 0) { + delete new_chain; + goto error; + } + if (pred.result) + break; + } + new_chains_set.push_back(new_chain); + } + + if (!new_chains_set.empty()) { + for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { + _current_chains_set.push_back(*it); + } + new_chains_set.clear(); + _current_set = &_current_chains_set; } - new_chains_set.push_back(new_chain); - } - - if (!new_chains_set.empty()) { + return 0; + +error: for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { - _current_chains_set.push_back(*it); + delete (*it); } new_chains_set.clear(); - _current_set = &_current_chains_set; - } - return 0; - -error: - for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { - delete (*it); - } - new_chains_set.clear(); - return -1; + return -1; } -int Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, - UnaryPredicate1D& pred) { - if (_current_view_edges_set.empty()) - return 0; - - unsigned id = 0; - Functions1D::IncrementChainingTimeStampF1D ts; - Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp()+1); - ViewEdge* edge; - I1DContainer new_chains_set; - - for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); - it_edge != _current_view_edges_set.end(); - ++it_edge) { - if (pred(**it_edge) < 0) - goto error; - if (pred.result) - continue; - if (pred_ts(**it_edge) < 0) - goto error; - if (pred_ts.result) - continue; - - edge = dynamic_cast(*it_edge); - it.setBegin(edge); - it.setCurrentEdge(edge); - - Chain* new_chain = new Chain(id);++id; - for (;;) { - new_chain->push_viewedge_back(*it, it.getOrientation()); - ts(**it); - ++it; - if (it.isEnd()) - break; - if (pred(**it) < 0) { - delete new_chain; - goto error; - } - if (pred.result) - break; - if (pred_ts(**it) < 0) { - delete new_chain; - goto error; - } - if (pred_ts.result) - break; +int Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, UnaryPredicate1D& pred) +{ + if (_current_view_edges_set.empty()) + return 0; + + unsigned id = 0; + Functions1D::IncrementChainingTimeStampF1D ts; + Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp() + 1); + ViewEdge *edge; + I1DContainer new_chains_set; + + for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); + it_edge != _current_view_edges_set.end(); + ++it_edge) + { + if (pred(**it_edge) < 0) + goto error; + if (pred.result) + continue; + if (pred_ts(**it_edge) < 0) + goto error; + if (pred_ts.result) + continue; + + edge = dynamic_cast(*it_edge); + it.setBegin(edge); + it.setCurrentEdge(edge); + + Chain *new_chain = new Chain(id); + ++id; + while (TRUE) { + new_chain->push_viewedge_back(*it, it.getOrientation()); + ts(**it); + ++it; + if (it.isEnd()) + break; + if (pred(**it) < 0) { + delete new_chain; + goto error; + } + if (pred.result) + break; + if (pred_ts(**it) < 0) { + delete new_chain; + goto error; + } + if (pred_ts.result) + break; + } + new_chains_set.push_back(new_chain); + } + + if (!new_chains_set.empty()) { + for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { + _current_chains_set.push_back(*it); + } + new_chains_set.clear(); + _current_set = &_current_chains_set; } - new_chains_set.push_back(new_chain); - } - - if (!new_chains_set.empty()) { + return 0; + +error: for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { - _current_chains_set.push_back(*it); + delete (*it); } new_chains_set.clear(); - _current_set = &_current_chains_set; - } - return 0; - -error: - for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { - delete (*it); - } - new_chains_set.clear(); - return -1; + return -1; } -//void Operators::bidirectionalChain(ViewEdgeIterator& it, -// UnaryPredicate1D& pred, -// UnaryFunction1D_void& modifier) { -// if (_current_view_edges_set.empty()) -// return; -// -// unsigned id = 0; -// ViewEdge* edge; -// Chain* new_chain; -// -// for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); -// it_edge != _current_view_edges_set.end(); -// ++it_edge) { -// if (pred(**it_edge)) -// continue; -// -// edge = dynamic_cast(*it_edge); -// it.setBegin(edge); -// it.setCurrentEdge(edge); -// -// Chain* new_chain = new Chain(id);++id; -// //ViewEdgeIterator it_back(it);--it_back; // FIXME -// do { -// new_chain->push_viewedge_back(*it, it.getOrientation()); -// modifier(**it); -// ++it; -// } while (!it.isEnd() && !pred(**it)); -// it.setBegin(edge); -// it.setCurrentEdge(edge); -// --it; -// while (!it.isEnd() && !pred(**it)) { -// new_chain->push_viewedge_front(*it, it.getOrientation()); -// modifier(**it); -// --it; -// } -// -// _current_chains_set.push_back(new_chain); -// } -// -// if (!_current_chains_set.empty()) -// _current_set = &_current_chains_set; -//} -// -//void Operators::bidirectionalChain(ViewEdgeIterator& it, -// UnaryPredicate1D& pred) { -// if (_current_view_edges_set.empty()) -// return; -// -// unsigned id = 0; -// Functions1D::IncrementChainingTimeStampF1D ts; -// Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp()+1); -// -// ViewEdge* edge; -// Chain* new_chain; -// -// for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); -// it_edge != _current_view_edges_set.end(); -// ++it_edge) { -// if (pred(**it_edge) || pred_ts(**it_edge)) -// continue; -// -// edge = dynamic_cast(*it_edge); -// it.setBegin(edge); -// it.setCurrentEdge(edge); - // - // Chain* new_chain = new Chain(id);++id; - // //ViewEdgeIterator it_back(it);--it_back;//FIXME - // do { - // new_chain->push_viewedge_back(*it, it.getOrientation()); - // ts(**it); - // ++it; - // } while (!it.isEnd() && !pred(**it) && !pred_ts(**it)); - // it.setBegin(edge); - // it.setCurrentEdge(edge); - // --it; - // while (!it.isEnd() && !pred(**it) && !pred_ts(**it)) { - // new_chain->push_viewedge_front(*it, it.getOrientation()); - // ts(**it); - // --it; - // } - // - // _current_chains_set.push_back(new_chain); - // } - // - // if (!_current_chains_set.empty()) - // _current_set = &_current_chains_set; - //} - -int Operators::bidirectionalChain(ChainingIterator& it, UnaryPredicate1D& pred) { - if (_current_view_edges_set.empty()) - return 0; - - unsigned id = 0; - Functions1D::IncrementChainingTimeStampF1D ts; - Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp()+1); - ViewEdge* edge; - I1DContainer new_chains_set; - - for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); - it_edge != _current_view_edges_set.end(); - ++it_edge) { - if (pred(**it_edge) < 0) - goto error; - if (pred.result) - continue; - if (pred_ts(**it_edge) < 0) - goto error; - if (pred_ts.result) - continue; - - edge = dynamic_cast(*it_edge); - // re-init iterator - it.setBegin(edge); - it.setCurrentEdge(edge); - it.setOrientation(true); - if (it.init() < 0) - goto error; - - Chain* new_chain = new Chain(id);++id; - //ViewEdgeIterator it_back(it);--it_back;//FIXME - for (;;) { - new_chain->push_viewedge_back(*it, it.getOrientation()); - ts(**it); - if (it.increment() < 0) { - delete new_chain; - goto error; - } - if (it.isEnd()) - break; - if (pred(**it) < 0) { - delete new_chain; - goto error; - } - if (pred.result) - break; - } - it.setBegin(edge); - it.setCurrentEdge(edge); - it.setOrientation(true); - if (it.decrement() < 0) { - delete new_chain; - goto error; +#if 0 +void Operators::bidirectionalChain(ViewEdgeIterator& it, UnaryPredicate1D& pred, UnaryFunction1D_void& modifier) +{ + if (_current_view_edges_set.empty()) + return; + + unsigned id = 0; + ViewEdge *edge; + Chain *new_chain; + + for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); + it_edge != _current_view_edges_set.end(); + ++it_edge) + { + if (pred(**it_edge)) + continue; + + edge = dynamic_cast(*it_edge); + it.setBegin(edge); + it.setCurrentEdge(edge); + + Chain *new_chain = new Chain(id); + ++id; +#if 0 // FIXME + ViewEdgeIterator it_back(it); + --it_back; +#endif + do { + new_chain->push_viewedge_back(*it, it.getOrientation()); + modifier(**it); + ++it; + } while (!it.isEnd() && !pred(**it)); + it.setBegin(edge); + it.setCurrentEdge(edge); + --it; + while (!it.isEnd() && !pred(**it)) { + new_chain->push_viewedge_front(*it, it.getOrientation()); + modifier(**it); + --it; + } + + _current_chains_set.push_back(new_chain); } - while (!it.isEnd()) { - if (pred(**it) < 0) { - delete new_chain; - goto error; - } - if (pred.result) - break; - new_chain->push_viewedge_front(*it, it.getOrientation()); - ts(**it); - if (it.decrement() < 0) { - delete new_chain; - goto error; - } - } - new_chains_set.push_back(new_chain); - } - - if (!new_chains_set.empty()) { - for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { - _current_chains_set.push_back(*it); + + if (!_current_chains_set.empty()) + _current_set = &_current_chains_set; +} + +void Operators::bidirectionalChain(ViewEdgeIterator& it, UnaryPredicate1D& pred) +{ + if (_current_view_edges_set.empty()) + return; + + unsigned id = 0; + Functions1D::IncrementChainingTimeStampF1D ts; + Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp() + 1); + + ViewEdge *edge; + Chain *new_chain; + + for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); + it_edge != _current_view_edges_set.end(); + ++it_edge) + { + if (pred(**it_edge) || pred_ts(**it_edge)) + continue; + + edge = dynamic_cast(*it_edge); + it.setBegin(edge); + it.setCurrentEdge(edge); + + Chain *new_chain = new Chain(id); + ++id; +#if 0 //FIXME + ViewEdgeIterator it_back(it); + --it_back; +#endif + do { + new_chain->push_viewedge_back(*it, it.getOrientation()); + ts(**it); + ++it; + } while (!it.isEnd() && !pred(**it) && !pred_ts(**it)); + it.setBegin(edge); + it.setCurrentEdge(edge); + --it; + while (!it.isEnd() && !pred(**it) && !pred_ts(**it)) { + new_chain->push_viewedge_front(*it, it.getOrientation()); + ts(**it); + --it; + } + + _current_chains_set.push_back(new_chain); } - new_chains_set.clear(); - _current_set = &_current_chains_set; - } - return 0; -error: - for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { - delete (*it); - } - new_chains_set.clear(); - return -1; + if (!_current_chains_set.empty()) + _current_set = &_current_chains_set; } +#endif + +int Operators::bidirectionalChain(ChainingIterator& it, UnaryPredicate1D& pred) +{ + if (_current_view_edges_set.empty()) + return 0; + + unsigned id = 0; + Functions1D::IncrementChainingTimeStampF1D ts; + Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp() + 1); + ViewEdge *edge; + I1DContainer new_chains_set; + + for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); + it_edge != _current_view_edges_set.end(); + ++it_edge) + { + if (pred(**it_edge) < 0) + goto error; + if (pred.result) + continue; + if (pred_ts(**it_edge) < 0) + goto error; + if (pred_ts.result) + continue; + + edge = dynamic_cast(*it_edge); + // re-init iterator + it.setBegin(edge); + it.setCurrentEdge(edge); + it.setOrientation(true); + if (it.init() < 0) + goto error; + + Chain *new_chain = new Chain(id); + ++id; +#if 0 // FIXME + ViewEdgeIterator it_back(it); + --it_back; +#endif + while (TRUE) { + new_chain->push_viewedge_back(*it, it.getOrientation()); + ts(**it); + if (it.increment() < 0) { + delete new_chain; + goto error; + } + if (it.isEnd()) + break; + if (pred(**it) < 0) { + delete new_chain; + goto error; + } + if (pred.result) + break; + } + it.setBegin(edge); + it.setCurrentEdge(edge); + it.setOrientation(true); + if (it.decrement() < 0) { + delete new_chain; + goto error; + } + while (!it.isEnd()) { + if (pred(**it) < 0) { + delete new_chain; + goto error; + } + if (pred.result) + break; + new_chain->push_viewedge_front(*it, it.getOrientation()); + ts(**it); + if (it.decrement() < 0) { + delete new_chain; + goto error; + } + } + new_chains_set.push_back(new_chain); + } -int Operators::bidirectionalChain(ChainingIterator& it) { - if (_current_view_edges_set.empty()) - return 0; - - unsigned id = 0; - Functions1D::IncrementChainingTimeStampF1D ts; - Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp()+1); - ViewEdge* edge; - I1DContainer new_chains_set; - - for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); - it_edge != _current_view_edges_set.end(); - ++it_edge) { - if (pred_ts(**it_edge) < 0) - goto error; - if (pred_ts.result) - continue; - - edge = dynamic_cast(*it_edge); - // re-init iterator - it.setBegin(edge); - it.setCurrentEdge(edge); - it.setOrientation(true); - if (it.init() < 0) - goto error; - - Chain* new_chain = new Chain(id);++id; - //ViewEdgeIterator it_back(it);--it_back;//FIXME - do { - new_chain->push_viewedge_back(*it, it.getOrientation()); - ts(**it); - if (it.increment() < 0) { // FIXME - delete new_chain; - goto error; - } - } while (!it.isEnd()); - it.setBegin(edge); - it.setCurrentEdge(edge); - it.setOrientation(true); - if (it.decrement() < 0) { // FIXME - delete new_chain; - goto error; + if (!new_chains_set.empty()) { + for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { + _current_chains_set.push_back(*it); + } + new_chains_set.clear(); + _current_set = &_current_chains_set; } - while (!it.isEnd()) { - new_chain->push_viewedge_front(*it, it.getOrientation()); - ts(**it); - if (it.decrement() < 0) { // FIXME - delete new_chain; - goto error; - } - } - new_chains_set.push_back(new_chain); - } - - if (!new_chains_set.empty()) { + return 0; + +error: for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { - _current_chains_set.push_back(*it); + delete (*it); } new_chains_set.clear(); - _current_set = &_current_chains_set; - } - return 0; + return -1; +} + +int Operators::bidirectionalChain(ChainingIterator& it) +{ + if (_current_view_edges_set.empty()) + return 0; + + unsigned id = 0; + Functions1D::IncrementChainingTimeStampF1D ts; + Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp() + 1); + ViewEdge *edge; + I1DContainer new_chains_set; + + for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); + it_edge != _current_view_edges_set.end(); + ++it_edge) + { + if (pred_ts(**it_edge) < 0) + goto error; + if (pred_ts.result) + continue; + + edge = dynamic_cast(*it_edge); + // re-init iterator + it.setBegin(edge); + it.setCurrentEdge(edge); + it.setOrientation(true); + if (it.init() < 0) + goto error; + + Chain *new_chain = new Chain(id); + ++id; +#if 0 // FIXME + ViewEdgeIterator it_back(it); + --it_back; +#endif + do { + new_chain->push_viewedge_back(*it, it.getOrientation()); + ts(**it); + if (it.increment() < 0) { // FIXME + delete new_chain; + goto error; + } + } while (!it.isEnd()); + it.setBegin(edge); + it.setCurrentEdge(edge); + it.setOrientation(true); + if (it.decrement() < 0) { // FIXME + delete new_chain; + goto error; + } + while (!it.isEnd()) { + new_chain->push_viewedge_front(*it, it.getOrientation()); + ts(**it); + if (it.decrement() < 0) { // FIXME + delete new_chain; + goto error; + } + } + new_chains_set.push_back(new_chain); + } + + if (!new_chains_set.empty()) { + for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { + _current_chains_set.push_back(*it); + } + new_chains_set.clear(); + _current_set = &_current_chains_set; + } + return 0; error: - for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { - delete (*it); - } - new_chains_set.clear(); - return -1; + for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { + delete (*it); + } + new_chains_set.clear(); + return -1; } -int Operators::sequentialSplit(UnaryPredicate0D& pred, - float sampling) +int Operators::sequentialSplit(UnaryPredicate0D& pred, float sampling) { - if (_current_chains_set.empty()) { - cerr << "Warning: current set empty" << endl; - return 0; - } - CurvePoint *point; - Chain * new_curve; - I1DContainer splitted_chains; - Interface0DIterator first; - Interface0DIterator end; - Interface0DIterator last; - Interface0DIterator it; - I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end(); - for (; - cit != citend; - ++cit) { - - Id currentId = (*cit)->getId(); - new_curve = new Chain(currentId); - first = (*cit)->pointsBegin(sampling); - end = (*cit)->pointsEnd(sampling); - last = end;--last; - it = first; - - point = dynamic_cast(&(*it)); - new_curve->push_vertex_back(point);++it; - for(; it!= end; ++it) - { - point = dynamic_cast(&(*it)); - new_curve->push_vertex_back(point); - if(pred(it) < 0) - { + if (_current_chains_set.empty()) { + cerr << "Warning: current set empty" << endl; + return 0; + } + CurvePoint *point; + Chain *new_curve; + I1DContainer splitted_chains; + Interface0DIterator first; + Interface0DIterator end; + Interface0DIterator last; + Interface0DIterator it; + I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end(); + for (; cit != citend; ++cit) { + Id currentId = (*cit)->getId(); + new_curve = new Chain(currentId); + first = (*cit)->pointsBegin(sampling); + end = (*cit)->pointsEnd(sampling); + last = end; + --last; + it = first; + + point = dynamic_cast(&(*it)); + new_curve->push_vertex_back(point); + ++it; + for (; it!= end; ++it) { + point = dynamic_cast(&(*it)); + new_curve->push_vertex_back(point); + if (pred(it) < 0) { + delete new_curve; + goto error; + } + if (pred.result && (it != last)) { + splitted_chains.push_back(new_curve); + currentId.setSecond(currentId.getSecond() + 1); + new_curve = new Chain(currentId); + new_curve->push_vertex_back(point); + } + } + if (new_curve->nSegments() == 0) { delete new_curve; - goto error; - } - if(pred.result && (it!=last)) - { - splitted_chains.push_back(new_curve); - currentId.setSecond(currentId.getSecond()+1); - new_curve = new Chain(currentId); - new_curve->push_vertex_back(point); - } - } - if(new_curve->nSegments() == 0){ - delete new_curve; - return 0; - } - - splitted_chains.push_back(new_curve); - } - - // Update the current set of chains: - cit = _current_chains_set.begin(); - for(; - cit != citend; - ++cit){ - delete (*cit); - } - _current_chains_set.clear(); + return 0; + } + + splitted_chains.push_back(new_curve); + } + + // Update the current set of chains: + cit = _current_chains_set.begin(); + for (; cit != citend; ++cit) { + delete (*cit); + } + _current_chains_set.clear(); #if 0 - _current_chains_set = splitted_chains; + _current_chains_set = splitted_chains; #else - for (cit = splitted_chains.begin(), citend = splitted_chains.end(); - cit != citend; - ++cit) { - if ((*cit)->getLength2D() < M_EPSILON) { - delete (*cit); - continue; + for (cit = splitted_chains.begin(), citend = splitted_chains.end(); cit != citend; ++cit) { + if ((*cit)->getLength2D() < M_EPSILON) { + delete (*cit); + continue; + } + _current_chains_set.push_back(*cit); } - _current_chains_set.push_back(*cit); - } #endif - splitted_chains.clear(); + splitted_chains.clear(); - if (!_current_chains_set.empty()) - _current_set = &_current_chains_set; - return 0; + if (!_current_chains_set.empty()) + _current_set = &_current_chains_set; + return 0; error: - cit = splitted_chains.begin(); - citend = splitted_chains.end(); - for(; - cit != citend; - ++cit){ - delete (*cit); - } - splitted_chains.clear(); - return -1; + cit = splitted_chains.begin(); + citend = splitted_chains.end(); + for (; cit != citend; ++cit) { + delete (*cit); + } + splitted_chains.clear(); + return -1; } -int Operators::sequentialSplit(UnaryPredicate0D& startingPred, UnaryPredicate0D& stoppingPred, - float sampling) +int Operators::sequentialSplit(UnaryPredicate0D& startingPred, UnaryPredicate0D& stoppingPred, float sampling) { - if (_current_chains_set.empty()) { - cerr << "Warning: current set empty" << endl; - return 0; - } - CurvePoint *point; - Chain * new_curve; - I1DContainer splitted_chains; - Interface0DIterator first; - Interface0DIterator end; - Interface0DIterator last; - Interface0DIterator itStart; - Interface0DIterator itStop; - I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end(); - for (; - cit != citend; - ++cit) { - Id currentId = (*cit)->getId(); - first = (*cit)->pointsBegin(sampling); - end = (*cit)->pointsEnd(sampling); - last = end;--last; - itStart = first; - do{ - itStop = itStart;++itStop; - - new_curve = new Chain(currentId); - currentId.setSecond(currentId.getSecond()+1); - - point = dynamic_cast(&(*itStart)); - new_curve->push_vertex_back(point); - do{ - point = dynamic_cast(&(*itStop)); - new_curve->push_vertex_back(point); - ++itStop; - if(itStop == end) - break; - if(stoppingPred(itStop) < 0){ - delete new_curve; - goto error; - } - }while(!stoppingPred.result); - if(itStop!=end){ - point = dynamic_cast(&(*itStop)); - new_curve->push_vertex_back(point); - } - if(new_curve->nSegments() == 0){ - delete new_curve; - }else{ - splitted_chains.push_back(new_curve); - } - // find next start - do{ - ++itStart; - if(itStart == end) - break; - if(startingPred(itStart) < 0) - goto error; - }while(!startingPred.result); - }while((itStart!=end) && (itStart!=last)); - } - - // Update the current set of chains: - cit = _current_chains_set.begin(); - for(; - cit != citend; - ++cit){ - delete (*cit); - } - _current_chains_set.clear(); + if (_current_chains_set.empty()) { + cerr << "Warning: current set empty" << endl; + return 0; + } + CurvePoint *point; + Chain *new_curve; + I1DContainer splitted_chains; + Interface0DIterator first; + Interface0DIterator end; + Interface0DIterator last; + Interface0DIterator itStart; + Interface0DIterator itStop; + I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end(); + for (; cit != citend; ++cit) { + Id currentId = (*cit)->getId(); + first = (*cit)->pointsBegin(sampling); + end = (*cit)->pointsEnd(sampling); + last = end; + --last; + itStart = first; + do { + itStop = itStart; + ++itStop; + + new_curve = new Chain(currentId); + currentId.setSecond(currentId.getSecond() + 1); + + point = dynamic_cast(&(*itStart)); + new_curve->push_vertex_back(point); + do { + point = dynamic_cast(&(*itStop)); + new_curve->push_vertex_back(point); + ++itStop; + if (itStop == end) + break; + if (stoppingPred(itStop) < 0) { + delete new_curve; + goto error; + } + } while (!stoppingPred.result); + if (itStop != end) { + point = dynamic_cast(&(*itStop)); + new_curve->push_vertex_back(point); + } + if (new_curve->nSegments() == 0) { + delete new_curve; + } + else { + splitted_chains.push_back(new_curve); + } + // find next start + do{ + ++itStart; + if (itStart == end) + break; + if (startingPred(itStart) < 0) + goto error; + } while (!startingPred.result); + } while ((itStart!=end) && (itStart!=last)); + } + + // Update the current set of chains: + cit = _current_chains_set.begin(); + for (; cit != citend; ++cit) { + delete (*cit); + } + _current_chains_set.clear(); #if 0 - _current_chains_set = splitted_chains; + _current_chains_set = splitted_chains; #else - for (cit = splitted_chains.begin(), citend = splitted_chains.end(); - cit != citend; - ++cit) { - if ((*cit)->getLength2D() < M_EPSILON) { - delete (*cit); - continue; + for (cit = splitted_chains.begin(), citend = splitted_chains.end(); cit != citend; ++cit) { + if ((*cit)->getLength2D() < M_EPSILON) { + delete (*cit); + continue; + } + _current_chains_set.push_back(*cit); } - _current_chains_set.push_back(*cit); - } #endif - splitted_chains.clear(); - - if (!_current_chains_set.empty()) - _current_set = &_current_chains_set; - return 0; + splitted_chains.clear(); + + if (!_current_chains_set.empty()) + _current_set = &_current_chains_set; + return 0; error: - cit = splitted_chains.begin(); - citend = splitted_chains.end(); - for(; - cit != citend; - ++cit){ - delete (*cit); - } - splitted_chains.clear(); - return -1; + cit = splitted_chains.begin(); + citend = splitted_chains.end(); + for (; cit != citend; ++cit) { + delete (*cit); + } + splitted_chains.clear(); + return -1; } #include "CurveIterators.h" @@ -646,591 +670,608 @@ error: static int __recursiveSplit(Chain *_curve, UnaryFunction0D& func, UnaryPredicate1D& pred, float sampling, Operators::I1DContainer& newChains, Operators::I1DContainer& splitted_chains) { - if(((_curve->nSegments() == 1) && (sampling == 0)) || (_curve->getLength2D() <= sampling)){ - newChains.push_back(_curve); - return 0; - } - - CurveInternal::CurvePointIterator first = _curve->curvePointsBegin(sampling); - CurveInternal::CurvePointIterator second = first; ++second; - CurveInternal::CurvePointIterator end = _curve->curvePointsEnd(sampling); - CurveInternal::CurvePointIterator it = second; - CurveInternal::CurvePointIterator split = second; - Interface0DIterator it0d = it.castToInterface0DIterator(); - real _min = FLT_MAX;++it;//func(it0d);++it; - CurveInternal::CurvePointIterator next = it;++next; - - bool bsplit = false; - for(; ((it != end) && (next != end)); ++it,++next){ - it0d = it.castToInterface0DIterator(); - if (func(it0d) < 0) - return -1; - if(func.result < _min){ - _min = func.result; - split = it; - bsplit = true; - } - } - - if(!bsplit){ // we didn't find any minimum - newChains.push_back(_curve); - return 0; - } - - // retrieves the current splitting id - Id * newId = _curve->getSplittingId(); - if(newId == 0){ - newId = new Id(_curve->getId()); - _curve->setSplittingId(newId); - } - - Chain *new_curve_a = new Chain(*newId); - newId->setSecond(newId->getSecond()+1); - new_curve_a->setSplittingId(newId); - Chain *new_curve_b = new Chain(*newId); - newId->setSecond(newId->getSecond()+1); - new_curve_b->setSplittingId(newId); - - CurveInternal::CurvePointIterator vit = _curve->curveVerticesBegin(), vitend=_curve->curveVerticesEnd(); - CurveInternal::CurvePointIterator vnext = vit; ++vnext; - - - for(; (vit!=vitend)&&(vnext!=vitend)&&(vnext._CurvilinearLengthpush_vertex_back(&(*vit)); - } - if((vit==vitend) || (vnext == vitend)){ - cout << "The split takes place in bad location" << endl; - newChains.push_back(_curve); - delete new_curve_a; - delete new_curve_b; - return 0; - } - - // build the two resulting chains - new_curve_a->push_vertex_back(&(*vit)); - new_curve_a->push_vertex_back(&(*split)); - new_curve_b->push_vertex_back(&(*split)); - - for(vit=vnext;vit!=vitend;++vit) - new_curve_b->push_vertex_back(&(*vit)); - - // let's check whether one or two of the two new curves - // satisfy the stopping condition or not. - // (if one of them satisfies it, we don't split) - if (pred(*new_curve_a) < 0 || (!pred.result && pred(*new_curve_b) < 0)) { - delete new_curve_a; - delete new_curve_b; - return -1; - } - if(pred.result){ - // we don't actually create these two chains - newChains.push_back(_curve); - delete new_curve_a; - delete new_curve_b; - return 0; - } - // here we know we'll split _curve: - splitted_chains.push_back(_curve); - - __recursiveSplit(new_curve_a, func, pred, sampling, newChains, splitted_chains); - __recursiveSplit(new_curve_b, func, pred, sampling, newChains, splitted_chains); - return 0; + if (((_curve->nSegments() == 1) && (sampling == 0)) || (_curve->getLength2D() <= sampling)) { + newChains.push_back(_curve); + return 0; + } + + CurveInternal::CurvePointIterator first = _curve->curvePointsBegin(sampling); + CurveInternal::CurvePointIterator second = first; + ++second; + CurveInternal::CurvePointIterator end = _curve->curvePointsEnd(sampling); + CurveInternal::CurvePointIterator it = second; + CurveInternal::CurvePointIterator split = second; + Interface0DIterator it0d = it.castToInterface0DIterator(); + real _min = FLT_MAX; // func(it0d); + ++it; + CurveInternal::CurvePointIterator next = it; + ++next; + + bool bsplit = false; + for (; ((it != end) && (next != end)); ++it, ++next) { + it0d = it.castToInterface0DIterator(); + if (func(it0d) < 0) + return -1; + if (func.result < _min) { + _min = func.result; + split = it; + bsplit = true; + } + } + + if (!bsplit) { // we didn't find any minimum + newChains.push_back(_curve); + return 0; + } + + // retrieves the current splitting id + Id *newId = _curve->getSplittingId(); + if (newId == 0) { + newId = new Id(_curve->getId()); + _curve->setSplittingId(newId); + } + + Chain *new_curve_a = new Chain(*newId); + newId->setSecond(newId->getSecond() + 1); + new_curve_a->setSplittingId(newId); + Chain *new_curve_b = new Chain(*newId); + newId->setSecond(newId->getSecond() + 1); + new_curve_b->setSplittingId(newId); + + CurveInternal::CurvePointIterator vit = _curve->curveVerticesBegin(), vitend = _curve->curveVerticesEnd(); + CurveInternal::CurvePointIterator vnext = vit; + ++vnext; + + for (; (vit != vitend) && (vnext != vitend) && (vnext._CurvilinearLength < split._CurvilinearLength); + ++vit, ++vnext) + { + new_curve_a->push_vertex_back(&(*vit)); + } + if ((vit == vitend) || (vnext == vitend)) { + cout << "The split takes place in bad location" << endl; + newChains.push_back(_curve); + delete new_curve_a; + delete new_curve_b; + return 0; + } + + // build the two resulting chains + new_curve_a->push_vertex_back(&(*vit)); + new_curve_a->push_vertex_back(&(*split)); + new_curve_b->push_vertex_back(&(*split)); + + for (vit = vnext; vit != vitend; ++vit) + new_curve_b->push_vertex_back(&(*vit)); + + // let's check whether one or two of the two new curves satisfy the stopping condition or not. + // (if one of them satisfies it, we don't split) + if (pred(*new_curve_a) < 0 || (!pred.result && pred(*new_curve_b) < 0)) { + delete new_curve_a; + delete new_curve_b; + return -1; + } + if (pred.result) { + // we don't actually create these two chains + newChains.push_back(_curve); + delete new_curve_a; + delete new_curve_b; + return 0; + } + // here we know we'll split _curve: + splitted_chains.push_back(_curve); + + __recursiveSplit(new_curve_a, func, pred, sampling, newChains, splitted_chains); + __recursiveSplit(new_curve_b, func, pred, sampling, newChains, splitted_chains); + return 0; } int Operators::recursiveSplit(UnaryFunction0D& func, UnaryPredicate1D& pred, float sampling) { - if (_current_chains_set.empty()) { - cerr << "Warning: current set empty" << endl; - return 0; - } - - Chain *currentChain = 0; - I1DContainer splitted_chains; - I1DContainer newChains; - I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end(); - for (; - cit != citend; - ++cit) { - currentChain = dynamic_cast(*cit); - if(!currentChain) - continue; - // let's check the first one: - if (pred(*currentChain) < 0) - return -1; - if(!pred.result){ - __recursiveSplit(currentChain, func, pred, sampling, newChains, splitted_chains); - }else{ - newChains.push_back(currentChain); - } - } - // Update the current set of chains: - if(!splitted_chains.empty()){ - for(cit = splitted_chains.begin(), citend = splitted_chains.end(); - cit != citend; - ++cit){ - delete (*cit); - } - splitted_chains.clear(); - } - - _current_chains_set.clear(); + if (_current_chains_set.empty()) { + cerr << "Warning: current set empty" << endl; + return 0; + } + + Chain *currentChain = 0; + I1DContainer splitted_chains; + I1DContainer newChains; + I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end(); + for (; cit != citend; ++cit) { + currentChain = dynamic_cast(*cit); + if (!currentChain) + continue; + // let's check the first one: + if (pred(*currentChain) < 0) + return -1; + if (!pred.result) { + __recursiveSplit(currentChain, func, pred, sampling, newChains, splitted_chains); + } + else { + newChains.push_back(currentChain); + } + } + // Update the current set of chains: + if (!splitted_chains.empty()) { + for (cit = splitted_chains.begin(), citend = splitted_chains.end(); cit != citend; ++cit) { + delete (*cit); + } + splitted_chains.clear(); + } + + _current_chains_set.clear(); #if 0 - _current_chains_set = newChains; + _current_chains_set = newChains; #else - for (cit = newChains.begin(), citend = newChains.end(); - cit != citend; - ++cit) { - if ((*cit)->getLength2D() < M_EPSILON) { - delete (*cit); - continue; + for (cit = newChains.begin(), citend = newChains.end(); cit != citend; ++cit) { + if ((*cit)->getLength2D() < M_EPSILON) { + delete (*cit); + continue; + } + _current_chains_set.push_back(*cit); } - _current_chains_set.push_back(*cit); - } #endif - newChains.clear(); + newChains.clear(); - if (!_current_chains_set.empty()) - _current_set = &_current_chains_set; - return 0; + if (!_current_chains_set.empty()) + _current_set = &_current_chains_set; + return 0; } // recursive split with pred 0D -static int __recursiveSplit(Chain *_curve, UnaryFunction0D& func, UnaryPredicate0D& pred0d, UnaryPredicate1D& pred, float sampling, +static int __recursiveSplit(Chain *_curve, UnaryFunction0D& func, UnaryPredicate0D& pred0d, + UnaryPredicate1D& pred, float sampling, Operators::I1DContainer& newChains, Operators::I1DContainer& splitted_chains) { - if(((_curve->nSegments() == 1) && (sampling == 0)) || (_curve->getLength2D() <= sampling)){ - newChains.push_back(_curve); - return 0; - } - - CurveInternal::CurvePointIterator first = _curve->curvePointsBegin(sampling); - CurveInternal::CurvePointIterator second = first; ++second; - CurveInternal::CurvePointIterator end = _curve->curvePointsEnd(sampling); - CurveInternal::CurvePointIterator it = second; - CurveInternal::CurvePointIterator split = second; - Interface0DIterator it0d = it.castToInterface0DIterator(); - //real _min = func(it0d);++it; - real _min = FLT_MAX;++it; - real mean = 0.f; - //soc unused - real variance = 0.f; - unsigned count = 0; - CurveInternal::CurvePointIterator next = it;++next; - - bool bsplit = false; - for(; ((it != end) && (next != end)); ++it,++next){ - ++count; - it0d = it.castToInterface0DIterator(); - if(pred0d(it0d) < 0) - return -1; - if(!pred0d.result) - continue; - if(func(it0d) < 0) - return -1; - mean += func.result; - if(func.result < _min){ - _min = func.result; - split = it; - bsplit = true; - } - } - mean /= (float)count; - - //if((!bsplit) || (mean-_min>mean)){ // we didn't find any minimum - if(!bsplit){ // we didn't find any minimum - newChains.push_back(_curve); - return 0; - } - - // retrieves the current splitting id - Id * newId = _curve->getSplittingId(); - if(newId == 0){ - newId = new Id(_curve->getId()); - _curve->setSplittingId(newId); - } - - Chain *new_curve_a = new Chain(*newId); - newId->setSecond(newId->getSecond()+1); - new_curve_a->setSplittingId(newId); - Chain *new_curve_b = new Chain(*newId); - newId->setSecond(newId->getSecond()+1); - new_curve_b->setSplittingId(newId); - - CurveInternal::CurvePointIterator vit = _curve->curveVerticesBegin(), vitend=_curve->curveVerticesEnd(); - CurveInternal::CurvePointIterator vnext = vit; ++vnext; - - - for(; (vit!=vitend)&&(vnext!=vitend)&&(vnext._CurvilinearLengthpush_vertex_back(&(*vit)); - } - if((vit==vitend) || (vnext == vitend)){ - cout << "The split takes place in bad location" << endl; - newChains.push_back(_curve); - delete new_curve_a; - delete new_curve_b; - return 0; - } - - // build the two resulting chains - new_curve_a->push_vertex_back(&(*vit)); - new_curve_a->push_vertex_back(&(*split)); - new_curve_b->push_vertex_back(&(*split)); - - for(vit=vnext;vit!=vitend;++vit) - new_curve_b->push_vertex_back(&(*vit)); - - // let's check whether one or two of the two new curves - // satisfy the stopping condition or not. - // (if one of them satisfies it, we don't split) - if (pred(*new_curve_a) < 0 || (!pred.result && pred(*new_curve_b) < 0)) { - delete new_curve_a; - delete new_curve_b; - return -1; - } - if(pred.result){ - // we don't actually create these two chains - newChains.push_back(_curve); - delete new_curve_a; - delete new_curve_b; - return 0; - } - // here we know we'll split _curve: - splitted_chains.push_back(_curve); - - __recursiveSplit(new_curve_a, func, pred0d, pred, sampling, newChains, splitted_chains); - __recursiveSplit(new_curve_b, func, pred0d, pred, sampling, newChains, splitted_chains); - return 0; + if (((_curve->nSegments() == 1) && (sampling == 0)) || (_curve->getLength2D() <= sampling)) { + newChains.push_back(_curve); + return 0; + } + + CurveInternal::CurvePointIterator first = _curve->curvePointsBegin(sampling); + CurveInternal::CurvePointIterator second = first; + ++second; + CurveInternal::CurvePointIterator end = _curve->curvePointsEnd(sampling); + CurveInternal::CurvePointIterator it = second; + CurveInternal::CurvePointIterator split = second; + Interface0DIterator it0d = it.castToInterface0DIterator(); +#if 0 + real _min = func(it0d); + ++it; +#endif + real _min = FLT_MAX; + ++it; + real mean = 0.f; + //soc unused - real variance = 0.0f; + unsigned count = 0; + CurveInternal::CurvePointIterator next = it; + ++next; + + bool bsplit = false; + for (; ((it != end) && (next != end)); ++it, ++next) { + ++count; + it0d = it.castToInterface0DIterator(); + if (pred0d(it0d) < 0) + return -1; + if (!pred0d.result) + continue; + if (func(it0d) < 0) + return -1; + mean += func.result; + if (func.result < _min) { + _min = func.result; + split = it; + bsplit = true; + } + } + mean /= (float)count; + + //if ((!bsplit) || (mean - _min > mean)) { // we didn't find any minimum + if (!bsplit) { // we didn't find any minimum + newChains.push_back(_curve); + return 0; + } + + // retrieves the current splitting id + Id *newId = _curve->getSplittingId(); + if (newId == NULL) { + newId = new Id(_curve->getId()); + _curve->setSplittingId(newId); + } + + Chain *new_curve_a = new Chain(*newId); + newId->setSecond(newId->getSecond() + 1); + new_curve_a->setSplittingId(newId); + Chain *new_curve_b = new Chain(*newId); + newId->setSecond(newId->getSecond() + 1); + new_curve_b->setSplittingId(newId); + + CurveInternal::CurvePointIterator vit = _curve->curveVerticesBegin(), vitend = _curve->curveVerticesEnd(); + CurveInternal::CurvePointIterator vnext = vit; + ++vnext; + + for (; + (vit != vitend) && (vnext != vitend) && (vnext._CurvilinearLength < split._CurvilinearLength); + ++vit, ++vnext) + { + new_curve_a->push_vertex_back(&(*vit)); + } + if ((vit == vitend) || (vnext == vitend)) { + cout << "The split takes place in bad location" << endl; + newChains.push_back(_curve); + delete new_curve_a; + delete new_curve_b; + return 0; + } + + // build the two resulting chains + new_curve_a->push_vertex_back(&(*vit)); + new_curve_a->push_vertex_back(&(*split)); + new_curve_b->push_vertex_back(&(*split)); + + for (vit = vnext; vit != vitend; ++vit) + new_curve_b->push_vertex_back(&(*vit)); + + // let's check whether one or two of the two new curves satisfy the stopping condition or not. + // (if one of them satisfies it, we don't split) + if (pred(*new_curve_a) < 0 || (!pred.result && pred(*new_curve_b) < 0)) { + delete new_curve_a; + delete new_curve_b; + return -1; + } + if (pred.result) { + // we don't actually create these two chains + newChains.push_back(_curve); + delete new_curve_a; + delete new_curve_b; + return 0; + } + // here we know we'll split _curve: + splitted_chains.push_back(_curve); + + __recursiveSplit(new_curve_a, func, pred0d, pred, sampling, newChains, splitted_chains); + __recursiveSplit(new_curve_b, func, pred0d, pred, sampling, newChains, splitted_chains); + return 0; } -int Operators::recursiveSplit(UnaryFunction0D& func, UnaryPredicate0D& pred0d, UnaryPredicate1D& pred, float sampling) +int Operators::recursiveSplit(UnaryFunction0D& func, UnaryPredicate0D& pred0d, UnaryPredicate1D& pred, + float sampling) { - if (_current_chains_set.empty()) { - cerr << "Warning: current set empty" << endl; - return 0; - } - - Chain *currentChain = 0; - I1DContainer splitted_chains; - I1DContainer newChains; - I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end(); - for (; - cit != citend; - ++cit) { - currentChain = dynamic_cast(*cit); - if(!currentChain) - continue; - // let's check the first one: - if(pred(*currentChain) < 0) - return -1; - if(!pred.result){ - __recursiveSplit(currentChain, func, pred0d, pred, sampling, newChains, splitted_chains); - }else{ - newChains.push_back(currentChain); - } - } - // Update the current set of chains: - if(!splitted_chains.empty()){ - for(cit = splitted_chains.begin(), citend = splitted_chains.end(); - cit != citend; - ++cit){ - delete (*cit); - } - splitted_chains.clear(); - } - - _current_chains_set.clear(); + if (_current_chains_set.empty()) { + cerr << "Warning: current set empty" << endl; + return 0; + } + + Chain *currentChain = 0; + I1DContainer splitted_chains; + I1DContainer newChains; + I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end(); + for (; cit != citend; ++cit) { + currentChain = dynamic_cast(*cit); + if (!currentChain) + continue; + // let's check the first one: + if (pred(*currentChain) < 0) + return -1; + if (!pred.result) { + __recursiveSplit(currentChain, func, pred0d, pred, sampling, newChains, splitted_chains); + } + else { + newChains.push_back(currentChain); + } + } + // Update the current set of chains: + if (!splitted_chains.empty()) { + for (cit = splitted_chains.begin(), citend = splitted_chains.end(); cit != citend; ++cit) { + delete (*cit); + } + splitted_chains.clear(); + } + + _current_chains_set.clear(); #if 0 - _current_chains_set = newChains; + _current_chains_set = newChains; #else - for (cit = newChains.begin(), citend = newChains.end(); - cit != citend; - ++cit) { - if ((*cit)->getLength2D() < M_EPSILON) { - delete (*cit); - continue; + for (cit = newChains.begin(), citend = newChains.end(); cit != citend; ++cit) { + if ((*cit)->getLength2D() < M_EPSILON) { + delete (*cit); + continue; + } + _current_chains_set.push_back(*cit); } - _current_chains_set.push_back(*cit); - } #endif - newChains.clear(); + newChains.clear(); - if (!_current_chains_set.empty()) - _current_set = &_current_chains_set; - return 0; + if (!_current_chains_set.empty()) + _current_set = &_current_chains_set; + return 0; } + // Internal class class PredicateWrapper { public: + inline PredicateWrapper(BinaryPredicate1D& pred) + { + _pred = &pred; + } - inline PredicateWrapper(BinaryPredicate1D& pred) { - _pred = &pred; - } - - inline bool operator()(Interface1D* i1, Interface1D* i2) { - if ((*_pred)(*i1, *i2) < 0) - throw std::runtime_error("comparison failed"); - return _pred->result; - } + inline bool operator()(Interface1D *i1, Interface1D *i2) + { + if ((*_pred)(*i1, *i2) < 0) + throw std::runtime_error("comparison failed"); + return _pred->result; + } private: - - BinaryPredicate1D* _pred; + BinaryPredicate1D *_pred; }; -int Operators::sort(BinaryPredicate1D& pred) { - if (!_current_set) - return 0; - PredicateWrapper wrapper(pred); - try { - std::sort(_current_set->begin(), _current_set->end(), wrapper); - } - catch (std::runtime_error &e) { - cerr << "Warning: Operator.sort(): " << e.what() << endl; - return -1; - } - return 0; +int Operators::sort(BinaryPredicate1D& pred) +{ + if (!_current_set) + return 0; + PredicateWrapper wrapper(pred); + try { + std::sort(_current_set->begin(), _current_set->end(), wrapper); + } + catch (std::runtime_error &e) { + cerr << "Warning: Operator.sort(): " << e.what() << endl; + return -1; + } + return 0; } -static Stroke* createStroke(Interface1D& inter) { - Stroke* stroke = new Stroke; - stroke->setId(inter.getId()); - - float currentCurvilignAbscissa = 0.f; - - Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd(); - Interface0DIterator itfirst = it; - - Vec2r current(it->getPoint2D()); - Vec2r previous = current; - SVertex* sv; - CurvePoint* cp; - StrokeVertex* stroke_vertex = NULL; - bool hasSingularity = false; - - do { - cp = dynamic_cast(&(*it)); - if (!cp) { - sv = dynamic_cast(&(*it)); - if (!sv) { - cerr << "Warning: unexpected Vertex type" << endl; - continue; - } - stroke_vertex = new StrokeVertex(sv); - } - else - stroke_vertex = new StrokeVertex(cp); - current = stroke_vertex->getPoint2D(); - Vec2r vec_tmp(current - previous); - real dist = vec_tmp.norm(); - if (dist < 1e-6) hasSingularity = true; - currentCurvilignAbscissa += dist; - stroke_vertex->setCurvilinearAbscissa(currentCurvilignAbscissa); - stroke->push_back(stroke_vertex); - previous = current; - ++it; - } while((it != itend) && (it != itfirst)); - - if (it == itfirst) { - // Add last vertex: - cp = dynamic_cast(&(*it)); - if (!cp) { - sv = dynamic_cast(&(*it)); - if (!sv) - cerr << "Warning: unexpected Vertex type" << endl; - else - stroke_vertex = new StrokeVertex(sv); - } - else - stroke_vertex = new StrokeVertex(cp); - current = stroke_vertex->getPoint2D(); - Vec2r vec_tmp(current - previous); - real dist = vec_tmp.norm(); - if (dist < 1e-6) hasSingularity = true; - currentCurvilignAbscissa += dist; - stroke_vertex->setCurvilinearAbscissa(currentCurvilignAbscissa); - stroke->push_back(stroke_vertex); - } - // Discard the stroke if the number of stroke vertices is less than two - if (stroke->strokeVerticesSize() < 2) { - delete stroke; - return NULL; - } - stroke->setLength(currentCurvilignAbscissa); - if (hasSingularity) { - // Try to address singular points such that the distance between two - // subsequent vertices are smaller than epsilon. - Interface0DIterator v = stroke->verticesBegin(); - Interface0DIterator vnext = v; ++vnext; - Vec2r next((*v).getPoint2D()); - while (!vnext.isEnd()) { - current = next; - next = (*vnext).getPoint2D(); - if ((next - current).norm() < 1e-6) { - Interface0DIterator vprevious = v; - if (!vprevious.isBegin()) - --vprevious; - - // collect a set of overlapping vertices (except the first one) - std::vector overlapping_vertices; - do { - overlapping_vertices.push_back(&(*vnext)); - current = next; - ++v; ++vnext; - if (vnext.isEnd()) - break; - next = (*vnext).getPoint2D(); - } while ((next - current).norm() < 1e-6); - - Vec2r target; - bool reverse; - if (!vnext.isEnd()) { - target = (*vnext).getPoint2D(); - reverse = false; - } else if (!vprevious.isBegin()) { - target = (*vprevious).getPoint2D(); - reverse = true; - } else { - // Discard the stroke because all stroke vertices are overlapping - delete stroke; - return NULL; - } - Vec2r dir(target - current); - real dist = dir.norm(); - real len = 1e-3; // default offset length - int nvert = overlapping_vertices.size(); - if (dist < len * nvert) { - len = dist / (nvert + 1); - } - dir.normalize(); - Vec2r offset(dir * len); - //cout << "#vert " << nvert << " len " << len << " reverse? " << reverse << endl; - - // add the offset to the overlapping vertices - StrokeVertex* sv; - std::vector::iterator it = overlapping_vertices.begin(), - itend = overlapping_vertices.end(); - if (!reverse) { - int n = 1; - for (; it != itend; ++it) { - sv = dynamic_cast(*it); - sv->setPoint(sv->getPoint() + offset * n); - ++n; - } - } else { - int n = nvert; - for (; it != itend; ++it) { - sv = dynamic_cast(*it); - sv->setPoint(sv->getPoint() + offset * n); - --n; - } - } - - if (vnext.isEnd()) - break; - } - ++v; ++vnext; - } - } - { - // Check if the stroke no longer contains singular points - Interface0DIterator v = stroke->verticesBegin(); - Interface0DIterator vnext = v; ++vnext; - Vec2r next((*v).getPoint2D()); - bool warning = false; - while (!vnext.isEnd()) { - current = next; - next = (*vnext).getPoint2D(); - if ((next - current).norm() < 1e-6) { - warning = true; - break; - } - ++v; ++vnext; - } - if (warning) { - printf("Warning: stroke contains singular points.\n"); - } - } - return stroke; +static Stroke *createStroke(Interface1D& inter) +{ + Stroke *stroke = new Stroke; + stroke->setId(inter.getId()); + + float currentCurvilignAbscissa = 0.0f; + + Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd(); + Interface0DIterator itfirst = it; + + Vec2r current(it->getPoint2D()); + Vec2r previous = current; + SVertex *sv; + CurvePoint *cp; + StrokeVertex *stroke_vertex = NULL; + bool hasSingularity = false; + + do { + cp = dynamic_cast(&(*it)); + if (!cp) { + sv = dynamic_cast(&(*it)); + if (!sv) { + cerr << "Warning: unexpected Vertex type" << endl; + continue; + } + stroke_vertex = new StrokeVertex(sv); + } + else { + stroke_vertex = new StrokeVertex(cp); + } + current = stroke_vertex->getPoint2D(); + Vec2r vec_tmp(current - previous); + real dist = vec_tmp.norm(); + if (dist < 1.0e-6) + hasSingularity = true; + currentCurvilignAbscissa += dist; + stroke_vertex->setCurvilinearAbscissa(currentCurvilignAbscissa); + stroke->push_back(stroke_vertex); + previous = current; + ++it; + } while ((it != itend) && (it != itfirst)); + + if (it == itfirst) { + // Add last vertex: + cp = dynamic_cast(&(*it)); + if (!cp) { + sv = dynamic_cast(&(*it)); + if (!sv) + cerr << "Warning: unexpected Vertex type" << endl; + else + stroke_vertex = new StrokeVertex(sv); + } + else { + stroke_vertex = new StrokeVertex(cp); + } + current = stroke_vertex->getPoint2D(); + Vec2r vec_tmp(current - previous); + real dist = vec_tmp.norm(); + if (dist < 1.0e-6) + hasSingularity = true; + currentCurvilignAbscissa += dist; + stroke_vertex->setCurvilinearAbscissa(currentCurvilignAbscissa); + stroke->push_back(stroke_vertex); + } + // Discard the stroke if the number of stroke vertices is less than two + if (stroke->strokeVerticesSize() < 2) { + delete stroke; + return NULL; + } + stroke->setLength(currentCurvilignAbscissa); + if (hasSingularity) { + // Try to address singular points such that the distance between two subsequent vertices + // are smaller than epsilon. + Interface0DIterator v = stroke->verticesBegin(); + Interface0DIterator vnext = v; + ++vnext; + Vec2r next((*v).getPoint2D()); + while (!vnext.isEnd()) { + current = next; + next = (*vnext).getPoint2D(); + if ((next - current).norm() < 1.0e-6) { + Interface0DIterator vprevious = v; + if (!vprevious.isBegin()) + --vprevious; + + // collect a set of overlapping vertices (except the first one) + std::vector overlapping_vertices; + do { + overlapping_vertices.push_back(&(*vnext)); + current = next; + ++v; + ++vnext; + if (vnext.isEnd()) + break; + next = (*vnext).getPoint2D(); + } while ((next - current).norm() < 1.0e-6); + + Vec2r target; + bool reverse; + if (!vnext.isEnd()) { + target = (*vnext).getPoint2D(); + reverse = false; + } + else if (!vprevious.isBegin()) { + target = (*vprevious).getPoint2D(); + reverse = true; + } + else { + // Discard the stroke because all stroke vertices are overlapping + delete stroke; + return NULL; + } + Vec2r dir(target - current); + real dist = dir.norm(); + real len = 1.0e-3; // default offset length + int nvert = overlapping_vertices.size(); + if (dist < len * nvert) { + len = dist / (nvert + 1); + } + dir.normalize(); + Vec2r offset(dir * len); + //cout << "#vert " << nvert << " len " << len << " reverse? " << reverse << endl; + + // add the offset to the overlapping vertices + StrokeVertex *sv; + std::vector::iterator it = overlapping_vertices.begin(), + itend = overlapping_vertices.end(); + if (!reverse) { + int n = 1; + for (; it != itend; ++it) { + sv = dynamic_cast(*it); + sv->setPoint(sv->getPoint() + offset * n); + ++n; + } + } + else { + int n = nvert; + for (; it != itend; ++it) { + sv = dynamic_cast(*it); + sv->setPoint(sv->getPoint() + offset * n); + --n; + } + } + + if (vnext.isEnd()) + break; + } + ++v; + ++vnext; + } + } + { + // Check if the stroke no longer contains singular points + Interface0DIterator v = stroke->verticesBegin(); + Interface0DIterator vnext = v; + ++vnext; + Vec2r next((*v).getPoint2D()); + bool warning = false; + while (!vnext.isEnd()) { + current = next; + next = (*vnext).getPoint2D(); + if ((next - current).norm() < 1.0e-6) { + warning = true; + break; + } + ++v; + ++vnext; + } + if (warning) { + printf("Warning: stroke contains singular points.\n"); + } + } + return stroke; } -inline int applyShading(Stroke& stroke, vector& shaders) { - for (vector::iterator it = shaders.begin(); it != shaders.end(); ++it) { - if ((*it)->shade(stroke) < 0) { - return -1; +inline int applyShading(Stroke& stroke, vector& shaders) +{ + for (vector::iterator it = shaders.begin(); it != shaders.end(); ++it) { + if ((*it)->shade(stroke) < 0) { + return -1; + } } - } - return 0; + return 0; } -int Operators::create(UnaryPredicate1D& pred, vector shaders) { - //Canvas* canvas = Canvas::getInstance(); - if (!_current_set) { - cerr << "Warning: current set empty" << endl; - return 0; - } - StrokesContainer new_strokes_set; - for (Operators::I1DContainer::iterator it = _current_set->begin(); - it != _current_set->end(); - ++it) { - if (pred(**it) < 0) - goto error; - if (!pred.result) - continue; - - Stroke* stroke = createStroke(**it); - if (stroke) { - if (applyShading(*stroke, shaders) < 0) { - delete stroke; - goto error; - } - //canvas->RenderStroke(stroke); - new_strokes_set.push_back(stroke); - } - } - - for (StrokesContainer::iterator it = new_strokes_set.begin(); it != new_strokes_set.end(); ++it) { - _current_strokes_set.push_back(*it); - } - new_strokes_set.clear(); - return 0; +int Operators::create(UnaryPredicate1D& pred, vector shaders) +{ + //Canvas* canvas = Canvas::getInstance(); + if (!_current_set) { + cerr << "Warning: current set empty" << endl; + return 0; + } + StrokesContainer new_strokes_set; + for (Operators::I1DContainer::iterator it = _current_set->begin(); it != _current_set->end(); ++it) { + if (pred(**it) < 0) + goto error; + if (!pred.result) + continue; + + Stroke *stroke = createStroke(**it); + if (stroke) { + if (applyShading(*stroke, shaders) < 0) { + delete stroke; + goto error; + } + //canvas->RenderStroke(stroke); + new_strokes_set.push_back(stroke); + } + } + + for (StrokesContainer::iterator it = new_strokes_set.begin(); it != new_strokes_set.end(); ++it) { + _current_strokes_set.push_back(*it); + } + new_strokes_set.clear(); + return 0; error: - for (StrokesContainer::iterator it = new_strokes_set.begin(); it != new_strokes_set.end(); ++it) { - delete (*it); - } - new_strokes_set.clear(); - return -1; + for (StrokesContainer::iterator it = new_strokes_set.begin(); it != new_strokes_set.end(); ++it) { + delete (*it); + } + new_strokes_set.clear(); + return -1; } - -void Operators::reset() { - ViewMap* vm = ViewMap::getInstance(); - if (!vm) { - cerr << "Error: no ViewMap computed yet" << endl; - return; - } - _current_view_edges_set.clear(); - for (I1DContainer::iterator it = _current_chains_set.begin(); - it != _current_chains_set.end(); - ++it) - delete *it; - _current_chains_set.clear(); +void Operators::reset() +{ + ViewMap *vm = ViewMap::getInstance(); + if (!vm) { + cerr << "Error: no ViewMap computed yet" << endl; + return; + } + _current_view_edges_set.clear(); + for (I1DContainer::iterator it = _current_chains_set.begin(); it != _current_chains_set.end(); ++it) + delete *it; + _current_chains_set.clear(); #if 0 - _current_view_edges_set.insert(_current_view_edges_set.begin(), - vm->ViewEdges().begin(), - vm->ViewEdges().end()); + _current_view_edges_set.insert(_current_view_edges_set.begin(), + vm->ViewEdges().begin(), + vm->ViewEdges().end()); #else - ViewMap::viewedges_container& vedges = vm->ViewEdges(); - ViewMap::viewedges_container::iterator ve=vedges.begin(), veend=vedges.end(); - for (; ve != veend; ++ve) { - if ((*ve)->getLength2D() < M_EPSILON) - continue; - _current_view_edges_set.push_back(*ve); - } + ViewMap::viewedges_container& vedges = vm->ViewEdges(); + ViewMap::viewedges_container::iterator ve = vedges.begin(), veend = vedges.end(); + for (; ve != veend; ++ve) { + if ((*ve)->getLength2D() < M_EPSILON) + continue; + _current_view_edges_set.push_back(*ve); + } #endif - _current_set = &_current_view_edges_set; - _current_strokes_set.clear(); + _current_set = &_current_view_edges_set; + _current_strokes_set.clear(); } diff --git a/source/blender/freestyle/intern/stroke/Operators.h b/source/blender/freestyle/intern/stroke/Operators.h index d705d5af5b2..aafbc2350d9 100644 --- a/source/blender/freestyle/intern/stroke/Operators.h +++ b/source/blender/freestyle/intern/stroke/Operators.h @@ -1,311 +1,274 @@ -// -// Filename : Operators.h -// Author(s) : Stephane Grabli, Emmanuel Turquin -// Purpose : Class gathering stroke creation algorithms -// Date of creation : 01/07/2003 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef OPERATORS_H -# define OPERATORS_H - -# include "../view_map/Interface1D.h" -# include -# include -# include "Predicates1D.h" -# include "Predicates0D.h" -# include "../view_map/ViewMap.h" -# include "Chain.h" -# include "ChainingIterators.h" -# include "../system/TimeStamp.h" -# include "StrokeShader.h" +/* + * ***** 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_OPERATORS_H__ +#define __FREESTYLE_OPERATORS_H__ + +/** \file blender/freestyle/intern/stroke/Operators.h + * \ingroup freestyle + * \brief Class gathering stroke creation algorithms + * \author Stephane Grabli + * \author Emmanuel Turquin + * \date 01/07/2003 + */ + +#include +#include + +#include "Chain.h" +#include "ChainingIterators.h" +#include "Predicates0D.h" +#include "Predicates1D.h" +#include "StrokeShader.h" + +#include "../system/TimeStamp.h" + +#include "../view_map/Interface1D.h" +#include "../view_map/ViewMap.h" /*! Class defining the operators used in a style module. - * There are 4 classes of operators: Selection, Chaining, - * Splitting and Creating. All these operators are user controlled - * in the scripting language through Functors, Predicates and Shaders - * that are taken as arguments. + * There are 4 classes of operators: Selection, Chaining, Splitting and Creating. All these operators are + * user controlled in the scripting language through Functors, Predicates and Shaders that are taken as arguments. */ class LIB_STROKE_EXPORT Operators { public: + typedef vector I1DContainer; + typedef vector StrokesContainer; - typedef vector I1DContainer; - typedef vector StrokesContainer; - - - // - // Operators - // - //////////////////////////////////////////////// - - /*! Selects the ViewEdges of the ViewMap verifying - * a specified condition. - * \param pred The predicate expressing this condition - */ - static int select(UnaryPredicate1D& pred); - - /*! Builds a set of chains from the current set of ViewEdges. - * Each ViewEdge of the current list starts a new chain. The chaining - * operator then iterates over the ViewEdges of the ViewMap using the - * user specified iterator. - * This operator only iterates using the increment operator and is - * therefore unidirectional. - * \param it - * The iterator on the ViewEdges of the ViewMap. It contains - * the chaining rule. - * \param pred - * The predicate on the ViewEdge that expresses the stopping - * condition. - * \param modifier - * A function that takes a ViewEdge as argument and that - * is used to modify the processed ViewEdge state (the timestamp - * incrementation is a typical illustration of such a modifier) - */ - static int chain(ViewEdgeInternal::ViewEdgeIterator& it, - UnaryPredicate1D& pred, - UnaryFunction1D_void& modifier); - - /*! Builds a set of chains from the current set of ViewEdges. - * Each ViewEdge of the current list starts a new chain. The chaining - * operator then iterates over the ViewEdges of the ViewMap using the - * user specified iterator. - * This operator only iterates using the increment operator and is - * therefore unidirectional. - * This chaining operator is different from the previous one because - * it doesn't take any modifier as argument. Indeed, the time stamp (insuring - * that a ViewEdge is processed one time) is automatically managed in this case. - * \param it - * The iterator on the ViewEdges of the ViewMap. It contains - * the chaining rule. - * \param pred - * The predicate on the ViewEdge that expresses the stopping - * condition. - */ - static int chain(ViewEdgeInternal::ViewEdgeIterator& it, - UnaryPredicate1D& pred); - - /*! Builds a set of chains from the current set of ViewEdges. - * Each ViewEdge of the current list potentially starts a new chain. The chaining - * operator then iterates over the ViewEdges of the ViewMap using the - * user specified iterator. - * This operator iterates both using the increment and decrement operators and is - * therefore bidirectional. - * This operator works with a ChainingIterator which contains the - * chaining rules. It is this last one which can be told - * to chain only edges that belong to the selection or not to - * process twice a ViewEdge during the chaining. - * Each time a ViewEdge is added to a chain, its chaining time stamp - * is incremented. This allows you to keep track of - * the number of chains to which a ViewEdge belongs to. - * \param it - * The ChainingIterator on the ViewEdges of the ViewMap. It contains - * the chaining rule. - * \param pred - * The predicate on the ViewEdge that expresses the stopping - * condition. - */ - static int bidirectionalChain(ChainingIterator& it, UnaryPredicate1D& pred); - - /*! The only difference with the above bidirectional chaining algorithm is - * that we don't need to pass a stopping criterion. This might be desirable - * when the stopping criterion is already contained in the iterator - * definition. - * Builds a set of chains from the current set of ViewEdges. - * Each ViewEdge of the current list potentially starts a new chain. The chaining - * operator then iterates over the ViewEdges of the ViewMap using the - * user specified iterator. - * This operator iterates both using the increment and decrement operators and is - * therefore bidirectional. - * This operator works with a ChainingIterator which contains the - * chaining rules. It is this last one which can be told - * to chain only edges that belong to the selection or not to - * process twice a ViewEdge during the chaining. - * Each time a ViewEdge is added to a chain, its chaining time stamp - * is incremented. This allows you to keep track of - * the number of chains to which a ViewEdge belongs to. - * \param it - * The ChainingIterator on the ViewEdges of the ViewMap. It contains - * the chaining rule. - */ - static int bidirectionalChain(ChainingIterator& it); - - /*! Splits each chain of the current set of chains in a sequential way. - * The points of each chain are processed (with a specified sampling) sequentially. - * Each time a user specified starting condition is verified, a new chain begins and - * ends as soon as a user-defined stopping predicate is verified. - * This allows chains overlapping rather than chains partitioning. - * The first point of the initial chain is the first point of one of the - * resulting chains. - * The splitting ends when no more chain can start. - * \param startingPred - * The predicate on a point that expresses the starting - * condition - * \param stoppingPred - * The predicate on a point that expresses the stopping - * condition - * \param sampling - * The resolution used to sample the chain for the predicates - * evaluation. (The chain is not actually resampled, a virtual point - * only progresses along the curve using this resolution) - */ - static int sequentialSplit(UnaryPredicate0D& startingPred, UnaryPredicate0D& stoppingPred, - float sampling = 0.f); - - /*! Splits each chain of the current set of chains in a sequential way. - * The points of each chain are processed (with a specified sampling) sequentially - * and each time a user specified condition is verified, the chain is split into two chains. - * The resulting set of chains is a partition of the initial chain - * \param pred - * The predicate on a point that expresses the splitting - * condition - * \param sampling - * The resolution used to sample the chain for the predicate - * evaluation. (The chain is not actually resampled, a virtual point - * only progresses along the curve using this resolution) - */ - static int sequentialSplit(UnaryPredicate0D& pred, - float sampling = 0.f); - - /*! Splits the current set of chains in a recursive way. - * We process the points of each chain (with a specified sampling) to find - * the point minimizing a specified function. The chain is split in two at this - * point and the two new chains are processed in the same way. - * The recursivity level is controlled through a predicate 1D that expresses a stopping condition - * on the chain that is about to be processed. - * \param func - * The Unary Function evaluated at each point of the chain. - * The splitting point is the point minimizing this function - * \param pred - * The Unary Predicate ex pressing the recursivity stopping condition. - * This predicate is evaluated for each curve before it actually gets - * split. If pred(chain) is true, the curve won't be split anymore. - * \param sampling - * The resolution used to sample the chain for the predicates - * evaluation. (The chain is not actually resampled, a virtual point - * only progresses along the curve using this resolution) - */ - static int recursiveSplit(UnaryFunction0D& func, UnaryPredicate1D& pred, float sampling = 0); - - /*! Splits the current set of chains in a recursive way. - * We process the points of each chain (with a specified sampling) to find - * the point minimizing a specified function. The chain is split in two at this - * point and the two new chains are processed in the same way. - * The user can specify a 0D predicate to make a first selection - * on the points that can potentially be split. - * A point that doesn't verify the 0D predicate won't be candidate - * in realizing the min. - * The recursivity level is controlled through a predicate 1D that expresses a stopping condition - * on the chain that is about to be processed. - * \param func - * The Unary Function evaluated at each point of the chain. - * The splitting point is the point minimizing this function - * \param pred0d - * The Unary Predicate 0D used to select the candidate points - * where the split can occur. - * For example, it is very likely that would rather have - * your chain splitting around its middle point than around - * one of its extremities. A 0D predicate working on - * the curvilinear abscissa allows to add this kind of constraints. - * \param pred - * The Unary Predicate ex pressing the recursivity stopping condition. - * This predicate is evaluated for each curve before it actually gets - * split. If pred(chain) is true, the curve won't be split anymore. - * \param sampling - * The resolution used to sample the chain for the predicates - * evaluation. (The chain is not actually resampled, a virtual point - * only progresses along the curve using this resolution) - * - */ - static int recursiveSplit(UnaryFunction0D& func, UnaryPredicate0D& pred0d, UnaryPredicate1D& pred, float sampling = 0); - - /*! Sorts the current set of chains (or viewedges) according to the - * comparison predicate given as argument. - * \param pred - * The binary predicate used for the comparison - */ - static int sort(BinaryPredicate1D& pred); - - /*! Creates and shades the strokes from the current set of chains. - * A predicate can be specified to make a selection pass on the - * chains. - * \param pred - * The predicate that a chain must verify in order to - * be transform as a stroke - * \param shaders - * The list of shaders used to shade the strokes - */ - static int create(UnaryPredicate1D& pred, vector shaders); - - // - // Data access - // - //////////////////////////////////////////////// - - static ViewEdge* getViewEdgeFromIndex(unsigned i) { - return dynamic_cast(_current_view_edges_set[i]); - } - - static Chain* getChainFromIndex(unsigned i) { - return dynamic_cast(_current_chains_set[i]); - } - - static Stroke* getStrokeFromIndex(unsigned i) { - return _current_strokes_set[i]; - } - - static unsigned getViewEdgesSize() { - return _current_view_edges_set.size(); - } - - static unsigned getChainsSize() { - return _current_chains_set.size(); - } - - static unsigned getStrokesSize() { - return _current_strokes_set.size(); - } - - // - // Not exported in Python - // - ////////////////////////////////////////////////// - - static StrokesContainer* getStrokesSet() { - return &_current_strokes_set; - } - - static void reset(); + // + // Operators + // + //////////////////////////////////////////////// -private: + /*! Selects the ViewEdges of the ViewMap verifying a specified condition. + * \param pred The predicate expressing this condition + */ + static int select(UnaryPredicate1D& pred); + + /*! Builds a set of chains from the current set of ViewEdges. + * Each ViewEdge of the current list starts a new chain. The chaining operator then iterates over the ViewEdges + * of the ViewMap using the user specified iterator. + * This operator only iterates using the increment operator and is therefore unidirectional. + * \param it + * The iterator on the ViewEdges of the ViewMap. It contains the chaining rule. + * \param pred + * The predicate on the ViewEdge that expresses the stopping condition. + * \param modifier + * A function that takes a ViewEdge as argument and that is used to modify the processed ViewEdge + * state (the timestamp incrementation is a typical illustration of such a modifier) + */ + static int chain(ViewEdgeInternal::ViewEdgeIterator& it, UnaryPredicate1D& pred, UnaryFunction1D_void& modifier); + + /*! Builds a set of chains from the current set of ViewEdges. + * Each ViewEdge of the current list starts a new chain. The chaining operator then iterates over the ViewEdges + * of the ViewMap using the user specified iterator. + * This operator only iterates using the increment operator and is therefore unidirectional. + * This chaining operator is different from the previous one because it doesn't take any modifier as argument. + * Indeed, the time stamp (insuring that a ViewEdge is processed one time) is automatically managed in this case. + * \param it + * The iterator on the ViewEdges of the ViewMap. It contains the chaining rule. + * \param pred + * The predicate on the ViewEdge that expresses the stopping condition. + */ + static int chain(ViewEdgeInternal::ViewEdgeIterator& it, UnaryPredicate1D& pred); + + /*! Builds a set of chains from the current set of ViewEdges. + * Each ViewEdge of the current list potentially starts a new chain. The chaining operator then iterates over + * the ViewEdges of the ViewMap using the user specified iterator. + * This operator iterates both using the increment and decrement operators and is therefore bidirectional. + * This operator works with a ChainingIterator which contains the chaining rules. It is this last one which can + * be told to chain only edges that belong to the selection or not to process twice a ViewEdge during the chaining. + * Each time a ViewEdge is added to a chain, its chaining time stamp is incremented. This allows you to keep track + * of the number of chains to which a ViewEdge belongs to. + * \param it + * The ChainingIterator on the ViewEdges of the ViewMap. It contains the chaining rule. + * \param pred + * The predicate on the ViewEdge that expresses the stopping condition. + */ + static int bidirectionalChain(ChainingIterator& it, UnaryPredicate1D& pred); + + /*! The only difference with the above bidirectional chaining algorithm is that we don't need to pass a stopping + * criterion. This might be desirable when the stopping criterion is already contained in the iterator definition. + * Builds a set of chains from the current set of ViewEdges. + * Each ViewEdge of the current list potentially starts a new chain. The chaining operator then iterates over + * the ViewEdges of the ViewMap using the user specified iterator. + * This operator iterates both using the increment and decrement operators and is therefore bidirectional. + * This operator works with a ChainingIterator which contains the chaining rules. It is this last one which can be + * told to chain only edges that belong to the selection or not to process twice a ViewEdge during the chaining. + * Each time a ViewEdge is added to a chain, its chaining time stamp is incremented. This allows you to keep track + * of the number of chains to which a ViewEdge belongs to. + * \param it + * The ChainingIterator on the ViewEdges of the ViewMap. It contains the chaining rule. + */ + static int bidirectionalChain(ChainingIterator& it); + + /*! Splits each chain of the current set of chains in a sequential way. + * The points of each chain are processed (with a specified sampling) sequentially. + * Each time a user specified starting condition is verified, a new chain begins and ends as soon as a + * user-defined stopping predicate is verified. + * This allows chains overlapping rather than chains partitioning. + * The first point of the initial chain is the first point of one of the resulting chains. + * The splitting ends when no more chain can start. + * \param startingPred + * The predicate on a point that expresses the starting condition + * \param stoppingPred + * The predicate on a point that expresses the stopping condition + * \param sampling + * The resolution used to sample the chain for the predicates evaluation. (The chain is not actually + * resampled, a virtual point only progresses along the curve using this resolution) + */ + static int sequentialSplit(UnaryPredicate0D& startingPred, UnaryPredicate0D& stoppingPred, float sampling = 0.0f); + + /*! Splits each chain of the current set of chains in a sequential way. + * The points of each chain are processed (with a specified sampling) sequentially and each time a user + * specified condition is verified, the chain is split into two chains. + * The resulting set of chains is a partition of the initial chain + * \param pred + * The predicate on a point that expresses the splitting condition + * \param sampling + * The resolution used to sample the chain for the predicate evaluation. (The chain is not actually + * resampled, a virtual point only progresses along the curve using this resolution) + */ + static int sequentialSplit(UnaryPredicate0D& pred, float sampling = 0.0f); - Operators() {} + /*! Splits the current set of chains in a recursive way. + * We process the points of each chain (with a specified sampling) to find the point minimizing a specified + * function. The chain is split in two at this point and the two new chains are processed in the same way. + * The recursivity level is controlled through a predicate 1D that expresses a stopping condition + * on the chain that is about to be processed. + * \param func + * The Unary Function evaluated at each point of the chain. + * The splitting point is the point minimizing this function + * \param pred + * The Unary Predicate ex pressing the recursivity stopping condition. + * This predicate is evaluated for each curve before it actually gets split. + * If pred(chain) is true, the curve won't be split anymore. + * \param sampling + * The resolution used to sample the chain for the predicates evaluation. (The chain is not actually + * resampled, a virtual point only progresses along the curve using this resolution) + */ + static int recursiveSplit(UnaryFunction0D& func, UnaryPredicate1D& pred, float sampling = 0); + + /*! Splits the current set of chains in a recursive way. + * We process the points of each chain (with a specified sampling) to find the point minimizing a specified + * function. The chain is split in two at this point and the two new chains are processed in the same way. + * The user can specify a 0D predicate to make a first selection on the points that can potentially be split. + * A point that doesn't verify the 0D predicate won't be candidate in realizing the min. + * The recursivity level is controlled through a predicate 1D that expresses a stopping condition + * on the chain that is about to be processed. + * \param func + * The Unary Function evaluated at each point of the chain. + * The splitting point is the point minimizing this function + * \param pred0d + * The Unary Predicate 0D used to select the candidate points where the split can occur. + * For example, it is very likely that would rather have your chain splitting around its middle point + * than around one of its extremities. A 0D predicate working on the curvilinear abscissa allows + * to add this kind of constraints. + * \param pred + * The Unary Predicate ex pressing the recursivity stopping condition. + * This predicate is evaluated for each curve before it actually gets split. + * If pred(chain) is true, the curve won't be split anymore. + * \param sampling + * The resolution used to sample the chain for the predicates evaluation. (The chain is not actually + * resampled, a virtual point only progresses along the curve using this resolution) + */ + static int recursiveSplit(UnaryFunction0D& func, UnaryPredicate0D& pred0d, UnaryPredicate1D& pred, + float sampling = 0.0f); + + /*! Sorts the current set of chains (or viewedges) according to the comparison predicate given as argument. + * \param pred + * The binary predicate used for the comparison + */ + static int sort(BinaryPredicate1D& pred); + + /*! Creates and shades the strokes from the current set of chains. + * A predicate can be specified to make a selection pass on the chains. + * \param pred + * The predicate that a chain must verify in order to be transform as a stroke + * \param shaders + * The list of shaders used to shade the strokes + */ + static int create(UnaryPredicate1D& pred, vector shaders); + + // + // Data access + // + //////////////////////////////////////////////// + + static ViewEdge *getViewEdgeFromIndex(unsigned i) + { + return dynamic_cast(_current_view_edges_set[i]); + } + + static Chain *getChainFromIndex(unsigned i) + { + return dynamic_cast(_current_chains_set[i]); + } + + static Stroke *getStrokeFromIndex(unsigned i) + { + return _current_strokes_set[i]; + } + + static unsigned getViewEdgesSize() + { + return _current_view_edges_set.size(); + } + + static unsigned getChainsSize() + { + return _current_chains_set.size(); + } + + static unsigned getStrokesSize() + { + return _current_strokes_set.size(); + } + + // + // Not exported in Python + // + ////////////////////////////////////////////////// + + static StrokesContainer *getStrokesSet() + { + return &_current_strokes_set; + } + + static void reset(); + +private: + Operators() {} - static I1DContainer _current_view_edges_set; - static I1DContainer _current_chains_set; - static I1DContainer* _current_set; - static StrokesContainer _current_strokes_set; + static I1DContainer _current_view_edges_set; + static I1DContainer _current_chains_set; + static I1DContainer *_current_set; + static StrokesContainer _current_strokes_set; }; -#endif // OPERATORS_H +#endif // __FREESTYLE_OPERATORS_H__ diff --git a/source/blender/freestyle/intern/stroke/PSStrokeRenderer.cpp b/source/blender/freestyle/intern/stroke/PSStrokeRenderer.cpp index dc9c94e0e11..0b527f9f2af 100644 --- a/source/blender/freestyle/intern/stroke/PSStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/stroke/PSStrokeRenderer.cpp @@ -1,89 +1,106 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/stroke/PSStrokeRenderer.cpp + * \ingroup freestyle + * \brief Class to define the Postscript rendering of a stroke + * \author Stephane Grabli + * \date 10/26/2004 + */ -# include "PSStrokeRenderer.h" -# include "Canvas.h" +#include "Canvas.h" +#include "PSStrokeRenderer.h" -PSStrokeRenderer::PSStrokeRenderer(const char* iFileName) -:StrokeRenderer(){ - if(!iFileName) - iFileName = "freestyle.ps"; - // open the stream: - _ofstream.open(iFileName, ios::out); - if(!_ofstream.is_open()){ - cerr << "couldn't open the output file " << iFileName << endl; - } - _ofstream << "%!PS-Adobe-2.0 EPSF-2.0" << endl; - _ofstream << "%%Creator: Freestyle (http://artis.imag.fr/Software/Freestyle)" << endl; - _ofstream << "%%BoundingBox: " << 0 << " "<< 0 << " " << Canvas::getInstance()->width() << " " << Canvas::getInstance()->height() << endl; - _ofstream << "%%EndComments" << endl; +PSStrokeRenderer::PSStrokeRenderer(const char *iFileName) : StrokeRenderer() +{ + if (!iFileName) + iFileName = "freestyle.ps"; + // open the stream: + _ofstream.open(iFileName, ios::out); + if (!_ofstream.is_open()) { + cerr << "couldn't open the output file " << iFileName << endl; + } + _ofstream << "%!PS-Adobe-2.0 EPSF-2.0" << endl; + _ofstream << "%%Creator: Freestyle (http://artis.imag.fr/Software/Freestyle)" << endl; + _ofstream << "%%BoundingBox: " << 0 << " "<< 0 << " " << Canvas::getInstance()->width() << " " + << Canvas::getInstance()->height() << endl; + _ofstream << "%%EndComments" << endl; } -PSStrokeRenderer::~PSStrokeRenderer(){ - Close(); +PSStrokeRenderer::~PSStrokeRenderer() +{ + Close(); } -void PSStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const{ - RenderStrokeRepBasic(iStrokeRep); +void PSStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const +{ + RenderStrokeRepBasic(iStrokeRep); } -void PSStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const{ - vector& strips = iStrokeRep->getStrips(); - Strip::vertex_container::iterator v[3]; - StrokeVertexRep *svRep[3]; - Vec3r color[3]; - for(vector::iterator s=strips.begin(), send=strips.end(); - s!=send; - ++s){ - Strip::vertex_container& vertices = (*s)->vertices(); - v[0] = vertices.begin(); - v[1] = v[0];++(v[1]); - v[2] = v[1]; ++(v[2]); +void PSStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const +{ + vector& strips = iStrokeRep->getStrips(); + Strip::vertex_container::iterator v[3]; + StrokeVertexRep *svRep[3]; + Vec3r color[3]; + for (vector::iterator s = strips.begin(), send = strips.end(); s != send; ++s) { + Strip::vertex_container& vertices = (*s)->vertices(); + v[0] = vertices.begin(); + v[1] = v[0]; + ++(v[1]); + v[2] = v[1]; + ++(v[2]); - while(v[2]!=vertices.end()){ - svRep[0] = *(v[0]); - svRep[1] = *(v[1]); - svRep[2] = *(v[2]); - - color[0] = svRep[0]->color(); - //color[1] = svRep[1]->color(); - //color[2] = svRep[2]->color(); - - _ofstream << "newpath" << endl; - _ofstream << (color[0])[0] << " " << (color[0])[1] << " " << (color[0])[2] << " setrgbcolor" <point2d()[0] << " " <point2d()[1] << " moveto" << endl; - _ofstream << svRep[1]->point2d()[0] << " " <point2d()[1] << " lineto" << endl; - _ofstream << svRep[2]->point2d()[0] << " " <point2d()[1] << " lineto" << endl; - _ofstream << "closepath" << endl; - _ofstream << "fill" << endl; + while (v[2] != vertices.end()) { + svRep[0] = *(v[0]); + svRep[1] = *(v[1]); + svRep[2] = *(v[2]); - ++v[0]; - ++v[1]; - ++v[2]; - } - } -} + color[0] = svRep[0]->color(); + //color[1] = svRep[1]->color(); + //color[2] = svRep[2]->color(); + + _ofstream << "newpath" << endl; + _ofstream << (color[0])[0] << " " << (color[0])[1] << " " << (color[0])[2] << " setrgbcolor" <point2d()[0] << " " <point2d()[1] << " moveto" << endl; + _ofstream << svRep[1]->point2d()[0] << " " <point2d()[1] << " lineto" << endl; + _ofstream << svRep[2]->point2d()[0] << " " <point2d()[1] << " lineto" << endl; + _ofstream << "closepath" << endl; + _ofstream << "fill" << endl; -void PSStrokeRenderer::Close(){ - if(_ofstream.is_open()) - _ofstream.close(); + ++v[0]; + ++v[1]; + ++v[2]; + } + } } +void PSStrokeRenderer::Close() +{ + if (_ofstream.is_open()) + _ofstream.close(); +} diff --git a/source/blender/freestyle/intern/stroke/PSStrokeRenderer.h b/source/blender/freestyle/intern/stroke/PSStrokeRenderer.h index b30949845ab..e01ec531471 100644 --- a/source/blender/freestyle/intern/stroke/PSStrokeRenderer.h +++ b/source/blender/freestyle/intern/stroke/PSStrokeRenderer.h @@ -1,38 +1,45 @@ -// -// Filename : PSStrokeRenderer.h -// Author(s) : Stephane Grabli -// Purpose : Class to define the Postscript rendering of a stroke -// Date of creation : 10/26/2004 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef PSSTROKERENDERER_H -# define PSSTROKERENDERER_H - -# include "StrokeRenderer.h" -# include "../system/FreestyleConfig.h" -# include +/* + * ***** 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_PS_STROKE_RENDERER_H__ +#define __FREESTYLE_PS_STROKE_RENDERER_H__ + +/** \file blender/freestyle/intern/stroke/PSStrokeRenderer.h + * \ingroup freestyle + * \brief Class to define the Postscript rendering of a stroke + * \author Stephane Grabli + * \date 10/26/2004 + */ + +#include + +#include "StrokeRenderer.h" + +#include "../system/FreestyleConfig.h" /**********************************/ /* */ @@ -45,19 +52,18 @@ class LIB_STROKE_EXPORT PSStrokeRenderer : public StrokeRenderer { public: - PSStrokeRenderer(const char * iFileName = 0); - virtual ~PSStrokeRenderer(); + PSStrokeRenderer(const char * iFileName = 0); + virtual ~PSStrokeRenderer(); - /*! Renders a stroke rep */ - virtual void RenderStrokeRep(StrokeRep *iStrokeRep) const; - virtual void RenderStrokeRepBasic(StrokeRep *iStrokeRep) const; + /*! Renders a stroke rep */ + virtual void RenderStrokeRep(StrokeRep *iStrokeRep) const; + virtual void RenderStrokeRepBasic(StrokeRep *iStrokeRep) const; - /*! Closes the output PS file */ - void Close(); + /*! Closes the output PS file */ + void Close(); protected: - mutable ofstream _ofstream; + mutable ofstream _ofstream; }; -#endif // PSSTROKERENDERER_H - +#endif // __FREESTYLE_PS_STROKE_RENDERER_H__ diff --git a/source/blender/freestyle/intern/stroke/Predicates0D.h b/source/blender/freestyle/intern/stroke/Predicates0D.h index 2f5d9551b3a..796bbdef0f6 100644 --- a/source/blender/freestyle/intern/stroke/Predicates0D.h +++ b/source/blender/freestyle/intern/stroke/Predicates0D.h @@ -1,82 +1,86 @@ -// -// Filename : Predicates0D.h -// Author(s) : Stephane Grabli, Emmanuel Turquin -// Purpose : Class gathering stroke creation algorithms -// Date of creation : 01/07/2003 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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_PREDICATES_0D_H__ +#define __FREESTYLE_PREDICATES_0D_H__ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef PREDICATES0D_H -# define PREDICATES0D_H +/** \file blender/freestyle/intern/stroke/Predicates0D.h + * \ingroup freestyle + * \brief Class gathering stroke creation algorithms + * \author Stephane Grabli + * \author Emmanuel Turquin + * \date 01/07/2003 + */ -# include "../view_map/Functions0D.h" +#include "../python/Director.h" -# include "../python/Director.h" +#include "../view_map/Functions0D.h" // // UnaryPredicate0D (base class for predicates in 0D) // /////////////////////////////////////////////////////////// -/*! Base class for Unary Predicates that work - * on Interface0DIterator. - * A UnaryPredicate0D is a functor that evaluates - * a condition on a Interface0DIterator and returns - * true or false depending on whether this condition is - * satisfied or not. + +/*! Base class for Unary Predicates that work on Interface0DIterator. + * A UnaryPredicate0D is a functor that evaluates a condition on a Interface0DIterator and returns + * true or false depending on whether this condition is satisfied or not. * The UnaryPredicate0D is used by calling its () operator. * Any inherited class must overload the () operator. */ class UnaryPredicate0D { public: - bool result; PyObject *py_up0D; - - /*! Default constructor. */ - UnaryPredicate0D() { py_up0D = 0; } - /*! Destructor. */ - virtual ~UnaryPredicate0D() {} - /*! Returns the string of the name - * of the UnaryPredicate0D. - */ - virtual string getName() const { - return "UnaryPredicate0D"; - } - /*! The () operator. Must be overload - * by inherited classes. - * \param it - * The Interface0DIterator pointing onto the - * Interface0D at which we wish to evaluate - * the predicate. - * \return true if the condition is satisfied, - * false otherwise. - */ - virtual int operator()(Interface0DIterator& it) { - return Director_BPy_UnaryPredicate0D___call__(this, it); - } + /*! Default constructor. */ + UnaryPredicate0D() + { + py_up0D = 0; + } + + /*! Destructor. */ + virtual ~UnaryPredicate0D() {} + + /*! Returns the string of the name of the UnaryPredicate0D. */ + virtual string getName() const + { + return "UnaryPredicate0D"; + } + + /*! The () operator. Must be overload by inherited classes. + * \param it + * The Interface0DIterator pointing onto the Interface0D at which we wish to evaluate the predicate. + * \return true if the condition is satisfied, false otherwise. + */ + virtual int operator()(Interface0DIterator& it) + { + return Director_BPy_UnaryPredicate0D___call__(this, it); + } }; @@ -84,43 +88,45 @@ public: // BinaryPredicate0D (base class for predicates in 0D) // /////////////////////////////////////////////////////////// + /*! Base class for Binary Predicates working on Interface0D. - * A BinaryPredicate0D is typically an ordering relation - * between two Interface0D. - * It evaluates a relation between 2 Interface0D and - * returns true or false. + * A BinaryPredicate0D is typically an ordering relation between two Interface0D. + * It evaluates a relation between 2 Interface0D and returns true or false. * It is used by calling the () operator. */ class BinaryPredicate0D { public: - - bool result; - PyObject *py_bp0D; - - /*! Default constructor. */ - BinaryPredicate0D() { py_bp0D = 0; } - /*! Destructor. */ - virtual ~BinaryPredicate0D() {} - /*! Returns the string of the name of the - * binary predicate. - */ - virtual string getName() const { - return "BinaryPredicate0D"; - } - - /*! The () operator. Must be overload by inherited classes. - * It evaluates a relation between 2 Interface0D. - * \param inter1 - * The first Interface0D. - * \param inter2 - * The second Interface0D. - * \return true or false. - */ - virtual int operator()(Interface0D& inter1, Interface0D& inter2) { - return Director_BPy_BinaryPredicate0D___call__(this, inter1, inter2); - } - + bool result; + PyObject *py_bp0D; + + /*! Default constructor. */ + BinaryPredicate0D() + { + py_bp0D = 0; + } + + /*! Destructor. */ + virtual ~BinaryPredicate0D() {} + + /*! Returns the string of the name of the binary predicate. */ + virtual string getName() const + { + return "BinaryPredicate0D"; + } + + /*! The () operator. Must be overload by inherited classes. + * It evaluates a relation between 2 Interface0D. + * \param inter1 + * The first Interface0D. + * \param inter2 + * The second Interface0D. + * \return true or false. + */ + virtual int operator()(Interface0D& inter1, Interface0D& inter2) + { + return Director_BPy_BinaryPredicate0D___call__(this, inter1, inter2); + } }; @@ -131,42 +137,50 @@ public: namespace Predicates0D { - // TrueUP0D - /*! Returns true any time */ - class TrueUP0D : public UnaryPredicate0D - { - public: - /*! Default constructor. */ - TrueUP0D() {} - /*! Returns the string "TrueUP0D"*/ - string getName() const { - return "TrueUP0D"; - } - /*! The () operator. */ - int operator()(Interface0DIterator&) { - result = true; - return 0; - } - }; - - // FalseUP0D - /*! Returns false any time */ - class FalseUP0D : public UnaryPredicate0D - { - public: - /*! Default constructor. */ - FalseUP0D() {} - /*! Returns the string "FalseUP0D"*/ - string getName() const { - return "FalseUP0D"; - } - /*! The () operator. */ - int operator()(Interface0DIterator&) { - result = false; - return 0; - } - }; +// TrueUP0D +/*! Returns true any time */ +class TrueUP0D : public UnaryPredicate0D +{ +public: + /*! Default constructor. */ + TrueUP0D() {} + + /*! Returns the string "TrueUP0D"*/ + string getName() const + { + return "TrueUP0D"; + } + + /*! The () operator. */ + int operator()(Interface0DIterator&) + { + result = true; + return 0; + } +}; + +// FalseUP0D +/*! Returns false any time */ +class FalseUP0D : public UnaryPredicate0D +{ +public: + /*! Default constructor. */ + FalseUP0D() {} + + /*! Returns the string "FalseUP0D"*/ + string getName() const + { + return "FalseUP0D"; + } + + /*! The () operator. */ + int operator()(Interface0DIterator&) + { + result = false; + return 0; + } +}; } // end of namespace Predicates0D -#endif // PREDICATES0D_H +#endif // __FREESTYLE_PREDICATES_0D_H__ diff --git a/source/blender/freestyle/intern/stroke/Predicates1D.h b/source/blender/freestyle/intern/stroke/Predicates1D.h index b1159a8332e..18e4328c4d5 100644 --- a/source/blender/freestyle/intern/stroke/Predicates1D.h +++ b/source/blender/freestyle/intern/stroke/Predicates1D.h @@ -1,85 +1,93 @@ -// -// Filename : Predicates1D.h -// Author(s) : Stephane Grabli, Emmanuel Turquin -// Purpose : Class gathering stroke creation algorithms -// Date of creation : 01/07/2003 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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_PREDICATES_1D_H__ +#define __FREESTYLE_PREDICATES_1D_H__ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/stroke/Predicates1D.h + * \ingroup freestyle + * \brief Class gathering stroke creation algorithms + * \author Stephane Grabli + * \author Emmanuel Turquin + * \date 01/07/2003 + */ -#ifndef PREDICATES1D_H -# define PREDICATES1D_H +#include -# include -# include "../system/TimeStamp.h" -# include "../view_map/Interface1D.h" -# include "../view_map/Functions1D.h" -# include "AdvancedFunctions1D.h" +#include "AdvancedFunctions1D.h" -# include "../python/Director.h" +#include "../python/Director.h" + +#include "../system/TimeStamp.h" + +#include "../view_map/Interface1D.h" +#include "../view_map/Functions1D.h" // // UnaryPredicate1D (base class for predicates in 1D) // /////////////////////////////////////////////////////////// -/*! Base class for Unary Predicates that work - * on Interface1D. - * A UnaryPredicate1D is a functor that evaluates - * a condition on a Interface1D and returns - * true or false depending on whether this condition is - * satisfied or not. + +/*! Base class for Unary Predicates that work on Interface1D. + * A UnaryPredicate1D is a functor that evaluates a condition on a Interface1D and returns + * true or false depending on whether this condition is satisfied or not. * The UnaryPredicate1D is used by calling its () operator. * Any inherited class must overload the () operator. */ class UnaryPredicate1D { public: - bool result; PyObject *py_up1D; - - /*! Default constructor. */ - UnaryPredicate1D() { py_up1D = 0; } - /*! Destructor. */ - virtual ~UnaryPredicate1D() {} - /*! Returns the string of the name - * of the UnaryPredicate1D. - */ - virtual string getName() const { - return "UnaryPredicate1D"; - } - /*! The () operator. Must be overload - * by inherited classes. - * \param inter - * The Interface1D on which we wish to evaluate - * the predicate. - * \return true if the condition is satisfied, - * false otherwise. - */ - virtual int operator()(Interface1D& inter) { - return Director_BPy_UnaryPredicate1D___call__(this, inter); - } + /*! Default constructor. */ + UnaryPredicate1D() + { + py_up1D = NULL; + } + + /*! Destructor. */ + virtual ~UnaryPredicate1D() {} + + /*! Returns the string of the name of the UnaryPredicate1D. */ + virtual string getName() const + { + return "UnaryPredicate1D"; + } + + /*! The () operator. Must be overload by inherited classes. + * \param inter + * The Interface1D on which we wish to evaluate the predicate. + * \return true if the condition is satisfied, false otherwise. + */ + virtual int operator()(Interface1D& inter) + { + return Director_BPy_UnaryPredicate1D___call__(this, inter); + } }; @@ -87,42 +95,45 @@ public: // BinaryPredicate1D (base class for predicates in 1D) // /////////////////////////////////////////////////////////// + /*! Base class for Binary Predicates working on Interface1D. - * A BinaryPredicate1D is typically an ordering relation - * between two Interface1D. - * It evaluates a relation between 2 Interface1D and - * returns true or false. + * A BinaryPredicate1D is typically an ordering relation between two Interface1D. + * It evaluates a relation between 2 Interface1D and returns true or false. * It is used by calling the () operator. */ class BinaryPredicate1D { public: - - bool result; - PyObject *py_bp1D; - - /*! Default constructor. */ - BinaryPredicate1D() { py_bp1D = 0; } - /*! Destructor. */ - virtual ~BinaryPredicate1D() {} - /*! Returns the string of the name of the - * binary predicate. - */ - virtual string getName() const { - return "BinaryPredicate1D"; - } - /*! The () operator. Must be overload by inherited classes. - * It evaluates a relation between 2 Interface1D. - * \param inter1 - * The first Interface1D. - * \param inter2 - * The second Interface1D. - * \return true or false. - */ - virtual int operator()(Interface1D& inter1, Interface1D& inter2) { - return Director_BPy_BinaryPredicate1D___call__(this, inter1, inter2); - } + bool result; + PyObject *py_bp1D; + + /*! Default constructor. */ + BinaryPredicate1D() + { + py_bp1D = NULL; + } + /*! Destructor. */ + virtual ~BinaryPredicate1D() {} + + /*! Returns the string of the name of the binary predicate. */ + virtual string getName() const + { + return "BinaryPredicate1D"; + } + + /*! The () operator. Must be overload by inherited classes. + * It evaluates a relation between 2 Interface1D. + * \param inter1 + * The first Interface1D. + * \param inter2 + * The second Interface1D. + * \return true or false. + */ + virtual int operator()(Interface1D& inter1, Interface1D& inter2) + { + return Director_BPy_BinaryPredicate1D___call__(this, inter1, inter2); + } }; @@ -133,408 +144,446 @@ public: namespace Predicates1D { - // TrueUP1D - /*! Returns true */ - class TrueUP1D : public UnaryPredicate1D - { - public: - /*! Constructor */ - TrueUP1D() {} - /*! Returns the string "TrueUP1D"*/ - string getName() const { - return "TrueUP1D"; - } - /*! the () operator */ - int operator()(Interface1D&) { - result = true; - return 0; - } - }; - - // FalseUP1D - /*! Returns false */ - class FalseUP1D : public UnaryPredicate1D - { - public: - /*! Constructor */ - FalseUP1D() {} - /*! Returns the string "FalseUP1D"*/ - string getName() const { - return "FalseUP1D"; - } - /*! the () operator */ - int operator()(Interface1D&) { - result = false; - return 0; - } - }; - - // QuantitativeInvisibilityUP1D - /*! Returns true if the Quantitative Invisibility evaluated - * at an Interface1D, using the QuantitativeInvisibilityF1D - * functor, equals a certain user-defined value. - */ - class QuantitativeInvisibilityUP1D : public UnaryPredicate1D - { - public: - /*! Builds the Predicate. - * \param qi - * The Quantitative Invisibility you want - * the Interface1D to have - */ - QuantitativeInvisibilityUP1D(unsigned qi = 0) : _qi(qi) {} - /*! Returns the string "QuantitativeInvisibilityUP1D"*/ - string getName() const { - return "QuantitativeInvisibilityUP1D"; - } - /*! the () operator */ - int operator()(Interface1D& inter) { - Functions1D::QuantitativeInvisibilityF1D func; - if (func(inter) < 0) - return -1; - result = (func.result == _qi); - return 0; - } - private: - unsigned _qi; - }; - - // ContourUP1D - /*! Returns true if the Interface1D is a contour. - * An Interface1D is a contour if it is borded - * by a different shape on each of its sides. - */ - class ContourUP1D : public UnaryPredicate1D - { - private: - Functions1D::CurveNatureF1D _getNature; - public: - /*! Returns the string "ContourUP1D"*/ - string getName() const { - return "ContourUP1D"; - } - /*! The () operator. */ - int operator()(Interface1D& inter) { - if (_getNature(inter) < 0) - return -1; - if((_getNature.result & Nature::SILHOUETTE) || (_getNature.result & Nature::BORDER)){ - Interface0DIterator it=inter.verticesBegin(); - for(; !it.isEnd(); ++it){ - if(Functions0D::getOccludeeF0D(it) != Functions0D::getShapeF0D(it)) { - result = true; - return 0; - } - } - } - result = false; - return 0; - } - }; - - // ExternalContourUP1D - /*! Returns true if the Interface1D is an external contour. - * An Interface1D is an external contour if it is borded - * by no shape on one of its sides. - */ - class ExternalContourUP1D : public UnaryPredicate1D - { - private: - Functions1D::CurveNatureF1D _getNature; - public: - /*! Returns the string "ExternalContourUP1D"*/ - string getName() const { - return "ExternalContourUP1D"; - } - /*! The () operator. */ - int operator()(Interface1D& inter) { - if (_getNature(inter) < 0) - return -1; - if((_getNature.result & Nature::SILHOUETTE) || (_getNature.result & Nature::BORDER)){ - set occluded; - Functions1D::getOccludeeF1D(inter, occluded); - for(set::iterator os=occluded.begin(), osend=occluded.end(); - os!=osend; - ++os){ - if((*os) == 0) { - result = true; - return 0; - } - } - } - result = false; - return 0; - } - }; - - // EqualToTimeStampUP1D - /*! Returns true if the Interface1D's time stamp - * is equal to a certain user-defined value. - */ - class EqualToTimeStampUP1D : public UnaryPredicate1D - { - protected: - unsigned _timeStamp; - public: - EqualToTimeStampUP1D(unsigned ts) : UnaryPredicate1D(){ - _timeStamp = ts; - } - /*! Returns the string "EqualToTimeStampUP1D"*/ - string getName() const { - return "EqualToTimeStampUP1D"; - } - /*! The () operator. */ - int operator()(Interface1D& inter) { - result = (inter.getTimeStamp() == _timeStamp); - return 0; - } - }; - - // EqualToChainingTimeStampUP1D - /*! Returns true if the Interface1D's time stamp - * is equal to a certain user-defined value. - */ - class EqualToChainingTimeStampUP1D : public UnaryPredicate1D - { - protected: - unsigned _timeStamp; - public: - EqualToChainingTimeStampUP1D(unsigned ts) : UnaryPredicate1D(){ - _timeStamp = ts; - } - /*! Returns the string "EqualToChainingTimeStampUP1D"*/ - string getName() const { - return "EqualToChainingTimeStampUP1D"; - } - /*! The () operator. */ - int operator()(Interface1D& inter) { - ViewEdge* edge = dynamic_cast(&inter); - if (!edge) { +// TrueUP1D +/*! Returns true */ +class TrueUP1D : public UnaryPredicate1D +{ +public: + /*! Constructor */ + TrueUP1D() {} + + /*! Returns the string "TrueUP1D"*/ + string getName() const + { + return "TrueUP1D"; + } + + /*! the () operator */ + int operator()(Interface1D&) + { + result = true; + return 0; + } +}; + +// FalseUP1D +/*! Returns false */ +class FalseUP1D : public UnaryPredicate1D +{ +public: + /*! Constructor */ + FalseUP1D() {} + + /*! Returns the string "FalseUP1D"*/ + string getName() const + { + return "FalseUP1D"; + } + + /*! the () operator */ + int operator()(Interface1D&) + { result = false; return 0; - } - result = (edge->getChainingTimeStamp() >= _timeStamp); - return 0; - } - }; - - // ShapeUP1D - /*! Returns true if the shape to which the Interface1D - * belongs to has the same Id as the one specified by the - * user. - */ - class ShapeUP1D: public UnaryPredicate1D - { - private: - Id _id; - public: - /*! Builds the Predicate. - * \param idFirst - * The first Id component. - * \param idSecond - * The second Id component. - */ - ShapeUP1D(unsigned idFirst, unsigned idSecond=0) - : UnaryPredicate1D(){ - _id = Id(idFirst, idSecond); - } - /*! Returns the string "ShapeUP1D"*/ - string getName() const { - return "ShapeUP1D"; - } - /*! The () operator. */ - int operator()(Interface1D& inter) { - set shapes; - Functions1D::getShapeF1D(inter, shapes); - for(set::iterator s=shapes.begin(), send=shapes.end(); - s!=send; - ++s){ - if((*s)->getId() == _id) { - result = true; - return 0; + } +}; + +// QuantitativeInvisibilityUP1D +/*! Returns true if the Quantitative Invisibility evaluated at an Interface1D, using the QuantitativeInvisibilityF1D + * functor, equals a certain user-defined value. + */ +class QuantitativeInvisibilityUP1D : public UnaryPredicate1D +{ +public: + /*! Builds the Predicate. + * \param qi + * The Quantitative Invisibility you want the Interface1D to have + */ + QuantitativeInvisibilityUP1D(unsigned qi = 0) : _qi(qi) {} + + /*! Returns the string "QuantitativeInvisibilityUP1D" */ + string getName() const + { + return "QuantitativeInvisibilityUP1D"; + } + + /*! the () operator */ + int operator()(Interface1D& inter) + { + Functions1D::QuantitativeInvisibilityF1D func; + if (func(inter) < 0) + return -1; + result = (func.result == _qi); + return 0; + } + +private: + unsigned _qi; +}; + +// ContourUP1D +/*! Returns true if the Interface1D is a contour. + * An Interface1D is a contour if it is borded by a different shape on each of its sides. + */ +class ContourUP1D : public UnaryPredicate1D +{ +private: + Functions1D::CurveNatureF1D _getNature; + +public: + /*! Returns the string "ContourUP1D"*/ + string getName() const + { + return "ContourUP1D"; + } + + /*! The () operator. */ + int operator()(Interface1D& inter) + { + if (_getNature(inter) < 0) + return -1; + if ((_getNature.result & Nature::SILHOUETTE) || (_getNature.result & Nature::BORDER)) { + Interface0DIterator it = inter.verticesBegin(); + for (; !it.isEnd(); ++it) { + if (Functions0D::getOccludeeF0D(it) != Functions0D::getShapeF0D(it)) { + result = true; + return 0; + } + } } - } - result = false; - return 0; - } - }; - - // WithinImageBoundaryUP1D - /*! Returns true if the Interface1D is (partly) within the image boundary. - */ - class WithinImageBoundaryUP1D: public UnaryPredicate1D - { - private: - real _xmin, _ymin, _xmax, _ymax; - public: - /*! Builds the Predicate. - * \param xmin - * The X lower bound of the image boundary. - * \param ymin - * The Y lower bound of the image boundary. - * \param xmax - * The X upper bound of the image boundary. - * \param ymax - * The Y upper bound of the image boundary. - */ - WithinImageBoundaryUP1D(const real xmin, const real ymin, const real xmax, const real ymax) : - _xmin(xmin), _ymin(ymin), _xmax(xmax), _ymax(ymax) {} - /*! Returns the string "WithinImageBoundaryUP1D"*/ - string getName() const { - return "WithinImageBoundaryUP1D"; - } - /*! The () operator. */ - int operator()(Interface1D& inter) { - // 1st pass: check if a point is within the image boundary. - Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd(); - for (; it != itend; ++it) { - real x = (*it).getProjectedX(); - real y = (*it).getProjectedY(); - if (_xmin <= x && x <= _xmax && _ymin <= y && y <= _ymax) { - result = true; - return 0; + result = false; + return 0; + } +}; + +// ExternalContourUP1D +/*! Returns true if the Interface1D is an external contour. + * An Interface1D is an external contour if it is borded by no shape on one of its sides. + */ +class ExternalContourUP1D : public UnaryPredicate1D +{ +private: + Functions1D::CurveNatureF1D _getNature; + +public: + /*! Returns the string "ExternalContourUP1D" */ + string getName() const + { + return "ExternalContourUP1D"; + } + + /*! The () operator. */ + int operator()(Interface1D& inter) + { + if (_getNature(inter) < 0) + return -1; + if ((_getNature.result & Nature::SILHOUETTE) || (_getNature.result & Nature::BORDER)) { + set occluded; + Functions1D::getOccludeeF1D(inter, occluded); + for (set::iterator os = occluded.begin(), osend = occluded.end(); os != osend; ++os) { + if ((*os) == 0) { + result = true; + return 0; + } + } } - } - // 2nd pass: check if a line segment intersects with the image boundary. - it = inter.verticesBegin(); - if (it != itend) { - Vec2r pmin(_xmin, _ymin); - Vec2r pmax(_xmax, _ymax); - Vec2r prev((*it).getPoint2D()); - ++it; - for (; it != itend; ++it) { - Vec2r p((*it).getPoint2D()); - if (GeomUtils::intersect2dSeg2dArea (pmin, pmax, prev, p)) { - result = true; + result = false; + return 0; + } +}; + +// EqualToTimeStampUP1D +/*! Returns true if the Interface1D's time stamp is equal to a certain user-defined value. */ +class EqualToTimeStampUP1D : public UnaryPredicate1D +{ +protected: + unsigned _timeStamp; + +public: + EqualToTimeStampUP1D(unsigned ts) : UnaryPredicate1D() + { + _timeStamp = ts; + } + + /*! Returns the string "EqualToTimeStampUP1D"*/ + string getName() const + { + return "EqualToTimeStampUP1D"; + } + + /*! The () operator. */ + int operator()(Interface1D& inter) + { + result = (inter.getTimeStamp() == _timeStamp); + return 0; + } +}; + +// EqualToChainingTimeStampUP1D +/*! Returns true if the Interface1D's time stamp is equal to a certain user-defined value. */ +class EqualToChainingTimeStampUP1D : public UnaryPredicate1D +{ +protected: + unsigned _timeStamp; + +public: + EqualToChainingTimeStampUP1D(unsigned ts) : UnaryPredicate1D() + { + _timeStamp = ts; + } + + /*! Returns the string "EqualToChainingTimeStampUP1D"*/ + string getName() const + { + return "EqualToChainingTimeStampUP1D"; + } + + /*! The () operator. */ + int operator()(Interface1D& inter) + { + ViewEdge *edge = dynamic_cast(&inter); + if (!edge) + { + result = false; return 0; - } - prev = p; } - } - result = false; - return 0; - } - }; - - // - // Binary Predicates definitions - // - /////////////////////////////////////////////////////////// - - // TrueBP1D - /*! Returns true. */ - class TrueBP1D : public BinaryPredicate1D - { - public: - /*! Returns the string "TrueBP1D"*/ - string getName() const { - return "TrueBP1D"; - } - /*! The () operator. */ - int operator()(Interface1D& i1, Interface1D& i2) { - result = true; - return 0; - } - }; - - // FalseBP1D - /*! Returns false. */ - class FalseBP1D : public BinaryPredicate1D - { - public: - /*! Returns the string "FalseBP1D"*/ - string getName() const { - return "FalseBP1D"; - } - /*! The () operator. */ - int operator()(Interface1D& i1, Interface1D& i2) { - result = false; - return 0; - } - }; - - // Length2DBP1D - /*! Returns true if the 2D length of the Interface1D i1 - * is less than the 2D length of the Interface1D i2. - */ - class Length2DBP1D : public BinaryPredicate1D - { - public: - /*! Returns the string "Length2DBP1D"*/ - string getName() const { - return "Length2DBP1D"; - } - /*! The () operator. */ - int operator()(Interface1D& i1, Interface1D& i2) { - result = (i1.getLength2D() > i2.getLength2D()); - return 0; - } - }; - - // SameShapeIdBP1D - /*! Returns true if the Interface1D i1 and i2 belong - * to the same shape. - */ - class SameShapeIdBP1D : public BinaryPredicate1D - { - public: - /*! Returns the string "SameShapeIdBP1D"*/ - string getName() const { - return "SameShapeIdBP1D"; - } - /*! The () operator. */ - int operator()(Interface1D& i1, Interface1D& i2) { - set shapes1; - Functions1D::getShapeF1D(i1, shapes1); - set shapes2; - Functions1D::getShapeF1D(i2, shapes2); - // FIXME:// n2 algo, can do better... - for(set::iterator s=shapes1.begin(), send=shapes1.end(); - s!=send; - ++s){ - Id current = (*s)->getId(); - for(set::iterator s2=shapes2.begin(), s2end=shapes2.end(); - s2!=s2end; - ++s2){ - if((*s2)->getId() == current) { - result = true; - return 0; - } - } - } - result = false; - return 0; - } - }; - - // ViewMapGradientNormBP1D - /*! Returns true if the evaluation of the - * Gradient norm Function is higher for Interface1D i1 - * than for i2. - */ - class ViewMapGradientNormBP1D : public BinaryPredicate1D - { - private: - Functions1D::GetViewMapGradientNormF1D _func; - public: - ViewMapGradientNormBP1D(int level, IntegrationType iType=MEAN, float sampling=2.0) - : BinaryPredicate1D(), _func(level, iType, sampling) { - } - /*! Returns the string "ViewMapGradientNormBP1D"*/ - string getName() const { - return "ViewMapGradientNormBP1D"; - } - /*! The () operator. */ - int operator()(Interface1D& i1, Interface1D& i2) { - if (_func(i1) < 0) - return -1; - real n1 = _func.result; - if (_func(i2) < 0) - return -1; - real n2 = _func.result; - result = (n1 > n2); - return 0; - } - }; + result = (edge->getChainingTimeStamp() >= _timeStamp); + return 0; + } +}; + +// ShapeUP1D +/*! Returns true if the shape to which the Interface1D belongs to has the same Id as the one specified by the user. */ +class ShapeUP1D: public UnaryPredicate1D +{ +private: + Id _id; + +public: + /*! Builds the Predicate. + * \param idFirst + * The first Id component. + * \param idSecond + * The second Id component. + */ + ShapeUP1D(unsigned idFirst, unsigned idSecond = 0) : UnaryPredicate1D() + { + _id = Id(idFirst, idSecond); + } + + /*! Returns the string "ShapeUP1D"*/ + string getName() const + { + return "ShapeUP1D"; + } + + /*! The () operator. */ + int operator()(Interface1D& inter) + { + set shapes; + Functions1D::getShapeF1D(inter, shapes); + for (set::iterator s = shapes.begin(), send = shapes.end(); s != send; ++s) { + if ((*s)->getId() == _id) { + result = true; + return 0; + } + } + result = false; + return 0; + } +}; + +// WithinImageBoundaryUP1D +/*! Returns true if the Interface1D is (partly) within the image boundary. */ +class WithinImageBoundaryUP1D: public UnaryPredicate1D +{ +private: + real _xmin, _ymin, _xmax, _ymax; + +public: + /*! Builds the Predicate. + * \param xmin + * The X lower bound of the image boundary. + * \param ymin + * The Y lower bound of the image boundary. + * \param xmax + * The X upper bound of the image boundary. + * \param ymax + * The Y upper bound of the image boundary. + */ + WithinImageBoundaryUP1D(const real xmin, const real ymin, const real xmax, const real ymax) + : _xmin(xmin), _ymin(ymin), _xmax(xmax), _ymax(ymax) + { + } + + /*! Returns the string "WithinImageBoundaryUP1D" */ + string getName() const + { + return "WithinImageBoundaryUP1D"; + } + + /*! The () operator. */ + int operator()(Interface1D& inter) + { + // 1st pass: check if a point is within the image boundary. + Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd(); + for (; it != itend; ++it) { + real x = (*it).getProjectedX(); + real y = (*it).getProjectedY(); + if (_xmin <= x && x <= _xmax && _ymin <= y && y <= _ymax) { + result = true; + return 0; + } + } + // 2nd pass: check if a line segment intersects with the image boundary. + it = inter.verticesBegin(); + if (it != itend) { + Vec2r pmin(_xmin, _ymin); + Vec2r pmax(_xmax, _ymax); + Vec2r prev((*it).getPoint2D()); + ++it; + for (; it != itend; ++it) { + Vec2r p((*it).getPoint2D()); + if (GeomUtils::intersect2dSeg2dArea (pmin, pmax, prev, p)) { + result = true; + return 0; + } + prev = p; + } + } + result = false; + return 0; + } +}; + +// +// Binary Predicates definitions +// +/////////////////////////////////////////////////////////// + +// TrueBP1D +/*! Returns true. */ +class TrueBP1D : public BinaryPredicate1D +{ +public: + /*! Returns the string "TrueBP1D" */ + string getName() const + { + return "TrueBP1D"; + } + + /*! The () operator. */ + int operator()(Interface1D& i1, Interface1D& i2) + { + result = true; + return 0; + } +}; + +// FalseBP1D +/*! Returns false. */ +class FalseBP1D : public BinaryPredicate1D +{ +public: + /*! Returns the string "FalseBP1D" */ + string getName() const + { + return "FalseBP1D"; + } + + /*! The () operator. */ + int operator()(Interface1D& i1, Interface1D& i2) + { + result = false; + return 0; + } +}; + +// Length2DBP1D +/*! Returns true if the 2D length of the Interface1D i1 is less than the 2D length of the Interface1D i2. */ +class Length2DBP1D : public BinaryPredicate1D +{ +public: + /*! Returns the string "Length2DBP1D" */ + string getName() const + { + return "Length2DBP1D"; + } + + /*! The () operator. */ + int operator()(Interface1D& i1, Interface1D& i2) + { + result = (i1.getLength2D() > i2.getLength2D()); + return 0; + } +}; + +// SameShapeIdBP1D +/*! Returns true if the Interface1D i1 and i2 belong to the same shape. */ +class SameShapeIdBP1D : public BinaryPredicate1D +{ +public: + /*! Returns the string "SameShapeIdBP1D" */ + string getName() const + { + return "SameShapeIdBP1D"; + } + + /*! The () operator. */ + int operator()(Interface1D& i1, Interface1D& i2) + { + set shapes1; + Functions1D::getShapeF1D(i1, shapes1); + set shapes2; + Functions1D::getShapeF1D(i2, shapes2); + // FIXME:// n2 algo, can do better... + for (set::iterator s = shapes1.begin(), send = shapes1.end(); s != send; ++s) { + Id current = (*s)->getId(); + for (set::iterator s2 = shapes2.begin(), s2end = shapes2.end(); s2 != s2end; ++s2) { + if ((*s2)->getId() == current) { + result = true; + return 0; + } + } + } + result = false; + return 0; + } +}; + +// ViewMapGradientNormBP1D +/*! Returns true if the evaluation of the Gradient norm Function is higher for Interface1D i1 than for i2. */ +class ViewMapGradientNormBP1D : public BinaryPredicate1D +{ +private: + Functions1D::GetViewMapGradientNormF1D _func; + +public: + ViewMapGradientNormBP1D(int level, IntegrationType iType = MEAN, float sampling = 2.0) + : BinaryPredicate1D(), _func(level, iType, sampling) + { + } + + /*! Returns the string "ViewMapGradientNormBP1D" */ + string getName() const + { + return "ViewMapGradientNormBP1D"; + } + + /*! The () operator. */ + int operator()(Interface1D& i1, Interface1D& i2) + { + if (_func(i1) < 0) + return -1; + real n1 = _func.result; + if (_func(i2) < 0) + return -1; + real n2 = _func.result; + result = (n1 > n2); + return 0; + } +}; + } // end of namespace Predicates1D -#endif // PREDICATES1D_H +#endif // __FREESTYLE_PREDICATES_1D_H__ diff --git a/source/blender/freestyle/intern/stroke/QInformationMap.h b/source/blender/freestyle/intern/stroke/QInformationMap.h index ef068f15061..38a126d0f66 100644 --- a/source/blender/freestyle/intern/stroke/QInformationMap.h +++ b/source/blender/freestyle/intern/stroke/QInformationMap.h @@ -1,58 +1,73 @@ -// -// Filename : QInformationMap.h -// Author : Stephane Grabli -// Purpose : Class defining an information map using a QImage -// Date of creation : 04/01/2003 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef QINFORMATIONMAP_H -# define QINFORMATIONMAP_H - -# include -# include "InformationMap.h" +/* + * ***** 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_Q_INFORMATION_MAP_H__ +#define __FREESTYLE_Q_INFORMATION_MAP_H__ + +/** \file blender/freestyle/intern/stroke/QInformationMap.h + * \ingroup freestyle + * \brief Class defining an information map using a QImage + * \author Stephane Grabli + * \date 04/01/2003 + */ + +#include + +#include "InformationMap.h" class QInformationMap : public InformationMap { private: - QImage _map; // the image or a piece of image + QImage _map; // the image or a piece of image public: - QInformationMap(); - QInformationMap(const QImage&); - QInformationMap(const QInformationMap&); - QInformationMap& operator=(const QInformationMap&); + QInformationMap(); + QInformationMap(const QImage&); + QInformationMap(const QInformationMap&); + QInformationMap& operator=(const QInformationMap&); + + //float getSmoothedPixel(int x, int y, float sigma = 0.2f);1 + virtual float getMean(int x, int y); + virtual void retrieveMeanAndVariance(int x, int y, float &oMean, float &oVariance); - //float getSmoothedPixel(int x, int y, float sigma = 0.2f) - virtual float getMean(int x, int y) ; - virtual void retrieveMeanAndVariance(int x, int y, float &oMean, float &oVariance) ; + inline const QImage& map() const + { + return _map; + } - inline const QImage& map() const {return _map;} - inline void setMap(const QImage& iMap, float iw, float ih) {_map = iMap.copy();_w=iw;_h=ih;} + inline void setMap(const QImage& iMap, float iw, float ih) + { + _map = iMap.copy(); + _w = iw; + _h = ih; + } protected: - virtual float computeGaussian(int x, int y); + virtual float computeGaussian(int x, int y); }; -#endif // QINFORMATIONMAP_H +#endif // __FREESTYLE_Q_INFORMATION_MAP_H__ diff --git a/source/blender/freestyle/intern/stroke/Stroke.cpp b/source/blender/freestyle/intern/stroke/Stroke.cpp index b42e673b4be..477092f2e7a 100644 --- a/source/blender/freestyle/intern/stroke/Stroke.cpp +++ b/source/blender/freestyle/intern/stroke/Stroke.cpp @@ -1,947 +1,940 @@ - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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 ***** + */ + +/** \file blender/freestyle/intern/stroke/Stroke.cpp + * \ingroup freestyle + * \brief Classes to define a stroke + * \author Stephane Grabli + * \date 09/09/2002 + */ #include "Stroke.h" -#include "StrokeRenderer.h" -#include "StrokeIterators.h" #include "StrokeAdvancedIterators.h" +#include "StrokeIterators.h" +#include "StrokeRenderer.h" - /**********************************/ - /* */ - /* */ - /* StrokeAttribute */ - /* */ - /* */ - /**********************************/ +/**********************************/ +/* */ +/* */ +/* StrokeAttribute */ +/* */ +/* */ +/**********************************/ StrokeAttribute::StrokeAttribute() { - int i; - _alpha = 1.f; - _thickness[0] = 1.f; - _thickness[1] = 1.f; - for(i=0; i<3; ++i) - _color[i] = 0.2f; - _color[0]=0.8; - _userAttributesReal = 0; - _userAttributesVec2f = 0; - _userAttributesVec3f = 0; - _visible = true; + int i; + _alpha = 1.0f; + _thickness[0] = 1.0f; + _thickness[1] = 1.0f; + for (i = 0; i < 3; ++i) + _color[i] = 0.2f; + _color[0] = 0.8f; + _userAttributesReal = NULL; + _userAttributesVec2f = NULL; + _userAttributesVec3f = NULL; + _visible = true; } + StrokeAttribute::StrokeAttribute(const StrokeAttribute& iBrother) { - _alpha = iBrother._alpha; - _thickness[0] = iBrother._thickness[0]; - _thickness[1] = iBrother._thickness[1]; - for(int i=0; i<3; ++i) - _color[i] = iBrother._color[i]; - _visible = iBrother._visible; - if(iBrother._userAttributesReal) - _userAttributesReal = new realMap(*iBrother._userAttributesReal); - else - _userAttributesReal = 0; - if(iBrother._userAttributesVec2f) - _userAttributesVec2f = new Vec2fMap(*iBrother._userAttributesVec2f); - else - _userAttributesVec2f = 0; - if(iBrother._userAttributesVec3f) - _userAttributesVec3f = new Vec3fMap(*iBrother._userAttributesVec3f); - else - _userAttributesVec3f = 0; -} -StrokeAttribute::StrokeAttribute( float iRColor, float iGColor, float iBColor, - float iAlpha, - float iRThickness, float iLThickness) -{ - _color[0] = iRColor; - _color[1] = iGColor; - _color[2] = iBColor; - - _alpha = iAlpha; - - _thickness[0] = iRThickness; - _thickness[1] = iLThickness; - - _visible = true; - - _userAttributesReal = 0; - _userAttributesVec2f = 0; - _userAttributesVec3f = 0; + _alpha = iBrother._alpha; + _thickness[0] = iBrother._thickness[0]; + _thickness[1] = iBrother._thickness[1]; + for (int i = 0; i < 3; ++i) + _color[i] = iBrother._color[i]; + _visible = iBrother._visible; + if (iBrother._userAttributesReal) + _userAttributesReal = new realMap(*iBrother._userAttributesReal); + else + _userAttributesReal = NULL; + if (iBrother._userAttributesVec2f) + _userAttributesVec2f = new Vec2fMap(*iBrother._userAttributesVec2f); + else + _userAttributesVec2f = NULL; + if (iBrother._userAttributesVec3f) + _userAttributesVec3f = new Vec3fMap(*iBrother._userAttributesVec3f); + else + _userAttributesVec3f = NULL; +} + +StrokeAttribute::StrokeAttribute(float iRColor, float iGColor, float iBColor, float iAlpha, + float iRThickness, float iLThickness) +{ + _color[0] = iRColor; + _color[1] = iGColor; + _color[2] = iBColor; + + _alpha = iAlpha; + + _thickness[0] = iRThickness; + _thickness[1] = iLThickness; + + _visible = true; + + _userAttributesReal = NULL; + _userAttributesVec2f = NULL; + _userAttributesVec3f = NULL; } -StrokeAttribute::StrokeAttribute(const StrokeAttribute& a1, const StrokeAttribute& a2, float t) +StrokeAttribute::StrokeAttribute(const StrokeAttribute& a1, const StrokeAttribute& a2, float t) { - - _alpha = (1-t)*a1._alpha + t*a2._alpha; - _thickness[0] = (1-t)*a1._thickness[0] + t*a2._thickness[0]; - _thickness[1] = (1-t)*a1._thickness[1] + t*a2._thickness[1]; - for(int i=0; i<3; ++i) - _color[i] = (1-t)*a1._color[i] + t*a2._color[i]; - - _visible = true; - - // FIXME: a verifier (et a ameliorer) - if((a1._userAttributesReal) && (a2._userAttributesReal)){ - if(a1._userAttributesReal->size() == a2._userAttributesReal->size()){ - _userAttributesReal = new realMap; - realMap::iterator it1=a1._userAttributesReal->begin(), it1end=a1._userAttributesReal->end(); - realMap::iterator it2=a2._userAttributesReal->begin(), it2end=a2._userAttributesReal->end(); - for(; (it1!=it1end); ++it1){ - (*_userAttributesReal)[(*it1).first] = ((1-t)*(*it1).second+t*(*it2).second); - } - } - }else{ - _userAttributesReal = 0; - } - if((a1._userAttributesVec2f) && (a2._userAttributesVec2f)){ - if(a1._userAttributesVec2f->size() == a2._userAttributesVec2f->size()){ - _userAttributesVec2f = new Vec2fMap; - Vec2fMap::iterator it1=a1._userAttributesVec2f->begin(), it1end=a1._userAttributesVec2f->end(); - Vec2fMap::iterator it2=a2._userAttributesVec2f->begin(), it2end=a2._userAttributesVec2f->end(); - for(; (it1!=it1end); ++it1){ - (*_userAttributesVec2f)[(*it1).first] = ((1-t)*(*it1).second+t*(*it2).second); - } - } - }else{ - _userAttributesVec2f = 0; - } - if((a1._userAttributesVec3f) && (a2._userAttributesVec3f)){ - if(a1._userAttributesVec3f->size() == a2._userAttributesVec3f->size()){ - _userAttributesVec3f = new Vec3fMap; - Vec3fMap::iterator it1=a1._userAttributesVec3f->begin(), it1end=a1._userAttributesVec3f->end(); - Vec3fMap::iterator it2=a2._userAttributesVec3f->begin(), it2end=a2._userAttributesVec3f->end(); - for(; (it1!=it1end); ++it1){ - (*_userAttributesVec3f)[(*it1).first] = ((1-t)*(*it1).second+t*(*it2).second); - } - } - }else{ - _userAttributesVec3f = 0; - } + _alpha = (1 - t) * a1._alpha + t * a2._alpha; + _thickness[0] = (1 - t) * a1._thickness[0] + t * a2._thickness[0]; + _thickness[1] = (1 - t) * a1._thickness[1] + t * a2._thickness[1]; + for (int i = 0; i < 3; ++i) + _color[i] = (1 - t) * a1._color[i] + t * a2._color[i]; + + _visible = true; + + // FIXME: to be checked (and enhanced) + if ((a1._userAttributesReal) && (a2._userAttributesReal)) { + if (a1._userAttributesReal->size() == a2._userAttributesReal->size()) { + _userAttributesReal = new realMap; + realMap::iterator it1 = a1._userAttributesReal->begin(), it1end = a1._userAttributesReal->end(); + realMap::iterator it2 = a2._userAttributesReal->begin(), it2end = a2._userAttributesReal->end(); + for (; it1 != it1end; ++it1) { + (*_userAttributesReal)[(*it1).first] = ((1 - t) * (*it1).second + t * (*it2).second); + } + } + } + else { + _userAttributesReal = NULL; + } + if ((a1._userAttributesVec2f) && (a2._userAttributesVec2f)) { + if (a1._userAttributesVec2f->size() == a2._userAttributesVec2f->size()) { + _userAttributesVec2f = new Vec2fMap; + Vec2fMap::iterator it1 = a1._userAttributesVec2f->begin(), it1end = a1._userAttributesVec2f->end(); + Vec2fMap::iterator it2 = a2._userAttributesVec2f->begin(), it2end = a2._userAttributesVec2f->end(); + for (; it1 != it1end; ++it1) { + (*_userAttributesVec2f)[(*it1).first] = ((1 - t) * (*it1).second + t * (*it2).second); + } + } + } + else { + _userAttributesVec2f = NULL; + } + if ((a1._userAttributesVec3f) && (a2._userAttributesVec3f)) { + if (a1._userAttributesVec3f->size() == a2._userAttributesVec3f->size()) { + _userAttributesVec3f = new Vec3fMap; + Vec3fMap::iterator it1 = a1._userAttributesVec3f->begin(), it1end = a1._userAttributesVec3f->end(); + Vec3fMap::iterator it2 = a2._userAttributesVec3f->begin(), it2end = a2._userAttributesVec3f->end(); + for (; it1 != it1end; ++it1) { + (*_userAttributesVec3f)[(*it1).first] = ((1 - t) * (*it1).second + t * (*it2).second); + } + } + } + else { + _userAttributesVec3f = NULL; + } } StrokeAttribute::~StrokeAttribute() { - if(_userAttributesReal){ - _userAttributesReal->clear(); - delete _userAttributesReal; - } - if(_userAttributesVec2f){ - _userAttributesVec2f->clear(); - delete _userAttributesVec2f; - } - if(_userAttributesVec3f){ - _userAttributesVec3f->clear(); - delete _userAttributesVec3f; - } + if (_userAttributesReal) { + _userAttributesReal->clear(); + delete _userAttributesReal; + } + if (_userAttributesVec2f) { + _userAttributesVec2f->clear(); + delete _userAttributesVec2f; + } + if (_userAttributesVec3f) { + _userAttributesVec3f->clear(); + delete _userAttributesVec3f; + } } StrokeAttribute& StrokeAttribute::operator=(const StrokeAttribute& iBrother) -{ - int i; - _alpha = iBrother._alpha; - _thickness[0] = iBrother._thickness[0]; - _thickness[1] = iBrother._thickness[1]; - for(i=0; i<3; ++i) - _color[i] = iBrother._color[i]; - _visible = iBrother._visible; - if(iBrother._userAttributesReal){ - if(!_userAttributesReal) - _userAttributesReal = new realMap; - _userAttributesReal = new realMap(*(iBrother._userAttributesReal)); - }else{ - _userAttributesReal = 0; - } - if(iBrother._userAttributesVec2f){ - if(!_userAttributesVec2f) - _userAttributesVec2f = new Vec2fMap; - _userAttributesVec2f = new Vec2fMap(*(iBrother._userAttributesVec2f)); - }else{ - _userAttributesVec2f = 0; - } - if(iBrother._userAttributesVec3f){ - if(!_userAttributesVec3f) - _userAttributesVec3f = new Vec3fMap; - _userAttributesVec3f = new Vec3fMap(*(iBrother._userAttributesVec3f)); - }else{ - _userAttributesVec3f = 0; - } - return *this; -} - -float StrokeAttribute::getAttributeReal(const char *iName) const{ - if(!_userAttributesReal){ - cout << "StrokeAttribute warning: no real attribute was defined"<< endl; - return 0; - } - realMap::iterator a = _userAttributesReal->find(iName); - if(a ==_userAttributesReal->end()){ - cout << "StrokeAttribute warning: no real attribute was added with the name " << iName << endl; - return 0; - } - return (*a).second; -} -Vec2f StrokeAttribute::getAttributeVec2f(const char *iName) const{ - if(!_userAttributesVec2f){ - cout << "StrokeAttribute warning: no Vec2f attribute was defined "<< endl; - return 0; - } - Vec2fMap::iterator a = _userAttributesVec2f->find(iName); - if(a ==_userAttributesVec2f->end()){ - cout << "StrokeAttribute warning: no Vec2f attribute was added with the name " << iName << endl; - return 0; - } - return (*a).second; -} -Vec3f StrokeAttribute::getAttributeVec3f(const char *iName) const{ - if(!_userAttributesVec3f){ - cout << "StrokeAttribute warning: no Vec3f attribute was defined"<< endl; - return 0; - } - Vec3fMap::iterator a = _userAttributesVec3f->find(iName); - if(a ==_userAttributesVec3f->end()){ - cout << "StrokeAttribute warning: no Vec3f attribute was added with the name " << iName << endl; - return 0; - } - return (*a).second; -} -bool StrokeAttribute::isAttributeAvailableReal(const char *iName) const{ - if(!_userAttributesReal){ - return false; - } - realMap::iterator a = _userAttributesReal->find(iName); - if(a ==_userAttributesReal->end()){ - return false; - } - return true; -} -bool StrokeAttribute::isAttributeAvailableVec2f(const char *iName) const{ - if(!_userAttributesVec2f){ - return false; - } - Vec2fMap::iterator a = _userAttributesVec2f->find(iName); - if(a ==_userAttributesVec2f->end()){ - return false; - } - return true; -} -bool StrokeAttribute::isAttributeAvailableVec3f(const char *iName) const{ - if(!_userAttributesVec3f){ - return false; - } - Vec3fMap::iterator a = _userAttributesVec3f->find(iName); - if(a ==_userAttributesVec3f->end()){ - return false; - } - return true; -} -void StrokeAttribute::setAttributeReal(const char *iName, float att){ - if(!_userAttributesReal) - _userAttributesReal = new realMap; - (*_userAttributesReal)[iName] = att; -} -void StrokeAttribute::setAttributeVec2f(const char *iName, const Vec2f& att){ - if(!_userAttributesVec2f) - _userAttributesVec2f = new Vec2fMap; - (*_userAttributesVec2f)[iName] = att; +{ + int i; + _alpha = iBrother._alpha; + _thickness[0] = iBrother._thickness[0]; + _thickness[1] = iBrother._thickness[1]; + for (i = 0; i < 3; ++i) + _color[i] = iBrother._color[i]; + _visible = iBrother._visible; + if (iBrother._userAttributesReal) { + if (!_userAttributesReal) + _userAttributesReal = new realMap; + _userAttributesReal = new realMap(*(iBrother._userAttributesReal)); + } + else { + _userAttributesReal = NULL; + } + if (iBrother._userAttributesVec2f) { + if (!_userAttributesVec2f) + _userAttributesVec2f = new Vec2fMap; + _userAttributesVec2f = new Vec2fMap(*(iBrother._userAttributesVec2f)); + } + else { + _userAttributesVec2f = NULL; + } + if (iBrother._userAttributesVec3f) { + if (!_userAttributesVec3f) + _userAttributesVec3f = new Vec3fMap; + _userAttributesVec3f = new Vec3fMap(*(iBrother._userAttributesVec3f)); + } + else { + _userAttributesVec3f = NULL; + } + return *this; +} + +float StrokeAttribute::getAttributeReal(const char *iName) const +{ + if (!_userAttributesReal) { + cout << "StrokeAttribute warning: no real attribute was defined" << endl; + return 0.0f; + } + realMap::iterator a = _userAttributesReal->find(iName); + if (a == _userAttributesReal->end()) { + cout << "StrokeAttribute warning: no real attribute was added with the name " << iName << endl; + return 0.0f; + } + return (*a).second; +} + +Vec2f StrokeAttribute::getAttributeVec2f(const char *iName) const +{ + if (!_userAttributesVec2f) { + cout << "StrokeAttribute warning: no Vec2f attribute was defined" << endl; + return 0; + } + Vec2fMap::iterator a = _userAttributesVec2f->find(iName); + if (a == _userAttributesVec2f->end()) { + cout << "StrokeAttribute warning: no Vec2f attribute was added with the name " << iName << endl; + return 0; + } + return (*a).second; +} + +Vec3f StrokeAttribute::getAttributeVec3f(const char *iName) const +{ + if (!_userAttributesVec3f) { + cout << "StrokeAttribute warning: no Vec3f attribute was defined" << endl; + return 0; + } + Vec3fMap::iterator a = _userAttributesVec3f->find(iName); + if (a == _userAttributesVec3f->end()) { + cout << "StrokeAttribute warning: no Vec3f attribute was added with the name " << iName << endl; + return 0; + } + return (*a).second; +} + +bool StrokeAttribute::isAttributeAvailableReal(const char *iName) const +{ + if (!_userAttributesReal) { + return false; + } + realMap::iterator a = _userAttributesReal->find(iName); + if (a == _userAttributesReal->end()) { + return false; + } + return true; } -void StrokeAttribute::setAttributeVec3f(const char *iName, const Vec3f& att){ - if(!_userAttributesVec3f) - _userAttributesVec3f = new Vec3fMap; - (*_userAttributesVec3f)[iName] = att; + +bool StrokeAttribute::isAttributeAvailableVec2f(const char *iName) const +{ + if (!_userAttributesVec2f) { + return false; + } + Vec2fMap::iterator a = _userAttributesVec2f->find(iName); + if (a == _userAttributesVec2f->end()) { + return false; + } + return true; } - /**********************************/ - /* */ - /* */ - /* StrokeVertex */ - /* */ - /* */ - /**********************************/ -StrokeVertex::StrokeVertex() +bool StrokeAttribute::isAttributeAvailableVec3f(const char *iName) const +{ + if (!_userAttributesVec3f) { + return false; + } + Vec3fMap::iterator a = _userAttributesVec3f->find(iName); + if (a == _userAttributesVec3f->end()) { + return false; + } + return true; +} -:CurvePoint() +void StrokeAttribute::setAttributeReal(const char *iName, float att) { + if (!_userAttributesReal) + _userAttributesReal = new realMap; + (*_userAttributesReal)[iName] = att; +} - _CurvilignAbscissa = 0.f; +void StrokeAttribute::setAttributeVec2f(const char *iName, const Vec2f& att) +{ + if (!_userAttributesVec2f) + _userAttributesVec2f = new Vec2fMap; + (*_userAttributesVec2f)[iName] = att; +} - _StrokeLength = 0.f; +void StrokeAttribute::setAttributeVec3f(const char *iName, const Vec3f& att) +{ + if (!_userAttributesVec3f) + _userAttributesVec3f = new Vec3fMap; + (*_userAttributesVec3f)[iName] = att; } +/**********************************/ +/* */ +/* */ +/* StrokeVertex */ +/* */ +/* */ +/**********************************/ -StrokeVertex::StrokeVertex(const StrokeVertex& iBrother) +StrokeVertex::StrokeVertex() : CurvePoint() +{ + _CurvilignAbscissa = 0.0f; + _StrokeLength = 0.0f; +} -:CurvePoint(iBrother) +StrokeVertex::StrokeVertex(const StrokeVertex& iBrother) : CurvePoint(iBrother) { - _Attribute = iBrother._Attribute; + _Attribute = iBrother._Attribute; + _CurvilignAbscissa = 0.0f; + _StrokeLength = 0.0f; +} - _CurvilignAbscissa = 0.f; +StrokeVertex::StrokeVertex(SVertex *iSVertex) : CurvePoint(iSVertex, 0, 0.0f) +{ + _CurvilignAbscissa = 0.0f; + _StrokeLength = 0.0f; +} - _StrokeLength = 0.f; +StrokeVertex::StrokeVertex(CurvePoint *iPoint) : CurvePoint(*iPoint) +{ + _CurvilignAbscissa = 0.0f; + _StrokeLength = 0.0f; } -StrokeVertex::StrokeVertex(SVertex *iSVertex) -:CurvePoint(iSVertex,0,0.f) +StrokeVertex::StrokeVertex(StrokeVertex *iA, StrokeVertex *iB, float t3) : CurvePoint(iA, iB, t3) +{ + // interpolate attributes: + _Attribute = StrokeAttribute(iA->attribute(), iB->attribute(), t3); + _CurvilignAbscissa = (1 - t3) * iA->curvilinearAbscissa() + t3 * iB->curvilinearAbscissa(); + _StrokeLength = iA->strokeLength(); +} +StrokeVertex::StrokeVertex(SVertex *iSVertex, const StrokeAttribute& iAttribute) : CurvePoint(iSVertex, 0, 0.0f) { + _Attribute = iAttribute; + _CurvilignAbscissa = 0.0f; + _StrokeLength = 0.0f; +} - _CurvilignAbscissa = 0.f; +StrokeVertex::~StrokeVertex() {} - _StrokeLength = 0.f; +StrokeVertex& StrokeVertex::operator=(const StrokeVertex& iBrother) +{ + ((CurvePoint*)this)->operator=(iBrother); + _Attribute = iBrother._Attribute; -} + _CurvilignAbscissa = 0.0f; + _StrokeLength = 0.0f; + return *this; +} -StrokeVertex::StrokeVertex(CurvePoint *iPoint) -:CurvePoint(*iPoint) +/**********************************/ +/* */ +/* */ +/* Stroke */ +/* */ +/* */ +/**********************************/ +Stroke::Stroke() { + _Length = 0; + _id = 0; + _sampling = FLT_MAX; + //_mediumType = DEFAULT_STROKE; + _mediumType = OPAQUE_MEDIUM; + _textureId = 0; + _tips = false; + _rep = NULL; +} - _CurvilignAbscissa = 0.f; +Stroke::Stroke(const Stroke& iBrother) +{ + for (vertex_container::const_iterator v = iBrother._Vertices.begin(), vend = iBrother._Vertices.end(); + v != vend; + v++) + { + _Vertices.push_back(*v); + } + _Length = 0; + _id = iBrother._id; + _ViewEdges = iBrother._ViewEdges; + _sampling = iBrother._sampling; + _mediumType = iBrother._mediumType; + _textureId = iBrother._textureId; + _tips = iBrother._tips; + if (iBrother._rep) + _rep = new StrokeRep(*(iBrother._rep)); + else + _rep = NULL; +} - _StrokeLength = 0.f; +Stroke::~Stroke() +{ + if (!_Vertices.empty()) { + for (vertex_container::iterator v = _Vertices.begin(), vend = _Vertices.end(); v != vend; v++) { + delete (*v); + } + _Vertices.clear(); + } + _ViewEdges.clear(); + if (_rep) { + delete _rep; + _rep = NULL; + } } +Stroke& Stroke::operator=(const Stroke& iBrother) +{ + if (!_Vertices.empty()) + _Vertices.clear(); + + for (vertex_container::const_iterator v = iBrother._Vertices.begin(), vend = iBrother._Vertices.end(); + v != vend; + v++) + { + _Vertices.push_back(*v); + } + _Length = iBrother._Length; + _id = iBrother._id; + _ViewEdges = iBrother._ViewEdges; + _sampling = iBrother._sampling; + if (_rep) + delete _rep; + if (iBrother._rep) + _rep = new StrokeRep(*(iBrother._rep)); + return *this; +} +void Stroke::setLength(float iLength) +{ + _Length = iLength; + for (vertex_container::iterator v = _Vertices.begin(), vend = _Vertices.end(); v != vend; ++v) { + (*v)->setStrokeLength(iLength); + } +} -StrokeVertex::StrokeVertex(StrokeVertex *iA, StrokeVertex *iB, float t3) +float Stroke::ComputeSampling(int iNVertices) +{ + if (iNVertices <= (int)_Vertices.size()) //soc + return _sampling; -:CurvePoint(iA,iB,t3) + float sampling = _Length / (float)(iNVertices - _Vertices.size() + 1); + return sampling; +} +class StrokeSegment { +public: + StrokeInternal::StrokeVertexIterator _begin; + StrokeInternal::StrokeVertexIterator _end; + float _length; + int _n; + float _sampling; + bool _resampled; + + StrokeSegment(StrokeInternal::StrokeVertexIterator ibegin, StrokeInternal::StrokeVertexIterator iend, + float ilength, int in, float isampling) + { + _begin = ibegin; + _end = iend; + _length = ilength; + _n = in; + _sampling = isampling; + _resampled = false; + } +}; - // interpolate attributes: +void Stroke::Resample(int iNPoints) +{ + int vertsize = strokeVerticesSize(); + if (iNPoints <= vertsize) + return; + + StrokeInternal::StrokeVertexIterator it = strokeVerticesBegin(); + StrokeInternal::StrokeVertexIterator next = it; + ++next; + StrokeInternal::StrokeVertexIterator itend = strokeVerticesEnd(); + + vertex_container newVertices; + real t = 0.0f; + StrokeVertex *newVertex = NULL; + vector strokeSegments; + int N = 0; + float meanlength = 0; + int nsegments = 0; + while ((it != itend) && (next != itend)) { + Vec2r a((it)->getPoint()); + Vec2r b((next)->getPoint()); + Vec2r vec_tmp(b - a); + real norm_var = vec_tmp.norm(); + int numberOfPointsToAdd = (int)floor((iNPoints - strokeVerticesSize()) * norm_var / _Length); + float csampling = norm_var / (float)(numberOfPointsToAdd + 1); + strokeSegments.push_back(StrokeSegment(it, next, norm_var, numberOfPointsToAdd, csampling)); + N += numberOfPointsToAdd; + meanlength += norm_var; + ++nsegments; + ++it; + ++next; + } + meanlength /= (float)nsegments; + + // if we don't have enough points let's resample finer some segments + int NPointsToAdd = iNPoints - vertsize; + bool checkEveryone = false; + while (N < NPointsToAdd) { + for (vector::iterator s = strokeSegments.begin(), send = strokeSegments.end(); s != send; ++s) { + if (s->_sampling == 0.0f) + continue; + + if (s->_resampled == false) { + if ((!checkEveryone) && (s->_length < meanlength)) + continue; + //resample + s->_n = s->_n + 1; + s->_sampling = s->_length / (float)(s->_n + 1); + s->_resampled = true; + N++; + if (N == NPointsToAdd) + break; + } + } + checkEveryone = true; + } + //actually resample: + for (vector::iterator s = strokeSegments.begin(), send = strokeSegments.end(); s != send; ++s) { + newVertices.push_back(&(*(s->_begin))); + if (s->_sampling < _sampling) + _sampling = s->_sampling; + + t = s->_sampling / s->_length; + for (int i = 0; i < s->_n; ++i) { + newVertex = new StrokeVertex(&(*(s->_begin)), &(*(s->_end)), t); + newVertices.push_back(newVertex); + t += s->_sampling / s->_length; + } + it = s->_begin; + next = s->_end; + } + + // add last: + ++it; + ++next; + if ((it != itend) && (next == itend)/* && (t == 0.0f)*/) + newVertices.push_back(&(*it)); + + int newsize = newVertices.size(); + if (newsize != iNPoints) + cerr << "Warning: incorrect points number" << endl; + + _Vertices.clear(); + _Vertices = newVertices; + newVertices.clear(); + + if (_rep) { + delete _rep; + _rep = new StrokeRep(this); + } +} - _Attribute = StrokeAttribute(iA->attribute(), iB->attribute(), t3); - _CurvilignAbscissa = (1-t3)*iA->curvilinearAbscissa()+t3*iB->curvilinearAbscissa(); - _StrokeLength = iA->strokeLength(); +void Stroke::Resample(float iSampling) +{ + //cerr << "old size :" << strokeVerticesSize() << endl; + if (iSampling == 0) + return; + if (iSampling >= _sampling) + return; + + _sampling = iSampling; + // Resample... + //real curvilinearLength = 0.0f; + vertex_container newVertices; + real t = 0.0f; + StrokeVertex *newVertex = NULL; + StrokeInternal::StrokeVertexIterator it = strokeVerticesBegin(); + StrokeInternal::StrokeVertexIterator next = it; + ++next; + StrokeInternal::StrokeVertexIterator itend = strokeVerticesEnd(); + while ((it != itend) && (next != itend)) { + newVertices.push_back(&(*it)); + Vec3r a((it)->point2d()); + Vec3r b((next)->point2d()); + Vec3r vec_tmp(b - a); + real norm_var = vec_tmp.norm(); + if (norm_var <= _sampling) { + //curvilinearLength += norm_var; + ++it; + ++next; + continue; + } + + //curvilinearLength += _sampling; + t = _sampling / norm_var; + float limit = 0.99f; + while (t < limit) { + newVertex = new StrokeVertex(&(*it), &(*next), t); + //newVertex->setCurvilinearAbscissa(curvilinearLength); + newVertices.push_back(newVertex); + t = t + _sampling / norm_var; + } + ++it; + ++next; + } + // add last: + if ((it != itend) && (next == itend)/* && (t == 0.f)*/) + newVertices.push_back(&(*it)); + + _Vertices.clear(); + _Vertices = newVertices; + newVertices.clear(); + + if (_rep) { + delete _rep; + _rep = new StrokeRep(this); + } +} +void Stroke::RemoveVertex(StrokeVertex *iVertex) +{ + vertex_container::iterator it = _Vertices.begin(), itend = _Vertices.end(); + for (; it != itend; ++it) { + if ((*it) == iVertex) { + delete iVertex; + it = _Vertices.erase(it); // it is now the element just after the erased element + break; + } + } + UpdateLength(); } - +void Stroke::InsertVertex(StrokeVertex *iVertex, StrokeInternal::StrokeVertexIterator next) +{ + vertex_container::iterator it = _Vertices.begin(), itend = _Vertices.end(); -StrokeVertex::StrokeVertex(SVertex *iSVertex, const StrokeAttribute& iAttribute) + vertex_container::iterator itnext = next.getIt(); + _Vertices.insert(itnext, iVertex); + UpdateLength(); +} -:CurvePoint(iSVertex,0,0.f) +void Stroke::UpdateLength() +{ + // recompute various values (length, curvilign abscissa) + float curvabsc = 0.0f; + vertex_container::iterator it = _Vertices.begin(), itend = _Vertices.end(); + vertex_container::iterator previous = it; + for (; it != itend; ++it) { + curvabsc += ((*it)->point2d() - (*previous)->point2d()).norm(); + (*it)->setCurvilinearAbscissa(curvabsc); + previous = it; + } + _Length = curvabsc; + for (; it != itend; ++it) { + (*it)->setStrokeLength(_Length); + } +} +//! embedding vertex iterator +Stroke::const_vertex_iterator Stroke::vertices_begin() const { + return const_vertex_iterator(_Vertices.begin(), _Vertices.begin(), _Vertices.end()); +} - _Attribute = iAttribute; +Stroke::const_vertex_iterator Stroke::vertices_end() const +{ + return const_vertex_iterator(_Vertices.end(), _Vertices.begin(), _Vertices.end()); +} - _CurvilignAbscissa = 0.f; +Stroke::vertex_iterator Stroke::vertices_end() +{ + return vertex_iterator(_Vertices.end(), _Vertices.begin(), _Vertices.end()); +} - _StrokeLength = 0.f; +StrokeInternal::StrokeVertexIterator Stroke::strokeVerticesBegin(float t) +{ + if ((t != 0) && (t < _sampling)) + Resample(t); + return StrokeInternal::StrokeVertexIterator(this->_Vertices.begin(), this->_Vertices.begin(), + this->_Vertices.end()); +} +StrokeInternal::StrokeVertexIterator Stroke::strokeVerticesEnd() +{ + return StrokeInternal::StrokeVertexIterator(this->_Vertices.end(), this->_Vertices.begin(), this->_Vertices.end()); } -StrokeVertex::~StrokeVertex() + +Interface0DIterator Stroke::verticesBegin() { +Interface0DIterator ret(new StrokeInternal::StrokeVertexIterator(this->_Vertices.begin(), this->_Vertices.begin(), + this->_Vertices.end())); +return ret; } -StrokeVertex& StrokeVertex::operator=(const StrokeVertex& iBrother) -{ - ((CurvePoint*)this)->operator=(iBrother); - _Attribute = iBrother._Attribute; +Interface0DIterator Stroke::verticesEnd() +{ + Interface0DIterator ret(new StrokeInternal::StrokeVertexIterator(this->_Vertices.end(), this->_Vertices.begin(), + this->_Vertices.end())); + return ret; +} - _CurvilignAbscissa = 0.f; +Interface0DIterator Stroke::pointsBegin(float t) +{ + return verticesBegin(); // FIXME +} - _StrokeLength = 0.f; - return *this; +Interface0DIterator Stroke::pointsEnd(float t) +{ + return verticesEnd(); } - /**********************************/ - /* */ - /* */ - /* Stroke */ - /* */ - /* */ - /**********************************/ +void Stroke::ScaleThickness(float iFactor) +{ + for (vertex_container::iterator it = _Vertices.begin(), itend = _Vertices.end(); it != itend; ++it) { + StrokeAttribute& attr = (*it)->attribute(); + attr.setThickness(iFactor * attr.getThicknessR(), iFactor * attr.getThicknessL()); + } +} -Stroke::Stroke() +void Stroke::Render(const StrokeRenderer *iRenderer) { - _Length = 0; - _id = 0; - _sampling = FLT_MAX; - //_mediumType = DEFAULT_STROKE; - _mediumType = OPAQUE_MEDIUM; - _textureId = 0; - _tips = false; - _rep = 0; + if (!_rep) + _rep = new StrokeRep(this); + iRenderer->RenderStrokeRep(_rep); } -Stroke::Stroke(const Stroke& iBrother) +void Stroke::RenderBasic(const StrokeRenderer *iRenderer) { - for(vertex_container::const_iterator v=iBrother._Vertices.begin(), vend=iBrother._Vertices.end(); - v!=vend; - v++) - { - _Vertices.push_back(*v); - } - _Length = 0; - _id = iBrother._id; - _ViewEdges = iBrother._ViewEdges; - _sampling = iBrother._sampling; - _mediumType = iBrother._mediumType; - _textureId = iBrother._textureId; - _tips = iBrother._tips; - if(iBrother._rep) - _rep = new StrokeRep(*(iBrother._rep)); - else - _rep = 0; + if (!_rep) + _rep = new StrokeRep(this); + iRenderer->RenderStrokeRepBasic(_rep); +} +Stroke::vertex_iterator Stroke::vertices_begin(float sampling) +{ + // Resample if necessary + if ((sampling != 0) && (sampling < _sampling)) + Resample(sampling); + return vertex_iterator(_Vertices.begin(), _Vertices.begin(), _Vertices.end()); + //return _Vertices.begin(); } -Stroke::~Stroke() +#if 0 +Stroke::vertex_iterator Stroke::vertices_last() { - if(!_Vertices.empty()) - { - for(vertex_container::iterator v=_Vertices.begin(), vend=_Vertices.end(); - v!=vend; - v++) - { - delete (*v); - } - _Vertices.clear(); - } - - _ViewEdges.clear(); - if(_rep != 0) - { - delete _rep; - _rep = 0; - } + vertex_iterator res = vertices_begin(); + vertex_iterator next = res; + ++next; + while (!next.end()) { + ++next; + ++res; + } + return res; } -Stroke& Stroke::operator=(const Stroke& iBrother) -{ - if(!_Vertices.empty()) - _Vertices.clear(); - - for(vertex_container::const_iterator v=iBrother._Vertices.begin(), vend=iBrother._Vertices.end(); - v!=vend; - v++) - { - _Vertices.push_back(*v); - } - _Length = iBrother._Length; - _id = iBrother._id; - _ViewEdges = iBrother._ViewEdges; - _sampling = iBrother._sampling; - if(_rep) delete _rep; - if(iBrother._rep) - _rep = new StrokeRep(*(iBrother._rep)); - return *this; +Stroke::const_vertex_iterator Stroke::vertices_last() const +{ + const_vertex_iterator res = vertices_begin(); + const_vertex_iterator next = res; + ++next; + while (!next.end()) { + ++next; + ++res; + } + return res; } +Stroke::vertex_container::reverse_iterator Stroke::vertices_last(float sampling) +{ + // Resample if necessary + if (sampling < _sampling) + Resample(sampling); + return _Vertices.rbegin(); +} -void Stroke::setLength(float iLength) + +inline Vec3r shaded_color(int iCombination = 0) const; + +inline Vec<3, real> Stroke::orientation2d(const_vertex_iterator it) const { - _Length = iLength; - for(vertex_container::iterator v=_Vertices.begin(), vend=_Vertices.end(); - v!=vend; - ++v) - { - (*v)->setStrokeLength(iLength); - } + return iterator_edge_orientation2d_function(this, it); } -float Stroke::ComputeSampling(int iNVertices) +Vec3r Stroke::orientation2d(int iCombination) const { - if(iNVertices <= (int)_Vertices.size()) //soc - return _sampling; + return edge_orientation2d_function(*this, iCombination); +} - float sampling = _Length/(float)(iNVertices-_Vertices.size()+1); - return sampling; +inline Vec3r Stroke::orientation3d(const_vertex_iterator it) const +{ + return iterator_edge_orientation3d_function(*this, it); } -class StrokeSegment +Vec3r Stroke::orientation3d(int iCombination) const { -public: - StrokeInternal::StrokeVertexIterator _begin; - StrokeInternal::StrokeVertexIterator _end; - float _length; - int _n; - float _sampling; - bool _resampled; - - StrokeSegment(StrokeInternal::StrokeVertexIterator ibegin, - StrokeInternal::StrokeVertexIterator iend, - float ilength, - int in, - float isampling) - { - _begin=ibegin; - _end=iend; - _length=ilength; - _n=in; - _sampling = isampling; - _resampled = false; - } -}; + return edge_orientation3d_function(*this, iCombination); +} -void Stroke::Resample(int iNPoints) +Material Stroke::material() const { - int vertsize = strokeVerticesSize(); - if(iNPoints <= vertsize) - return; - - StrokeInternal::StrokeVertexIterator it = strokeVerticesBegin(); - StrokeInternal::StrokeVertexIterator next = it;++next; - StrokeInternal::StrokeVertexIterator itend = strokeVerticesEnd(); - - vertex_container newVertices; - real t=0.f; - StrokeVertex * newVertex = 0; - vector strokeSegments; - int N=0; - float meanlength = 0; - int nsegments = 0; - while(((it!=itend)&&(next!=itend))) - { - Vec2r a((it)->getPoint()); - Vec2r b((next)->getPoint()); - Vec2r vec_tmp(b - a); - real norm_var = vec_tmp.norm(); - int numberOfPointsToAdd = (int)floor((iNPoints-strokeVerticesSize())*norm_var/_Length); - float csampling = norm_var/(float)(numberOfPointsToAdd+1); - strokeSegments.push_back(StrokeSegment(it,next,norm_var,numberOfPointsToAdd, csampling)); - N+=numberOfPointsToAdd; - meanlength += norm_var; - ++nsegments; - ++it; ++next; - } - meanlength /= (float)nsegments; - - // if we don't have enough points let's resample - // finer some segments - int NPointsToAdd = iNPoints-vertsize; - bool checkEveryone = false; - while(N < NPointsToAdd) - { - for(vector::iterator s=strokeSegments.begin(), send=strokeSegments.end(); - s!=send; - ++s) - { - if(s->_sampling == 0.f) - continue; - - if(s->_resampled == false) - { - if((!checkEveryone) && (s->_length < meanlength)) - continue; - //resample - s->_n = s->_n+1; - s->_sampling = s->_length/(float)(s->_n+1); - s->_resampled = true; - N++; - if(N == NPointsToAdd) - break; - } - } - checkEveryone = true; - } - //actually resample: - for(vector::iterator s=strokeSegments.begin(), send=strokeSegments.end(); - s!=send; - ++s) - { - newVertices.push_back(&(*(s->_begin))); - if(s->_sampling < _sampling) - _sampling = s->_sampling; - - t = s->_sampling/s->_length; - for(int i=0; i_n; ++i) - { - newVertex = new StrokeVertex(&(*(s->_begin)),&(*(s->_end)),t); - newVertices.push_back(newVertex); - t += s->_sampling/s->_length; - } - it=s->_begin; - next=s->_end; - } - - // add last: - ++it;++next; - if((it != itend) && (next == itend))// && (t == 0.f)) - newVertices.push_back(&(*it)); - - int newsize = newVertices.size(); - if(newsize != iNPoints) - cerr << "Warning: incorrect points number" << endl; - - _Vertices.clear(); - _Vertices = newVertices; - newVertices.clear(); - - if(_rep) - { - delete _rep; - _rep = new StrokeRep(this); - } + const_vertex_iterator v = vertices_begin(), vend = strokeVerticesEnd(); + Material mat = (*v)->material(); + for (; v != vend; ++v) { + if (mat != (*v)->material()) + Exception::raiseException(); + } + return mat; } +int Stroke::qi() const +{ + const_vertex_iterator v = vertices_begin(), vend = vertices_end(); + int qi_= (*v)->qi(); + for (; v != vend; ++v) { + if ((*v)->qi() != qi_) + Exception::raiseException(); + } + return qi_; +} -void Stroke::Resample(float iSampling) +inline occluder_container::const_iterator occluders_begin() const { - // cerr<<"old size :"<= _sampling) - return ; - - _sampling = iSampling; - // Resample... - //real curvilinearLength = 0.f; - vertex_container newVertices; - real t=0.f; - StrokeVertex * newVertex = 0; - StrokeInternal::StrokeVertexIterator it = strokeVerticesBegin(); - StrokeInternal::StrokeVertexIterator next = it;++next; - StrokeInternal::StrokeVertexIterator itend = strokeVerticesEnd(); - while(((it!=itend)&&(next!=itend))) - { - newVertices.push_back(&(*it)); - Vec3r a((it)->point2d()); - Vec3r b((next)->point2d()); - Vec3r vec_tmp(b - a); - real norm_var = vec_tmp.norm(); - if(norm_var <= _sampling) - { - //curvilinearLength += norm_var; - ++it; ++next; - continue; - } - - //curvilinearLength += _sampling; - t = _sampling/norm_var; - float limit = 0.99f; - while(tsetCurvilinearAbscissa(curvilinearLength); - newVertices.push_back(newVertex); - t = t + _sampling/norm_var; - } - ++it; ++next; - } - // add last: - if((it != itend) && (next == itend))// && (t == 0.f)) - newVertices.push_back(&(*it)); - - _Vertices.clear(); - _Vertices = newVertices; - newVertices.clear(); - - if(_rep) - { - delete _rep; - _rep = new StrokeRep(this); - } + return _FEdgeA->occluders().begin(); } -void Stroke::RemoveVertex(StrokeVertex *iVertex) +inline occluder_container::const_iterator occluders_end() const { - vertex_container::iterator it=_Vertices.begin(), itend=_Vertices.end(); - for(; - it!=itend; - ++it) - { - if((*it) == iVertex) - { - delete iVertex; - it = _Vertices.erase(it); // it is now the element just after the erased element - break; - } - } - UpdateLength(); + return _FEdgeA->occluders().end(); } -void Stroke::InsertVertex(StrokeVertex *iVertex, StrokeInternal::StrokeVertexIterator next) +int Stroke::occluders_size() const { - vertex_container::iterator it=_Vertices.begin(), itend=_Vertices.end(); + return qi(); +} - vertex_container::iterator itnext = next.getIt(); - _Vertices.insert(itnext, iVertex); - UpdateLength(); +bool Stroke::occluders_empty() const +{ + const_vertex_iterator v = vertices_begin(), vend = vertices_end(); + bool empty = (*v)->occluders_empty(); + for (; v != vend; ++v) { + if ((*v)->occluders_empty() != empty) + Exception::raiseException(); + } + return empty; } -void Stroke::UpdateLength() +#if 0 +inline const polygon3d& occludee() const { - // recompute various values (length, curvilign abscissa) - float curvabsc = 0.f; - vertex_container::iterator it=_Vertices.begin(), itend=_Vertices.end(); - vertex_container::iterator previous=it; - for(; - (it!=itend); - ++it) - { - curvabsc += ((*it)->point2d()-(*previous)->point2d()).norm(); - (*it)->setCurvilinearAbscissa(curvabsc); - previous = it; - } - _Length = curvabsc; - for(; - (it!=itend); - ++it) - { - (*it)->setStrokeLength(_Length); - } + return *(_FEdgeA->aFace()); } +#endif -//! embedding vertex iterator -Stroke::const_vertex_iterator Stroke::vertices_begin() const { return const_vertex_iterator(_Vertices.begin(),_Vertices.begin(), _Vertices.end()); } -Stroke::const_vertex_iterator Stroke::vertices_end() const { return const_vertex_iterator(_Vertices.end(),_Vertices.begin(), _Vertices.end()); } -Stroke::vertex_iterator Stroke::vertices_end() { return vertex_iterator(_Vertices.end(),_Vertices.begin(), _Vertices.end()); } +const SShape * Stroke::occluded_shape() const +{ + const_vertex_iterator v = vertices_begin(), vend = vertices_end(); + const SShape *sshape = (*v)->occluded_shape(); + for (; v != vend; ++v) { + if ((*v)->occluded_shape() != sshape) + Exception::raiseException(); + } + return sshape; +} -StrokeInternal::StrokeVertexIterator Stroke::strokeVerticesBegin(float t) { - if((t!=0) && (t < _sampling)) - Resample(t); - return StrokeInternal::StrokeVertexIterator(this->_Vertices.begin(), this->_Vertices.begin(), this->_Vertices.end()); +const bool Stroke::occludee_empty() const +{ + const_vertex_iterator v = vertices_begin(), vend = vertices_end(); + bool empty = (*v)->occludee_empty(); + for (; v != vend; ++v) { + if ((*v)->occludee_empty() != empty) + Exception::raiseException(); + } + return empty; } -StrokeInternal::StrokeVertexIterator Stroke::strokeVerticesEnd() { - return StrokeInternal::StrokeVertexIterator(this->_Vertices.end(), this->_Vertices.begin(), this->_Vertices.end()); +const SShape * Stroke::shape() const +{ + const_vertex_iterator v = vertices_begin(), vend = vertices_end(); + const SShape *sshape = (*v)->shape(); + for (; v != vend; ++v) { + if ((*v)->shape() != sshape) + Exception::raiseException(); + } + return sshape; } -Interface0DIterator Stroke::verticesBegin() { - Interface0DIterator ret(new StrokeInternal::StrokeVertexIterator(this->_Vertices.begin(), - this->_Vertices.begin(), - this->_Vertices.end())); - return ret; +real Stroke::z_discontinuity(int iCombination) const +{ + return z_discontinuity_edge_function(*this, iCombination); } -Interface0DIterator Stroke::verticesEnd() { - Interface0DIterator ret(new StrokeInternal::StrokeVertexIterator(this->_Vertices.end(), - this->_Vertices.begin(), - this->_Vertices.end())); - return ret; +Vec3r Stroke::curvature2d_as_vector(int iCombination) const +{ + return curvature2d_as_vector_edge_function(*this, iCombination); } -Interface0DIterator Stroke::pointsBegin(float t) { - return verticesBegin(); // FIXME +real Stroke::curvature2d_as_angle(int iCombination) const +{ + return curvature2d_as_angle_edge_function(*this, iCombination); } -Interface0DIterator Stroke::pointsEnd(float t) { - return verticesEnd(); +float Stroke::shape_importance(int iCombination) const +{ + return shape_importance_edge_function(*this, iCombination); } -void Stroke::ScaleThickness(float iFactor) + +float Stroke::local_average_depth(int iCombination ) const { - for(vertex_container::iterator it=_Vertices.begin(), itend=_Vertices.end(); - it!=itend; - ++it) - { - StrokeAttribute& attr = (*it)->attribute(); - attr.setThickness(iFactor * attr.getThicknessR(), iFactor * attr.getThicknessL()); - } + return local_average_depth_edge_function(*this, iCombination); } -void Stroke::Render(const StrokeRenderer *iRenderer) +float Stroke::local_depth_variance(int iCombination) const { - if(!_rep) - _rep = new StrokeRep(this); - iRenderer->RenderStrokeRep(_rep); + return local_depth_variance_edge_function(*this, iCombination); } -void Stroke::RenderBasic(const StrokeRenderer *iRenderer) +real Stroke::local_average_density(float sigma , int iCombination ) const { - if(!_rep) - _rep = new StrokeRep(this); - iRenderer->RenderStrokeRepBasic(_rep); -} - -Stroke::vertex_iterator Stroke::vertices_begin(float sampling) -{ - // Resample if necessary - if((sampling != 0) && (sampling < _sampling)) - Resample(sampling); - return vertex_iterator(_Vertices.begin(),_Vertices.begin(),_Vertices.end()); - //return _Vertices.begin(); -} -// -//Stroke::vertex_iterator Stroke::vertices_last() -//{ -// vertex_iterator res = vertices_begin(); -// vertex_iterator next = res;++next; -// while(!next.end()) -// { -// ++next; -// ++res; -// } -// return res; -//} -// -//Stroke::const_vertex_iterator Stroke::vertices_last() const -//{ -// const_vertex_iterator res = vertices_begin(); -// const_vertex_iterator next = res;++next; -// while(!next.end()) -// { -// ++next; -// ++res; -// } -// return res; -//} - -//Stroke::vertex_container::reverse_iterator Stroke::vertices_last(float sampling) -//{ -// // Resample if necessary -// if(sampling < _sampling) -// Resample(sampling); -// return _Vertices.rbegin(); -//} - - -//inline Vec3r shaded_color(int iCombination = 0) const ; -//inline Vec<3,real> Stroke::orientation2d(const_vertex_iterator it) const -//{ -// return iterator_edge_orientation2d_function(this, it); -//} -// Vec3r Stroke::orientation2d(int iCombination) const -// { -// return edge_orientation2d_function(*this, iCombination); -// } -//inline Vec3r Stroke::orientation3d(const_vertex_iterator it) const -//{ -// return iterator_edge_orientation3d_function(*this, it); -//} -// Vec3r Stroke::orientation3d(int iCombination) const -// { -// return edge_orientation3d_function(*this, iCombination); -// } - -//Material Stroke::material() const -//{ -// const_vertex_iterator v=vertices_begin(), vend=strokeVerticesEnd(); -// Material mat = (*v)->material(); -// for(;v!=vend;++v) -// { -// if(mat != (*v)->material()) -// Exception::raiseException(); -// } -// return mat; -//} - -//int Stroke::qi() const -//{ -// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); -// int qi_= (*v)->qi(); -// for(;v!=vend;++v) -// { -// if((*v)->qi() != qi_) -// Exception::raiseException(); -// } -// return qi_; -//} -//inline occluder_container::const_iterator occluders_begin() const {return _FEdgeA->occluders().begin();} -//inline occluder_container::const_iterator occluders_end() const {return _FEdgeA->occluders().end();} - -//int Stroke::occluders_size() const -//{ -// return qi(); -//} -// -//bool Stroke::occluders_empty() const -//{ -// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); -// bool empty = (*v)->occluders_empty(); -// for(;v!=vend;++v) -// { -// if((*v)->occluders_empty() != empty) -// Exception::raiseException(); -// } -// return empty; -//} -////inline const polygon3d& occludee() const {return *(_FEdgeA->aFace());} -//const SShape * Stroke::occluded_shape() const -//{ -// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); -// const SShape *sshape = (*v)->occluded_shape(); -// for(;v!=vend;++v) -// { -// if((*v)->occluded_shape() != sshape) -// Exception::raiseException(); -// } -// return sshape; -//} -// -//const bool Stroke::occludee_empty() const -//{ -// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); -// bool empty = (*v)->occludee_empty(); -// for(;v!=vend;++v) -// { -// if((*v)->occludee_empty() != empty) -// Exception::raiseException(); -// } -// return empty; -//} - -//const SShape * Stroke::shape() const -//{ -// const_vertex_iterator v=vertices_begin(), vend=vertices_end(); -// const SShape *sshape = (*v)->shape(); -// for(;v!=vend;++v) -// { -// if((*v)->shape() != sshape) -// Exception::raiseException(); -// } -// return sshape; -//} - -// real Stroke::z_discontinuity(int iCombination) const -// { -// return z_discontinuity_edge_function(*this, iCombination); -// } - -// Vec3r Stroke::curvature2d_as_vector(int iCombination) const -// { -// return curvature2d_as_vector_edge_function(*this, iCombination); -// } - -// real Stroke::curvature2d_as_angle(int iCombination) const -// { -// return curvature2d_as_angle_edge_function(*this, iCombination); -// } - -// float Stroke::shape_importance(int iCombination) const -// { -// return shape_importance_edge_function(*this, iCombination); -// } - - -// float Stroke::local_average_depth(int iCombination ) const -// { -// return local_average_depth_edge_function(*this, iCombination); -// } - -// float Stroke::local_depth_variance(int iCombination) const -// { -// return local_depth_variance_edge_function(*this, iCombination); -// } - -// real Stroke::local_average_density(float sigma , int iCombination ) const -// { -// return density_edge_function(*this, iCombination); -// } + return density_edge_function(*this, iCombination); +} +#endif diff --git a/source/blender/freestyle/intern/stroke/Stroke.h b/source/blender/freestyle/intern/stroke/Stroke.h index 5b20bcac896..51733a058a9 100644 --- a/source/blender/freestyle/intern/stroke/Stroke.h +++ b/source/blender/freestyle/intern/stroke/Stroke.h @@ -1,42 +1,50 @@ -// -// Filename : Stroke.h -// Author(s) : Stephane Grabli -// Purpose : Classes to define a stroke -// Date of creation : 09/09/2002 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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__ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/stroke/Stroke.h + * \ingroup freestyle + * \brief Classes to define a stroke + * \author Stephane Grabli + * \date 09/09/2002 + */ + +#include +#include -#ifndef STROKE_H -# define STROKE_H +#include "Curve.h" -# include "../view_map/Silhouette.h" -# include -# include -# include "../system/FreestyleConfig.h" -# include "Curve.h" -# include "../view_map/Interface1D.h" -# include "../system/StringUtils.h" +#include "../view_map/Interface1D.h" +#include "../view_map/Silhouette.h" + +#include "../system/FreestyleConfig.h" +#include "../system/StringUtils.h" // @@ -45,190 +53,256 @@ //////////////////////////////////////////////////////// /*! Class to define an attribute associated to a Stroke Vertex. - * This attribute stores the color, alpha and thickness values - * for 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); + /*! 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 realMap ; - typedef std::map Vec2fMap ; - typedef std::map 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; + typedef std::map realMap; + typedef std::map Vec2fMap; + typedef std::map 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; }; @@ -237,87 +311,157 @@ private: // //////////////////////////////////////////////////////// -/*! Class to define a stroke vertex. - */ +/*! 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"; - } + /*! 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 - 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 */ - + /*! 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 */ }; @@ -330,246 +474,335 @@ class StrokeRenderer; class StrokeRep; namespace StrokeInternal { - class vertex_const_traits ; - class vertex_nonconst_traits ; - template class vertex_iterator_base; - class StrokeVertexIterator; + +class vertex_const_traits; +class vertex_nonconst_traits; +template 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. + * 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; - /*! 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 vertex_container; // the vertices container - typedef std::vector viewedge_container; // the viewedges container - typedef StrokeInternal::vertex_iterator_base vertex_iterator; - typedef StrokeInternal::vertex_iterator_base const_vertex_iterator; + typedef std::deque vertex_container; // the vertices container + typedef std::vector viewedge_container; // the viewedges container + typedef StrokeInternal::vertex_iterator_base vertex_iterator; + typedef StrokeInternal::vertex_iterator_base const_vertex_iterator; public: - //typedef StrokeVertex vertex_type; + //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; + 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 - 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. - * Is 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.f); - 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.f); - /*! 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.f); - virtual Interface0DIterator pointsEnd(float t=0.f); + /*! 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 + 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 // @@ -579,14 +812,11 @@ public: template Stroke::Stroke(InputVertexIterator iBegin, InputVertexIterator iEnd) { - for(InputVertexIterator v=iBegin, vend=iEnd; - v!=vend; - v++) - { - _Vertices.push_back(*v); - } - _Length = 0; - _id = 0; + for (InputVertexIterator v = iBegin, vend = iEnd; v != vend; v++) { + _Vertices.push_back(*v); + } + _Length = 0; + _id = 0; } -#endif // STROKE_H +#endif // __FREESTYLE_STROKE_H__ diff --git a/source/blender/freestyle/intern/stroke/StrokeAdvancedIterators.h b/source/blender/freestyle/intern/stroke/StrokeAdvancedIterators.h index 2768a2fd794..adaa5548bf9 100644 --- a/source/blender/freestyle/intern/stroke/StrokeAdvancedIterators.h +++ b/source/blender/freestyle/intern/stroke/StrokeAdvancedIterators.h @@ -1,142 +1,191 @@ -// -// Filename : StrokeAdvancedIterators.h -// Author(s) : Stephane Grabli -// Purpose : Iterators used to iterate over the elements of the Stroke -// Can't be used in python -// Date of creation : 01/07/2003 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef STROKEADVANCEDITERATORS_H -# define STROKEADVANCEDITERATORS_H - -# include "Stroke.h" +/* + * ***** 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_ADVANCED_ITERATORS_H__ +#define __FREESTYLE_STROKE_ADVANCED_ITERATORS_H__ + +/** \file blender/freestyle/intern/stroke/StrokeAdvancedIterators.h + * \ingroup freestyle + * \brief Iterators used to iterate over the elements of the Stroke. Can't be used in python + * \author Stephane Grabli + * \author Emmanuel Turquin + * \date 01/07/2003 + */ + +#include "Stroke.h" namespace StrokeInternal { - class vertex_const_traits : public Const_traits { - public: - typedef std::deque vertex_container; - typedef vertex_container::const_iterator vertex_container_iterator ; - }; - class vertex_nonconst_traits : public Nonconst_traits { - public: - typedef std::deque vertex_container; //! the vertices container - typedef vertex_container::iterator vertex_container_iterator ; - }; - - - template - class vertex_iterator_base : public IteratorBase - { - public: - typedef vertex_iterator_base Self; - protected: - typedef IteratorBase parent_class; - typedef typename Traits::vertex_container_iterator vertex_container_iterator; - typedef vertex_iterator_base iterator; - typedef vertex_iterator_base const_iterator; - //protected: - public: - vertex_container_iterator _it; - vertex_container_iterator _begin; - vertex_container_iterator _end; - public: - friend class Stroke; - //friend class vertex_iterator; - inline vertex_iterator_base() - : parent_class() - {} - inline vertex_iterator_base(const iterator& iBrother) - : parent_class() - {_it = iBrother._it;_begin = iBrother._begin;_end = iBrother._end;} - inline vertex_iterator_base(const const_iterator& iBrother) - : parent_class() - {_it = iBrother._it;_begin = iBrother._begin;_end = iBrother._end;} - //protected://FIXME - public: - inline vertex_iterator_base(vertex_container_iterator it, vertex_container_iterator begin, vertex_container_iterator end) - : parent_class() - { - _it = it; - _begin = begin; - _end = end; - } - - public: - virtual ~vertex_iterator_base() {} - - virtual bool begin() const {return _it==_begin? true : false;} - virtual bool end() const {return _it==_end ? true : false;} - - // operators - inline Self& operator++() // operator corresponding to ++i - { - ++_it; - return *(this); - } - inline Self operator++(int) // opérateur correspondant à i++ - { - Self tmp = *this; // C'est pour cela qu'on stocke la valeur - ++_it; // dans un temporaire. - return tmp; - } - inline Self& operator--() // operator corresponding to ++i - { - --_it; - return *(this); - } - inline Self operator--(int) // opérateur correspondant à i++ - { // c.a.d qui renvoie la valeur *puis* incrémente. - Self tmp = *this; // C'est pour cela qu'on stocke la valeur - --_it; // dans un temporaire. - return tmp; - } - - // comparibility - virtual bool operator!=(const Self& b) const - { - return (_it != b._it); - } - virtual bool operator==(const Self& b) const - { - return !(*this != b); - } - - // dereferencing - virtual typename Traits::reference operator*() const {return *(_it);} - virtual typename Traits::pointer operator->() const { return &(operator*());} - - /*! accessors */ - inline vertex_container_iterator it() const {return _it;} - inline vertex_container_iterator getBegin() const {return _begin;} - inline vertex_container_iterator getEnd() const {return _end;} - }; +class vertex_const_traits : public Const_traits +{ +public: + typedef std::deque vertex_container; + typedef vertex_container::const_iterator vertex_container_iterator; +}; -} // end of namespace StrokeInternal +class vertex_nonconst_traits : public Nonconst_traits +{ +public: + typedef std::deque vertex_container; //! the vertices container + typedef vertex_container::iterator vertex_container_iterator; +}; + + +template +class vertex_iterator_base : public IteratorBase +{ +public: + typedef vertex_iterator_base Self; + +protected: + typedef IteratorBase parent_class; + typedef typename Traits::vertex_container_iterator vertex_container_iterator; + typedef vertex_iterator_base iterator; + typedef vertex_iterator_base const_iterator; + +//protected: +public: + vertex_container_iterator _it; + vertex_container_iterator _begin; + vertex_container_iterator _end; + +public: + friend class Stroke; + //friend class vertex_iterator; + + inline vertex_iterator_base() : parent_class() {} + + inline vertex_iterator_base(const iterator& iBrother) : parent_class() + { + _it = iBrother._it; + _begin = iBrother._begin; + _end = iBrother._end; + } + + inline vertex_iterator_base(const const_iterator& iBrother) : parent_class() + { + _it = iBrother._it; + _begin = iBrother._begin; + _end = iBrother._end; + } + +//protected: //FIXME +public: + inline vertex_iterator_base(vertex_container_iterator it, vertex_container_iterator begin, + vertex_container_iterator end) + : parent_class() + { + _it = it; + _begin = begin; + _end = end; + } +public: + virtual ~vertex_iterator_base() {} -#endif // STROKEADVANCEDITERATORS_H + virtual bool begin() const + { + return (_it == _begin) ? true : false; + } + virtual bool end() const + { + return (_it == _end) ? true : false; + } + + // operators + inline Self& operator++() // operator corresponding to ++i + { + ++_it; + return *(this); + } + + /* Operator corresponding to i++, i.e. which returns the value *and then* increments. + * That's why we store the value in a temp. + */ + inline Self operator++(int) + { + Self tmp = *this; + ++_it; + return tmp; + } + + inline Self& operator--() // operator corresponding to --i + { + --_it; + return *(this); + } + + inline Self operator--(int) + { + Self tmp = *this; + --_it; + return tmp; + } + + // comparibility + virtual bool operator!=(const Self& b) const + { + return (_it != b._it); + } + + virtual bool operator==(const Self& b) const + { + return !(*this != b); + } + + // dereferencing + virtual typename Traits::reference operator*() const + { + return *(_it); + } + + virtual typename Traits::pointer operator->() const + { + return &(operator*()); + } + + /*! accessors */ + inline vertex_container_iterator it() const + { + return _it; + } + + inline vertex_container_iterator getBegin() const + { + return _begin; + } + + inline vertex_container_iterator getEnd() const + { + return _end; + } +}; + +} // end of namespace StrokeInternal +#endif // __FREESTYLE_STROKE_ADVANCED_ITERATORS_H__ diff --git a/source/blender/freestyle/intern/stroke/StrokeIO.cpp b/source/blender/freestyle/intern/stroke/StrokeIO.cpp index 903a198adc2..a101ec67618 100644 --- a/source/blender/freestyle/intern/stroke/StrokeIO.cpp +++ b/source/blender/freestyle/intern/stroke/StrokeIO.cpp @@ -1,55 +1,73 @@ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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 ***** + */ + +/** \file blender/freestyle/intern/stroke/StrokeIO.cpp + * \ingroup freestyle + * \brief Functions to manage I/O for the stroke + * \author Stephane Grabli + * \date 03/02/2004 + */ -#include "StrokeIO.h" #include "StrokeAdvancedIterators.h" +#include "StrokeIO.h" -ostream& operator<<(ostream& out, const StrokeAttribute& iStrokeAttribute){ - out << " StrokeAttribute" << endl; - out << " color : (" << iStrokeAttribute.getColorR() << "," << iStrokeAttribute.getColorG() << "," << iStrokeAttribute.getColorB() << ")" << endl; - out << " alpha : " << iStrokeAttribute.getAlpha() << endl; - out << " thickness : " << iStrokeAttribute.getThicknessR() << ", " << iStrokeAttribute.getThicknessL() << endl; - out << " visible : " << iStrokeAttribute.isVisible() << endl; - return out; +ostream& operator<<(ostream& out, const StrokeAttribute& iStrokeAttribute) +{ + out << " StrokeAttribute" << endl; + out << " color : (" << iStrokeAttribute.getColorR() << "," << iStrokeAttribute.getColorG() + << "," << iStrokeAttribute.getColorB() << ")" << endl; + out << " alpha : " << iStrokeAttribute.getAlpha() << endl; + out << " thickness : " << iStrokeAttribute.getThicknessR() << ", " << iStrokeAttribute.getThicknessL() << endl; + out << " visible : " << iStrokeAttribute.isVisible() << endl; + return out; } -ostream& operator<<(ostream& out, const StrokeVertex& iStrokeVertex){ - out << " StrokeVertex" << endl; - out << " id : " << iStrokeVertex.getId() << endl; - out << " curvilinear length : " << iStrokeVertex.curvilinearAbscissa() << endl; - out << " 2d coordinates : (" << iStrokeVertex.getProjectedX() << "," << iStrokeVertex.getProjectedY() << "," << iStrokeVertex.getProjectedZ() << ")" << endl; - out << " 3d coordinates : (" << iStrokeVertex.getX() << "," << iStrokeVertex.getY() << "," << iStrokeVertex.getZ() << ")"<< endl; - out << iStrokeVertex.attribute() << endl; - return out; +ostream& operator<<(ostream& out, const StrokeVertex& iStrokeVertex) +{ + out << " StrokeVertex" << endl; + out << " id : " << iStrokeVertex.getId() << endl; + out << " curvilinear length : " << iStrokeVertex.curvilinearAbscissa() << endl; + out << " 2d coordinates : (" << iStrokeVertex.getProjectedX() << "," << iStrokeVertex.getProjectedY() + << "," << iStrokeVertex.getProjectedZ() << ")" << endl; + out << " 3d coordinates : (" << iStrokeVertex.getX() << "," << iStrokeVertex.getY() + << "," << iStrokeVertex.getZ() << ")" << endl; + out << iStrokeVertex.attribute() << endl; + return out; } -ostream& operator<<(ostream& out, const Stroke& iStroke){ - out << "Stroke" << endl; - out << " id : " << iStroke.getId() << endl; - out << " length : " << iStroke.getLength2D() << endl; - out << " medium type : " << iStroke.getMediumType() << endl; - for(Stroke::const_vertex_iterator v=iStroke.vertices_begin(), vend=iStroke.vertices_end(); - v!=vend; - ++v){ - out << *(*v) << endl; - } - return out; +ostream& operator<<(ostream& out, const Stroke& iStroke) +{ + out << "Stroke" << endl; + out << " id : " << iStroke.getId() << endl; + out << " length : " << iStroke.getLength2D() << endl; + out << " medium type : " << iStroke.getMediumType() << endl; + for(Stroke::const_vertex_iterator v = iStroke.vertices_begin(), vend = iStroke.vertices_end(); v != vend; ++v) { + out << *(*v) << endl; + } + return out; } diff --git a/source/blender/freestyle/intern/stroke/StrokeIO.h b/source/blender/freestyle/intern/stroke/StrokeIO.h index 150c8340778..789c9c92c93 100644 --- a/source/blender/freestyle/intern/stroke/StrokeIO.h +++ b/source/blender/freestyle/intern/stroke/StrokeIO.h @@ -1,38 +1,45 @@ -// -// Filename : StrokeIO.h -// Author(s) : Stephane Grabli -// Purpose : Functions to manage I/O for the stroke -// Date of creation : 03/02/2004 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef STROKEIO_H -# define STROKEIO_H - -# include "Stroke.h" -# include -# include "../system/FreestyleConfig.h" +/* + * ***** 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_IO_H__ +#define __FREESTYLE_STROKE_IO_H__ + +/** \file blender/freestyle/intern/stroke/StrokeIO.h + * \ingroup freestyle + * \brief Functions to manage I/O for the stroke + * \author Stephane Grabli + * \date 03/02/2004 + */ + +#include + +#include "Stroke.h" + +#include "../system/FreestyleConfig.h" LIB_STROKE_EXPORT ostream& operator<<(ostream& out, const StrokeAttribute& iStrokeAttribute); @@ -43,5 +50,4 @@ ostream& operator<<(ostream& out, const StrokeVertex& iStrokeVertex); LIB_STROKE_EXPORT ostream& operator<<(ostream& out, const Stroke& iStroke); - -#endif // STROKEIO_H +#endif // __FREESTYLE_STROKE_IO_H__ diff --git a/source/blender/freestyle/intern/stroke/StrokeIterators.h b/source/blender/freestyle/intern/stroke/StrokeIterators.h index b51189f3990..37f6a8843bd 100644 --- a/source/blender/freestyle/intern/stroke/StrokeIterators.h +++ b/source/blender/freestyle/intern/stroke/StrokeIterators.h @@ -1,229 +1,229 @@ -// -// Filename : StrokeIterators.h -// Author(s) : Stephane Grabli -// Purpose : Iterators used to iterate over the elements of the Stroke -// Date of creation : 01/07/2003 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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_ITERATORS_H__ +#define __FREESTYLE_STROKE_ITERATORS_H__ + +/** \file blender/freestyle/intern/stroke/StrokeIterators.h + * \ingroup freestyle + * \brief Iterators used to iterate over the elements of the Stroke + * \author Stephane Grabli + * \date 01/07/2003 + */ + +#include "Stroke.h" +namespace StrokeInternal { // -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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. +// StrokeVertexIterator // -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef STROKEITERATORS_H -# define STROKEITERATORS_H - -# include "Stroke.h" - -namespace StrokeInternal { - - // - // StrokeVertexIterator - // - ///////////////////////////////////////////////// - - /*! Class defining an iterator designed to iterate over - * the StrokeVertex of a Stroke. - * An instance of a StrokeVertexIterator can only be obtained - * from a Stroke by calling strokeVerticesBegin() or strokeVerticesEnd(). - * It is iterating over the same vertices as an Interface0DIterator. - * The difference resides in the object access. Indeed, an Interface0DIterator - * allows only an access to an Interface0D whereas we could need - * to access the specialized StrokeVertex type. In this case, one - * should use a StrokeVertexIterator. - * The castToInterface0DIterator() method is useful to get an Interface0DIterator - * from a StrokeVertexIterator in order to call any functions of the - * type UnaryFunction0D. - * \attention In the scripting language, you must call - * \code it2 = StrokeVertexIterator(it1) \endcode instead of - * \code it2 = it1 \endcode - * where \a it1 and \a it2 are 2 StrokeVertexIterator. - * Otherwise, incrementing \a it1 will also increment \a it2. - */ - class StrokeVertexIterator : public Interface0DIteratorNested - { - public: - - /*! Default constructor. */ - StrokeVertexIterator() {} - - /*! Copy constructor. */ - StrokeVertexIterator(const StrokeVertexIterator& vi) { - _it = vi._it; - _begin = vi._begin; - _end = vi._end; - } - - StrokeVertexIterator(const ::Stroke::vertex_container::iterator& it, - const ::Stroke::vertex_container::iterator& begin, - const ::Stroke::vertex_container::iterator& end) { - _it = it; - _begin = begin; - _end = end; - } - - virtual ~StrokeVertexIterator() {} - - /*! Casts this StrokeVertexIterator into an Interface0DIterator. - * Useful for any call to a function of the type UnaryFunction0D. - */ - inline Interface0DIterator castToInterface0DIterator() const { - Interface0DIterator ret(new StrokeVertexIterator(*this)); - return ret; - } - /*! operator= - * \attention In the scripting language, you must call - * \code it2 = StrokeVertexIterator(it1) \endcode instead of - * \code it2 = it1 \endcode - * where \a it1 and \a it2 are 2 StrokeVertexIterator. - * Otherwise, incrementing \a it1 will also increment \a it2. - * - */ - StrokeVertexIterator& operator=(const StrokeVertexIterator& vi) { - _it = vi._it; - _begin = vi._begin; - _end = vi._end; - return *this; - } - - /*! Returns the string "StrokeVertexIterator". */ - virtual string getExactTypeName() const { - return "StrokeVertexIterator"; - } - - /*! Returns a reference to the pointed StrokeVertex. - * In the scripting language, you must call - * "getObject()"instead. - */ - virtual StrokeVertex& operator*() { - return **_it; - } - - /*! Returns a pointer to the pointed StrokeVertex. - * Can't be called in the scripting language. - */ - virtual StrokeVertex* operator->() { - return &(operator*()); - } - - /*! Increments. In the scripting language, call - * "increment()". - */ - virtual StrokeVertexIterator& operator++() { - increment(); - return *this; - } - - /*! Increments. In the scripting language, call - * "increment()". - */ - virtual StrokeVertexIterator operator++(int) { - StrokeVertexIterator ret(*this); - increment(); - return ret; - } - - /*! Decrements. In the scripting language, call - * "decrement()". - */ - virtual StrokeVertexIterator& operator--() { - decrement(); - return *this; - } - - /*! Decrements. In the scripting language, call - * "decrement()". - */ - virtual StrokeVertexIterator operator--(int) { - StrokeVertexIterator ret(*this); - decrement(); - return ret; - } - - /*! Increments. */ - virtual int increment() { - ++_it; - return 0; - } - - /*! Decrements. */ - virtual int decrement() { - --_it; - return 0; - } - - /*! Returns true if the pointed StrokeVertex is the - * first of the Stroke. - */ - bool isBegin() const { - return _it == _begin; - } - - /*! Returns true if the pointed StrokeVertex is after the - * last StrokeVertex of the Stroke. - */ - bool isEnd() const { - return _it == _end; - } - - /*! operator == */ - virtual bool operator==(const Interface0DIteratorNested& it) const { - const StrokeVertexIterator* it_exact = dynamic_cast(&it); - if (!it_exact) - return false; - return (_it == it_exact->_it); - } - - /*! Returns the curvilinear abscissa of the current point */ - virtual float t() const{ - return (*_it)->curvilinearAbscissa(); - } - /*! Returns the point's parameter in the stroke */ - virtual float u() const{ - return (*_it)->u(); - } - - /*! Cloning method */ - virtual StrokeVertexIterator* copy() const { - return new StrokeVertexIterator(*this); - } - - // - // Not exported in Python - // - ////////////////////////////////////////////////// - - const ::Stroke::vertex_container::iterator& getIt() { - return _it; - } - - private: - - ::Stroke::vertex_container::iterator _it; - ::Stroke::vertex_container::iterator _begin; - ::Stroke::vertex_container::iterator _end; - }; +///////////////////////////////////////////////// + +/*! Class defining an iterator designed to iterate over the StrokeVertex of a Stroke. + * An instance of a StrokeVertexIterator can only be obtained from a Stroke by calling strokeVerticesBegin() or + * strokeVerticesEnd(). + * It is iterating over the same vertices as an Interface0DIterator. + * The difference resides in the object access. Indeed, an Interface0DIterator allows only an access to an + * Interface0D whereas we could need to access the specialized StrokeVertex type. In this case, one + * should use a StrokeVertexIterator. + * The castToInterface0DIterator() method is useful to get an Interface0DIterator from a StrokeVertexIterator in + * order to call any functions of the type UnaryFunction0D. + * \attention In the scripting language, you must call \code it2 = StrokeVertexIterator(it1) \endcode instead of + * \code it2 = it1 \endcode where \a it1 and \a it2 are 2 StrokeVertexIterator. + * Otherwise, incrementing \a it1 will also increment \a it2. + */ +class StrokeVertexIterator : public Interface0DIteratorNested +{ +public: + /*! Default constructor. */ + StrokeVertexIterator() {} + + /*! Copy constructor. */ + StrokeVertexIterator(const StrokeVertexIterator& vi) + { + _it = vi._it; + _begin = vi._begin; + _end = vi._end; + } + + StrokeVertexIterator(const ::Stroke::vertex_container::iterator& it, + const ::Stroke::vertex_container::iterator& begin, + const ::Stroke::vertex_container::iterator& end) + { + _it = it; + _begin = begin; + _end = end; + } + + virtual ~StrokeVertexIterator() {} + + /*! Casts this StrokeVertexIterator into an Interface0DIterator. + * Useful for any call to a function of the type UnaryFunction0D. + */ + inline Interface0DIterator castToInterface0DIterator() const + { + Interface0DIterator ret(new StrokeVertexIterator(*this)); + return ret; + } + + /*! operator= + * \attention In the scripting language, you must call \code it2 = StrokeVertexIterator(it1) \endcode instead of + * \code it2 = it1 \endcode, where \a it1 and \a it2 are 2 StrokeVertexIterator. + * Otherwise, incrementing \a it1 will also increment \a it2. + */ + StrokeVertexIterator& operator=(const StrokeVertexIterator& vi) + { + _it = vi._it; + _begin = vi._begin; + _end = vi._end; + return *this; + } + + /*! Returns the string "StrokeVertexIterator". */ + virtual string getExactTypeName() const + { + return "StrokeVertexIterator"; + } + + /*! Returns a reference to the pointed StrokeVertex. + * In the scripting language, you must call "getObject()"instead. + */ + virtual StrokeVertex& operator*() + { + return **_it; + } + + /*! Returns a pointer to the pointed StrokeVertex. + * Can't be called in the scripting language. + */ + virtual StrokeVertex* operator->() + { + return &(operator*()); + } + + /*! Increments. In the scripting language, call "increment()". */ + virtual StrokeVertexIterator& operator++() + { + increment(); + return *this; + } + + /*! Increments. In the scripting language, call "increment()". */ + virtual StrokeVertexIterator operator++(int) + { + StrokeVertexIterator ret(*this); + increment(); + return ret; + } + + /*! Decrements. In the scripting language, call "decrement()". */ + virtual StrokeVertexIterator& operator--() + { + decrement(); + return *this; + } + + /*! Decrements. In the scripting language, call "decrement()". */ + virtual StrokeVertexIterator operator--(int) + { + StrokeVertexIterator ret(*this); + decrement(); + return ret; + } + + /*! Increments. */ + virtual int increment() + { + ++_it; + return 0; + } + + /*! Decrements. */ + virtual int decrement() + { + --_it; + return 0; + } + + /*! Returns true if the pointed StrokeVertex is the first of the Stroke. */ + bool isBegin() const + { + return _it == _begin; + } + + /*! Returns true if the pointed StrokeVertex is after the last StrokeVertex of the Stroke. */ + bool isEnd() const + { + return _it == _end; + } + + /*! operator == */ + virtual bool operator==(const Interface0DIteratorNested& it) const + { + const StrokeVertexIterator* it_exact = dynamic_cast(&it); + if (!it_exact) + return false; + return (_it == it_exact->_it); + } + + /*! Returns the curvilinear abscissa of the current point */ + virtual float t() const + { + return (*_it)->curvilinearAbscissa(); + } + + /*! Returns the point's parameter in the stroke */ + virtual float u() const + { + return (*_it)->u(); + } + + /*! Cloning method */ + virtual StrokeVertexIterator* copy() const + { + return new StrokeVertexIterator(*this); + } + + // + // Not exported in Python + // + ////////////////////////////////////////////////// + const ::Stroke::vertex_container::iterator& getIt() + { + return _it; + } + +private: + ::Stroke::vertex_container::iterator _it; + ::Stroke::vertex_container::iterator _begin; + ::Stroke::vertex_container::iterator _end; +}; } // end of namespace StrokeInternal - -#endif // STROKEITERATORS_H - - +#endif // __FREESTYLE_STROKE_ITERATORS_H__ diff --git a/source/blender/freestyle/intern/stroke/StrokeLayer.cpp b/source/blender/freestyle/intern/stroke/StrokeLayer.cpp index 93d695be406..b12477c3e34 100644 --- a/source/blender/freestyle/intern/stroke/StrokeLayer.cpp +++ b/source/blender/freestyle/intern/stroke/StrokeLayer.cpp @@ -1,64 +1,70 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/stroke/StrokeLayer.cpp + * \ingroup freestyle + * \brief Class to define a layer of strokes. + * \author Stephane Grabli + * \date 18/12/2002 + */ +#include "Canvas.h" #include "Stroke.h" #include "StrokeLayer.h" -#include "Canvas.h" StrokeLayer::~StrokeLayer() { - clear(); + clear(); } void StrokeLayer::ScaleThickness(float iFactor) { - for(StrokeLayer::stroke_container::iterator s=_strokes.begin(), send=_strokes.end(); - s!=send; - ++s){ - (*s)->ScaleThickness(iFactor); - } + for (StrokeLayer::stroke_container::iterator s = _strokes.begin(), send = _strokes.end(); s != send; ++s) { + (*s)->ScaleThickness(iFactor); + } } -void StrokeLayer::Render(const StrokeRenderer *iRenderer ) +void StrokeLayer::Render(const StrokeRenderer *iRenderer) { - for(StrokeLayer::stroke_container::iterator s=_strokes.begin(), send=_strokes.end(); - s!=send; - ++s){ - (*s)->Render(iRenderer); - } + for (StrokeLayer::stroke_container::iterator s = _strokes.begin(), send = _strokes.end(); s != send; ++s) { + (*s)->Render(iRenderer); + } } -void StrokeLayer::RenderBasic(const StrokeRenderer *iRenderer ) +void StrokeLayer::RenderBasic(const StrokeRenderer *iRenderer) { - for(StrokeLayer::stroke_container::iterator s=_strokes.begin(), send=_strokes.end(); - s!=send; - ++s){ - (*s)->RenderBasic(iRenderer); - } + for (StrokeLayer::stroke_container::iterator s = _strokes.begin(), send = _strokes.end(); s != send; ++s) { + (*s)->RenderBasic(iRenderer); + } } + void StrokeLayer::clear() { - for(stroke_container::iterator s=_strokes.begin(), send=_strokes.end(); - s!=send; - ++s) - delete *s; - _strokes.clear(); + for (stroke_container::iterator s = _strokes.begin(), send = _strokes.end(); s != send; ++s) + delete *s; + _strokes.clear(); } diff --git a/source/blender/freestyle/intern/stroke/StrokeLayer.h b/source/blender/freestyle/intern/stroke/StrokeLayer.h index eb8e7891bdd..ff830db337a 100644 --- a/source/blender/freestyle/intern/stroke/StrokeLayer.h +++ b/source/blender/freestyle/intern/stroke/StrokeLayer.h @@ -1,76 +1,106 @@ -// -// Filename : StrokeLayer.h -// Author : Stephane Grabli -// Purpose : Class to define a layer of strokes. -// Date of creation : 18/12/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef STROKELAYER_H -# define STROKELAYER_H - -# include +/* + * ***** 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_LAYER_H__ +#define __FREESTYLE_STROKE_LAYER_H__ + +/** \file blender/freestyle/intern/stroke/StrokeLayer.h + * \ingroup freestyle + * \brief Class to define a layer of strokes. + * \author Stephane Grabli + * \date 18/12/2002 + */ + +#include class Stroke; class StrokeRenderer; -class StrokeLayer +class StrokeLayer { public: - typedef std::deque stroke_container; + typedef std::deque stroke_container; protected: - stroke_container _strokes; + stroke_container _strokes; + public: - StrokeLayer() {} - StrokeLayer(const stroke_container& iStrokes) - { - _strokes = iStrokes; - } - StrokeLayer(const StrokeLayer& iBrother) - { - _strokes = iBrother._strokes; - } - virtual ~StrokeLayer() ; - - /*! Render method */ - void ScaleThickness(float iFactor); - void Render(const StrokeRenderer *iRenderer ); - void RenderBasic(const StrokeRenderer *iRenderer ); - - /*! clears the layer */ - void clear() ; - - /*! accessors */ - inline stroke_container::iterator strokes_begin() {return _strokes.begin();} - inline stroke_container::iterator strokes_end() {return _strokes.end();} - inline int strokes_size() const {return _strokes.size();} - inline bool empty() const {return _strokes.empty();} - - /*! modifiers */ - inline void setStrokes(stroke_container& iStrokes) {_strokes = iStrokes;} - inline void AddStroke(Stroke *iStroke) {_strokes.push_back(iStroke);} - + StrokeLayer() {} + + StrokeLayer(const stroke_container& iStrokes) + { + _strokes = iStrokes; + } + + StrokeLayer(const StrokeLayer& iBrother) + { + _strokes = iBrother._strokes; + } + + virtual ~StrokeLayer(); + + /*! Render method */ + void ScaleThickness(float iFactor); + void Render(const StrokeRenderer *iRenderer); + void RenderBasic(const StrokeRenderer *iRenderer); + + /*! clears the layer */ + void clear(); + + /*! accessors */ + inline stroke_container::iterator strokes_begin() + { + return _strokes.begin(); + } + + inline stroke_container::iterator strokes_end() + { + return _strokes.end(); + } + + inline int strokes_size() const + { + return _strokes.size(); + } + + inline bool empty() const + { + return _strokes.empty(); + } + + /*! modifiers */ + inline void setStrokes(stroke_container& iStrokes) + { + _strokes = iStrokes; + } + + inline void AddStroke(Stroke *iStroke) + { + _strokes.push_back(iStroke); + } }; -#endif // STROKELAYER_H +#endif // __FREESTYLE_STROKE_LAYER_H__ diff --git a/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp b/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp index 19e5ba35fed..6f12dbf2083 100644 --- a/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp +++ b/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp @@ -1,26 +1,41 @@ - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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 ***** + */ + +/** \file blender/freestyle/intern/stroke/StrokeRenderer.cpp + * \ingroup freestyle + * \brief Classes to render a stroke with OpenGL + * \author Fredo Durand + * \date 09/09/2002 + */ #include "StrokeRenderer.h" + #include "../geometry/GeomUtils.h" + using namespace std; /**********************************/ @@ -34,18 +49,14 @@ using namespace std; LIB_STROKE_EXPORT TextureManager *StrokeRenderer::_textureManager = 0; -StrokeRenderer::StrokeRenderer () -{ -} +StrokeRenderer::StrokeRenderer() {} -StrokeRenderer::~StrokeRenderer () -{ -} +StrokeRenderer::~StrokeRenderer() {} bool StrokeRenderer::loadTextures() { - _textureManager->load(); - return true; + _textureManager->load(); + return true; } @@ -67,55 +78,61 @@ string TextureManager::_patterns_path; LIB_STROKE_EXPORT string TextureManager::_brushes_path; -TextureManager::TextureManager () +TextureManager::TextureManager() { - _hasLoadedTextures=false; - _pInstance = this; - _defaultTextureId = 0; + _hasLoadedTextures = false; + _pInstance = this; + _defaultTextureId = 0; } -TextureManager::~TextureManager () +TextureManager::~TextureManager() { - if(!_brushesMap.empty()) - _brushesMap.clear(); - _pInstance = 0; + if (!_brushesMap.empty()) + _brushesMap.clear(); + _pInstance = 0; } void TextureManager::load() { - if(_hasLoadedTextures) - return; - loadStandardBrushes(); - _hasLoadedTextures = true; + if (_hasLoadedTextures) + return; + loadStandardBrushes(); + _hasLoadedTextures = true; } unsigned TextureManager::getBrushTextureIndex(string name, Stroke::MediumType loadingMode) { - BrushTexture bt(name,loadingMode); - brushesMap::iterator b = _brushesMap.find(bt); - if(b == _brushesMap.end()){ - unsigned texId = loadBrush(name, loadingMode); - _brushesMap[bt] = texId; - return texId; - cout << "brush file " << name << " not found" << endl; - return 0; - }else{ - return _brushesMap[bt]; - } + BrushTexture bt(name,loadingMode); + brushesMap::iterator b = _brushesMap.find(bt); + if (b == _brushesMap.end()) { + unsigned texId = loadBrush(name, loadingMode); + _brushesMap[bt] = texId; + return texId; + // XXX! + cout << "brush file " << name << " not found" << endl; + return 0; + } + else { + return _brushesMap[bt]; + } } -void TextureManager::Options::setPatternsPath(const string& path) { - _patterns_path = path; +void TextureManager::Options::setPatternsPath(const string& path) +{ + _patterns_path = path; } -string TextureManager::Options::getPatternsPath() { - return _patterns_path; +string TextureManager::Options::getPatternsPath() +{ + return _patterns_path; } -void TextureManager::Options::setBrushesPath(const string& path) { - _brushes_path = path; +void TextureManager::Options::setBrushesPath(const string& path) +{ + _brushes_path = path; } -string TextureManager::Options::getBrushesPath() { - return _brushes_path; +string TextureManager::Options::getBrushesPath() +{ + return _brushes_path; } diff --git a/source/blender/freestyle/intern/stroke/StrokeRenderer.h b/source/blender/freestyle/intern/stroke/StrokeRenderer.h index c7c6df635d5..ab451a14496 100644 --- a/source/blender/freestyle/intern/stroke/StrokeRenderer.h +++ b/source/blender/freestyle/intern/stroke/StrokeRenderer.h @@ -1,43 +1,49 @@ -// -// Filename : StrokeRenderer.h -// Author(s) : Fredo Durand -// Purpose : Classes to render a stroke with OpenGL -// Date of creation : 09/09/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef STROKE_RENDERER_H -# define STROKE_RENDERER_H - -# include "Stroke.h" -# include -# include -# include -# include "../system/FreestyleConfig.h" -# include "StrokeRep.h" -# include +/* + * ***** 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_RENDERER_H__ +#define __FREESTYLE_STROKE_RENDERER_H__ + +/** \file blender/freestyle/intern/stroke/StrokeRenderer.h + * \ingroup freestyle + * \brief Classes to render a stroke with OpenGL + * \author Fredo Durand + * \date 09/09/2002 + */ +#include +#include +#include +#include + +#include "Stroke.h" +#include "StrokeRep.h" + +#include "../system/FreestyleConfig.h" /**********************************/ /* */ @@ -48,53 +54,64 @@ /**********************************/ -/*! Class to load textures - */ +/*! Class to load textures */ class LIB_STROKE_EXPORT TextureManager { public: - - TextureManager (); - virtual ~TextureManager (); - static TextureManager * getInstance() {return _pInstance;} - void load () ; - unsigned getBrushTextureIndex(string name, Stroke::MediumType iType = Stroke::OPAQUE_MEDIUM) ; - - inline bool hasLoaded() const {return _hasLoadedTextures;} - inline unsigned int getDefaultTextureId() const {return _defaultTextureId;} - - struct LIB_STROKE_EXPORT Options - { - - static void setPatternsPath(const string& path); - static string getPatternsPath(); - - static void setBrushesPath(const string& path); - static string getBrushesPath(); - }; - - protected: - virtual void loadStandardBrushes() = 0; - virtual unsigned loadBrush(string fileName, Stroke::MediumType = Stroke::OPAQUE_MEDIUM) = 0; - - typedef std::pair BrushTexture; - struct cmpBrushTexture{ - bool operator()(const BrushTexture& bt1, const BrushTexture& bt2) const{ - int r = strcmp(bt1.first.c_str(), bt2.first.c_str()); - if(r != 0) - return (r<0); - else - return (bt1.second < bt2.second); - } - }; - typedef std::map brushesMap; - - static TextureManager * _pInstance; - bool _hasLoadedTextures; - brushesMap _brushesMap; - static string _patterns_path; - static string _brushes_path; - unsigned int _defaultTextureId; + TextureManager (); + virtual ~TextureManager (); + + static TextureManager *getInstance() + { + return _pInstance; + } + + void load(); + unsigned getBrushTextureIndex(string name, Stroke::MediumType iType = Stroke::OPAQUE_MEDIUM); + + inline bool hasLoaded() const + { + return _hasLoadedTextures; + } + + inline unsigned int getDefaultTextureId() const + { + return _defaultTextureId; + } + + struct LIB_STROKE_EXPORT Options + { + static void setPatternsPath(const string& path); + static string getPatternsPath(); + + static void setBrushesPath(const string& path); + static string getBrushesPath(); + }; + +protected: + virtual void loadStandardBrushes() = 0; + virtual unsigned loadBrush(string fileName, Stroke::MediumType = Stroke::OPAQUE_MEDIUM) = 0; + + typedef std::pair BrushTexture; + struct cmpBrushTexture + { + bool operator()(const BrushTexture& bt1, const BrushTexture& bt2) const + { + int r = strcmp(bt1.first.c_str(), bt2.first.c_str()); + if (r != 0) + return (r < 0); + else + return (bt1.second < bt2.second); + } + }; + typedef std::map brushesMap; + + static TextureManager *_pInstance; + bool _hasLoadedTextures; + brushesMap _brushesMap; + static string _patterns_path; + static string _brushes_path; + unsigned int _defaultTextureId; }; @@ -106,27 +123,23 @@ public: /* */ /**********************************/ -/*! Class to render a stroke. - Creates a triangle strip and stores it - strip is lazily created at the first rendering -*/ +/*! Class to render a stroke. Creates a triangle strip and stores it strip is lazily created at the first rendering */ class LIB_STROKE_EXPORT StrokeRenderer { - public: - StrokeRenderer(); - virtual ~StrokeRenderer (); - - /*! Renders a stroke rep */ - virtual void RenderStrokeRep(StrokeRep *iStrokeRep) const = 0; - virtual void RenderStrokeRepBasic(StrokeRep *iStrokeRep) const = 0; - - // initializes the texture manager - // lazy, checks if it has already been done - static bool loadTextures() ; - - //static unsigned int getTextureIndex(unsigned int index) ; - static TextureManager *_textureManager; -}; +public: + StrokeRenderer(); + virtual ~StrokeRenderer(); + /*! Renders a stroke rep */ + virtual void RenderStrokeRep(StrokeRep *iStrokeRep) const = 0; + virtual void RenderStrokeRepBasic(StrokeRep *iStrokeRep) const = 0; + + // initializes the texture manager + // lazy, checks if it has already been done + static bool loadTextures(); + + //static unsigned int getTextureIndex(unsigned int index); + static TextureManager *_textureManager; +}; -#endif // STROKE_RENDERER_H +#endif // __FREESTYLE_STROKE_RENDERER_H__ diff --git a/source/blender/freestyle/intern/stroke/StrokeRep.cpp b/source/blender/freestyle/intern/stroke/StrokeRep.cpp index 91f9d866c86..e69b4dab712 100644 --- a/source/blender/freestyle/intern/stroke/StrokeRep.cpp +++ b/source/blender/freestyle/intern/stroke/StrokeRep.cpp @@ -1,652 +1,689 @@ - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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 ***** + */ + +/** \file blender/freestyle/intern/stroke/StrokeRep.cpp + * \ingroup freestyle + * \brief Class to define the representation of a stroke (for display purpose) + * \author Stephane Grabli + * \date 05/03/2003 + */ #include "Stroke.h" -#include "StrokeRep.h" -#include "StrokeRenderer.h" #include "StrokeAdvancedIterators.h" #include "StrokeIterators.h" +#include "StrokeRenderer.h" +#include "StrokeRep.h" using namespace std; // // STROKE VERTEX REP ///////////////////////////////////// -StrokeVertexRep::StrokeVertexRep(const StrokeVertexRep& iBrother){ - _point2d = iBrother._point2d; - _texCoord = iBrother._texCoord; - _color = iBrother._color; - _alpha = iBrother._alpha; + +StrokeVertexRep::StrokeVertexRep(const StrokeVertexRep& iBrother) +{ + _point2d = iBrother._point2d; + _texCoord = iBrother._texCoord; + _color = iBrother._color; + _alpha = iBrother._alpha; } // // STRIP ///////////////////////////////////// -Strip::Strip(const vector& iStrokeVertices, bool hasTips, bool beginTip, bool endTip){ - createStrip(iStrokeVertices); - if (!hasTips) - computeTexCoord (iStrokeVertices); - else - computeTexCoordWithTips (iStrokeVertices, beginTip, endTip); +Strip::Strip(const vector& iStrokeVertices, bool hasTips, bool beginTip, bool endTip) +{ + createStrip(iStrokeVertices); + if (!hasTips) + computeTexCoord (iStrokeVertices); + else + computeTexCoordWithTips (iStrokeVertices, beginTip, endTip); } -Strip::Strip(const Strip& iBrother){ - if(!iBrother._vertices.empty()){ - for(vertex_container::const_iterator v=iBrother._vertices.begin(), vend=iBrother._vertices.end(); - v!=vend; - ++v){ - _vertices.push_back(new StrokeVertexRep(**v)); - } - } - _averageThickness = iBrother._averageThickness; + +Strip::Strip(const Strip& iBrother) +{ + if (!iBrother._vertices.empty()) { + for (vertex_container::const_iterator v = iBrother._vertices.begin(), vend = iBrother._vertices.end(); + v != vend; + ++v) + { + _vertices.push_back(new StrokeVertexRep(**v)); + } + } + _averageThickness = iBrother._averageThickness; } -Strip::~Strip(){ - if(!_vertices.empty()){ - for(vertex_container::iterator v=_vertices.begin(), vend=_vertices.end(); - v!=vend; - ++v){ - delete (*v); - } - _vertices.clear(); - } +Strip::~Strip() +{ + if (!_vertices.empty()) { + for (vertex_container::iterator v = _vertices.begin(), vend = _vertices.end(); v != vend; ++v) { + delete (*v); + } + _vertices.clear(); + } } ////////////////////////// // Strip creation ////////////////////////// + #define EPS_SINGULARITY_RENDERER 0.05 #define ZERO 0.00001 #define MAX_RATIO_LENGTH_SINGU 2 -#define HUGE_COORD 1e4 +#define HUGE_COORD 1.0e4 static bool notValid (Vec2r p) { - return (p[0]!=p[0]) || (p[1]!=p[1]) || (fabs(p[0])>HUGE_COORD) || (fabs(p[1])>HUGE_COORD) - || (p[0] <-HUGE_COORD) || (p[1]<-HUGE_COORD); + return (p[0] != p[0]) || (p[1] != p[1]) || (fabs(p[0]) > HUGE_COORD) || (fabs(p[1]) > HUGE_COORD) || + (p[0] < -HUGE_COORD) || (p[1] < -HUGE_COORD); } -static real crossP(const Vec2r& A, const Vec2r& B){ - return A[0]*B[1] - A[1]*B[0]; +static real crossP(const Vec2r& A, const Vec2r& B) +{ + return A[0] * B[1] - A[1] * B[0]; } -void -Strip::createStrip (const vector& iStrokeVertices) +void Strip::createStrip (const vector& iStrokeVertices) { - //computeParameterization(); - if (iStrokeVertices.size() <2) - { - cerr << "Warning: strip has less than 2 vertices" << endl; - return; - } - _vertices.reserve(2*iStrokeVertices.size()); - if(!_vertices.empty()){ - for(vertex_container::iterator v=_vertices.begin(), vend=_vertices.end(); - v!=vend; - ++v){ - delete (*v); - } - _vertices.clear(); - } - _averageThickness=0.0; - - vector::const_iterator v ,vend, v2, vPrev; - StrokeVertex *sv, *sv2, *svPrev; - - //special case of first vertex - v=iStrokeVertices.begin(); - sv=*v; - vPrev=v; //in case the stroke has only 2 vertices; - ++v; sv2=*v; - Vec2r dir(sv2->getPoint()-sv->getPoint()); - Vec2r orthDir(-dir[1], dir[0]); - if (orthDir.norm() > ZERO) - orthDir.normalize(); - Vec2r stripDir(orthDir); - // check whether the orientation was user defined - if(sv->attribute().isAttributeAvailableVec2f("orientation")){ - Vec2r userDir = sv->attribute().getAttributeVec2f("orientation"); - userDir.normalize(); - real dp = userDir*orthDir; - if(dp<0) - userDir = userDir*(-1.f); - stripDir = userDir; - } - const float *thickness = sv->attribute().getThickness(); - _vertices.push_back(new StrokeVertexRep(sv->getPoint()+thickness[1]*stripDir)); - _vertices.push_back(new StrokeVertexRep(sv->getPoint()-thickness[0]*stripDir)); - - // Vec2r userDir = _stroke->getBeginningOrientation(); - // if(userDir != Vec2r(0,0)){ - // userDir.normalize(); - // real o1 = (orthDir*userDir); - // real o2 = crossP(orthDir,userDir); - // real orientation = o1 * o2; - // if(orientation > 0){ - // // then the vertex to move is v0 - // if(o1 > 0) - // _vertex[0]=_vertex[1]+userDir; - // else - // _vertex[0]=_vertex[1]-userDir; - // } - // if(orientation < 0){ - // // then we must move v1 - // if(o1 < 0) - // _vertex[1]=_vertex[0]+userDir; - // else - // _vertex[1]=_vertex[0]-userDir; - // } - // } - - int i=2; //2 because we have already processed the first vertex - - for(vend=iStrokeVertices.end(); - v!=vend; - v++){ - v2=v; ++v2; - if (v2==vend) break; - sv= (*v); sv2 = (*v2); svPrev=(*vPrev); - Vec2r p(sv->getPoint()), p2(sv2->getPoint()), pPrev(svPrev->getPoint()); - - //direction and orthogonal vector to the next segment - Vec2r dir(p2-p); - float dirNorm=dir.norm(); - dir.normalize(); - Vec2r orthDir(-dir[1], dir[0]); - Vec2r stripDir = orthDir; - if(sv->attribute().isAttributeAvailableVec2f("orientation")){ - Vec2r userDir = sv->attribute().getAttributeVec2f("orientation"); - userDir.normalize(); - real dp = userDir*orthDir; - if(dp<0) - userDir = userDir*(-1.f); - stripDir = userDir; - } - - //direction and orthogonal vector to the previous segment - Vec2r dirPrev(p-pPrev); - float dirPrevNorm=dirPrev.norm(); - dirPrev.normalize(); - Vec2r orthDirPrev(-dirPrev[1], dirPrev[0]); - Vec2r stripDirPrev = orthDirPrev; - if(svPrev->attribute().isAttributeAvailableVec2f("orientation")){ - Vec2r userDir = svPrev->attribute().getAttributeVec2f("orientation"); - userDir.normalize(); - real dp = userDir*orthDir; - if(dp<0) - userDir = userDir*(-1.f); - stripDirPrev = userDir; - } - - const float *thickness = sv->attribute().getThickness(); - _averageThickness+=thickness[0]+thickness[1]; - Vec2r pInter; - int interResult; - - interResult=GeomUtils::intersect2dLine2dLine(Vec2r(pPrev+thickness[1]*stripDirPrev), Vec2r(p+thickness[1]*stripDirPrev), - Vec2r(p+thickness[1]*stripDir), Vec2r(p2+thickness[1]*stripDir), - pInter); - - if (interResult==GeomUtils::DO_INTERSECT) - _vertices.push_back(new StrokeVertexRep(pInter)); - else - _vertices.push_back(new StrokeVertexRep(p+thickness[1]*stripDir)); - ++i; - - interResult=GeomUtils::intersect2dLine2dLine(Vec2r(pPrev-thickness[0]*stripDirPrev), Vec2r(p-thickness[0]*stripDirPrev), - Vec2r(p-thickness[0]*stripDir), Vec2r(p2-thickness[0]*stripDir), - pInter); - if (interResult==GeomUtils::DO_INTERSECT) - _vertices.push_back(new StrokeVertexRep(pInter)); - else - _vertices.push_back(new StrokeVertexRep(p-thickness[0]*stripDir)); - ++i; - - // if the angle is obtuse, we simply average the directions to avoid the singularity - stripDir=stripDir+stripDirPrev; - if ((dirNormpoint2d()-p); - if ((vec_tmp.norm() > thickness[1]*MAX_RATIO_LENGTH_SINGU) || - (dirNormpoint2d()) - || (fabs(stripDir * dir) < EPS_SINGULARITY_RENDERER)) - _vertices[i-2]->setPoint2d(p+thickness[1]*stripDir); - - vec_tmp = _vertices[i-1]->point2d()-p; - if ((vec_tmp.norm() > thickness[0]*MAX_RATIO_LENGTH_SINGU) || - (dirNormpoint2d()) - || (fabs(stripDir * dir)setPoint2d(p-thickness[0]*stripDir); - - vPrev=v; - } // end of for - - //special case of last vertex - sv=*v; - sv2=*vPrev; - dir=Vec2r (sv->getPoint()-sv2->getPoint()); - orthDir=Vec2r(-dir[1], dir[0]); - if (orthDir.norm() > ZERO) - orthDir.normalize(); - Vec2r stripDirLast(orthDir); - // check whether the orientation was user defined - if(sv->attribute().isAttributeAvailableVec2f("orientation")){ - Vec2r userDir = sv->attribute().getAttributeVec2f("orientation"); - userDir.normalize(); - real dp = userDir*orthDir; - if(dp<0) - userDir = userDir*(-1.f); - stripDirLast = userDir; - } - const float *thicknessLast = sv->attribute().getThickness(); - _vertices.push_back(new StrokeVertexRep(sv->getPoint()+thicknessLast[1]*stripDirLast)); - ++i; - _vertices.push_back(new StrokeVertexRep(sv->getPoint()-thicknessLast[0]*stripDirLast)); - int n = i; - ++i; - - // check whether the orientation of the extremity - // was user defined - // userDir = _stroke->getEndingOrientation(); - // if(userDir != Vec2r(0,0)){ - // userDir.normalize(); - // real o1 = (orthDir*userDir); - // real o2 = crossP(orthDir,userDir); - // real orientation = o1 * o2; - // if(orientation > 0){ - // // then the vertex to move is vn - // if(o1 < 0) - // _vertex[n]=_vertex[n-1]+userDir; - // else - // _vertex[n]=_vertex[n-1]-userDir; - // } - // if(orientation < 0){ - // // then we must move vn-1 - // if(o1 > 0) - // _vertex[n-1]=_vertex[n]+userDir; - // else - // _vertex[n-1]=_vertex[n]-userDir; - // } - // } - - _averageThickness/=float(iStrokeVertices.size()-2); - //I did not use the first and last vertex for the average - if (iStrokeVertices.size()<3) - _averageThickness=0.5*(thicknessLast[1]+thicknessLast[0]+thickness[0]+thickness[1]); - - if (i != 2*(int)iStrokeVertices.size()) - cerr << "Warning: problem with stripe size\n"; - - cleanUpSingularities (iStrokeVertices); -} + //computeParameterization(); + if (iStrokeVertices.size() < 2) { + cerr << "Warning: strip has less than 2 vertices" << endl; + return; + } + _vertices.reserve(2 * iStrokeVertices.size()); + if (!_vertices.empty()) { + for (vertex_container::iterator v = _vertices.begin(), vend = _vertices.end(); v != vend; ++v) { + delete (*v); + } + _vertices.clear(); + } + _averageThickness = 0.0; + + vector::const_iterator v ,vend, v2, vPrev; + StrokeVertex *sv, *sv2, *svPrev; + + //special case of first vertex + v = iStrokeVertices.begin(); + sv = *v; + vPrev = v; //in case the stroke has only 2 vertices; + ++v; + sv2 = *v; + Vec2r dir(sv2->getPoint() - sv->getPoint()); + Vec2r orthDir(-dir[1], dir[0]); + if (orthDir.norm() > ZERO) + orthDir.normalize(); + Vec2r stripDir(orthDir); + // check whether the orientation was user defined + if (sv->attribute().isAttributeAvailableVec2f("orientation")) { + Vec2r userDir = sv->attribute().getAttributeVec2f("orientation"); + userDir.normalize(); + real dp = userDir * orthDir; + if (dp < 0) + userDir = userDir * (-1.0f); + stripDir = userDir; + } + const float *thickness = sv->attribute().getThickness(); + _vertices.push_back(new StrokeVertexRep(sv->getPoint() + thickness[1] * stripDir)); + _vertices.push_back(new StrokeVertexRep(sv->getPoint() - thickness[0] * stripDir)); + +#if 0 + Vec2r userDir = _stroke->getBeginningOrientation(); + if (userDir != Vec2r(0, 0)) { + userDir.normalize(); + real o1 = (orthDir * userDir); + real o2 = crossP(orthDir, userDir); + real orientation = o1 * o2; + if (orientation > 0) { + // then the vertex to move is v0 + if (o1 > 0) + _vertex[0] = _vertex[1] + userDir; + else + _vertex[0] = _vertex[1] - userDir; + } + if (orientation < 0) { + // then we must move v1 + if (o1 < 0) + _vertex[1] = _vertex[0] + userDir; + else + _vertex[1] = _vertex[0] - userDir; + } + } +#endif + + int i = 2; // 2 because we have already processed the first vertex + + for (vend = iStrokeVertices.end(); v != vend; ++v) { + v2 = v; + ++v2; + if (v2 == vend) + break; + sv = (*v); + sv2 = (*v2); + svPrev = (*vPrev); + Vec2r p(sv->getPoint()), p2(sv2->getPoint()), pPrev(svPrev->getPoint()); + + //direction and orthogonal vector to the next segment + Vec2r dir(p2 - p); + float dirNorm = dir.norm(); + dir.normalize(); + Vec2r orthDir(-dir[1], dir[0]); + Vec2r stripDir = orthDir; + if (sv->attribute().isAttributeAvailableVec2f("orientation")) { + Vec2r userDir = sv->attribute().getAttributeVec2f("orientation"); + userDir.normalize(); + real dp = userDir * orthDir; + if (dp < 0) + userDir = userDir * (-1.0f); + stripDir = userDir; + } + + //direction and orthogonal vector to the previous segment + Vec2r dirPrev(p - pPrev); + float dirPrevNorm = dirPrev.norm(); + dirPrev.normalize(); + Vec2r orthDirPrev(-dirPrev[1], dirPrev[0]); + Vec2r stripDirPrev = orthDirPrev; + if (svPrev->attribute().isAttributeAvailableVec2f("orientation")) { + Vec2r userDir = svPrev->attribute().getAttributeVec2f("orientation"); + userDir.normalize(); + real dp = userDir * orthDir; + if (dp < 0) + userDir = userDir * (-1.0f); + stripDirPrev = userDir; + } + + const float *thickness = sv->attribute().getThickness(); + _averageThickness += thickness[0] + thickness[1]; + Vec2r pInter; + int interResult; + + interResult = GeomUtils::intersect2dLine2dLine(Vec2r(pPrev + thickness[1] * stripDirPrev), + Vec2r(p + thickness[1] * stripDirPrev), + Vec2r(p + thickness[1] * stripDir), + Vec2r(p2 + thickness[1] * stripDir), + pInter); + if (interResult == GeomUtils::DO_INTERSECT) + _vertices.push_back(new StrokeVertexRep(pInter)); + else + _vertices.push_back(new StrokeVertexRep(p + thickness[1] * stripDir)); + ++i; + + interResult = GeomUtils::intersect2dLine2dLine(Vec2r(pPrev - thickness[0] * stripDirPrev), + Vec2r(p - thickness[0] * stripDirPrev), + Vec2r(p - thickness[0] * stripDir), + Vec2r(p2 - thickness[0] * stripDir), + pInter); + if (interResult == GeomUtils::DO_INTERSECT) + _vertices.push_back(new StrokeVertexRep(pInter)); + else + _vertices.push_back(new StrokeVertexRep(p - thickness[0] * stripDir)); + ++i; + + // if the angle is obtuse, we simply average the directions to avoid the singularity + stripDir = stripDir + stripDirPrev; + if ((dirNorm < ZERO) || (dirPrevNorm < ZERO) || (stripDir.norm() < ZERO)) { + stripDir[0] = 0; + stripDir[1] = 0; + } + else { + stripDir.normalize(); + } + + Vec2r vec_tmp(_vertices[i - 2]->point2d() - p); + if ((vec_tmp.norm() > thickness[1] * MAX_RATIO_LENGTH_SINGU) || (dirNorm < ZERO) || (dirPrevNorm < ZERO) || + notValid(_vertices[i - 2]->point2d()) || (fabs(stripDir * dir) < EPS_SINGULARITY_RENDERER)) + { + _vertices[i - 2]->setPoint2d(p + thickness[1] * stripDir); + } + + vec_tmp = _vertices[i - 1]->point2d() - p; + if ((vec_tmp.norm() > thickness[0] * MAX_RATIO_LENGTH_SINGU) || (dirNorm < ZERO) || (dirPrevNorm < ZERO) || + notValid(_vertices[i - 1]->point2d()) || (fabs(stripDir * dir) < EPS_SINGULARITY_RENDERER)) + { + _vertices[i - 1]->setPoint2d(p - thickness[0] * stripDir); + } + + vPrev = v; + } // end of for + + //special case of last vertex + sv = *v; + sv2 = *vPrev; + dir = Vec2r(sv->getPoint() - sv2->getPoint()); + orthDir = Vec2r(-dir[1], dir[0]); + if (orthDir.norm() > ZERO) + orthDir.normalize(); + Vec2r stripDirLast(orthDir); + // check whether the orientation was user defined + if (sv->attribute().isAttributeAvailableVec2f("orientation")) { + Vec2r userDir = sv->attribute().getAttributeVec2f("orientation"); + userDir.normalize(); + real dp = userDir * orthDir; + if (dp < 0) + userDir = userDir * (-1.0f); + stripDirLast = userDir; + } + const float *thicknessLast = sv->attribute().getThickness(); + _vertices.push_back(new StrokeVertexRep(sv->getPoint() + thicknessLast[1] * stripDirLast)); + ++i; + _vertices.push_back(new StrokeVertexRep(sv->getPoint() - thicknessLast[0] * stripDirLast)); + int n = i; + ++i; + +#if 0 + // check whether the orientation of the extremity was user defined + userDir = _stroke->getEndingOrientation(); + if (userDir != Vec2r(0, 0)) { + userDir.normalize(); + real o1 = (orthDir * userDir); + real o2 = crossP(orthDir, userDir); + real orientation = o1 * o2; + if (orientation > 0) { + // then the vertex to move is vn + if (o1 < 0) + _vertex[n] = _vertex[n - 1] + userDir; + else + _vertex[n] = _vertex[n - 1] - userDir; + } + if (orientation < 0) { + // then we must move vn-1 + if (o1 > 0) + _vertex[n - 1] = _vertex[n] + userDir; + else + _vertex[n - 1] = _vertex[n] - userDir; + } + } +#endif + + _averageThickness /= float(iStrokeVertices.size() - 2); + //I did not use the first and last vertex for the average + if (iStrokeVertices.size() < 3) + _averageThickness = 0.5 * (thicknessLast[1] + thicknessLast[0] + thickness[0] + thickness[1]); + + if (i != 2 * (int)iStrokeVertices.size()) + cerr << "Warning: problem with stripe size\n"; + + cleanUpSingularities (iStrokeVertices); +} // CLEAN UP ///////////////////////// -void -Strip::cleanUpSingularities (const vector& iStrokeVertices) +void Strip::cleanUpSingularities (const vector& iStrokeVertices) { - int k; - int sizeStrip = _vertices.size(); - - for (k=0; kpoint2d())) - { - cerr << "Warning: strip vertex " << k << " non valid" << endl; - return; - } - - //return; - if (iStrokeVertices.size()<2) return; - int i=0, j; - vector::const_iterator v ,vend, v2, vPrev; -StrokeVertex *sv, *sv2; //soc unused - *svPrev; - - bool singu1=false, singu2=false; - int timeSinceSingu1=0, timeSinceSingu2=0; - - //special case of first vertex - v=iStrokeVertices.begin(); - for(vend=iStrokeVertices.end(); - v!=vend; - v++) - { - v2=v; ++v2; - if (v2==vend) break; - sv= (*v); sv2 = (*v2); - Vec2r p(sv->getPoint()), p2(sv2->getPoint()); - - Vec2r dir(p2-p); - if (dir.norm() > ZERO) - dir.normalize(); - Vec2r dir1, dir2; - dir1=_vertices[2*i+2]->point2d()-_vertices[2*i]->point2d(); - dir2=_vertices[2*i+3]->point2d()-_vertices[2*i+1]->point2d(); - - if ((dir1 * dir) < -ZERO) - { - singu1=true; - timeSinceSingu1++; + int k; + int sizeStrip = _vertices.size(); + + for (k = 0; k < sizeStrip; k++) { + if (notValid(_vertices[k]->point2d())) { + cerr << "Warning: strip vertex " << k << " non valid" << endl; + return; + } } - else - { - if (singu1) - { - int toto=i-timeSinceSingu1; - if (toto<0) - cerr << "Stephane dit \"Toto\"" << endl; - //traverse all the vertices of the singularity and average them - Vec2r avP(0.0,0.0); - for (j=i-timeSinceSingu1; jpoint2d()); - avP=Vec2r(1.0/float(timeSinceSingu1+1)*avP); - for (j=i-timeSinceSingu1; jsetPoint2d(avP); - //_vertex[2*j]=_vertex[2*i]; - singu1=false; timeSinceSingu1=0; - } + + //return; + if (iStrokeVertices.size() < 2) + return; + int i = 0, j; + vector::const_iterator v ,vend, v2, vPrev; + StrokeVertex *sv, *sv2; //soc unused - *svPrev; + + bool singu1 = false, singu2 = false; + int timeSinceSingu1 = 0, timeSinceSingu2 = 0; + + //special case of first vertex + v = iStrokeVertices.begin(); + for (vend = iStrokeVertices.end(); v != vend; v++) { + v2 = v; + ++v2; + if (v2 == vend) + break; + sv = (*v); + sv2 = (*v2); + Vec2r p(sv->getPoint()), p2(sv2->getPoint()); + + Vec2r dir(p2-p); + if (dir.norm() > ZERO) + dir.normalize(); + Vec2r dir1, dir2; + dir1 = _vertices[2 * i + 2]->point2d() - _vertices[2 * i]->point2d(); + dir2 = _vertices[2 * i + 3]->point2d() - _vertices[2 * i + 1]->point2d(); + + if ((dir1 * dir) < -ZERO) { + singu1 = true; + timeSinceSingu1++; + } + else { + if (singu1) { + int toto = i - timeSinceSingu1; + if (toto < 0) + cerr << "Stephane dit \"Toto\"" << endl; + //traverse all the vertices of the singularity and average them + Vec2r avP(0.0, 0.0); + for (j = i - timeSinceSingu1; j < i + 1; j++) + avP=Vec2r(avP + _vertices[2 * j]->point2d()); + avP = Vec2r( 1.0 / float(timeSinceSingu1 + 1) * avP); + for (j = i - timeSinceSingu1; j < i + 1; j++) + _vertices[2 * j]->setPoint2d(avP); + //_vertex[2 * j] = _vertex[2 * i]; + singu1 = false; + timeSinceSingu1 = 0; + } + } + if ((dir2 * dir) < -ZERO) { + singu2 = true; + timeSinceSingu2++; + } + else { + if (singu2) { + int toto = i - timeSinceSingu2; + if (toto < 0) + cerr << "Stephane dit \"Toto\"" << endl; + //traverse all the vertices of the singularity and average them + Vec2r avP(0.0, 0.0); + for (j = i - timeSinceSingu2; j < i + 1; j++) + avP = Vec2r(avP + _vertices[2 * j + 1]->point2d()); + avP = Vec2r(1.0 / float(timeSinceSingu2 + 1) * avP); + for (j = i - timeSinceSingu2; j < i + 1; j++) + _vertices[2 * j + 1]->setPoint2d(avP); + //_vertex[2 * j + 1] = _vertex[2 * i + 1]; + singu2 = false; + timeSinceSingu2 = 0; + } + } + i++; } - if ((dir2 * dir) < -ZERO) - { - singu2=true; - timeSinceSingu2++; + + if (singu1) { + //traverse all the vertices of the singularity and average them + Vec2r avP(0.0, 0.0); + for (j = i - timeSinceSingu1; j < i; j++) + avP = Vec2r(avP + _vertices[2 * j]->point2d()); + avP = Vec2r(1.0 / float(timeSinceSingu1) * avP); + for (j = i - timeSinceSingu1; j < i; j++) + _vertices[2 * j]->setPoint2d(avP); + } + if (singu2) { + //traverse all the vertices of the singularity and average them + Vec2r avP(0.0, 0.0); + for (j = i - timeSinceSingu2; j < i; j++) + avP = Vec2r(avP + _vertices[2 * j + 1]->point2d()); + avP = Vec2r(1.0 / float(timeSinceSingu2) * avP); + for (j = i - timeSinceSingu2; j < i; j++) + _vertices[2 * j + 1]->setPoint2d(avP); + } + + for (k=0; kpoint2d())) { + cerr << "Warning: strip vertex " << k << " non valid after cleanup" << endl; + return; + } } - else - { - if (singu2) - { - int toto=i-timeSinceSingu2; - if (toto<0) - cerr << "Stephane dit \"Toto\"" << endl; - //traverse all the vertices of the singularity and average them - Vec2r avP(0.0,0.0); - for (j=i-timeSinceSingu2; jpoint2d()); - avP=Vec2r(1.0/float(timeSinceSingu2+1)*avP); - for (j=i-timeSinceSingu2; jsetPoint2d(avP); - //_vertex[2*j+1]=_vertex[2*i+1]; - singu2=false; timeSinceSingu2=0; - } - } - i++; - } - - if (singu1) - { - //traverse all the vertices of the singularity and average them - Vec2r avP(0.0,0.0); - for (j=i-timeSinceSingu1; jpoint2d()); - avP=Vec2r(1.0/float(timeSinceSingu1)*avP); - for (j=i-timeSinceSingu1; jsetPoint2d(avP); - } - if (singu2) - { - //traverse all the vertices of the singularity and average them - Vec2r avP(0.0,0.0); - for (j=i-timeSinceSingu2; jpoint2d()); - avP=Vec2r(1.0/float(timeSinceSingu2)*avP); - for (j=i-timeSinceSingu2; jsetPoint2d(avP); - } - - - for (k=0; kpoint2d())) - { - cerr << "Warning: strip vertex " << k << " non valid after cleanup"<& iStrokeVertices) +void Strip::computeTexCoord (const vector& iStrokeVertices) { - vector::const_iterator v ,vend; - StrokeVertex *sv; - int i=0; - for(v=iStrokeVertices.begin(), vend=iStrokeVertices.end(); - v!=vend; v++) - { - sv= (*v); - _vertices[i]->setTexCoord(Vec2r((real)(sv->curvilinearAbscissa() / _averageThickness),0)); - _vertices[i]->setColor(Vec3r(sv->attribute().getColor()[0],sv->attribute().getColor()[1],sv->attribute().getColor()[2])); - _vertices[i]->setAlpha(sv->attribute().getAlpha()); - i++; - _vertices[i]->setTexCoord(Vec2r((real)(sv->curvilinearAbscissa() / _averageThickness),1)); - _vertices[i]->setColor(Vec3r(sv->attribute().getColor()[0],sv->attribute().getColor()[1],sv->attribute().getColor()[2])); - _vertices[i]->setAlpha(sv->attribute().getAlpha()); - i++; - // cerr<<"col=("<attribute().getColor()[0]<<", " - // <attribute().getColor()[1]<<", "<attribute().getColor()[2]<<")"<::const_iterator v ,vend; + StrokeVertex *sv; + int i = 0; + for (v = iStrokeVertices.begin(), vend = iStrokeVertices.end(); v != vend; v++) { + sv = (*v); + _vertices[i]->setTexCoord(Vec2r((real)(sv->curvilinearAbscissa() / _averageThickness), 0)); + _vertices[i]->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1], + sv->attribute().getColor()[2])); + _vertices[i]->setAlpha(sv->attribute().getAlpha()); + i++; + _vertices[i]->setTexCoord(Vec2r((real)(sv->curvilinearAbscissa() / _averageThickness), 1)); + _vertices[i]->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1], + sv->attribute().getColor()[2])); + _vertices[i]->setAlpha(sv->attribute().getAlpha()); + i++; +#if 0 + cerr << "col=("<attribute().getColor()[0] << ", " + << sv->attribute().getColor()[1] << ", " << sv->attribute().getColor()[2] << ")" << endl; +#endif + } } -void -Strip::computeTexCoordWithTips (const vector& iStrokeVertices, bool tipBegin, bool tipEnd) +void Strip::computeTexCoordWithTips (const vector& iStrokeVertices, bool tipBegin, bool tipEnd) { - //soc unused - unsigned int sizeStrip = _vertices.size()+8; //for the transition between the tip and the body - vector::const_iterator v ,vend; - StrokeVertex *sv = 0; - - v=iStrokeVertices.begin(); - vend=iStrokeVertices.end(); - float l=(*v)->strokeLength()/_averageThickness; - int tiles=int(l); - float fact=(float(tiles)+0.5)/l; - //soc unused - float uTip2=float(tiles)+0.25; - float u=0; - float uPrev=0; - int i=0; - float t; - StrokeVertexRep *tvRep1, *tvRep2; - - // cerr<<"l="< 4*_averageThickness) - // cerr << "Warning (from Fredo): There is a pb in the texture coordinates computation" << endl; + //soc unused - unsigned int sizeStrip = _vertices.size() + 8; //for the transition between the tip and the body + vector::const_iterator v, vend; + StrokeVertex *sv = NULL; + + v = iStrokeVertices.begin(); + vend = iStrokeVertices.end(); + float l = (*v)->strokeLength() / _averageThickness; + int tiles = int(l); + float fact = (float(tiles) + 0.5) / l; + //soc unused - float uTip2 = float(tiles) + 0.25; + float u = 0; + float uPrev = 0; + int i = 0; + float t; + StrokeVertexRep *tvRep1, *tvRep2; + +#if 0 + cerr << "l=" << l << " tiles=" << tiles << " _averageThicnkess=" + << _averageThickness << " strokeLength=" << (*v)->strokeLength() << endl; +#endif + + vector::iterator currentSV = _vertices.begin(); + StrokeVertexRep *svRep; + if (tipBegin) { + for (; v != vend; v++) { + sv = (*v); + svRep = *currentSV; + u = sv->curvilinearAbscissa() / _averageThickness * fact; + if (u > 0.25) + break; + + svRep->setTexCoord(Vec2r((real)u, 0.5)); + svRep->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1], + sv->attribute().getColor()[2])); + svRep->setAlpha(sv->attribute().getAlpha()); + i++; + ++currentSV; + + svRep = *currentSV; + svRep->setTexCoord(Vec2r((real)u, 1)); + svRep->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1], + sv->attribute().getColor()[2])); + svRep->setAlpha(sv->attribute().getAlpha()); + i++; + ++currentSV; + uPrev = u; + } + //first transition vertex + + if (fabs(u - uPrev) > ZERO) + t = (0.25 - uPrev) / (u - uPrev); + else + t = 0; +#if 0 + if (!tiles) + t = 0.5; +#endif + tvRep1 = new StrokeVertexRep(Vec2r((1 - t) * _vertices[i - 2]->point2d() + t * _vertices[i]->point2d())); + tvRep1->setTexCoord(Vec2r(0.25, 0.5)); + tvRep1->setColor(Vec3r((1 - t) * _vertices[i - 2]->color() + + t * Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1], + sv->attribute().getColor()[2]))); + tvRep1->setAlpha((1 - t) * _vertices[i - 2]->alpha() + t * sv->attribute().getAlpha()); + i++; + + tvRep2 = new StrokeVertexRep(Vec2r((1 - t) * _vertices[i - 2]->point2d() + t *_vertices[i]->point2d())); + tvRep2->setTexCoord(Vec2r(0.25, 1)); + tvRep2->setColor(Vec3r((1 - t) * _vertices[i - 2]->color() + + t * Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1], + sv->attribute().getColor()[2]))); + tvRep2->setAlpha((1 - t) * _vertices[i - 2]->alpha() + t * sv->attribute().getAlpha()); + i++; + + currentSV = _vertices.insert(currentSV, tvRep1); + ++currentSV; + currentSV = _vertices.insert(currentSV, tvRep2); + ++currentSV; + + // copy the vertices with different texture coordinates + tvRep1 = new StrokeVertexRep(_vertices[i - 2]->point2d()); + tvRep1->setTexCoord(Vec2r(0.25, 0)); + tvRep1->setColor(_vertices[i - 2]->color()); + tvRep1->setAlpha(_vertices[i - 2]->alpha()); + i++; + + tvRep2 = new StrokeVertexRep(_vertices[i - 2]->point2d()); + tvRep2->setTexCoord(Vec2r(0.25, 0.5)); + tvRep2->setColor(_vertices[i - 2]->color()); + tvRep2->setAlpha(_vertices[i - 2]->alpha()); + i++; + + currentSV = _vertices.insert(currentSV, tvRep1); + ++currentSV; + currentSV = _vertices.insert(currentSV, tvRep2); + ++currentSV; + } + uPrev = 0; + + //body of the stroke + for (; v != vend; v++) { + sv = (*v); + svRep = *currentSV; + u = sv->curvilinearAbscissa() / _averageThickness * fact - 0.25; + if (u > tiles) + break; + + svRep->setTexCoord(Vec2r((real)u, 0)); + svRep->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1], + sv->attribute().getColor()[2])); + svRep->setAlpha(sv->attribute().getAlpha()); + i++; + ++currentSV; + + svRep = *currentSV; + svRep->setTexCoord(Vec2r((real)u, 0.5)); + svRep->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1], + sv->attribute().getColor()[2])); + svRep->setAlpha(sv->attribute().getAlpha()); + i++; + ++currentSV; + + uPrev = u; + } + if (tipEnd) { + //second transition vertex + if ((fabs(u - uPrev) > ZERO)) + t = (float(tiles) - uPrev) / (u - uPrev); + else + t = 0; + + tvRep1 = new StrokeVertexRep(Vec2r((1 - t) * _vertices[i - 2]->point2d() + t * _vertices[i]->point2d())); + tvRep1->setTexCoord(Vec2r((real)tiles, 0)); + tvRep1->setColor(Vec3r((1 - t) * _vertices[i - 2]->color() + + t * Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1], + sv->attribute().getColor()[2]))); + tvRep1->setAlpha((1 - t) * _vertices[i - 2]->alpha() + t * sv->attribute().getAlpha()); + i++; + + tvRep2 = new StrokeVertexRep(Vec2r((1 - t) * _vertices[i - 2]->point2d() + t * _vertices[i]->point2d())); + tvRep2->setTexCoord(Vec2r((real)tiles, 0.5)); + tvRep2->setColor(Vec3r((1 - t) * _vertices[i - 2]->color() + + t * Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1], + sv->attribute().getColor()[2]))); + tvRep2->setAlpha((1 - t) * _vertices[i - 2]->alpha() + t * sv->attribute().getAlpha()); + i++; + + currentSV = _vertices.insert(currentSV, tvRep1); + ++currentSV; + currentSV = _vertices.insert(currentSV, tvRep2); + ++currentSV; + + //copy the vertices with different texture coordinates + tvRep1 = new StrokeVertexRep(_vertices[i - 2]->point2d()); + tvRep1->setTexCoord(Vec2r(0.75, 0.5)); + tvRep1->setColor(_vertices[i - 2]->color()); + tvRep1->setAlpha(_vertices[i - 2]->alpha()); + i++; + + tvRep2 = new StrokeVertexRep(_vertices[i - 2]->point2d()); + tvRep2->setTexCoord(Vec2r(0.75, 1)); + tvRep2->setColor(_vertices[i - 2]->color()); + tvRep2->setAlpha(_vertices[i - 2]->alpha()); + i++; + + currentSV = _vertices.insert(currentSV, tvRep1); + ++currentSV; + currentSV = _vertices.insert(currentSV, tvRep2); + ++currentSV; + + //end tip + for (; v != vend; v++) { + sv = (*v); + svRep = *currentSV; + u = 0.75 + sv->curvilinearAbscissa() / _averageThickness * fact - float(tiles) - 0.25; + + svRep->setTexCoord(Vec2r((real)u, 0.5)); + svRep->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1], + sv->attribute().getColor()[2])); + svRep->setAlpha(sv->attribute().getAlpha()); + i++; + ++currentSV; + + svRep = *currentSV; + svRep->setTexCoord(Vec2r((real)u, 1)); + svRep->setColor(Vec3r(sv->attribute().getColor()[0], sv->attribute().getColor()[1], + sv->attribute().getColor()[2])); + svRep->setAlpha(sv->attribute().getAlpha()); + i++; + ++currentSV; + } + } + +#if 0 + cerr << "u=" << u << " i=" << i << "/" << _sizeStrip << endl; + + for (i = 0; i < _sizeStrip; i++) + _alpha[i] = 1.0; + + for (i = 0; i < _sizeStrip; i++) + cerr << "(" << _texCoord[i][0] << ", " << _texCoord[i][1] << ") "; + cerr << endl; + + Vec2r vec_tmp; + for (i = 0; i < _sizeStrip / 2; i++) + vec_tmp = _vertex[2 * i] - _vertex[2 * i + 1]; + if (vec_tmp.norm() > 4 * _averageThickness) + cerr << "Warning (from Fredo): There is a pb in the texture coordinates computation" << endl; +#endif } // @@ -655,97 +692,98 @@ Strip::computeTexCoordWithTips (const vector& iStrokeVertices, bo StrokeRep::StrokeRep() { - _stroke = 0; - _strokeType=Stroke::OPAQUE_MEDIUM; - TextureManager * ptm = TextureManager::getInstance(); - if(ptm) - _textureId = ptm->getDefaultTextureId(); - // _averageTextureAlpha=0.5; //default value - // if (_strokeType==OIL_STROKE) - // _averageTextureAlpha=0.75; - // if (_strokeType>=NO_BLEND_STROKE) - // _averageTextureAlpha=1.0 -} + _stroke = 0; + _strokeType = Stroke::OPAQUE_MEDIUM; + TextureManager *ptm = TextureManager::getInstance(); + if (ptm) + _textureId = ptm->getDefaultTextureId(); +#if 0 + _averageTextureAlpha = 0.5; //default value + if (_strokeType == OIL_STROKE) + _averageTextureAlpha = 0.75; + if (_strokeType >= NO_BLEND_STROKE) + _averageTextureAlpha = 1.0 +#endif +} StrokeRep::StrokeRep(Stroke *iStroke) { - _stroke = iStroke; - _strokeType = iStroke->getMediumType(); - _textureId = iStroke->getTextureId(); - if(_textureId == 0){ - TextureManager * ptm = TextureManager::getInstance(); - if(ptm) - _textureId = ptm->getDefaultTextureId(); - } - - // _averageTextureAlpha=0.5; //default value - // if (_strokeType==OIL_STROKE) - // _averageTextureAlpha=0.75; - // if (_strokeType>=NO_BLEND_STROKE) - // _averageTextureAlpha=1.0; - create(); + _stroke = iStroke; + _strokeType = iStroke->getMediumType(); + _textureId = iStroke->getTextureId(); + if (_textureId == 0) { + TextureManager *ptm = TextureManager::getInstance(); + if (ptm) + _textureId = ptm->getDefaultTextureId(); + } + +#if 0 + _averageTextureAlpha = 0.5; //default value + if (_strokeType == OIL_STROKE) + _averageTextureAlpha = 0.75; + if (_strokeType >= NO_BLEND_STROKE) + _averageTextureAlpha = 1.0; +#endif + create(); } StrokeRep::StrokeRep(const StrokeRep& iBrother) { - //soc unused - int i=0; - _stroke = iBrother._stroke; - _strokeType=iBrother._strokeType; - _textureId = iBrother._textureId; - for(vector::const_iterator s=iBrother._strips.begin(), send=iBrother._strips.end(); - s!=send; - ++s){ - _strips.push_back(new Strip(**s)); - } + //soc unused - int i = 0; + _stroke = iBrother._stroke; + _strokeType = iBrother._strokeType; + _textureId = iBrother._textureId; + for (vector::const_iterator s = iBrother._strips.begin(), send = iBrother._strips.end(); + s != send; + ++s) + { + _strips.push_back(new Strip(**s)); + } } - StrokeRep::~StrokeRep() { - if(!_strips.empty()){ - for(vector::iterator s=_strips.begin(), send=_strips.end(); - s!=send; - ++s){ - delete (*s); - } - _strips.clear(); - } + if (!_strips.empty()) { + for (vector::iterator s = _strips.begin(), send = _strips.end(); s != send; ++s) { + delete (*s); + } + _strips.clear(); + } } -void StrokeRep::create(){ - vector strip; - StrokeInternal::StrokeVertexIterator v = _stroke->strokeVerticesBegin(); - StrokeInternal::StrokeVertexIterator vend = _stroke->strokeVerticesEnd(); - - bool first=true; - bool end=false; - while(v!=vend){ - while((v!=vend) && (!(*v).attribute().isVisible())){ - ++v; - first = false; - } - while( (v!=vend) && ((*v).attribute().isVisible()) ) { - strip.push_back(&(*v)); - ++v; - } - if(v!=vend){ - // add the last vertex and create - strip.push_back(&(*v)); - }else{ - end=true; - } - if((!strip.empty()) && (strip.size()>1) ){ - _strips.push_back(new Strip(strip, _stroke->hasTips(), first, end)); - strip.clear(); - } - first = false; - } -} +void StrokeRep::create() +{ + vector strip; + StrokeInternal::StrokeVertexIterator v = _stroke->strokeVerticesBegin(); + StrokeInternal::StrokeVertexIterator vend = _stroke->strokeVerticesEnd(); + + bool first = true; + bool end = false; + while (v != vend) { + while ((v != vend) && (!(*v).attribute().isVisible())) { + ++v; + first = false; + } + while ((v != vend) && ((*v).attribute().isVisible())) { + strip.push_back(&(*v)); + ++v; + } + if (v != vend) { + // add the last vertex and create + strip.push_back(&(*v)); + } + else { + end = true; + } + if ((!strip.empty()) && (strip.size() > 1)) { + _strips.push_back(new Strip(strip, _stroke->hasTips(), first, end)); + strip.clear(); + } + first = false; + } +} void StrokeRep::Render(const StrokeRenderer *iRenderer) { - iRenderer->RenderStrokeRep(this); + iRenderer->RenderStrokeRep(this); } - - - diff --git a/source/blender/freestyle/intern/stroke/StrokeRep.h b/source/blender/freestyle/intern/stroke/StrokeRep.h index d8a8dc2d609..c8d84cb237a 100644 --- a/source/blender/freestyle/intern/stroke/StrokeRep.h +++ b/source/blender/freestyle/intern/stroke/StrokeRep.h @@ -1,138 +1,217 @@ -// -// Filename : StrokeRep.h -// Author(s) : Stephane Grabli -// Purpose : Class to define the representation of a stroke -// (for display purpose) -// Date of creation : 05/03/2003 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef STROKEREP_H -# define STROKEREP_H - -# include "../geometry/Geom.h" +/* + * ***** 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_REP_H__ +#define __FREESTYLE_STROKE_REP_H__ + +/** \file blender/freestyle/intern/stroke/StrokeRep.h + * \ingroup freestyle + * \brief Class to define the representation of a stroke (for display purpose) + * \author Stephane Grabli + * \date 05/03/2003 + */ + +#include "Stroke.h" + +#include "../geometry/Geom.h" + using namespace Geometry; +#if 0 //symbolic constant to call the appropriate renderers and textures -// # define NO_TEXTURE_WITH_BLEND_STROKE -2 -// # define NO_TEXTURE_STROKE -1 -// # define PSEUDO_CHARCOAL_STROKE 0 -// # define WASH_BRUSH_STROKE 1 -// # define OIL_STROKE 2 -// # define NO_BLEND_STROKE 3 -// # define CHARCOAL_MIN_STROKE 4 -// # define BRUSH_MIN_STROKE 5 -// # define OPAQUE_DRY_STROKE 6 -// # define OPAQUE_STROKE 7 -// -// # define DEFAULT_STROKE 0 -// -// # define NUMBER_STROKE_RENDERER 8 +#define NO_TEXTURE_WITH_BLEND_STROKE -2 +#define NO_TEXTURE_STROKE -1 +#define PSEUDO_CHARCOAL_STROKE 0 +#define WASH_BRUSH_STROKE 1 +#define OIL_STROKE 2 +#define NO_BLEND_STROKE 3 +#define CHARCOAL_MIN_STROKE 4 +#define BRUSH_MIN_STROKE 5 +#define OPAQUE_DRY_STROKE 6 +#define OPAQUE_STROKE 7 -#include "Stroke.h" +#define DEFAULT_STROKE 0 + +#define NUMBER_STROKE_RENDERER 8 + +#endif -class StrokeVertexRep{ +class StrokeVertexRep +{ public: - StrokeVertexRep(){} - StrokeVertexRep(const Vec2r& iPoint2d){_point2d=iPoint2d;} - StrokeVertexRep(const StrokeVertexRep& iBrother); - virtual ~StrokeVertexRep(){} - - inline Vec2r& point2d() {return _point2d;} - inline Vec2r& texCoord() {return _texCoord;} - inline Vec3r& color() {return _color;} - inline float alpha() {return _alpha;} - - inline void setPoint2d(const Vec2r& p){_point2d = p;} - inline void setTexCoord(const Vec2r& p){_texCoord = p;} - inline void setColor(const Vec3r& p){_color = p;} - inline void setAlpha(float a){_alpha = a;} + StrokeVertexRep(){} + + StrokeVertexRep(const Vec2r& iPoint2d) + { + _point2d = iPoint2d; + } + + StrokeVertexRep(const StrokeVertexRep& iBrother); + + virtual ~StrokeVertexRep(){} + + inline Vec2r& point2d() + { + return _point2d; + } + + inline Vec2r& texCoord() + { + return _texCoord; + } + + inline Vec3r& color() + { + return _color; + } + + inline float alpha() + { + return _alpha; + } + + inline void setPoint2d(const Vec2r& p) + { + _point2d = p; + } + + inline void setTexCoord(const Vec2r& p) + { + _texCoord = p; + } + + inline void setColor(const Vec3r& p) + { + _color = p; + } + + inline void setAlpha(float a) + { + _alpha = a; + } + protected: - Vec2r _point2d; - Vec2r _texCoord; - Vec3r _color; - float _alpha; + Vec2r _point2d; + Vec2r _texCoord; + Vec3r _color; + float _alpha; }; -class Strip{ -public: - typedef std::vector vertex_container; -protected: - vertex_container _vertices; - float _averageThickness; +class Strip +{ +public: + typedef std::vector vertex_container; +protected: + vertex_container _vertices; + float _averageThickness; public: - Strip(const std::vector& iStrokeVertices, bool hasTips=false, bool tipBegin=false, bool tipEnd=false) ; - Strip(const Strip& iBrother); - virtual ~Strip() ; + Strip(const std::vector& iStrokeVertices, bool hasTips = false, + bool tipBegin = false, bool tipEnd = false); + Strip(const Strip& iBrother); + virtual ~Strip(); protected: - void createStrip(const std::vector& iStrokeVertices); - void cleanUpSingularities(const std::vector& iStrokeVertices); - void computeTexCoord (const std::vector& iStrokeVertices); - void computeTexCoordWithTips (const std::vector& iStrokeVertices, bool tipBegin, bool tipEnd); + void createStrip(const std::vector& iStrokeVertices); + void cleanUpSingularities(const std::vector& iStrokeVertices); + void computeTexCoord (const std::vector& iStrokeVertices); + void computeTexCoordWithTips (const std::vector& iStrokeVertices, bool tipBegin, bool tipEnd); + public: - inline int sizeStrip() const {return _vertices.size();} - inline vertex_container& vertices() {return _vertices;} + inline int sizeStrip() const + { + return _vertices.size(); + } + + inline vertex_container& vertices() + { + return _vertices; + } }; class StrokeRep { protected: - Stroke *_stroke; - vector _strips; - Stroke::MediumType _strokeType; - unsigned int _textureId; + Stroke *_stroke; + vector _strips; + Stroke::MediumType _strokeType; + unsigned int _textureId; - // float _averageTextureAlpha; - + // float _averageTextureAlpha; public: - StrokeRep(); - StrokeRep(const StrokeRep&); - StrokeRep(Stroke *iStroke); - virtual ~StrokeRep(); - - /*! Creates the strips */ - virtual void create() ; - - /*! Renders the stroke using a Renderer */ - virtual void Render(const StrokeRenderer *iRenderer) ; - - /*! accessors */ - inline Stroke::MediumType getMediumType() const {return _strokeType;} - inline unsigned getTextureId() const {return _textureId;} - inline vector& getStrips() {return _strips;} - inline unsigned int getNumberOfStrips() const {return _strips.size();} - inline Stroke * getStroke() {return _stroke;} - - /*! modifiers */ - inline void setMediumType(Stroke::MediumType itype) {_strokeType=itype;} - inline void setTextureId(unsigned textureId) {_textureId = textureId;} - - + StrokeRep(); + StrokeRep(const StrokeRep&); + StrokeRep(Stroke *iStroke); + virtual ~StrokeRep(); + + /*! Creates the strips */ + virtual void create(); + + /*! Renders the stroke using a Renderer */ + virtual void Render(const StrokeRenderer *iRenderer); + + /*! accessors */ + inline Stroke::MediumType getMediumType() const + { + return _strokeType; + } + + inline unsigned getTextureId() const + { + return _textureId; + } + + inline vector& getStrips() + { + return _strips; + } + + inline unsigned int getNumberOfStrips() const + { + return _strips.size(); + } + + inline Stroke * getStroke() + { + return _stroke; + } + + /*! modifiers */ + inline void setMediumType(Stroke::MediumType itype) + { + _strokeType = itype; + } + + inline void setTextureId(unsigned textureId) + { + _textureId = textureId; + } }; -#endif // STROKEREP_H +#endif // __FREESTYLE_STROKE_REP_H__ diff --git a/source/blender/freestyle/intern/stroke/StrokeShader.h b/source/blender/freestyle/intern/stroke/StrokeShader.h index 63185438e91..c8364f7a737 100644 --- a/source/blender/freestyle/intern/stroke/StrokeShader.h +++ b/source/blender/freestyle/intern/stroke/StrokeShader.h @@ -1,39 +1,45 @@ -// -// Filename : StrokeShader.h -// Author(s) : Stephane Grabli, Emmanuel Turquin -// Purpose : Class defining StrokeShader -// Date of creation : 01/07/2003 -// -/////////////////////////////////////////////////////////////////////////////// - +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +#ifndef __FREESTYLE_STROKE_SHADERS_H__ +#define __FREESTYLE_STROKE_SHADERS_H__ -#ifndef SHADERS_H -# define SHADERS_H +/** \file blender/freestyle/intern/stroke/StrokeShader.h + * \ingroup freestyle + * \brief Class defining StrokeShader + * \author Stephane Grabli + * \author Emmanuel Turquin + * \date 01/07/2003 + */ -# include -# include +#include +#include -# include "../python/Director.h" +#include "../python/Director.h" // // StrokeShader base class @@ -41,84 +47,61 @@ ////////////////////////////////////////////////////// class Stroke; + /*! Base class for Stroke Shaders. - * Any Stroke Shader must inherit from - * this class and overload the shade() method. - * A StrokeShader is designed to modify any - * Stroke's attribute such as Thickness, Color, + * Any Stroke Shader must inherit from this class and overload the shade() method. + * A StrokeShader is designed to modify any Stroke's attribute such as Thickness, Color, * Geometry, Texture, Blending mode... - * The basic way to achieve this operation consists - * in iterating over the StrokeVertices of the Stroke + * The basic way to achieve this operation consists in iterating over the StrokeVertices of the Stroke * and to modify each one's StrokeAttribute. * Here is a python code example of such an iteration: * \code * it = ioStroke.strokeVerticesBegin() - * while it.isEnd() == 0: + * while not it.isEnd(): * att = it.getObject().attribute() * ## perform here any attribute modification * it.increment() * \endcode * Here is a C++ code example of such an iteration: * \code - * for(StrokeInternal::StrokeVertexIterator v=ioStroke.strokeVerticesBegin(), vend=ioStroke.strokeVerticesEnd(); - * v!=vend; - * ++v){ - * StrokeAttribute& att = v->attribute(); - * // perform any attribute modification here... + * for(StrokeInternal::StrokeVertexIterator v = ioStroke.strokeVerticesBegin(), vend = ioStroke.strokeVerticesEnd(); + * v != vend; + * ++v) + * { + * StrokeAttribute& att = v->attribute(); + * // perform any attribute modification here... * } * \endcode */ class LIB_STROKE_EXPORT StrokeShader { public: - PyObject *py_ss; - - /*! Default constructor. */ - StrokeShader() { py_ss = 0; } - /*! Destructor. */ - virtual ~StrokeShader() {} - /*! Returns the string corresponding to the - * shader's name. - */ - virtual string getName() const { - return "StrokeShader"; - } - /*! The shading method. This method must - * be overloaded by inherited classes. - * The shading method is designed to modify any - * Stroke's attribute such as Thickness, Color, - * Geometry, Texture, Blending mode... - * The basic way to achieve this operation consists - * in iterating over the StrokeVertices of the Stroke - * and to modify each one's StrokeAttribute. - * Here is a python code example of such an iteration: - * \code - * it = ioStroke.strokeVerticesBegin() - * while it.isEnd() == 0: - * att = it.getObject().attribute() - * ## perform here any attribute modification - * it.increment() - * \endcode - * Here is a C++ code example of such an iteration: - * \code - * for(StrokeInternal::StrokeVertexIterator v=ioStroke.strokeVerticesBegin(), vend=ioStroke.strokeVerticesEnd(); - * v!=vend; - * ++v){ - * StrokeAttribute& att = v->attribute(); - * // perform any attribute modification here... - * } - * \endcode - * \param ioStroke - * The stroke we wish to shade. this Stroke - * is modified by the Shader (which typically - * modifies the Stroke's attribute's values such - * as Color, Thickness, Geometry...) - */ - virtual int shade(Stroke& ioStroke) const { - return Director_BPy_StrokeShader_shade( const_cast(this), ioStroke ); - } + /*! Default constructor. */ + StrokeShader() + { + py_ss = 0; + } + + /*! Destructor. */ + virtual ~StrokeShader() {} + + /*! Returns the string corresponding to the shader's name. */ + virtual string getName() const + { + return "StrokeShader"; + } + + /*! The shading method. This method must be overloaded by inherited classes. + * \param ioStroke + * The stroke we wish to shade. this Stroke is modified by the Shader (which typically + * modifies the Stroke's attribute's values such as Color, Thickness, Geometry...) + */ + virtual int shade(Stroke& ioStroke) const + { + return Director_BPy_StrokeShader_shade( const_cast(this), ioStroke); + } }; -# endif // SHADERS_H +#endif // __FREESTYLE_STROKE_SHADERS_H__ diff --git a/source/blender/freestyle/intern/stroke/StrokeTesselator.cpp b/source/blender/freestyle/intern/stroke/StrokeTesselator.cpp index a8b71f9f3c3..43cf1818fb0 100644 --- a/source/blender/freestyle/intern/stroke/StrokeTesselator.cpp +++ b/source/blender/freestyle/intern/stroke/StrokeTesselator.cpp @@ -1,88 +1,94 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/stroke/StrokeTesselator.cpp + * \ingroup freestyle + * \brief Class to build a Node Tree designed to be displayed from a set of strokes structure. + * \author Stephane Grabli + * \date 26/03/2002 + */ +#include "StrokeAdvancedIterators.h" #include "StrokeTesselator.h" + #include "../scene_graph/OrientedLineRep.h" #include "../scene_graph/NodeGroup.h" #include "../scene_graph/NodeShape.h" -#include "StrokeAdvancedIterators.h" -LineRep* StrokeTesselator::Tesselate(Stroke *iStroke) +LineRep *StrokeTesselator::Tesselate(Stroke *iStroke) { - if(0 == iStroke) - return 0; + if (0 == iStroke) + return 0; - LineRep* line; - line = new OrientedLineRep(); - - Stroke::vertex_iterator v,vend; - if(2 == iStroke->vertices_size()) - { - line->setStyle(LineRep::LINES); - v = iStroke->vertices_begin(); - StrokeVertex *svA= (*v); - v++; - StrokeVertex *svB = (*v); - Vec3r A((*svA)[0], (*svA)[1], 0); - Vec3r B((*svB)[0], (*svB)[1], 0); - line->AddVertex(A); - line->AddVertex(B); - } - else - { - if(_overloadFrsMaterial) - line->setFrsMaterial(_FrsMaterial); + LineRep* line; + line = new OrientedLineRep(); - line->setStyle(LineRep::LINE_STRIP); + Stroke::vertex_iterator v,vend; + if (2 == iStroke->vertices_size()) { + line->setStyle(LineRep::LINES); + v = iStroke->vertices_begin(); + StrokeVertex *svA = (*v); + v++; + StrokeVertex *svB = (*v); + Vec3r A((*svA)[0], (*svA)[1], 0); + Vec3r B((*svB)[0], (*svB)[1], 0); + line->AddVertex(A); + line->AddVertex(B); + } + else { + if (_overloadFrsMaterial) + line->setFrsMaterial(_FrsMaterial); - for(v=iStroke->vertices_begin(), vend=iStroke->vertices_end(); - v!=vend; - v++) - { - StrokeVertex *sv= (*v); - Vec3r V((*sv)[0], (*sv)[1], 0); - line->AddVertex(V); - } - } - line->setId(iStroke->getId()); - line->ComputeBBox(); + line->setStyle(LineRep::LINE_STRIP); - return line; + for (v = iStroke->vertices_begin(), vend = iStroke->vertices_end(); v != vend; v++) { + StrokeVertex *sv = (*v); + Vec3r V((*sv)[0], (*sv)[1], 0); + line->AddVertex(V); + } + } + line->setId(iStroke->getId()); + line->ComputeBBox(); + + return line; } template -NodeGroup* StrokeTesselator::Tesselate(StrokeVertexIterator begin, StrokeVertexIterator end) +NodeGroup *StrokeTesselator::Tesselate(StrokeVertexIterator begin, StrokeVertexIterator end) { - NodeGroup *group = new NodeGroup; - NodeShape *tshape = new NodeShape; - group->AddChild(tshape); - //tshape->material().setDiffuse(0.f, 0.f, 0.f, 1.f); - tshape->setFrsMaterial(_FrsMaterial); + NodeGroup *group = new NodeGroup; + NodeShape *tshape = new NodeShape; + group->AddChild(tshape); + //tshape->material().setDiffuse(0.0f, 0.0f, 0.0f, 1.0f); + tshape->setFrsMaterial(_FrsMaterial); + + for (StrokeVertexIterator c = begin, cend = end; c != cend; c++) { + tshape->AddRep(Tesselate((*c))); + } - for(StrokeVertexIterator c=begin, cend=end; - c!=cend; - c++) - { - tshape->AddRep(Tesselate((*c))); - } - - return group; + return group; } diff --git a/source/blender/freestyle/intern/stroke/StrokeTesselator.h b/source/blender/freestyle/intern/stroke/StrokeTesselator.h index 671df00ef84..e04f75a6f3e 100644 --- a/source/blender/freestyle/intern/stroke/StrokeTesselator.h +++ b/source/blender/freestyle/intern/stroke/StrokeTesselator.h @@ -1,67 +1,78 @@ -// -// Filename : StrokeTesselator.h -// Author(s) : Stephane Grabli -// Purpose : Class to build a Node Tree designed to be displayed -// from a set of strokes structure. -// Date of creation : 26/03/2002 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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_TESSELATOR_H__ +#define __FREESTYLE_STROKE_TESSELATOR_H__ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/stroke/StrokeTesselator.h + * \ingroup freestyle + * \brief Class to build a Node Tree designed to be displayed from a set of strokes structure. + * \author Stephane Grabli + * \date 26/03/2002 + */ -#ifndef STROKETESSELATOR_H -# define STROKETESSELATOR_H +#include "Stroke.h" -# include "Stroke.h" -# include "../scene_graph/LineRep.h" +#include "../scene_graph/LineRep.h" class StrokeTesselator { public: + inline StrokeTesselator() + { + _FrsMaterial.setDiffuse(0, 0, 0, 1); + _overloadFrsMaterial = false; + } - inline StrokeTesselator() {_FrsMaterial.setDiffuse(0,0,0,1);_overloadFrsMaterial=false;} - virtual ~StrokeTesselator() {} + virtual ~StrokeTesselator() {} - /*! Builds a line rep contained from a Stroke - */ - LineRep* Tesselate(Stroke* iStroke) ; + /*! Builds a line rep contained from a Stroke */ + LineRep *Tesselate(Stroke *iStroke); - /*! Builds a set of lines rep contained under a - * a NodeShape, itself contained under a NodeGroup from a - * set of strokes - */ - template - NodeGroup* Tesselate(StrokeIterator begin, StrokeIterator end) ; + /*! Builds a set of lines rep contained under a a NodeShape, itself contained under a NodeGroup + * from a set of strokes. + */ + template + NodeGroup *Tesselate(StrokeIterator begin, StrokeIterator end); - - - inline void setFrsMaterial(const FrsMaterial& iMaterial) {_FrsMaterial=iMaterial;_overloadFrsMaterial=true;} - inline const FrsMaterial& frs_material() const {return _FrsMaterial;} + inline void setFrsMaterial(const FrsMaterial& iMaterial) + { + _FrsMaterial = iMaterial; + _overloadFrsMaterial = true; + } -private: + inline const FrsMaterial& frs_material() const + { + return _FrsMaterial; + } - FrsMaterial _FrsMaterial; - bool _overloadFrsMaterial; +private: + FrsMaterial _FrsMaterial; + bool _overloadFrsMaterial; }; -#endif // STROKETESSELATOR_H - +#endif // __FREESTYLE_STROKE_TESSELATOR_H__ diff --git a/source/blender/freestyle/intern/stroke/StyleModule.h b/source/blender/freestyle/intern/stroke/StyleModule.h index c97a8d7f999..12f645f125b 100644 --- a/source/blender/freestyle/intern/stroke/StyleModule.h +++ b/source/blender/freestyle/intern/stroke/StyleModule.h @@ -1,172 +1,184 @@ -// -// Filename : StyleModule.h -// Author(s) : Stephane Grabli, Emmanuel Turquin -// Purpose : Class representing a style module -// Date of creation : 01/07/2003 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef STYLE_MODULE_H -# define STYLE_MODULE_H - -# include -# include -# include "../system/StringUtils.h" -# include "StrokeLayer.h" -# include "../system/Interpreter.h" -# include "Operators.h" -# include "StrokeShader.h" +/* + * ***** 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_STYLE_MODULE_H__ +#define __FREESTYLE_STYLE_MODULE_H__ + +/** \file blender/freestyle/intern/stroke/StyleModule.h + * \ingroup freestyle + * \brief Class representing a style module + * \author Stephane Grabli + * \author Emmanuel Turquin + * \date 01/07/2003 + */ + +#include +#include + +#include "Operators.h" +#include "StrokeLayer.h" +#include "StrokeShader.h" + +#include "../system/Interpreter.h" +#include "../system/StringUtils.h" using namespace std; class StyleModule { public: - - StyleModule(const string& file_name, - Interpreter* inter) : _file_name(file_name) { - _always_refresh = false; - _causal = false; - _drawable = true; - _modified = true; - _displayed = true; - _inter = inter; - } - - virtual ~StyleModule() {} - - StrokeLayer* execute() { - if (!_inter) { - cerr << "Error: no interpreter was found to execute the script" << endl; - return NULL; - } - - if (!_drawable) { - cerr << "Error: not drawable" << endl; - return NULL; - } - - Operators::reset(); - - if( interpret() ) { - cerr << "Error: interpretation failed" << endl; - Operators::reset(); - return NULL; - } - - Operators::StrokesContainer* strokes_set = Operators::getStrokesSet(); - if( strokes_set->empty() ) { - cerr << "Error: strokes set empty" << endl; - Operators::reset(); - return NULL; + StyleModule(const string& file_name, Interpreter *inter) : _file_name(file_name) + { + _always_refresh = false; + _causal = false; + _drawable = true; + _modified = true; + _displayed = true; + _inter = inter; } - StrokeLayer* sl = new StrokeLayer; - for (Operators::StrokesContainer::iterator it = strokes_set->begin(); - it != strokes_set->end(); - ++it) - sl->AddStroke(*it); - - Operators::reset(); - - return sl; - } + virtual ~StyleModule() {} + + StrokeLayer *execute() + { + if (!_inter) { + cerr << "Error: no interpreter was found to execute the script" << endl; + return NULL; + } + + if (!_drawable) { + cerr << "Error: not drawable" << endl; + return NULL; + } + + Operators::reset(); + + if (interpret()) { + cerr << "Error: interpretation failed" << endl; + Operators::reset(); + return NULL; + } + + Operators::StrokesContainer *strokes_set = Operators::getStrokesSet(); + if (strokes_set->empty()) { + cerr << "Error: strokes set empty" << endl; + Operators::reset(); + return NULL; + } + + StrokeLayer *sl = new StrokeLayer; + for (Operators::StrokesContainer::iterator it = strokes_set->begin(); it != strokes_set->end(); ++it) + sl->AddStroke(*it); + + Operators::reset(); + return sl; + } protected: - - virtual int interpret() { - return _inter->interpretFile(_file_name); - } + virtual int interpret() + { + return _inter->interpretFile(_file_name); + } public: + // accessors + const string getFileName() const + { + return _file_name; + } - // accessors - - const string getFileName() const { - return _file_name; - } - - bool getAlwaysRefresh() const { - return _always_refresh; - } - - bool getCausal() const { - return _causal; - } + bool getAlwaysRefresh() const + { + return _always_refresh; + } - bool getDrawable() const { - return _drawable; - } + bool getCausal() const + { + return _causal; + } - bool getModified() const { - return _modified; - } + bool getDrawable() const + { + return _drawable; + } - bool getDisplayed() const { - return _displayed; - } + bool getModified() const + { + return _modified; + } - // modifiers + bool getDisplayed() const + { + return _displayed; + } - void setFileName(const string& file_name) { - _file_name = file_name; - } + // modifiers + void setFileName(const string& file_name) + { + _file_name = file_name; + } - void setAlwaysRefresh(bool b = true) { - _always_refresh = b; - } + void setAlwaysRefresh(bool b = true) + { + _always_refresh = b; + } - void setCausal(bool b = true) { - _causal = b; - } + void setCausal(bool b = true) + { + _causal = b; + } - void setDrawable(bool b = true) { - _drawable = b; - } + void setDrawable(bool b = true) + { + _drawable = b; + } - void setModified(bool b = true) { - if (_always_refresh) - return; - _modified = b; - } + void setModified(bool b = true) + { + if (_always_refresh) + return; + _modified = b; + } - void setDisplayed(bool b = true) { - _displayed = b; - } + void setDisplayed(bool b = true) + { + _displayed = b; + } private: - - string _file_name; - bool _always_refresh; - bool _causal; - bool _drawable; - bool _modified; - bool _displayed; + string _file_name; + bool _always_refresh; + bool _causal; + bool _drawable; + bool _modified; + bool _displayed; protected: - - Interpreter* _inter; + Interpreter *_inter; }; -#endif // STYLE_MODULE_H +#endif // __FREESTYLE_STYLE_MODULE_H__ diff --git a/source/blender/freestyle/intern/stroke/TextStrokeRenderer.h b/source/blender/freestyle/intern/stroke/TextStrokeRenderer.h index 8b4b6bc80d7..cc6f5c05073 100644 --- a/source/blender/freestyle/intern/stroke/TextStrokeRenderer.h +++ b/source/blender/freestyle/intern/stroke/TextStrokeRenderer.h @@ -42,7 +42,7 @@ /**********************************/ /* */ /* */ -/* TextStrokeRenderer */ +/* TextStrokeRenderer */ /* */ /* */ /**********************************/ diff --git a/source/blender/freestyle/intern/system/BaseIterator.h b/source/blender/freestyle/intern/system/BaseIterator.h index 45cc19df4fe..836f6c83eb8 100644 --- a/source/blender/freestyle/intern/system/BaseIterator.h +++ b/source/blender/freestyle/intern/system/BaseIterator.h @@ -1,90 +1,97 @@ -// -// Filename : BaseIterator.h -// Author(s) : Stephane Grabli -// Purpose : Classes defining the basic "Iterator" design pattern -// Date of creation : 18/03/2003 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef BASEITERATOR_H -# define BASEITERATOR_H - -# include +/* + * ***** 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_BASE_ITERATOR_H__ +#define __FREESTYLE_BASE_ITERATOR_H__ + +/** \file blender/freestyle/intern/system/BaseIterator.h + * \ingroup freestyle + * \brief Classes defining the basic "Iterator" design pattern + * \author Stephane Grabli + * \date 18/03/2003 + */ + +#include // use for iterators defintions template class Nonconst_traits; template -class Const_traits { +class Const_traits +{ public: - typedef Element value_type; - typedef const Element& reference; - typedef const Element* pointer; - typedef ptrdiff_t difference_type; - typedef Nonconst_traits Non_const_traits; + typedef Element value_type; + typedef const Element& reference; + typedef const Element *pointer; + typedef ptrdiff_t difference_type; + typedef Nonconst_traits Non_const_traits; }; template -class Nonconst_traits { +class Nonconst_traits +{ public: - typedef Element value_type; - typedef Element& reference; - typedef Element* pointer; - typedef ptrdiff_t difference_type; - typedef Nonconst_traits Non_const_traits; + typedef Element value_type; + typedef Element& reference; + typedef Element *pointer; + typedef ptrdiff_t difference_type; + typedef Nonconst_traits Non_const_traits; }; -class InputIteratorTag_Traits { +class InputIteratorTag_Traits +{ public: - typedef std::input_iterator_tag iterator_category; + typedef std::input_iterator_tag iterator_category; }; -class BidirectionalIteratorTag_Traits { +class BidirectionalIteratorTag_Traits +{ public: - typedef std::bidirectional_iterator_tag iterator_category; + typedef std::bidirectional_iterator_tag iterator_category; }; template class IteratorBase { public: + virtual ~IteratorBase() {} - virtual ~IteratorBase() {} + virtual bool begin() const = 0; + virtual bool end() const = 0; - virtual bool begin() const = 0; - virtual bool end() const = 0; - - typedef typename IteratorTagTraits::iterator_category iterator_category; - typedef typename Traits::value_type value_type; - typedef typename Traits::difference_type difference_type; - typedef typename Traits::pointer pointer; - typedef typename Traits::reference reference; + typedef typename IteratorTagTraits::iterator_category iterator_category; + typedef typename Traits::value_type value_type; + typedef typename Traits::difference_type difference_type; + typedef typename Traits::pointer pointer; + typedef typename Traits::reference reference; protected: - - IteratorBase() {} + IteratorBase() {} }; #endif // BASEITERATOR_H diff --git a/source/blender/freestyle/intern/system/BaseObject.cpp b/source/blender/freestyle/intern/system/BaseObject.cpp index 0cf1c917195..2088585c33b 100644 --- a/source/blender/freestyle/intern/system/BaseObject.cpp +++ b/source/blender/freestyle/intern/system/BaseObject.cpp @@ -1 +1,36 @@ +/* + * ***** 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 ***** + */ + +/** \file blender/freestyle/intern/system/BaseObject.cpp + * \ingroup freestyle + * \brief Base Class for most shared objects (Node, Rep). Defines the addRef, release system. + * \brief Inspired by COM IUnknown system. + * \author Stephane Grabli + * \date 06/02/2002 + */ + #include "BaseObject.h" diff --git a/source/blender/freestyle/intern/system/BaseObject.h b/source/blender/freestyle/intern/system/BaseObject.h index a8515f98385..1fe2770c313 100644 --- a/source/blender/freestyle/intern/system/BaseObject.h +++ b/source/blender/freestyle/intern/system/BaseObject.h @@ -1,73 +1,77 @@ -// -// Filename : BaseObject.h -// Author(s) : Stephane Grabli -// Purpose : Base Class for most shared objects (Node, Rep). -// Defines the addRef, release system. -// Inspired by COM IUnknown system. -// Date of creation : 06/02/2002 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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_BASE_OBJECT_H__ +#define __FREESTYLE_BASE_OBJECT_H__ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef BASEOBJECT_H -# define BASEOBJECT_H +/** \file blender/freestyle/intern/system/BaseObject.h + * \ingroup freestyle + * \brief Base Class for most shared objects (Node, Rep). Defines the addRef, release system. + * \brief Inspired by COM IUnknown system. + * \author Stephane Grabli + * \date 06/02/2002 + */ #include "FreestyleConfig.h" class LIB_SYSTEM_EXPORT BaseObject { public: + inline BaseObject() + { + _ref_counter = 0; + } - inline BaseObject() { - _ref_counter = 0; - } - - virtual ~BaseObject() {} + virtual ~BaseObject() {} - /*! At least makes a release on this. - * The BaseObject::destroy method must be - * explicitely called at the end of any - * overloaded destroy - */ - virtual int destroy() { - return release(); - } + /*! At least makes a release on this. + * The BaseObject::destroy method must be explicitely called at the end of any overloaded destroy + */ + virtual int destroy() + { + return release(); + } - /*! Increments the reference counter */ - inline int addRef() { - return ++_ref_counter; - } + /*! Increments the reference counter */ + inline int addRef() + { + return ++_ref_counter; + } - /*! Decrements the reference counter */ - inline int release() { - if (_ref_counter) - _ref_counter--; - return _ref_counter; - } + /*! Decrements the reference counter */ + inline int release() + { + if (_ref_counter) + _ref_counter--; + return _ref_counter; + } private: - - unsigned _ref_counter; + unsigned _ref_counter; }; -#endif // BASEOBJECT_H +#endif // __FREESTYLE_BASE_OBJECT_H__ diff --git a/source/blender/freestyle/intern/system/Cast.h b/source/blender/freestyle/intern/system/Cast.h index 15af767443e..02dd5699214 100644 --- a/source/blender/freestyle/intern/system/Cast.h +++ b/source/blender/freestyle/intern/system/Cast.h @@ -1,44 +1,49 @@ -// -// Filename : Cast.h -// Author(s) : Emmanuel Turquin -// Purpose : Cast function -// Date of creation : 01/07/2003 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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_CAST_H__ +#define __FREESTYLE_CAST_H__ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef CAST_HPP -# define CAST_HPP - -namespace Cast { - - template - U* cast(T* in) { - if (!in) - return NULL; - return dynamic_cast(in); - } +/** \file blender/freestyle/intern/system/Cast.h + * \ingroup freestyle + * \brief Cast function + * \author Emmanuel Turquin + * \date 01/07/2003 + */ +namespace Cast +{ + template + U *cast(T *in) + { + if (!in) + return NULL; + return dynamic_cast(in); + } } // end of namespace Cast -#endif // CAST_HPP +#endif // __FREESTYLE_CAST_H__ diff --git a/source/blender/freestyle/intern/system/Exception.cpp b/source/blender/freestyle/intern/system/Exception.cpp index d1d12d18297..7c7c16fdf40 100644 --- a/source/blender/freestyle/intern/system/Exception.cpp +++ b/source/blender/freestyle/intern/system/Exception.cpp @@ -1,23 +1,36 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/system/Exception.cpp + * \ingroup freestyle + * \brief Singleton to manage exceptions + * \author Stephane Grabli + * \date 10/01/2003 + */ #include "Exception.h" diff --git a/source/blender/freestyle/intern/system/Exception.h b/source/blender/freestyle/intern/system/Exception.h index 378de6b558f..b9bfa00cf97 100644 --- a/source/blender/freestyle/intern/system/Exception.h +++ b/source/blender/freestyle/intern/system/Exception.h @@ -1,64 +1,70 @@ -// -// Filename : Exception.h -// Author(s) : Stephane Grabli -// Purpose : Singleton to manage exceptions -// Date of creation : 10/01/2003 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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_EXCEPTION_H__ +#define __FREESTYLE_EXCEPTION_H__ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/system/Exception.h + * \ingroup freestyle + * \brief Singleton to manage exceptions + * \author Stephane Grabli + * \date 10/01/2003 + */ -#ifndef EXCEPTION_H -# define EXCEPTION_H - -# include "FreestyleConfig.h" +#include "FreestyleConfig.h" class LIB_SYSTEM_EXPORT Exception { public: + typedef enum { + NO_EXCEPTION, + UNDEFINED, + } exception_type; - typedef enum { - NO_EXCEPTION, - UNDEFINED - } exception_type; - - static int getException() { - exception_type e = _exception; - _exception = NO_EXCEPTION; - return e; - } + static int getException() + { + exception_type e = _exception; + _exception = NO_EXCEPTION; + return e; + } - static int raiseException(exception_type exception = UNDEFINED) { - _exception = exception; - return _exception; - } + static int raiseException(exception_type exception = UNDEFINED) + { + _exception = exception; + return _exception; + } - static void reset() { - _exception = NO_EXCEPTION; - } + static void reset() + { + _exception = NO_EXCEPTION; + } private: - - static exception_type _exception; + static exception_type _exception; }; -#endif // EXCEPTION_H +#endif // __FREESTYLE_EXCEPTION_H__ diff --git a/source/blender/freestyle/intern/system/FreestyleConfig.h b/source/blender/freestyle/intern/system/FreestyleConfig.h index f06b9928d1d..9d81af1be3b 100644 --- a/source/blender/freestyle/intern/system/FreestyleConfig.h +++ b/source/blender/freestyle/intern/system/FreestyleConfig.h @@ -1,90 +1,96 @@ -// -// Filename : Config.h -// Author(s) : Emmanuel Turquin -// Purpose : Configuration definitions -// Date of creation : 25/02/2003 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - - -#ifndef CONFIG_H -# define CONFIG_H - -# include -# include "BLI_math.h" +/* + * ***** 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_CONFIG_H__ +#define __FREESTYLE_CONFIG_H__ + +/** \file blender/freestyle/intern/system/Config.h + * \ingroup freestyle + * \brief Configuration definitions + * \author Emmanuel Turquin + * \date 25/02/2003 + */ + +#include + +#include "BLI_math.h" using namespace std; namespace Config { - // Directory separators -# ifdef WIN32 - static const string DIR_SEP("\\"); - static const string PATH_SEP(";"); -# else - static const string DIR_SEP("/"); - static const string PATH_SEP(":"); -# endif // WIN32 +// Directory separators +// TODO Use Blender's stuff for such things! +#ifdef WIN32 + static const string DIR_SEP("\\"); + static const string PATH_SEP(";"); +#else + static const string DIR_SEP("/"); + static const string PATH_SEP(":"); +#endif // WIN32 - // DLL import/export macros for Win32 +// DLL import/export macros for Win32 -# ifndef LIB_SYSTEM_EXPORT -# define LIB_SYSTEM_EXPORT -# endif // LIB_SYSTEM_EXPORT +#ifndef LIB_SYSTEM_EXPORT +# define LIB_SYSTEM_EXPORT +#endif // LIB_SYSTEM_EXPORT -# ifndef LIB_IMAGE_EXPORT -# define LIB_IMAGE_EXPORT -# endif // LIB_IMAGE_EXPORT +#ifndef LIB_IMAGE_EXPORT +# define LIB_IMAGE_EXPORT +#endif // LIB_IMAGE_EXPORT -# ifndef LIB_GEOMETRY_EXPORT -# define LIB_GEOMETRY_EXPORT -# endif // LIB_GEOMETRY_EXPORT +#ifndef LIB_GEOMETRY_EXPORT +# define LIB_GEOMETRY_EXPORT +#endif // LIB_GEOMETRY_EXPORT -# ifndef LIB_SCENE_GRAPH_EXPORT -# define LIB_SCENE_GRAPH_EXPORT -# endif // LIB_SCENE_GRAPH_EXPORT +#ifndef LIB_SCENE_GRAPH_EXPORT +# define LIB_SCENE_GRAPH_EXPORT +#endif // LIB_SCENE_GRAPH_EXPORT -# ifndef LIB_WINGED_EDGE_EXPORT -# define LIB_WINGED_EDGE_EXPORT -# endif // LIB_WINGED_EDGE_EXPORT +#ifndef LIB_WINGED_EDGE_EXPORT +# define LIB_WINGED_EDGE_EXPORT +#endif // LIB_WINGED_EDGE_EXPORT -# ifndef LIB_VIEW_MAP_EXPORT -# define LIB_VIEW_MAP_EXPORT -# endif // LIB_VIEW_MAP_EXPORT +#ifndef LIB_VIEW_MAP_EXPORT +# define LIB_VIEW_MAP_EXPORT +#endif // LIB_VIEW_MAP_EXPORT -# ifndef LIB_STROKE_EXPORT -# define LIB_STROKE_EXPORT -# endif // LIB_STROKE_EXPORT +#ifndef LIB_STROKE_EXPORT +# define LIB_STROKE_EXPORT +#endif // LIB_STROKE_EXPORT -# ifndef LIB_RENDERING_EXPORT -# define LIB_RENDERING_EXPORT -# endif // LIB_RENDERING_EXPORT +#ifndef LIB_RENDERING_EXPORT +# define LIB_RENDERING_EXPORT +#endif // LIB_RENDERING_EXPORT -# ifndef LIB_WRAPPER_EXPORT -# define LIB_WRAPPER_EXPORT -# endif // LIB_WRAPPER_EXPORT +#ifndef LIB_WRAPPER_EXPORT +# define LIB_WRAPPER_EXPORT +#endif // LIB_WRAPPER_EXPORT } // end of namespace Config -#endif // CONFIG_H +#endif // __FREESTYLE_CONFIG_H__ diff --git a/source/blender/freestyle/intern/system/Id.h b/source/blender/freestyle/intern/system/Id.h index 1f2206ed337..d6e39bff167 100644 --- a/source/blender/freestyle/intern/system/Id.h +++ b/source/blender/freestyle/intern/system/Id.h @@ -1,126 +1,142 @@ -// -// Filename : Id.h -// Author(s) : Emmanuel Turquin -// Purpose : Identification system -// Date of creation : 01/07/2003 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef ID_H -# define ID_H - -/*! Class used to tag any object by an id . +/* + * ***** 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_ID_H__ +#define __FREESTYLE_ID_H__ + +/** \file blender/freestyle/intern/system/Id.h + * \ingroup freestyle + * \brief Identification system + * \author Emmanuel Turquin + * \date 01/07/2003 + */ + +/*! Class used to tag any object by an id. * It is made of two unsigned integers. */ class Id { public: - - typedef unsigned id_type; - - /*! Default constructor */ - Id() { - _first = 0; - _second = 0; - } - - /*! Builds an Id from an integer. - * The second number is set to 0. - */ - Id(id_type id) { - _first = id; - _second = 0; - } - - /*! Builds the Id from the two numbers */ - Id(id_type ifirst, id_type isecond) { - _first = ifirst; - _second = isecond; - } - - /*! Copy constructor */ - Id(const Id& iBrother) { - _first = iBrother._first; - _second = iBrother._second; - } - - /*! Operator= */ - Id& operator=(const Id& iBrother) { - _first = iBrother._first; - _second = iBrother._second; - return *this; - } - - /*! Returns the first Id number */ - id_type getFirst() const { - return _first; - } - - /*! Returns the second Id number */ - id_type getSecond() const { - return _second; - } - - /*! Sets the first number constituing the Id */ - void setFirst(id_type first) { - _first = first; - } - - /*! Sets the second number constituing the Id */ - void setSecond(id_type second) { - _second = second; - } - - /*! Operator== */ - bool operator==(const Id& id) const { - return ((_first == id._first) && (_second == id._second)); - } - - /*! Operator!= */ - bool operator!=(const Id& id) const { - return !((*this)==id); - } - - /*! Operator< */ - bool operator<(const Id& id) const { - if (_first < id._first) - return true; - if (_first == id._first && _second < id._second) - return true; - return false; -} + typedef unsigned id_type; + + /*! Default constructor */ + Id() + { + _first = 0; + _second = 0; + } + + /*! Builds an Id from an integer. + * The second number is set to 0. + */ + Id(id_type id) + { + _first = id; + _second = 0; + } + + /*! Builds the Id from the two numbers */ + Id(id_type ifirst, id_type isecond) + { + _first = ifirst; + _second = isecond; + } + + /*! Copy constructor */ + Id(const Id& iBrother) + { + _first = iBrother._first; + _second = iBrother._second; + } + + /*! Operator= */ + Id& operator=(const Id& iBrother) + { + _first = iBrother._first; + _second = iBrother._second; + return *this; + } + + /*! Returns the first Id number */ + id_type getFirst() const + { + return _first; + } + + /*! Returns the second Id number */ + id_type getSecond() const + { + return _second; + } + + /*! Sets the first number constituing the Id */ + void setFirst(id_type first) + { + _first = first; + } + + /*! Sets the second number constituing the Id */ + void setSecond(id_type second) + { + _second = second; + } + + /*! Operator== */ + bool operator==(const Id& id) const + { + return ((_first == id._first) && (_second == id._second)); + } + + /*! Operator!= */ + bool operator!=(const Id& id) const + { + return !((*this) == id); + } + + /*! Operator< */ + bool operator<(const Id& id) const + { + if (_first < id._first) + return true; + if (_first == id._first && _second < id._second) + return true; + return false; + } private: - - id_type _first; - id_type _second; + id_type _first; + id_type _second; }; // stream operator -inline std::ostream& operator<<(std::ostream& s, const Id& id) { - s << "[" << id.getFirst() << ", " << id.getSecond() << "]"; - return s; +inline std::ostream& operator<<(std::ostream& s, const Id& id) +{ + s << "[" << id.getFirst() << ", " << id.getSecond() << "]"; + return s; } -# endif // ID_H +# endif // __FREESTYLE_ID_H__ diff --git a/source/blender/freestyle/intern/system/Interpreter.h b/source/blender/freestyle/intern/system/Interpreter.h index 75aaa2ccd18..7928db9aed2 100644 --- a/source/blender/freestyle/intern/system/Interpreter.h +++ b/source/blender/freestyle/intern/system/Interpreter.h @@ -1,56 +1,65 @@ -// -// Filename : Interpreter.h -// Author(s) : Emmanuel Turquin -// Purpose : Base Class of all script interpreters -// Date of creation : 17/04/2003 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef INTERPRETER_H -# define INTERPRETER_H - -# include +/* + * ***** 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_INTERPRETER_H__ +#define __FREESTYLE_INTERPRETER_H__ + +/** \file blender/freestyle/intern/system/Interpreter.h + * \ingroup freestyle + * \brief Base Class of all script interpreters + * \author Emmanuel Turquin + * \date 17/04/2003 + */ + +#include using namespace std; class LIB_SYSTEM_EXPORT Interpreter { - public: - - Interpreter() { _language = "Unknown"; } - - virtual ~Interpreter() {}; //soc +public: + Interpreter() + { + _language = "Unknown"; + } - virtual int interpretFile(const string& filename) = 0; + virtual ~Interpreter() {}; //soc - virtual string getLanguage() const { return _language; } + virtual int interpretFile(const string& filename) = 0; - virtual void reset() = 0; + virtual string getLanguage() const + { + return _language; + } - protected: + virtual void reset() = 0; - string _language; +protected: + string _language; }; -#endif // INTERPRETER_H +#endif // __FREESTYLE_INTERPRETER_H__ diff --git a/source/blender/freestyle/intern/system/Iterator.cpp b/source/blender/freestyle/intern/system/Iterator.cpp index 67acc893589..2e89880b3d7 100644 --- a/source/blender/freestyle/intern/system/Iterator.cpp +++ b/source/blender/freestyle/intern/system/Iterator.cpp @@ -1 +1,32 @@ +/* + * ***** 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 ***** + */ + +/** \file blender/freestyle/intern/system/Iterator.cpp + * \ingroup freestyle + */ + #include "Iterator.h" diff --git a/source/blender/freestyle/intern/system/Iterator.h b/source/blender/freestyle/intern/system/Iterator.h index 1801c1e3b2f..9cd0f16275b 100644 --- a/source/blender/freestyle/intern/system/Iterator.h +++ b/source/blender/freestyle/intern/system/Iterator.h @@ -1,41 +1,75 @@ -#ifndef ITERATOR_H -#define ITERATOR_H +/* + * ***** 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_ITERATOR_H__ +#define __FREESTYLE_ITERATOR_H__ + +/** \file blender/freestyle/intern/system/Iterator.h + * \ingroup freestyle + */ #include #include -using namespace std; +using namespace std; class Iterator { public: + virtual ~Iterator() {} - virtual ~Iterator() {} - - virtual string getExactTypeName() const { - return "Iterator"; - } - - virtual int increment() { - cerr << "Warning: increment() not implemented" << endl; - return 0; - } + virtual string getExactTypeName() const + { + return "Iterator"; + } - virtual int decrement() { - cerr << "Warning: decrement() not implemented" << endl; - return 0; - } + virtual int increment() + { + cerr << "Warning: increment() not implemented" << endl; + return 0; + } - virtual bool isBegin() const { - cerr << "Warning: isBegin() not implemented" << endl; - return false; - } + virtual int decrement() + { + cerr << "Warning: decrement() not implemented" << endl; + return 0; + } - virtual bool isEnd() const { - cerr << "Warning: isEnd() not implemented" << endl; - return false; - } + virtual bool isBegin() const + { + cerr << "Warning: isBegin() not implemented" << endl; + return false; + } + virtual bool isEnd() const + { + cerr << "Warning: isEnd() not implemented" << endl; + return false; + } }; -#endif // ITERATOR_H +#endif // __FREESTYLE_ITERATOR_H__ diff --git a/source/blender/freestyle/intern/system/PointerSequence.h b/source/blender/freestyle/intern/system/PointerSequence.h index 72c6aa458fd..c97f4516d00 100644 --- a/source/blender/freestyle/intern/system/PointerSequence.h +++ b/source/blender/freestyle/intern/system/PointerSequence.h @@ -1,97 +1,96 @@ -// -// Filename : PointerSequence.h -// Author(s) : Alexander Beels -// Purpose : Class to define a cell grid surrounding -// the projected image of a scene -// Date of creation : 22/11/2010 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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_POINTER_SEQUENCE_H__ +#define __FREESTYLE_POINTER_SEQUENCE_H__ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -// -// Simple RAII wrappers for std:: sequential containers -// -/////////////////////////////////////////////////////////////////////////////// - -// -// PointerSequence -// -// Produces a wrapped version of a sequence type (std::vector, std::deque, std::list) -// that will take ownership of pointers tht it stores. Those pointers will be deleted -// in its destructor. -// -// Because the contained pointers are wholly owned by the sequence, you cannot make a -// copy of the sequence. Making a copy would result in a double free. -// -// This is a no-frills class that provides no additional facilities. The user is -// responsible for managing any pointers that are removed from the list, and for making -// sure that any pointers contained in the class are not deleted elsewhere. Because -// this class does no reference counting, the user must also make sure that any pointer -// appears only once in the sequence. -// -// If more sophisticated facilities are needed, use tr1::shared_ptr or boost::shared_ptr. -// This class is only intended to allow one to eke by in projects where tr1 or boost are -// not available. -// -// Usage: The template takes two parameters, the standard container, and the class held -// in the container. This is a limitation of C++ templates, where T::iterator is not a -// type when T is a template parameter. If anyone knows a way around this -// limitation, then the second parameter can be eliminated. -// -// Example: -// PointerSequence, Widget*> v; -// v.push_back(new Widget); -// cout << v[0] << endl; // operator[] is provided by std::vector, not by PointerSequence -// v.destroy(); // Deletes all pointers in sequence and sets them to NULL. -// -// The idiom for removing a pointer from a sequence is: -// Widget* w = v[3]; -// v.erase(v.begin() + 3); // or v[3] = 0; -// The user is now responsible for disposing of w properly. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef POINTERSEQUENCE_H -# define POINTERSEQUENCE_H +/** \file blender/freestyle/intern/system/PointerSequence.h + * \ingroup freestyle + * \brief Simple RAII wrappers for std:: sequential containers + * \author 22/11/2010 + * \date 18/03/2003 + * + * PointerSequence + * + * Produces a wrapped version of a sequence type (std::vector, std::deque, std::list) that will take ownership of + * pointers tht it stores. Those pointers will be deleted in its destructor. + * + * Because the contained pointers are wholly owned by the sequence, you cannot make a copy of the sequence. + * Making a copy would result in a double free. + * + * This is a no-frills class that provides no additional facilities. The user is responsible for managing any + * pointers that are removed from the list, and for making sure that any pointers contained in the class are not + * deleted elsewhere. Because this class does no reference counting, the user must also make sure that any pointer + * appears only once in the sequence. + * + * If more sophisticated facilities are needed, use tr1::shared_ptr or boost::shared_ptr. + * This class is only intended to allow one to eke by in projects where tr1 or boost are not available. + * + * Usage: The template takes two parameters, the standard container, and the class held in the container. This is a + * limitation of C++ templates, where T::iterator is not a type when T is a template parameter. If anyone knows a way + * around this limitation, then the second parameter can be eliminated. + * + * Example: + * PointerSequence, Widget*> v; + * v.push_back(new Widget); + * cout << v[0] << endl; // operator[] is provided by std::vector, not by PointerSequence + * v.destroy(); // Deletes all pointers in sequence and sets them to NULL. + * + * The idiom for removing a pointer from a sequence is: + * Widget* w = v[3]; + * v.erase(v.begin() + 3); // or v[3] = 0; + * The user is now responsible for disposing of w properly. + */ #include template -class PointerSequence : public C { +class PointerSequence : public C +{ PointerSequence (PointerSequence& other); - PointerSequence& operator= (PointerSequence& other); - static void destroyer (T t) { + PointerSequence& operator=(PointerSequence& other); + + static void destroyer(T t) + { delete t; } + public: PointerSequence () {}; - ~PointerSequence () { + + ~PointerSequence () + { destroy(); } - void destroy () { - for_each (this->begin(), this->end(), destroyer); + + void destroy () + { + for_each(this->begin(), this->end(), destroyer); } }; -#endif // POINTERSEQUENCE_H - +#endif // __FREESTYLE_POINTER_SEQUENCE_H__ diff --git a/source/blender/freestyle/intern/system/Precision.h b/source/blender/freestyle/intern/system/Precision.h index 24327a280df..c2a9e24e635 100644 --- a/source/blender/freestyle/intern/system/Precision.h +++ b/source/blender/freestyle/intern/system/Precision.h @@ -1,39 +1,44 @@ -// -// Filename : Precision.h -// Author(s) : Stephane Grabli -// Purpose : Define the float precision used in the program -// Date of creation : 30/07/2002 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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_PRECISION_H__ +#define __FREESTYLE_PRECISION_H__ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef PRECISION_H -# define PRECISION_H +/** \file blender/freestyle/intern/system/Precision.h + * \ingroup freestyle + * \brief Define the float precision used in the program + * \author Stephane Grabli + * \date 30/07/2002 + */ typedef double real; -# ifndef SWIG -static const real M_EPSILON = 0.00000001; -# endif // SWIG +#ifndef SWIG + static const real M_EPSILON = 0.00000001; +#endif // SWIG -#endif // PRECISION_H +#endif // __FREESTYLE_PRECISION_H__ diff --git a/source/blender/freestyle/intern/system/ProgressBar.h b/source/blender/freestyle/intern/system/ProgressBar.h index 5b61f936c90..2837c148754 100644 --- a/source/blender/freestyle/intern/system/ProgressBar.h +++ b/source/blender/freestyle/intern/system/ProgressBar.h @@ -1,85 +1,96 @@ -// -// Filename : ProgressBar.h -// Author(s) : Stephane Grabli -// Purpose : Class to encapsulate a progress bar -// Date of creation : 27/08/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef PROGRESSBAR_H -# define PROGRESSBAR_H - -# include +/* + * ***** 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_PROGRESS_BAR_H__ +#define __FREESTYLE_PROGRESS_BAR_H__ + +/** \file blender/freestyle/intern/system/ProgressBar.h + * \ingroup freestyle + * \brief Class to encapsulate a progress bar + * \author Stephane Grabli + * \date 27/08/2002 + */ + +#include using namespace std; class ProgressBar { public: + inline ProgressBar() + { + _numtotalsteps = 0; + _progress = 0; + } + + virtual ~ProgressBar() {} + + virtual void reset() + { + _numtotalsteps = 0; + _progress = 0; + } + + virtual void setTotalSteps(unsigned n) + { + _numtotalsteps = n; + } + + virtual void setProgress(unsigned i) + { + _progress = i; + } + + virtual void setLabelText(const string& s) + { + _label = s; + } + + /*! accessors */ + inline unsigned int getTotalSteps() const + { + return _numtotalsteps; + } + + inline unsigned int getProgress() const + { + return _progress; + } + + inline string getLabelText() const + { + return _label; + } - inline ProgressBar() { - _numtotalsteps = 0; - _progress = 0; - } - - virtual ~ProgressBar() {} - - virtual void reset() { - _numtotalsteps = 0; - _progress = 0; - } - - virtual void setTotalSteps(unsigned n) { - _numtotalsteps = n; - } - - virtual void setProgress(unsigned i) { - _progress = i; - } - - virtual void setLabelText(const string& s) { - _label = s; - } - - /*! accessors */ - inline unsigned int getTotalSteps() const { - return _numtotalsteps; - } - - inline unsigned int getProgress() const { - return _progress; - } - - inline string getLabelText() const { - return _label; - } - protected: - - unsigned _numtotalsteps; - unsigned _progress; - string _label; + unsigned _numtotalsteps; + unsigned _progress; + string _label; }; -#endif // PROGRESSBAR_H +#endif // __FREESTYLE_PROGRESS_BAR_H__ diff --git a/source/blender/freestyle/intern/system/PseudoNoise.cpp b/source/blender/freestyle/intern/system/PseudoNoise.cpp index 069027ed3e0..27158bfd4aa 100644 --- a/source/blender/freestyle/intern/system/PseudoNoise.cpp +++ b/source/blender/freestyle/intern/system/PseudoNoise.cpp @@ -1,109 +1,116 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/system/PseudoNoise.cpp + * \ingroup freestyle + * \brief Class to define a pseudo Perlin noise + * \author Fredo Durand + * \date 16/06/2003 + */ #include -#include "RandGen.h" + #include "PseudoNoise.h" +#include "RandGen.h" static const unsigned NB_VALUE_NOISE = 512; real *PseudoNoise::_values; -PseudoNoise::PseudoNoise () -{ -} +PseudoNoise::PseudoNoise() {} -void -PseudoNoise::init (long seed) +void PseudoNoise::init(long seed) { - _values = new real[NB_VALUE_NOISE]; - RandGen::srand48(seed); - for (unsigned int i=0; i2) return 0; - if (fabs(t) 2) + return 0; + if (fabs(t) < M_EPSILON) + return 1.0; + return sin(M_PI * t) / (M_PI * t) * sin(M_PI * t / 2.0) / (M_PI * t / 2.0); } -real -PseudoNoise::smoothNoise (real x) +real PseudoNoise::smoothNoise(real x) { - real tmp; - int i = modf(x, &tmp) * NB_VALUE_NOISE; - int h = i - 1; - if (h < 0) - { - h = NB_VALUE_NOISE + h; - } + real tmp; + int i = modf(x, &tmp) * NB_VALUE_NOISE; + int h = i - 1; + if (h < 0) { + h = NB_VALUE_NOISE + h; + } - real x1=_values[i], x2=_values[(i+1)%NB_VALUE_NOISE]; - real x0=_values[h], x3=_values[(i+2)%NB_VALUE_NOISE]; + real x1 = _values[i], x2 = _values[(i + 1) % NB_VALUE_NOISE]; + real x0 = _values[h], x3 = _values[(i + 2) % NB_VALUE_NOISE]; - real t = modf(x * NB_VALUE_NOISE, &tmp); - real y0=LanczosWindowed(-1-t); - real y1=LanczosWindowed(-t); - real y2=LanczosWindowed(1-t); - real y3=LanczosWindowed(2-t); - // cerr<<"x0="< -# include -# include "StringUtils.h" -# include "Interpreter.h" +/* + * ***** 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_PYTHON_INTERPRETER_H__ +#define __FREESTYLE_PYTHON_INTERPRETER_H__ + +/** \file blender/freestyle/intern/system/PythonInterpreter.h + * \ingroup freestyle + * \brief Python Interpreter + * \author Emmanuel Turquin + * \date 17/04/2003 + */ + +#include +#include + +#include "StringUtils.h" +#include "Interpreter.h" //soc extern "C" { + #include "MEM_guardedalloc.h" + #include "DNA_text_types.h" -#include "BKE_main.h" + #include "BKE_context.h" #include "BKE_global.h" +#include "BKE_library.h" +#include "BKE_main.h" #include "BKE_report.h" #include "BKE_text.h" -#include "BKE_library.h" + #include "BPY_extern.h" + } class LIB_SYSTEM_EXPORT PythonInterpreter : public Interpreter { - public: - - PythonInterpreter() { - _language = "Python"; - _context = 0; - //Py_Initialize(); - } +public: + PythonInterpreter() + { + _language = "Python"; + _context = 0; + //Py_Initialize(); + } - virtual ~PythonInterpreter() { - //Py_Finalize(); - } + virtual ~PythonInterpreter() + { + //Py_Finalize(); + } - void setContext(bContext *C) { - _context = C; - } + void setContext(bContext *C) + { + _context = C; + } - int interpretFile(const string& filename) { + int interpretFile(const string& filename) + { + initPath(); - initPath(); - - ReportList* reports = CTX_wm_reports(_context); - BKE_reports_clear(reports); - char *fn = const_cast(filename.c_str()); + ReportList *reports = CTX_wm_reports(_context); + BKE_reports_clear(reports); + char *fn = const_cast(filename.c_str()); #if 0 - int status = BPY_filepath_exec(_context, fn, reports); + int status = BPY_filepath_exec(_context, fn, reports); #else - int status; - Text *text = BKE_text_load(fn, G.main->name); - if (text) { - status = BPY_text_exec(_context, text, reports, false); - BKE_text_unlink(G.main, text); - BKE_libblock_free(&G.main->text, text); - } else { - BKE_reportf(reports, RPT_ERROR, "Cannot open file: %s", fn); - status = 0; - } + int status; + Text *text = BKE_text_load(fn, G.main->name); + if (text) { + status = BPY_text_exec(_context, text, reports, false); + BKE_text_unlink(G.main, text); + BKE_libblock_free(&G.main->text, text); + } + else { + BKE_reportf(reports, RPT_ERROR, "Cannot open file: %s", fn); + status = 0; + } #endif - if (status != 1) { - cout << "\nError executing Python script from PythonInterpreter::interpretFile" << endl; - cout << "File: " << fn << endl; - cout << "Errors: " << endl; - BKE_reports_print(reports, RPT_ERROR); - return 1; + if (status != 1) { + cout << "\nError executing Python script from PythonInterpreter::interpretFile" << endl; + cout << "File: " << fn << endl; + cout << "Errors: " << endl; + BKE_reports_print(reports, RPT_ERROR); + return 1; + } + + // cleaning up + BKE_reports_clear(reports); + + return 0; } - // cleaning up - BKE_reports_clear(reports); - - return 0; - } + int interpretText(struct Text *text, const string& name) { + initPath(); - int interpretText(struct Text *text, const string& name) { + ReportList *reports = CTX_wm_reports(_context); - initPath(); + BKE_reports_clear(reports); - ReportList* reports = CTX_wm_reports(_context); + if (!BPY_text_exec(_context, text, reports, false)) { + cout << "\nError executing Python script from PythonInterpreter::interpretText" << endl; + cout << "Name: " << name << endl; + cout << "Errors: " << endl; + BKE_reports_print(reports, RPT_ERROR); + return 1; + } - BKE_reports_clear(reports); + BKE_reports_clear(reports); - if (!BPY_text_exec(_context, text, reports, false)) { - cout << "\nError executing Python script from PythonInterpreter::interpretText" << endl; - cout << "Name: " << name << endl; - cout << "Errors: " << endl; - BKE_reports_print(reports, RPT_ERROR); - return 1; + return 0; } - BKE_reports_clear(reports); + struct Options + { + static void setPythonPath(const string& path) + { + _path = path; + } - return 0; - } + static string getPythonPath() + { + return _path; + } + }; - struct Options - { - static void setPythonPath(const string& path) { - _path = path; - } + void reset() + { + Py_Finalize(); + Py_Initialize(); + _initialized = false; + } - static string getPythonPath() { - return _path; - } - }; +private: + bContext *_context; + + void initPath() + { + if (_initialized) + return; + + vector pathnames; + StringUtils::getPathName(_path, "", pathnames); + + struct Text *text = BKE_text_add("tmp_freestyle_initpath.txt"); + string cmd = "import sys\n"; + txt_insert_buf(text, const_cast(cmd.c_str())); + + for (vector::const_iterator it = pathnames.begin(); it != pathnames.end(); ++it) { + if (!it->empty()) { + cout << "Adding Python path: " << *it << endl; + cmd = "sys.path.append(r\"" + *it + "\")\n"; + txt_insert_buf(text, const_cast(cmd.c_str())); + } + } - void reset() { - Py_Finalize(); - Py_Initialize(); - _initialized = false; - } + BPY_text_exec(_context, text, NULL, false); -private: + // cleaning up + BKE_text_unlink(G.main, text); + BKE_libblock_free(&G.main->text, text); - bContext* _context; - - void initPath() { - if (_initialized) - return; - - vector pathnames; - StringUtils::getPathName(_path, "", pathnames); - - struct Text *text = BKE_text_add("tmp_freestyle_initpath.txt"); - string cmd = "import sys\n"; - txt_insert_buf(text, const_cast(cmd.c_str())); - - for (vector::const_iterator it = pathnames.begin(); it != pathnames.end();++it) { - if ( !it->empty() ) { - cout << "Adding Python path: " << *it << endl; - cmd = "sys.path.append(r\"" + *it + "\")\n"; - txt_insert_buf(text, const_cast(cmd.c_str())); - } + //PyRun_SimpleString("from Freestyle import *"); + _initialized = true; } - - BPY_text_exec(_context, text, NULL, false); - - // cleaning up - BKE_text_unlink(G.main, text); - BKE_libblock_free(&G.main->text, text); - - //PyRun_SimpleString("from Freestyle import *"); - _initialized = true; - } - - static bool _initialized; - static string _path; + + static bool _initialized; + static string _path; }; -#endif // PYTHON_INTERPRETER_H +#endif // __FREESTYLE_PYTHON_INTERPRETER_H__ diff --git a/source/blender/freestyle/intern/system/RandGen.cpp b/source/blender/freestyle/intern/system/RandGen.cpp index a328cb7f583..193df1b4239 100644 --- a/source/blender/freestyle/intern/system/RandGen.cpp +++ b/source/blender/freestyle/intern/system/RandGen.cpp @@ -1,23 +1,36 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/system/RandGen.cpp + * \ingroup freestyle + * \brief Pseudo-random number generator + * \author Fredo Durand + * \date 20/05/2003 + */ #include "RandGen.h" @@ -26,61 +39,94 @@ // /////////////////////////////////////////////////////////////////////////////// -#define N 16 -#define MASK ((unsigned)(1 << (N - 1)) + (1 << (N - 1)) - 1) -#define X0 0x330E -#define X1 0xABCD -#define X2 0x1234 -#define A0 0xE66D -#define A1 0xDEEC -#define A2 0x5 -#define C 0xB -#define HI_BIT (1L << (2 * N - 1)) +#define N 16 +#define MASK ((unsigned)(1 << (N - 1)) + (1 << (N - 1)) - 1) +#define X0 0x330E +#define X1 0xABCD +#define X2 0x1234 +#define A0 0xE66D +#define A1 0xDEEC +#define A2 0x5 +#define C 0xB +#define HI_BIT (1L << (2 * N - 1)) -#define LOW(x) ((unsigned)(x) & MASK) -#define HIGH(x) LOW((x) >> N) -#define MUL(x, y, z) { long l = (long)(x) * (long)(y); \ - (z)[0] = LOW(l); (z)[1] = HIGH(l); } -#define CARRY(x, y) ((unsigned long)((long)(x) + (long)(y)) > MASK) -#define ADDEQU(x, y, z) (z = CARRY(x, (y)), x = LOW(x + (y))) -#define SET3(x, x0, x1, x2) ((x)[0] = (x0), (x)[1] = (x1), (x)[2] = (x2)) -#define SETLOW(x, y, n) SET3(x, LOW((y)[n]), LOW((y)[(n)+1]), LOW((y)[(n)+2])) -#define SEED(x0, x1, x2) (SET3(x, x0, x1, x2), SET3(a, A0, A1, A2), c = C) -#define REST(v) for (i = 0; i < 3; i++) { xsubi[i] = x[i]; x[i] = temp[i]; } \ - return (v); -#define NEST(TYPE, f, F) TYPE f(register unsigned short *xsubi) { \ - register int i; register TYPE v; unsigned temp[3]; \ - for (i = 0; i < 3; i++) { temp[i] = x[i]; x[i] = LOW(xsubi[i]); } \ - v = F(); REST(v); } +#define LOW(x) ((unsigned)(x) & MASK) +#define HIGH(x) LOW((x) >> N) -static unsigned x[3] = { X0, X1, X2 }, a[3] = { A0, A1, A2 }, c = C; +#define MUL(x, y, z) \ + { \ + long l = (long)(x) * (long)(y); \ + (z)[0] = LOW(l); \ + (z)[1] = HIGH(l); \ + } + +#define CARRY(x, y) ((unsigned long)((long)(x) + (long)(y)) > MASK) +#define ADDEQU(x, y, z) (z = CARRY(x, (y)), x = LOW(x + (y))) +#define SET3(x, x0, x1, x2) ((x)[0] = (x0), (x)[1] = (x1), (x)[2] = (x2)) +#define SETLOW(x, y, n) SET3(x, LOW((y)[n]), LOW((y)[(n)+1]), LOW((y)[(n)+2])) +#define SEED(x0, x1, x2) (SET3(x, x0, x1, x2), SET3(a, A0, A1, A2), c = C) + +#define REST(v) \ + for (i = 0; i < 3; i++) { \ + xsubi[i] = x[i]; \ + x[i] = temp[i]; \ + } \ + return (v); \ + (void) 0 + +#define NEST(TYPE, f, F) \ + TYPE f(register unsigned short *xsubi) { \ + register int i; \ + register TYPE v; \ + unsigned temp[3]; \ + for (i = 0; i < 3; i++) { \ + temp[i] = x[i]; \ + x[i] = LOW(xsubi[i]); \ + } \ + v = F(); \ + REST(v); \ + } + +static unsigned x[3] = { + X0, + X1, + X2 +}; +static unsigned a[3] = { + A0, + A1, + A2 +}; +static unsigned c = C; // // Methods implementation // /////////////////////////////////////////////////////////////////////////////// -real RandGen::drand48() { - static real two16m = 1.0 / (1L << N); - next(); - return (two16m * (two16m * (two16m * x[0] + x[1]) + x[2])); +real RandGen::drand48() +{ + static real two16m = 1.0 / (1L << N); + next(); + return (two16m * (two16m * (two16m * x[0] + x[1]) + x[2])); } -void RandGen::srand48(long seedval) { - SEED(X0, LOW(seedval), HIGH(seedval)); +void RandGen::srand48(long seedval) +{ + SEED(X0, LOW(seedval), HIGH(seedval)); } -void RandGen::next() { - unsigned p[2], q[2], r[2], carry0, carry1; - - MUL(a[0], x[0], p); - ADDEQU(p[0], c, carry0); - ADDEQU(p[1], carry0, carry1); - MUL(a[0], x[1], q); - ADDEQU(p[1], q[0], carry0); - MUL(a[1], x[0], r); - x[2] = LOW(carry0 + carry1 + CARRY(p[1], r[0]) + q[1] + r[1] + - a[0] * x[2] + a[1] * x[1] + a[2] * x[0]); - x[1] = LOW(p[1] + r[0]); - x[0] = LOW(p[0]); +void RandGen::next() +{ + unsigned p[2], q[2], r[2], carry0, carry1; + + MUL(a[0], x[0], p); + ADDEQU(p[0], c, carry0); + ADDEQU(p[1], carry0, carry1); + MUL(a[0], x[1], q); + ADDEQU(p[1], q[0], carry0); + MUL(a[1], x[0], r); + x[2] = LOW(carry0 + carry1 + CARRY(p[1], r[0]) + q[1] + r[1] + a[0] * x[2] + a[1] * x[1] + a[2] * x[0]); + x[1] = LOW(p[1] + r[0]); + x[0] = LOW(p[0]); } diff --git a/source/blender/freestyle/intern/system/RandGen.h b/source/blender/freestyle/intern/system/RandGen.h index 409d3b79609..914b405d7f3 100644 --- a/source/blender/freestyle/intern/system/RandGen.h +++ b/source/blender/freestyle/intern/system/RandGen.h @@ -1,48 +1,54 @@ -// -// Filename : RandGen.h -// Author(s) : Fredo Durand -// Purpose : Pseudo-random number generator -// Date of creation : 20/05/2003 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef RAND_GEN_H -# define RAND_GEN_H - -# include "FreestyleConfig.h" -# include "../system/Precision.h" +/* + * ***** 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_RAND_GEN_H__ +#define __FREESTYLE_RAND_GEN_H__ + +/** \file blender/freestyle/intern/system/RandGen.h + * \ingroup freestyle + * \brief Pseudo-random number generator + * \author Fredo Durand + * \date 20/05/2003 + */ + +// TODO Check whether we could replace this with BLI rand stuff... + +#include "FreestyleConfig.h" + +#include "../system/Precision.h" class LIB_SYSTEM_EXPORT RandGen { public: - - static real drand48(); - static void srand48(long value); + static real drand48(); + static void srand48(long value); private: - - static void next(); + static void next(); }; -#endif // RAND_GEN_H +#endif // __FREESTYLE_RAND_GEN_H__ diff --git a/source/blender/freestyle/intern/system/RenderMonitor.h b/source/blender/freestyle/intern/system/RenderMonitor.h index 7d148e65c90..bd50e0c5392 100644 --- a/source/blender/freestyle/intern/system/RenderMonitor.h +++ b/source/blender/freestyle/intern/system/RenderMonitor.h @@ -1,47 +1,63 @@ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef RENDERMONITOR_H -#define RENDERMONITOR_H +/* + * ***** 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_RENDER_MONITOR_H__ +#define __FREESTYLE_RENDER_MONITOR_H__ + +/** \file blender/freestyle/intern/system/BaseIterator.h + * \ingroup freestyle + * \brief Classes defining the basic "Iterator" design pattern + * \author Stephane Grabli + * \date 18/03/2003 + */ extern "C" { + #include "render_types.h" + } class RenderMonitor { public: + inline RenderMonitor(Render *re) + { + _re = re; + } - inline RenderMonitor(Render *re) { - _re = re; - } + virtual ~RenderMonitor() {} - virtual ~RenderMonitor() {} + inline bool testBreak() + { + return _re && _re->test_break(_re->tbh); + } - inline bool testBreak() { - return _re && _re->test_break(_re->tbh); - } - protected: - - Render *_re; + Render *_re; }; -#endif // RENDERMONITOR_H +#endif // __FREESTYLE_RENDER_MONITOR_H__ diff --git a/source/blender/freestyle/intern/system/StringUtils.cpp b/source/blender/freestyle/intern/system/StringUtils.cpp index 58798daf42a..ee06d3d1f4b 100644 --- a/source/blender/freestyle/intern/system/StringUtils.cpp +++ b/source/blender/freestyle/intern/system/StringUtils.cpp @@ -1,74 +1,89 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/system/StringUtils.cpp + * \ingroup freestyle + * \brief String utilities + * \author Emmanuel Turquin + * \date 20/05/2003 + */ //soc #include + #include "FreestyleConfig.h" #include "StringUtils.h" namespace StringUtils { - void getPathName(const string& path, const string& base, vector& pathnames) { - string dir; +void getPathName(const string& path, const string& base, vector& pathnames) +{ + string dir; string res; char cleaned[FILE_MAX]; - unsigned size = path.size(); - - pathnames.push_back(base); + unsigned size = path.size(); - for ( unsigned pos = 0, sep = path.find(Config::PATH_SEP, pos); - pos < size; - pos = sep + 1, sep = path.find(Config::PATH_SEP, pos)) { + pathnames.push_back(base); + for (unsigned int pos = 0, sep = path.find(Config::PATH_SEP, pos); + pos < size; + pos = sep + 1, sep = path.find(Config::PATH_SEP, pos)) + { if (sep == (unsigned)string::npos) sep = size; - + dir = path.substr(pos, sep - pos); BLI_strncpy(cleaned, dir.c_str(), FILE_MAX); BLI_cleanup_file(NULL, cleaned); - res = toAscii( string(cleaned) ); - + res = toAscii(string(cleaned)); + if (!base.empty()) res += Config::DIR_SEP + base; - + pathnames.push_back(res); - } - } - - string toAscii( const string &str ){ - stringstream out(""); - char s; - - for(unsigned int i=0; i < str.size() ; i++){ - s = ((char)(str.at(i) & 0x7F)); - out << s; - } - - return out.str(); } - - const char* toAscii( const char *str ){ - return toAscii(string(str)).c_str(); +} + +string toAscii(const string &str) +{ + stringstream out(""); + char s; + + for (unsigned int i = 0; i < str.size() ; i++) { + s = ((char)(str.at(i) & 0x7F)); + out << s; } - + return out.str(); +} + +const char *toAscii(const char *str) +{ + return toAscii(string(str)).c_str(); +} } // end of namespace StringUtils diff --git a/source/blender/freestyle/intern/system/StringUtils.h b/source/blender/freestyle/intern/system/StringUtils.h index d44d3f62732..d8970da0dce 100644 --- a/source/blender/freestyle/intern/system/StringUtils.h +++ b/source/blender/freestyle/intern/system/StringUtils.h @@ -1,62 +1,75 @@ -// -// Filename : StringUtils.h -// Author(s) : Emmanuel Turquin -// Purpose : String utilities -// Date of creation : 20/05/2003 -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef STRING_UTILS_H -# define STRING_UTILS_H - -# include -# include -# include -# include -# include -# include "FreestyleConfig.h" +/* + * ***** 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_STRING_UTILS_H__ +#define __FREESTYLE_STRING_UTILS_H__ + +/** \file blender/freestyle/intern/system/StringUtils.h + * \ingroup freestyle + * \brief String utilities + * \author Emmanuel Turquin + * \date 20/05/2003 + */ + +#include +#include +#include +#include +#include + +#include "FreestyleConfig.h" //soc extern "C" { + #include "BKE_utildefines.h" + #include "BLI_blenlib.h" + } using namespace std; namespace StringUtils { - LIB_SYSTEM_EXPORT - void getPathName(const string& path, const string& base, vector& pathnames); - string toAscii( const string &str ); - const char* toAscii( const char *str ); +LIB_SYSTEM_EXPORT +void getPathName(const string& path, const string& base, vector& pathnames); +string toAscii(const string &str); +const char *toAscii(const char *str); - // STL related - struct ltstr{ - bool operator()(const char* s1, const char* s2) const{ - return strcmp(s1, s2) < 0; - } +// STL related +struct ltstr +{ + bool operator()(const char *s1, const char *s2) const + { + return strcmp(s1, s2) < 0; + } }; } // end of namespace StringUtils -#endif // STRING_UTILS_H +#endif // __FREESTYLE_STRING_UTILS_H__ diff --git a/source/blender/freestyle/intern/system/TimeStamp.cpp b/source/blender/freestyle/intern/system/TimeStamp.cpp index c66e1131611..6a7f0b00b79 100644 --- a/source/blender/freestyle/intern/system/TimeStamp.cpp +++ b/source/blender/freestyle/intern/system/TimeStamp.cpp @@ -1,25 +1,38 @@ +/* + * ***** 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 ***** + */ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/system/TimeStamp.cpp + * \ingroup freestyle + * \brief Class defining a singleton used as timestamp + * \author Stephane Grabli + * \date 12/12/2002 + */ #include "TimeStamp.h" -LIB_SYSTEM_EXPORT -TimeStamp* TimeStamp::_instance = 0; +LIB_SYSTEM_EXPORT +TimeStamp *TimeStamp::_instance = 0; diff --git a/source/blender/freestyle/intern/system/TimeStamp.h b/source/blender/freestyle/intern/system/TimeStamp.h index 568a7851e30..6f9bb3d4e44 100644 --- a/source/blender/freestyle/intern/system/TimeStamp.h +++ b/source/blender/freestyle/intern/system/TimeStamp.h @@ -1,71 +1,78 @@ -// -// Filename : TimeStamp.h -// Author(s) : Stephane Grabli -// Purpose : Class defining a singleton used as timestamp -// Date of creation : 12/12/2002 -// -/////////////////////////////////////////////////////////////////////////////// +/* + * ***** 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_TIME_STAMP_H__ +#define __FREESTYLE_TIME_STAMP_H__ -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// +/** \file blender/freestyle/intern/system/TimeStamp.h + * \ingroup freestyle + * \brief Class defining a singleton used as timestamp + * \author Stephane Grabli + * \date 12/12/2002 + */ -#ifndef TIMESTAMP_H -# define TIMESTAMP_H +#include "FreestyleConfig.h" -# include "FreestyleConfig.h" - -class LIB_SYSTEM_EXPORT TimeStamp +class LIB_SYSTEM_EXPORT TimeStamp { - public: - - static inline TimeStamp* instance() { - if (_instance == 0) - _instance = new TimeStamp; - return _instance; - } - - inline unsigned getTimeStamp() const { - return _time_stamp; - } +public: + static inline TimeStamp *instance() + { + if (_instance == NULL) + _instance = new TimeStamp; + return _instance; + } - inline void increment() { - ++_time_stamp; - } + inline unsigned getTimeStamp() const + { + return _time_stamp; + } - inline void reset() { - _time_stamp = 1; - } + inline void increment() + { + ++_time_stamp; + } - protected: - - TimeStamp() { - _time_stamp = 1; - } + inline void reset() + { + _time_stamp = 1; + } - TimeStamp(const TimeStamp&) {} +protected: + TimeStamp() + { + _time_stamp = 1; + } - private: + TimeStamp(const TimeStamp&) {} - static TimeStamp* _instance; - unsigned _time_stamp; +private: + static TimeStamp *_instance; + unsigned _time_stamp; }; -#endif // TIMESTAMP_H +#endif // __FREESTYLE_TIME_STAMP_H__ diff --git a/source/blender/freestyle/intern/system/TimeUtils.h b/source/blender/freestyle/intern/system/TimeUtils.h index 99dd5b0a669..d42813dd560 100644 --- a/source/blender/freestyle/intern/system/TimeUtils.h +++ b/source/blender/freestyle/intern/system/TimeUtils.h @@ -1,58 +1,64 @@ -// -// Filename : TimeUtils.h -// Author(s) : Stephane Grabli -// Purpose : Class to measure ellapsed time -// Date of creation : 10/04/2002 -// -/////////////////////////////////////////////////////////////////////////////// - - -// -// Copyright (C) : Please refer to the COPYRIGHT file distributed -// with this source distribution. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef TIMEUTILS_H -# define TIMEUTILS_H +/* + * ***** 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_TIME_UTILS_H__ +#define __FREESTYLE_TIME_UTILS_H__ + +/** \file blender/freestyle/intern/system/TimeUtils.h + * \ingroup freestyle + * \brief Class to measure ellapsed time + * \author Stephane Grabli + * \date 10/04/2002 + */ #include + #include "FreestyleConfig.h" -class Chronometer +class Chronometer { - public: - - inline Chronometer() {} - inline ~Chronometer() {} - - inline clock_t start() { - _start = clock(); - return _start; - } +public: + inline Chronometer() {} + inline ~Chronometer() {} - inline double stop() { - clock_t stop = clock(); - return (double)(stop - _start) / CLOCKS_PER_SEC ; - } + inline clock_t start() + { + _start = clock(); + return _start; + } - private: + inline double stop() + { + clock_t stop = clock(); + return (double)(stop - _start) / CLOCKS_PER_SEC; + } - clock_t _start; +private: + clock_t _start; }; -#endif // TIMEUTILS_H +#endif // __FREESTYLE_TIME_UTILS_H__ -- cgit v1.2.3