From a0682124459d870e53f1bc5d9b1d2930e5a907f3 Mon Sep 17 00:00:00 2001 From: Tamito Kajiyama Date: Fri, 20 Mar 2009 22:55:07 +0000 Subject: Made changes to the C++ API in order to allow for proper error propagation up to the toplevel error handler in BPY_txt_do_python_Text(). Before these changes were made, the operator() methods of predicates and functions, for example, returned a value of various types such as bool, double and Vec2f. These returned values were not capable to represent an error state in many cases. Now the operator() methods always return 0 on normal exit and -1 on error. The original returned values are stored in the "result" member variables of the predicate/function classes. This means that if we have a code fragment like below: UnaryPredicate1D& pred; Interface1D& inter; if (pred(inter)) { /* do something */ } then we have to rewrite it as follows: UnaryPredicate1D& pred; Interface1D& inter; if (pred(inter) < 0) return -1; /* an error in pred() is propagated */ if (pred.result) { /* do something */ } Suppose that pred is a user-defined predicate in Python, i.e. the predicate is likely error-prone (especially when debugging the predicate). The first code fragment shown above prevents the proper error propagation because the boolean return value of UnaryPredicate1D::operator() cannot inform the occurrence of an error to the caller; the second code fragment can. In addition to the operator() methods of predicates and functions, similar improvements have been made to all other C++ API functions and methods that are involved in the execution of user-defined Python code snippets. Changes in the signatures of functions and methods are summarized as follows (note that all subclasses of listed classes are also subject to the changes). Old signatures: virtual void Iterator::increment(); virtual void Iterator::decrement(); virtual void ChainingIterator::init(); virtual ViewEdge * ChainingIterator::traverse(const AdjacencyIterator &it); static void Operators::select(UnaryPredicate1D& pred); static void Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, UnaryPredicate1D& pred, UnaryFunction1D_void& modifier); static void Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, UnaryPredicate1D& pred); static void Operators::bidirectionalChain(ChainingIterator& it, UnaryPredicate1D& pred); static void Operators::bidirectionalChain(ChainingIterator& it); static void Operators::sequentialSplit(UnaryPredicate0D& startingPred, UnaryPredicate0D& stoppingPred, float sampling = 0); static void Operators::sequentialSplit(UnaryPredicate0D& pred, float sampling = 0); static void Operators::recursiveSplit(UnaryFunction0D& func, UnaryPredicate1D& pred, float sampling = 0); static void Operators::recursiveSplit(UnaryFunction0D& func, UnaryPredicate0D& pred0d, UnaryPredicate1D& pred, float sampling = 0); static void Operators::sort(BinaryPredicate1D& pred); static void Operators::create(UnaryPredicate1D& pred, vector shaders); virtual bool UnaryPredicate0D::operator()(Interface0DIterator& it); virtual bool BinaryPredicate0D::operator()(Interface0D& inter1, Interface0D& inter2); virtual bool UnaryPredicate1D::operator()(Interface1D& inter); virtual bool BinaryPredicate1D::operator()(Interface1D& inter1, Interface1D& inter2); virtual void StrokeShader::shade(Stroke& ioStroke) const; virtual T UnaryFunction0D::operator()(Interface0DIterator& iter); virtual T UnaryFunction1D::operator()(Interface1D& inter); New signatures: virtual int Iterator::increment(); virtual int Iterator::decrement(); virtual int ChainingIterator::init(); virtual int ChainingIterator::traverse(const AdjacencyIterator &it); static int Operators::select(UnaryPredicate1D& pred); static int Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, UnaryPredicate1D& pred, UnaryFunction1D_void& modifier); static int Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, UnaryPredicate1D& pred); static int Operators::bidirectionalChain(ChainingIterator& it, UnaryPredicate1D& pred); static int Operators::bidirectionalChain(ChainingIterator& it); static int Operators::sequentialSplit(UnaryPredicate0D& startingPred, UnaryPredicate0D& stoppingPred, float sampling = 0); static int Operators::sequentialSplit(UnaryPredicate0D& pred, float sampling = 0); static int Operators::recursiveSplit(UnaryFunction0D& func, UnaryPredicate1D& pred, float sampling = 0); static int Operators::recursiveSplit(UnaryFunction0D& func, UnaryPredicate0D& pred0d, UnaryPredicate1D& pred, float sampling = 0); static int Operators::sort(BinaryPredicate1D& pred); static int Operators::create(UnaryPredicate1D& pred, vector shaders); virtual int UnaryPredicate0D::operator()(Interface0DIterator& it); virtual int BinaryPredicate0D::operator()(Interface0D& inter1, Interface0D& inter2); virtual int UnaryPredicate1D::operator()(Interface1D& inter); virtual int BinaryPredicate1D::operator()(Interface1D& inter1, Interface1D& inter2); virtual int StrokeShader::shade(Stroke& ioStroke) const; virtual int UnaryFunction0D::operator()(Interface0DIterator& iter); virtual int UnaryFunction1D::operator()(Interface1D& inter); --- .../intern/stroke/AdvancedFunctions0D.cpp | 45 +-- .../freestyle/intern/stroke/AdvancedFunctions0D.h | 12 +- .../intern/stroke/AdvancedFunctions1D.cpp | 22 +- .../freestyle/intern/stroke/AdvancedFunctions1D.h | 18 +- .../freestyle/intern/stroke/AdvancedPredicates1D.h | 7 +- .../intern/stroke/AdvancedStrokeShaders.cpp | 20 +- .../intern/stroke/AdvancedStrokeShaders.h | 8 +- .../freestyle/intern/stroke/BasicStrokeShaders.cpp | 128 ++++++--- .../freestyle/intern/stroke/BasicStrokeShaders.h | 52 ++-- .../freestyle/intern/stroke/ChainingIterators.cpp | 69 +++-- .../freestyle/intern/stroke/ChainingIterators.h | 42 +-- .../freestyle/intern/stroke/CurveIterators.h | 16 +- .../blender/freestyle/intern/stroke/Operators.cpp | 320 ++++++++++++++++----- source/blender/freestyle/intern/stroke/Operators.h | 22 +- .../blender/freestyle/intern/stroke/Predicates0D.h | 32 ++- .../blender/freestyle/intern/stroke/Predicates1D.h | 137 ++++++--- .../freestyle/intern/stroke/StrokeIterators.h | 6 +- .../blender/freestyle/intern/stroke/StrokeShader.h | 9 +- 18 files changed, 644 insertions(+), 321 deletions(-) (limited to 'source/blender/freestyle/intern/stroke') diff --git a/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.cpp b/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.cpp index c22e183eccb..7a51a1a78df 100755 --- a/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.cpp +++ b/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.cpp @@ -26,60 +26,67 @@ namespace Functions0D { - double DensityF0D::operator()(Interface0DIterator& iter) { + 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())) - return 0.0; + || (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); - return _filter.getSmoothedPixel(&image, (int)iter->getProjectedX(), + result = _filter.getSmoothedPixel(&image, (int)iter->getProjectedX(), (int)iter->getProjectedY()); + return 0; } - double LocalAverageDepthF0D::operator()(Interface0DIterator& iter) { + 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())) - return 0.0; + || (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); - return _filter.getSmoothedPixel(&image, (int)iter->getProjectedX(), (int)iter->getProjectedY()); + result = _filter.getSmoothedPixel(&image, (int)iter->getProjectedX(), (int)iter->getProjectedY()); + return 0; } - float ReadMapPixelF0D::operator()(Interface0DIterator& iter) { + int ReadMapPixelF0D::operator()(Interface0DIterator& iter) { Canvas * canvas = Canvas::getInstance(); - return canvas->readMapPixel(_mapName, _level, (int)iter->getProjectedX(), (int)iter->getProjectedY()); + result = canvas->readMapPixel(_mapName, _level, (int)iter->getProjectedX(), (int)iter->getProjectedY()); + return 0; } - float ReadSteerableViewMapPixelF0D::operator()(Interface0DIterator& iter) { + int ReadSteerableViewMapPixelF0D::operator()(Interface0DIterator& iter) { SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap(); - float v = svm->readSteerableViewMapPixel(_orientation, _level,(int)iter->getProjectedX(), (int)iter->getProjectedY()); - return v; + result = svm->readSteerableViewMapPixel(_orientation, _level,(int)iter->getProjectedX(), (int)iter->getProjectedY()); + return 0; } - float ReadCompleteViewMapPixelF0D::operator()(Interface0DIterator& iter) { + int ReadCompleteViewMapPixelF0D::operator()(Interface0DIterator& iter) { SteerableViewMap *svm = Canvas::getInstance()->getSteerableViewMap(); - float v = svm->readCompleteViewMapPixel(_level,(int)iter->getProjectedX(), (int)iter->getProjectedY()); - return v; + result = svm->readCompleteViewMapPixel(_level,(int)iter->getProjectedX(), (int)iter->getProjectedY()); + return 0; } - float GetViewMapGradientNormF0D::operator()(Interface0DIterator& iter){ + 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; - float f = Vec2f(gx,gy).norm(); - return f; + 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 9eee6714b09..5d62ea8d9eb 100755 --- a/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.h +++ b/source/blender/freestyle/intern/stroke/AdvancedFunctions0D.h @@ -66,7 +66,7 @@ namespace Functions0D { return "DensityF0D"; } /*! The () operator. */ - double operator()(Interface0DIterator& iter); + int operator()(Interface0DIterator& iter); private: @@ -94,7 +94,7 @@ namespace Functions0D { return "LocalAverageDepthF0D"; } /*! the () operator.*/ - double operator()(Interface0DIterator& iter); + int operator()(Interface0DIterator& iter); }; // ReadMapPixel @@ -123,7 +123,7 @@ namespace Functions0D { return "ReadMapPixelF0D"; } /*! the () operator.*/ - float operator()(Interface0DIterator& iter); + int operator()(Interface0DIterator& iter); }; // ReadSteerableViewMapPixel @@ -152,7 +152,7 @@ namespace Functions0D { return "ReadSteerableViewMapPixelF0D"; } /*! the () operator.*/ - float operator()(Interface0DIterator& iter); + int operator()(Interface0DIterator& iter); }; // ReadCompleteViewMapPixel @@ -176,7 +176,7 @@ namespace Functions0D { return "ReadCompleteViewMapPixelF0D"; } /*! the () operator.*/ - float operator()(Interface0DIterator& iter); + int operator()(Interface0DIterator& iter); }; // GetViewMapGradientNormF0D @@ -202,7 +202,7 @@ namespace Functions0D { return "GetViewMapGradientNormF0D"; } /*! the () operator.*/ - float operator()(Interface0DIterator& iter); + int operator()(Interface0DIterator& iter); }; } // end of namespace Functions0D diff --git a/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.cpp b/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.cpp index ca0e97e68c1..2548ce38659 100755 --- a/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.cpp +++ b/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.cpp @@ -26,7 +26,7 @@ // FIXME namespace Functions1D { - real GetSteerableViewMapDensityF1D::operator()(Interface1D& inter) { + int GetSteerableViewMapDensityF1D::operator()(Interface1D& inter) { SteerableViewMap * svm = Canvas::getInstance()->getSteerableViewMap(); Interface0DIterator it = inter.pointsBegin(_sampling); Interface0DIterator itnext = it;++itnext; @@ -85,24 +85,26 @@ namespace Functions1D { res /= (size ? size : 1); break; } - return res; + result = res; + return 0; } - double GetDirectionalViewMapDensityF1D::operator()(Interface1D& inter) { + int GetDirectionalViewMapDensityF1D::operator()(Interface1D& inter) { //soc unsigned size; - double res = integrate(_fun, inter.pointsBegin(_sampling), inter.pointsEnd(_sampling), _integration); - return res; + result = integrate(_fun, inter.pointsBegin(_sampling), inter.pointsEnd(_sampling), _integration); + return 0; } - double GetCompleteViewMapDensityF1D::operator()(Interface1D& inter) { + int GetCompleteViewMapDensityF1D::operator()(Interface1D& inter) { //soc unsigned size; Id id = inter.getId(); - double res = integrate(_fun, inter.pointsBegin(_sampling), inter.pointsEnd(_sampling), _integration); - return res; + result = integrate(_fun, inter.pointsBegin(_sampling), inter.pointsEnd(_sampling), _integration); + return 0; } - real GetViewMapGradientNormF1D::operator()(Interface1D& inter){ - return integrate(_func, inter.pointsBegin(_sampling), inter.pointsEnd(_sampling), _integration); + int GetViewMapGradientNormF1D::operator()(Interface1D& inter){ + result = integrate(_func, inter.pointsBegin(_sampling), inter.pointsEnd(_sampling), _integration); + return 0; } } diff --git a/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h b/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h index 65b0eec36fd..46a28c20917 100755 --- a/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h +++ b/source/blender/freestyle/intern/stroke/AdvancedFunctions1D.h @@ -78,8 +78,9 @@ namespace Functions1D { return "DensityF1D"; } /*! the () operator.*/ - double operator()(Interface1D& inter) { - return integrate(_fun, inter.pointsBegin(_sampling), inter.pointsEnd(_sampling), _integration); + int operator()(Interface1D& inter) { + result = integrate(_fun, inter.pointsBegin(_sampling), inter.pointsEnd(_sampling), _integration); + return 0; } private: Functions0D::DensityF0D _fun; @@ -112,8 +113,9 @@ namespace Functions1D { return "LocalAverageDepthF1D"; } /*! the () operator.*/ - double operator()(Interface1D& inter) { - return integrate(_fun, inter.verticesBegin(), inter.verticesEnd(), _integration); + int operator()(Interface1D& inter) { + result = integrate(_fun, inter.verticesBegin(), inter.verticesEnd(), _integration); + return 0; } private: Functions0D::LocalAverageDepthF0D _fun; @@ -150,7 +152,7 @@ namespace Functions1D { return "GetCompleteViewMapDensityF1D"; } /*! the () operator.*/ - double operator()(Interface1D& inter); + int operator()(Interface1D& inter); private: Functions0D::ReadCompleteViewMapPixelF0D _fun; @@ -193,7 +195,7 @@ namespace Functions1D { return "GetDirectionalViewMapDensityF1D"; } /*! the () operator.*/ - double operator()(Interface1D& inter); + int operator()(Interface1D& inter); private: Functions0D::ReadSteerableViewMapPixelF0D _fun; @@ -238,7 +240,7 @@ namespace Functions1D { return "GetSteerableViewMapDensityF1D"; } /*! the () operator.*/ - real operator()(Interface1D& inter); + int operator()(Interface1D& inter); }; // GetViewMapGradientNormF1D @@ -279,7 +281,7 @@ namespace Functions1D { return "GetViewMapGradientNormF1D"; } /*! the () operator.*/ - real operator()(Interface1D& inter); + int operator()(Interface1D& inter); }; } // end of namespace Functions1D diff --git a/source/blender/freestyle/intern/stroke/AdvancedPredicates1D.h b/source/blender/freestyle/intern/stroke/AdvancedPredicates1D.h index f348f8593e5..91b63168aa9 100755 --- a/source/blender/freestyle/intern/stroke/AdvancedPredicates1D.h +++ b/source/blender/freestyle/intern/stroke/AdvancedPredicates1D.h @@ -67,9 +67,12 @@ namespace Predicates1D { return "DensityLowerThanUP1D"; } /*! The () operator. */ - bool operator()(Interface1D& inter) { + int operator()(Interface1D& inter) { Functions1D::DensityF1D fun(_sigma); - return (fun(inter) < _threshold); + if (fun(inter) < 0) + return -1; + result = (fun.result < _threshold); + return 0; } private: double _sigma; diff --git a/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp index 653e0158538..2075f7ca6ad 100755 --- a/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp +++ b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp @@ -44,7 +44,7 @@ CalligraphicShader::CalligraphicShader (real iMinThickness, real iMaxThickness, float ksinToto=0; -void +int CalligraphicShader::shade(Stroke &ioStroke) const { Interface0DIterator v; @@ -55,7 +55,9 @@ CalligraphicShader::shade(Stroke &ioStroke) const ++v) { real thickness; - Vec2f vertexOri(fun(v)); + if (fun(v) < 0) + return -1; + Vec2f vertexOri(fun.result); Vec2r ori2d(-vertexOri[1], vertexOri[0]); ori2d.normalizeSafe(); real scal = ori2d * _orientation; @@ -74,6 +76,7 @@ CalligraphicShader::shade(Stroke &ioStroke) const sv->attribute().setThickness(thickness/2.0,thickness/2.0); } + return 0; } //void @@ -116,7 +119,7 @@ SpatialNoiseShader::SpatialNoiseShader (float ioamount, float ixScale, int nbOct _smooth=smooth; _pureRandom=pureRandom; } -void +int SpatialNoiseShader::shade(Stroke &ioStroke) const { Interface0DIterator v, v2; @@ -135,7 +138,9 @@ SpatialNoiseShader::shade(Stroke &ioStroke) const { sv = dynamic_cast(&(*v)); Vec2r p(sv->getPoint()); - Vec2r vertexOri(fun(v)); + if (fun(v) < 0) + return -1; + Vec2r vertexOri(fun.result); Vec2r ori2d(vertexOri[0], vertexOri[1]); ori2d = Vec2r(p-p0); ori2d.normalizeSafe(); @@ -159,6 +164,7 @@ SpatialNoiseShader::shade(Stroke &ioStroke) const ++v; } + return 0; } @@ -186,7 +192,7 @@ SmoothingShader::SmoothingShader (int ionbIteration, real iFactorPoint, real ifa -void +int SmoothingShader::shade(Stroke &ioStroke) const { //cerr<<" Smoothing a stroke "<attribute().setThickness(_thickness/2.0, _thickness/2.0); } + return 0; } - void ConstantExternThicknessShader::shade(Stroke& stroke) const + int ConstantExternThicknessShader::shade(Stroke& stroke) const { StrokeInternal::StrokeVertexIterator v, vend; int i=0; @@ -102,9 +103,10 @@ namespace StrokeShaders { v->attribute().setThickness(_thickness, 0); } + return 0; } - void IncreasingThicknessShader::shade(Stroke& stroke) const + int IncreasingThicknessShader::shade(Stroke& stroke) const { int n=stroke.strokeVerticesSize()-1; @@ -123,9 +125,10 @@ namespace StrokeShaders { v->attribute().setThickness(t/2.0, t/2.0); ++i; } + return 0; } - void ConstrainedIncreasingThicknessShader::shade(Stroke& stroke) const + int ConstrainedIncreasingThicknessShader::shade(Stroke& stroke) const { float slength = stroke.getLength2D(); float maxT = min(_ratio*slength,_ThicknessMax); @@ -147,10 +150,11 @@ namespace StrokeShaders { v->attribute().setThickness(_ThicknessMin/2.0, _ThicknessMin/2.0); ++i; } + return 0; } - void LengthDependingThicknessShader::shade(Stroke& stroke) const + int LengthDependingThicknessShader::shade(Stroke& stroke) const { float step = (_maxThickness-_minThickness)/3.f; float l = stroke.getLength2D(); @@ -178,6 +182,7 @@ namespace StrokeShaders { v->attribute().setThickness(thickness/2.0, thickness/2.0); } + return 0; } @@ -209,7 +214,7 @@ namespace StrokeShaders { convert(image, &_aThickness, _size); } - void ThicknessVariationPatternShader::shade(Stroke& stroke) const + int ThicknessVariationPatternShader::shade(Stroke& stroke) const { StrokeInternal::StrokeVertexIterator v, vend; float *array = 0; @@ -253,6 +258,7 @@ namespace StrokeShaders { v->attribute().setThickness(thicknessR, thicknessL); ++sig; } + return 0; } @@ -266,7 +272,7 @@ namespace StrokeShaders { {_amplitude=iAmplitude;_scale=1.f/iPeriod/(float)NB_VALUE_NOISE;} - void ThicknessNoiseShader::shade(Stroke& stroke) const + 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); @@ -289,6 +295,7 @@ namespace StrokeShaders { v->attribute().setThickness(r,l); } + return 0; } // @@ -296,7 +303,7 @@ namespace StrokeShaders { // /////////////////////////////////////////////////////////////////////////////// - void ConstantColorShader::shade(Stroke& stroke) const + int ConstantColorShader::shade(Stroke& stroke) const { StrokeInternal::StrokeVertexIterator v, vend; for(v=stroke.strokeVerticesBegin(), vend=stroke.strokeVerticesEnd(); @@ -306,9 +313,10 @@ namespace StrokeShaders { v->attribute().setColor(_color[0], _color[1], _color[2]); v->attribute().setAlpha(_color[3]); } + return 0; } - void IncreasingColorShader::shade(Stroke& stroke) const + int IncreasingColorShader::shade(Stroke& stroke) const { StrokeInternal::StrokeVertexIterator v, vend; int n=stroke.strokeVerticesSize()-1; @@ -327,6 +335,7 @@ namespace StrokeShaders { v->attribute().setAlpha(newcolor[3]); ++yo; } + return 0; } ColorVariationPatternShader::ColorVariationPatternShader(const string pattern_name, @@ -352,7 +361,7 @@ namespace StrokeShaders { convert(image, &_aVariation, _size); } - void ColorVariationPatternShader::shade(Stroke& stroke) const + int ColorVariationPatternShader::shade(Stroke& stroke) const { StrokeInternal::StrokeVertexIterator v, vend; unsigned index; @@ -375,9 +384,10 @@ namespace StrokeShaders { float b = _aVariation[index]*originalColor[2]; v->attribute().setColor(r,g,b); } + return 0; } - void MaterialColorShader::shade(Stroke& stroke) const + int MaterialColorShader::shade(Stroke& stroke) const { Interface0DIterator v, vend; Functions0D::MaterialF0D fun; @@ -386,15 +396,18 @@ namespace StrokeShaders { v!=vend; ++v) { - const float *diffuse = fun(v).diffuse(); + 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; } - void CalligraphicColorShader::shade(Stroke& stroke) const + int CalligraphicColorShader::shade(Stroke& stroke) const { Interface0DIterator v; Functions0D::VertexOrientation2DF0D fun; @@ -403,7 +416,9 @@ namespace StrokeShaders { !v.isEnd(); ++v) { - Vec2f vertexOri(fun(v)); + if (fun(v) < 0) + return -1; + Vec2f vertexOri(fun.result); Vec2d ori2d(-vertexOri[1], vertexOri[0]); ori2d.normalizeSafe(); real scal = ori2d * _orientation; @@ -413,6 +428,7 @@ namespace StrokeShaders { else sv->attribute().setColor(1,1,1); } + return 0; } @@ -425,7 +441,7 @@ namespace StrokeShaders { {_amplitude=iAmplitude;_scale=1.f/iPeriod/(float)NB_VALUE_NOISE;} - void ColorNoiseShader::shade(Stroke& stroke) const + 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); @@ -446,6 +462,7 @@ namespace StrokeShaders { v->attribute().setColor(r,g,b); } + return 0; } @@ -454,7 +471,7 @@ namespace StrokeShaders { // /////////////////////////////////////////////////////////////////////////////// - void TextureAssignerShader::shade(Stroke& stroke) const + int TextureAssignerShader::shade(Stroke& stroke) const { // getBrushTextureIndex(TEXTURES_DIR "/brushes/charcoalAlpha.bmp", Stroke::HUMID_MEDIUM); // getBrushTextureIndex(TEXTURES_DIR "/brushes/washbrushAlpha.bmp", Stroke::HUMID_MEDIUM); @@ -467,7 +484,7 @@ namespace StrokeShaders { TextureManager * instance = TextureManager::getInstance(); if(!instance) - return; + return 0; string pathname; Stroke::MediumType mediumType; bool hasTips = false; @@ -523,19 +540,21 @@ namespace StrokeShaders { stroke.setMediumType(mediumType); stroke.setTips(hasTips); stroke.setTextureId(texId); + return 0; } // FIXME - void StrokeTextureShader::shade(Stroke& stroke) const + int StrokeTextureShader::shade(Stroke& stroke) const { TextureManager * instance = TextureManager::getInstance(); if(!instance) - return; + 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; } // @@ -543,11 +562,11 @@ namespace StrokeShaders { // /////////////////////////////////////////////////////////////////////////////// - void BackboneStretcherShader::shade(Stroke& stroke) const + int BackboneStretcherShader::shade(Stroke& stroke) const { float l=stroke.getLength2D(); if(l <= 50) - return; + return 0; StrokeInternal::StrokeVertexIterator v0=stroke.strokeVerticesBegin(); StrokeInternal::StrokeVertexIterator v1=v0;++v1; @@ -567,14 +586,16 @@ namespace StrokeShaders { (v0)->setPoint(newFirst[0], newFirst[1]); Vec2d newLast(last+_amount*dn); (vn)->setPoint(newLast[0], newLast[1]); + return 0; } - void SamplingShader::shade(Stroke& stroke) const + int SamplingShader::shade(Stroke& stroke) const { stroke.Resample(_sampling); + return 0; } - void ExternalContourStretcherShader::shade(Stroke& stroke) const + int ExternalContourStretcherShader::shade(Stroke& stroke) const { //float l=stroke.getLength2D(); Interface0DIterator it=stroke.verticesBegin(); @@ -582,18 +603,21 @@ namespace StrokeShaders { StrokeVertex* sv; while (!it.isEnd()) { - Vec2f n(fun(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]); ++it; } + return 0; } - void BSplineShader::shade(Stroke& stroke) const + int BSplineShader::shade(Stroke& stroke) const { if(stroke.strokeVerticesSize() < 4) - return; + return 0; // Find the new vertices vector newVertices; @@ -702,13 +726,14 @@ namespace StrokeShaders { ++it; ++n; } + return 0; } //!! Bezier curve stroke shader - void BezierCurveShader::shade(Stroke& stroke) const + int BezierCurveShader::shade(Stroke& stroke) const { if(stroke.strokeVerticesSize() < 4) - return; + return 0; // Build the Bezier curve from this set of data points: vector data; @@ -822,7 +847,7 @@ namespace StrokeShaders { // Deal with extra vertices: if(nExtraVertex == 0) - return; + return 0; // nExtraVertex should stay unassigned vector attributes; @@ -864,15 +889,18 @@ namespace StrokeShaders { ++a; ++index; } + return 0; } - void InflateShader::shade(Stroke& stroke) const + 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) > _curvatureThreshold) - return; + if (fun(stroke) < 0) + return -1; + if (fun.result > _curvatureThreshold) + return 0; Functions0D::VertexOrientation2DF0D ori_fun; Functions0D::Curvature2DAngleF0D curv_fun; @@ -881,9 +909,13 @@ namespace StrokeShaders { StrokeVertex* sv; while (!it.isEnd()) { - Vec2f ntmp = ori_fun(it); + if (ori_fun(it) < 0) + return -1; + Vec2f ntmp(ori_fun.result); Vec2f n(ntmp.y(), -ntmp.x()); - Vec2f strokeN(norm_fun(stroke)); + if (norm_fun(stroke) < 0) + return -1; + Vec2f strokeN(norm_fun.result); if(n*strokeN < 0) { n[0] = -n[0]; @@ -892,11 +924,14 @@ namespace StrokeShaders { sv = dynamic_cast(&(*it)); float u=sv->u(); float t = 4.f*(0.25f - (u-0.5)*(u-0.5)); - float curvature_coeff = (M_PI-curv_fun(it))/M_PI; + 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; } class CurvePiece @@ -953,7 +988,7 @@ namespace StrokeShaders { } }; - void PolygonalizationShader::shade(Stroke& stroke) const + int PolygonalizationShader::shade(Stroke& stroke) const { vector _pieces; vector _results; @@ -1012,9 +1047,10 @@ namespace StrokeShaders { delete (*cp); } _results.clear(); + return 0; } - void GuidingLinesShader::shade(Stroke& stroke) const + int GuidingLinesShader::shade(Stroke& stroke) const { Functions1D::Normal2DF1D norm_fun; StrokeInternal::StrokeVertexIterator a=stroke.strokeVerticesBegin(); @@ -1024,7 +1060,9 @@ namespace StrokeShaders { Vec2d u = piece.B-piece.A; Vec2f n(u[1], -u[0]);n.normalize(); - Vec2f strokeN(norm_fun(stroke)); + if (norm_fun(stroke) < 0) + return -1; + Vec2f strokeN(norm_fun.result); if(n*strokeN < 0) { n[0] = -n[0]; @@ -1038,6 +1076,7 @@ namespace StrokeShaders { { v->setPoint(piece.A.x()+v->u()*u.x()+n.x()*offset, piece.A.y()+v->u()*u.y()+n.y()*offset); } + return 0; } ///////////////////////////////////////// @@ -1053,13 +1092,13 @@ namespace StrokeShaders { _tipLength = tipLength; } - void + int TipRemoverShader::shade(Stroke& stroke) const { int originalSize = stroke.strokeVerticesSize(); if(originalSize<4) - return; + return 0; StrokeInternal::StrokeVertexIterator v, vend; vector verticesToRemove; @@ -1078,7 +1117,7 @@ namespace StrokeShaders { } if(originalSize-verticesToRemove.size() < 2) - return; + return 0; vector::iterator sv=verticesToRemove.begin(), svend=verticesToRemove.end(); for(; @@ -1105,13 +1144,16 @@ namespace StrokeShaders { //cout << "thickness = " << (*a).getThickness()[0] << "-" << (*a).getThickness()[1] << endl; } // we're done! + return 0; } - void streamShader::shade(Stroke& stroke) const{ + int streamShader::shade(Stroke& stroke) const{ cout << stroke << endl; + return 0; } - void fstreamShader::shade(Stroke& stroke) const{ + 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 d54c38bb6cd..a0c0a44c9b6 100755 --- a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h +++ b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h @@ -67,7 +67,7 @@ namespace StrokeShaders { return "ConstantThicknessShader"; } /*! The shading method. */ - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; private: float _thickness; @@ -94,7 +94,7 @@ namespace StrokeShaders { return "ConstantExternThicknessShader"; } - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; private: @@ -132,7 +132,7 @@ namespace StrokeShaders { } /*! The shading method. */ - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; private: @@ -176,7 +176,7 @@ namespace StrokeShaders { } /*! The shading method. */ - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; }; /* [ Thickness Shader ]. @@ -206,7 +206,7 @@ namespace StrokeShaders { return "LengthDependingThicknessShader"; } - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; }; /*! [ Thickness Shader ]. @@ -248,7 +248,7 @@ namespace StrokeShaders { } /*! The shading method. */ - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; private: @@ -283,7 +283,7 @@ namespace StrokeShaders { } /*! The shading method. */ - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; }; @@ -320,7 +320,7 @@ namespace StrokeShaders { return "ConstantColorShader"; } /*! The shading method. */ - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; private: @@ -377,7 +377,7 @@ namespace StrokeShaders { } /*! The shading method. */ - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; }; /*! [ Color Shader ]. @@ -411,7 +411,7 @@ namespace StrokeShaders { } /*! The shading method. */ - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; private: @@ -438,7 +438,7 @@ namespace StrokeShaders { return "MaterialColorShader"; } - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; }; class LIB_STROKE_EXPORT CalligraphicColorShader : public StrokeShader @@ -459,7 +459,7 @@ namespace StrokeShaders { return "CalligraphicColorShader"; } - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; }; @@ -487,7 +487,7 @@ namespace StrokeShaders { } /*! The shading method. */ - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; }; // @@ -531,7 +531,7 @@ namespace StrokeShaders { } /*! The shading method */ - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; }; /*! [ Texture Shader ]. @@ -585,7 +585,7 @@ namespace StrokeShaders { } /*! The shading method */ - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; }; @@ -618,7 +618,7 @@ namespace StrokeShaders { } /*! The shading method */ - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; }; /*! [ Geometry Shader. ] @@ -646,7 +646,7 @@ namespace StrokeShaders { } /*! The shading method */ - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; }; @@ -665,7 +665,7 @@ namespace StrokeShaders { return "ExternalContourStretcherShader"; } - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; }; // B-Spline stroke shader @@ -680,7 +680,7 @@ namespace StrokeShaders { return "BSplineShader"; } - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; }; @@ -711,7 +711,7 @@ namespace StrokeShaders { } /*! The shading method */ - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; }; /* Shader to inflate the curves. It keeps the extreme @@ -747,7 +747,7 @@ namespace StrokeShaders { } /*! The shading method */ - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; }; /*! [ Geometry Shader ]. @@ -781,7 +781,7 @@ namespace StrokeShaders { } /*! The shading method */ - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; }; @@ -816,7 +816,7 @@ namespace StrokeShaders { } /*! The shading method */ - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; }; /*! [ Geometry Shader ]. @@ -838,7 +838,7 @@ namespace StrokeShaders { return "TipRemoverShader"; } - virtual void shade(Stroke &stroke) const; + virtual int shade(Stroke &stroke) const; protected: @@ -858,7 +858,7 @@ namespace StrokeShaders { return "streamShader"; } /*! The shading method. */ - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; }; /*! [ output Shader ]. @@ -883,7 +883,7 @@ namespace StrokeShaders { return "fstreamShader"; } /*! The shading method. */ - virtual void shade(Stroke& stroke) const; + virtual int shade(Stroke& stroke) const; }; } // end of namespace StrokeShaders diff --git a/source/blender/freestyle/intern/stroke/ChainingIterators.cpp b/source/blender/freestyle/intern/stroke/ChainingIterators.cpp index ede3488c546..c54ee6ea1ee 100755 --- a/source/blender/freestyle/intern/stroke/ChainingIterators.cpp +++ b/source/blender/freestyle/intern/stroke/ChainingIterators.cpp @@ -28,10 +28,11 @@ bool AdjacencyIterator::isIncoming() const{ return (*_internalIterator).second; } -void AdjacencyIterator::increment(){ +int AdjacencyIterator::increment(){ ++_internalIterator; while((!_internalIterator.isEnd()) && (!isValid((*_internalIterator).first))) ++_internalIterator; + return 0; } bool AdjacencyIterator::isValid(ViewEdge* edge){ @@ -44,44 +45,52 @@ bool AdjacencyIterator::isValid(ViewEdge* edge){ return true; } -void ChainingIterator::increment() { +int ChainingIterator::increment() { _increment = true; ViewVertex * vertex = getVertex(); if(!vertex){ _edge = 0; - return; + return 0; } AdjacencyIterator it = AdjacencyIterator(vertex, _restrictToSelection, _restrictToUnvisited); - if(it.isEnd()) + if(it.isEnd()) { _edge = 0; - else - _edge = traverse(it); + return 0; + } + if (traverse(it) < 0) + return -1; + _edge = result; if(_edge == 0) - return; + return 0; if(_edge->A() == vertex) _orientation = true; else _orientation = false; + return 0; } -void ChainingIterator::decrement() { +int ChainingIterator::decrement() { _increment = false; ViewVertex * vertex = getVertex(); if(!vertex){ _edge = 0; - return; + return 0; } AdjacencyIterator it = AdjacencyIterator(vertex, _restrictToSelection, _restrictToUnvisited); - if(it.isEnd()) + if(it.isEnd()) { _edge = 0; - else - _edge = traverse(it); + return 0; + } + if (traverse(it) < 0) + return -1; + _edge = result; if(_edge == 0) - return; + return 0; if(_edge->B() == vertex) _orientation = true; else _orientation = false; + return 0; } // @@ -89,7 +98,7 @@ void ChainingIterator::decrement() { // /////////////////////////////////////////////////////////// -ViewEdge * ChainSilhouetteIterator::traverse(const AdjacencyIterator& ait){ +int ChainSilhouetteIterator::traverse(const AdjacencyIterator& ait){ AdjacencyIterator it(ait); ViewVertex* nextVertex = getVertex(); // we can't get a NULL nextVertex here, it was intercepted @@ -99,11 +108,14 @@ ViewEdge * ChainSilhouetteIterator::traverse(const AdjacencyIterator& ait){ ViewEdge *mate = (tvertex)->mate(getCurrentEdge()); while(!it.isEnd()){ ViewEdge *ve = *it; - if(ve == mate) - return ve; + if(ve == mate) { + result = ve; + return 0; + } ++it; } - return 0; + result = 0; + return 0; } if(nextVertex->getNature() & Nature::NON_T_VERTEX){ //soc NonTVertex * nontvertex = (NonTVertex*)nextVertex; @@ -123,25 +135,36 @@ ViewEdge * ChainSilhouetteIterator::traverse(const AdjacencyIterator& ait){ ++it; } if(n == 1){ - return newEdge; + result = newEdge; }else{ - return 0; + result = 0; } - } + return 0; + } } } + result = 0; return 0; } -ViewEdge * ChainPredicateIterator::traverse(const AdjacencyIterator& ait){ +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)(*ve)) && ((*_binary_predicate)(*(getCurrentEdge()),*(ve)))) - return ve; + 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; } + result = 0; return 0; } diff --git a/source/blender/freestyle/intern/stroke/ChainingIterators.h b/source/blender/freestyle/intern/stroke/ChainingIterators.h index 1f33f99db67..1a40144d704 100755 --- a/source/blender/freestyle/intern/stroke/ChainingIterators.h +++ b/source/blender/freestyle/intern/stroke/ChainingIterators.h @@ -102,10 +102,11 @@ public: increment(); return tmp; } - virtual void increment(); + virtual int increment(); - virtual void decrement(){ + virtual int decrement(){ cerr << "Warning: method decrement() not implemented" << endl; + return 0; } protected: @@ -138,6 +139,7 @@ protected: public: + ViewEdge *result; PyObject *py_c_it; /*! Builds a Chaining Iterator from the first ViewEdge used for iteration @@ -183,15 +185,17 @@ public: * history information that you * might want to keep. */ - virtual void init() { + virtual int init() { string name( py_c_it ? PyString_AsString(PyObject_CallMethod(py_c_it, "getExactTypeName", "")) : getExactTypeName() ); if( py_c_it && PyObject_HasAttrString(py_c_it, "init") ) { - Director_BPy_ChainingIterator_init( py_c_it ); + if (Director_BPy_ChainingIterator_init( py_c_it ) < 0) { + return -1; + } } else { - cerr << "Warning: " << name << " method init() not implemented" << endl; + cerr << "Warning: " << name << " init() method not implemented" << endl; } - + return 0; } /*! This method iterates over the potential next @@ -205,15 +209,17 @@ public: * The Adjacency iterator reflects the restriction * rules by only iterating over the valid ViewEdges. */ - virtual ViewEdge * traverse(const AdjacencyIterator &it){ + virtual int traverse(const AdjacencyIterator &it){ string name( py_c_it ? PyString_AsString(PyObject_CallMethod(py_c_it, "getExactTypeName", "")) : getExactTypeName() ); if( py_c_it && PyObject_HasAttrString(py_c_it, "traverse") ) { - return Director_BPy_ChainingIterator_traverse(py_c_it, const_cast(it) ); + if (Director_BPy_ChainingIterator_traverse(py_c_it, const_cast(it), &result ) < 0) { + return -1; + } } else { - cerr << "Warning: the " << name << " traverse method was not defined" << endl; - return 0; + cerr << "Warning: the " << name << " traverse() method not defined" << endl; } + return 0; } /* accessors */ @@ -244,8 +250,8 @@ public: } /* increments.*/ - virtual void increment() ; - virtual void decrement() ; + virtual int increment() ; + virtual int decrement() ; }; // @@ -294,10 +300,12 @@ public: * followed next. * When reaching the end of a chain, 0 is returned. */ - virtual ViewEdge * traverse(const AdjacencyIterator& it); + virtual int traverse(const AdjacencyIterator& it); /*! Inits the iterator context */ - virtual void init() {} + virtual int init() { + return 0; + } }; // @@ -392,10 +400,12 @@ public: * followed next. * When reaching the end of a chain, 0 is returned. */ - virtual ViewEdge * traverse(const AdjacencyIterator &it); + virtual int traverse(const AdjacencyIterator &it); /*! Inits the iterator context */ - virtual void init() {} + virtual int init() { + return 0; + } }; diff --git a/source/blender/freestyle/intern/stroke/CurveIterators.h b/source/blender/freestyle/intern/stroke/CurveIterators.h index 2ba77a3c478..a45ef4bfdaf 100755 --- a/source/blender/freestyle/intern/stroke/CurveIterators.h +++ b/source/blender/freestyle/intern/stroke/CurveIterators.h @@ -186,7 +186,7 @@ namespace CurveInternal { // protected: - virtual void increment() + virtual int increment() { if((_currentn == _n-1) && (_t == 1.f)) { @@ -195,7 +195,7 @@ namespace CurveInternal { ++__B; ++_currentn; _t = 0.f; - return; + return 0; } if(0 == _step) // means we iterate over initial vertices @@ -205,12 +205,12 @@ namespace CurveInternal { if(_currentn == _n-1) { _t = 1.f; - return; + return 0; } ++__B; ++__A; ++_currentn; - return; + return 0; } // compute the new position: @@ -237,8 +237,9 @@ namespace CurveInternal { ++__A;++__B; } } + return 0; } - virtual void decrement() + virtual int decrement() { if(_t == 0.f) //we're at the beginning of the edge { @@ -246,7 +247,7 @@ namespace CurveInternal { --_currentn; --__A; --__B; if(_currentn == _n-1) - return; + return 0; } if(0 == _step) // means we iterate over initial vertices @@ -254,7 +255,7 @@ namespace CurveInternal { Vec3r vec_tmp((*__B)->point2d() - (*__A)->point2d()); _CurvilinearLength -= (float)vec_tmp.norm(); _t = 0; - return; + return 0; } // compute the new position: @@ -280,6 +281,7 @@ namespace CurveInternal { _CurvilinearLength += normAB*(-_t); _t = 0.f; } + return 0; } virtual float t() const{ diff --git a/source/blender/freestyle/intern/stroke/Operators.cpp b/source/blender/freestyle/intern/stroke/Operators.cpp index 391b21a9555..ab940d9a24d 100755 --- a/source/blender/freestyle/intern/stroke/Operators.cpp +++ b/source/blender/freestyle/intern/stroke/Operators.cpp @@ -29,11 +29,11 @@ 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; -void Operators::select(UnaryPredicate1D& pred) { +int Operators::select(UnaryPredicate1D& pred) { if (!_current_set) - return; + return 0; if(_current_set->empty()) - return; + return 0; I1DContainer new_set; I1DContainer rejected; Functions1D::ChainingTimeStampF1D cts; @@ -43,7 +43,12 @@ void Operators::select(UnaryPredicate1D& pred) { while (it != _current_set->end()) { Interface1D * i1d = *it; cts(*i1d); // mark everyone's chaining time stamp anyway - if (pred(*i1d)){ + if(pred(*i1d) < 0){ + new_set.clear(); + rejected.clear(); + return -1; + } + if(pred.result){ new_set.push_back(i1d); ts(*i1d); }else{ @@ -60,14 +65,15 @@ void Operators::select(UnaryPredicate1D& pred) { rejected.clear(); _current_set->clear(); *_current_set = new_set; + return 0; } -void Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, +int Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, UnaryPredicate1D& pred, UnaryFunction1D_void& modifier) { if (_current_view_edges_set.empty()) - return; + return 0; unsigned id = 0; ViewEdge* edge; @@ -76,7 +82,9 @@ void Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); it_edge != _current_view_edges_set.end(); ++it_edge) { - if (pred(**it_edge)) + if (pred(**it_edge) < 0) + return -1; + if (pred.result) continue; edge = dynamic_cast(*it_edge); @@ -84,24 +92,36 @@ void Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, it.setCurrentEdge(edge); Chain* new_chain = new Chain(id);++id; - do { + for (;;) { new_chain->push_viewedge_back(*it, it.getOrientation()); - modifier(**it); + if (modifier(**it) < 0) { + delete new_chain; + return -1; + } ++it; - } while (!it.isEnd() && !pred(**it)); + if (it.isEnd()) + break; + if (pred(**it) < 0) { + delete new_chain; + return -1; + } + if (pred.result) + break; + } _current_chains_set.push_back(new_chain); } if (!_current_chains_set.empty()) _current_set = &_current_chains_set; + return 0; } -void Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, +int Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, UnaryPredicate1D& pred) { if (_current_view_edges_set.empty()) - return; + return 0; unsigned id = 0; Functions1D::IncrementChainingTimeStampF1D ts; @@ -113,7 +133,13 @@ void Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, 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)) + if (pred(**it_edge) < 0) + return -1; + if (pred.result) + continue; + if (pred_ts(**it_edge) < 0) + return -1; + if (pred_ts.result) continue; edge = dynamic_cast(*it_edge); @@ -121,17 +147,32 @@ void Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, it.setCurrentEdge(edge); Chain* new_chain = new Chain(id);++id; - do { + for (;;) { new_chain->push_viewedge_back(*it, it.getOrientation()); ts(**it); ++it; - } while (!it.isEnd() && !pred(**it) && !pred_ts(**it)); + if (it.isEnd()) + break; + if (pred(**it) < 0) { + delete new_chain; + return -1; + } + if (pred.result) + break; + if (pred_ts(**it) < 0) { + delete new_chain; + return -1; + } + if (pred_ts.result) + break; + } _current_chains_set.push_back(new_chain); } if (!_current_chains_set.empty()) _current_set = &_current_chains_set; + return 0; } @@ -223,9 +264,9 @@ void Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, // _current_set = &_current_chains_set; //} -void Operators::bidirectionalChain(ChainingIterator& it, UnaryPredicate1D& pred) { +int Operators::bidirectionalChain(ChainingIterator& it, UnaryPredicate1D& pred) { if (_current_view_edges_set.empty()) - return; + return 0; unsigned id = 0; Functions1D::IncrementChainingTimeStampF1D ts; @@ -237,7 +278,13 @@ void Operators::bidirectionalChain(ChainingIterator& it, UnaryPredicate1D& pred) 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)) + if (pred(**it_edge) < 0) + return -1; + if (pred.result) + continue; + if (pred_ts(**it_edge) < 0) + return -1; + if (pred_ts.result) continue; edge = dynamic_cast(*it_edge); @@ -245,34 +292,59 @@ void Operators::bidirectionalChain(ChainingIterator& it, UnaryPredicate1D& pred) it.setBegin(edge); it.setCurrentEdge(edge); it.setOrientation(true); - it.init(); + if (it.init() < 0) + return -1; Chain* new_chain = new Chain(id);++id; //ViewEdgeIterator it_back(it);--it_back;//FIXME - do { + for (;;) { new_chain->push_viewedge_back(*it, it.getOrientation()); ts(**it); - it.increment(); // FIXME - } while (!it.isEnd() && !pred(**it)); + if (it.increment() < 0) { // FIXME + delete new_chain; + return -1; + } + if (it.isEnd()) + break; + if (pred(**it) < 0) { + delete new_chain; + return -1; + } + if (pred.result) + break; + } it.setBegin(edge); it.setCurrentEdge(edge); it.setOrientation(true); - it.decrement(); // FIXME - while (!it.isEnd() && !pred(**it)) { + if (it.decrement() < 0) { // FIXME + delete new_chain; + return -1; + } + while (!it.isEnd()) { + if (pred(**it) < 0) { + delete new_chain; + return -1; + } + if (pred.result) + break; new_chain->push_viewedge_front(*it, it.getOrientation()); ts(**it); - it.decrement();// FIXME + if (it.decrement() < 0) { // FIXME + delete new_chain; + return -1; + } } _current_chains_set.push_back(new_chain); } if (!_current_chains_set.empty()) _current_set = &_current_chains_set; + return 0; } -void Operators::bidirectionalChain(ChainingIterator& it) { +int Operators::bidirectionalChain(ChainingIterator& it) { if (_current_view_edges_set.empty()) - return; + return 0; unsigned id = 0; Functions1D::IncrementChainingTimeStampF1D ts; @@ -284,7 +356,9 @@ void Operators::bidirectionalChain(ChainingIterator& it) { for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); it_edge != _current_view_edges_set.end(); ++it_edge) { - if (pred_ts(**it_edge)) + if (pred_ts(**it_edge) < 0) + return -1; + if (pred_ts.result) continue; edge = dynamic_cast(*it_edge); @@ -292,37 +366,48 @@ void Operators::bidirectionalChain(ChainingIterator& it) { it.setBegin(edge); it.setCurrentEdge(edge); it.setOrientation(true); - it.init(); + if (it.init() < 0) + return -1; 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.increment(); // FIXME + if (it.increment() < 0) { // FIXME + delete new_chain; + return -1; + } } while (!it.isEnd()); it.setBegin(edge); it.setCurrentEdge(edge); it.setOrientation(true); - it.decrement(); // FIXME + if (it.decrement() < 0) { // FIXME + delete new_chain; + return -1; + } while (!it.isEnd()) { new_chain->push_viewedge_front(*it, it.getOrientation()); ts(**it); - it.decrement();// FIXME + if (it.decrement() < 0) { // FIXME + delete new_chain; + return -1; + } } _current_chains_set.push_back(new_chain); } if (!_current_chains_set.empty()) _current_set = &_current_chains_set; + return 0; } -void Operators::sequentialSplit(UnaryPredicate0D& pred, +int Operators::sequentialSplit(UnaryPredicate0D& pred, float sampling) { if (_current_chains_set.empty()) { cerr << "Warning: current set empty" << endl; - return; + return 0; } CurvePoint *point; Chain * new_curve; @@ -349,7 +434,12 @@ void Operators::sequentialSplit(UnaryPredicate0D& pred, { point = dynamic_cast(&(*it)); new_curve->push_vertex_back(point); - if((pred(it)) && (it!=last)) + 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); @@ -359,7 +449,7 @@ void Operators::sequentialSplit(UnaryPredicate0D& pred, } if(new_curve->nSegments() == 0){ delete new_curve; - return; + return 0; } splitted_chains.push_back(new_curve); @@ -378,14 +468,26 @@ void Operators::sequentialSplit(UnaryPredicate0D& pred, 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; } -void Operators::sequentialSplit(UnaryPredicate0D& startingPred, UnaryPredicate0D& stoppingPred, +int Operators::sequentialSplit(UnaryPredicate0D& startingPred, UnaryPredicate0D& stoppingPred, float sampling) { if (_current_chains_set.empty()) { cerr << "Warning: current set empty" << endl; - return; + return 0; } CurvePoint *point; Chain * new_curve; @@ -416,7 +518,13 @@ void Operators::sequentialSplit(UnaryPredicate0D& startingPred, UnaryPredicate0D point = dynamic_cast(&(*itStop)); new_curve->push_vertex_back(point); ++itStop; - }while((itStop!=end) && (!stoppingPred(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); @@ -429,7 +537,11 @@ void Operators::sequentialSplit(UnaryPredicate0D& startingPred, UnaryPredicate0D // find next start do{ ++itStart; - }while((itStart!=end) && (!startingPred(itStart))); + if(itStart == end) + break; + if(startingPred(itStart) < 0) + goto error; + }while(!startingPred.result); }while((itStart!=end) && (itStart!=last)); } @@ -446,17 +558,29 @@ void Operators::sequentialSplit(UnaryPredicate0D& startingPred, UnaryPredicate0D 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; } #include "CurveIterators.h" // Internal function -void __recursiveSplit(Chain *_curve, UnaryFunction0D& func, UnaryPredicate1D& pred, float sampling, +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; + return 0; } CurveInternal::CurvePointIterator first = _curve->curvePointsBegin(sampling); @@ -467,14 +591,14 @@ void __recursiveSplit(Chain *_curve, UnaryFunction0D& func, UnaryPredica Interface0DIterator it0d = it.castToInterface0DIterator(); real _min = FLT_MAX;++it;//func(it0d);++it; CurveInternal::CurvePointIterator next = it;++next; - real tmp; bool bsplit = false; for(; ((it != end) && (next != end)); ++it,++next){ it0d = it.castToInterface0DIterator(); - tmp = func(it0d); - if(tmp < _min){ - _min = tmp; + if (func(it0d) < 0) + return -1; + if(func.result < _min){ + _min = func.result; split = it; bsplit = true; } @@ -482,7 +606,7 @@ void __recursiveSplit(Chain *_curve, UnaryFunction0D& func, UnaryPredica if(!bsplit){ // we didn't find any minimum newChains.push_back(_curve); - return; + return 0; } // retrieves the current splitting id @@ -511,7 +635,7 @@ void __recursiveSplit(Chain *_curve, UnaryFunction0D& func, UnaryPredica newChains.push_back(_curve); delete new_curve_a; delete new_curve_b; - return; + return 0; } // build the two resulting chains @@ -529,25 +653,31 @@ void __recursiveSplit(Chain *_curve, UnaryFunction0D& func, UnaryPredica // 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)) || (pred(*new_curve_b))){ + 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; + 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; } -void Operators::recursiveSplit(UnaryFunction0D& func, UnaryPredicate1D& pred, float sampling) +int Operators::recursiveSplit(UnaryFunction0D& func, UnaryPredicate1D& pred, float sampling) { if (_current_chains_set.empty()) { cerr << "Warning: current set empty" << endl; - return; + return 0; } Chain *currentChain = 0; @@ -561,7 +691,9 @@ void Operators::recursiveSplit(UnaryFunction0D& func, UnaryPredicate1D& if(!currentChain) continue; // let's check the first one: - if(!pred(*currentChain)){ + if (pred(*currentChain) < 0) + return -1; + if(!pred.result){ __recursiveSplit(currentChain, func, pred, sampling, newChains, splitted_chains); }else{ newChains.push_back(currentChain); @@ -583,16 +715,17 @@ void Operators::recursiveSplit(UnaryFunction0D& func, UnaryPredicate1D& if (!_current_chains_set.empty()) _current_set = &_current_chains_set; + return 0; } // recursive split with pred 0D -void __recursiveSplit(Chain *_curve, UnaryFunction0D& func, UnaryPredicate0D& pred0d, UnaryPredicate1D& pred, float sampling, +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; + return 0; } CurveInternal::CurvePointIterator first = _curve->curvePointsBegin(sampling); @@ -607,18 +740,20 @@ void __recursiveSplit(Chain *_curve, UnaryFunction0D& func, UnaryPredica //soc unused - real variance = 0.f; unsigned count = 0; CurveInternal::CurvePointIterator next = it;++next; - real tmp; bool bsplit = false; for(; ((it != end) && (next != end)); ++it,++next){ ++count; it0d = it.castToInterface0DIterator(); - if(!pred0d(it0d)) + if(pred0d(it0d) < 0) + return -1; + if(!pred0d.result) continue; - tmp = func(it0d); - mean += tmp; - if(tmp < _min){ - _min = tmp; + if(func(it0d) < 0) + return -1; + mean += func.result; + if(func.result < _min){ + _min = func.result; split = it; bsplit = true; } @@ -628,7 +763,7 @@ void __recursiveSplit(Chain *_curve, UnaryFunction0D& func, UnaryPredica //if((!bsplit) || (mean-_min>mean)){ // we didn't find any minimum if(!bsplit){ // we didn't find any minimum newChains.push_back(_curve); - return; + return 0; } // retrieves the current splitting id @@ -657,7 +792,7 @@ void __recursiveSplit(Chain *_curve, UnaryFunction0D& func, UnaryPredica newChains.push_back(_curve); delete new_curve_a; delete new_curve_b; - return; + return 0; } // build the two resulting chains @@ -675,25 +810,31 @@ void __recursiveSplit(Chain *_curve, UnaryFunction0D& func, UnaryPredica // 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)) || (pred(*new_curve_b))){ + 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; + 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; } -void 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; + return 0; } Chain *currentChain = 0; @@ -707,7 +848,9 @@ void Operators::recursiveSplit(UnaryFunction0D& func, UnaryPredicate0D& if(!currentChain) continue; // let's check the first one: - if(!pred(*currentChain)){ + if(pred(*currentChain) < 0) + return -1; + if(!pred.result){ __recursiveSplit(currentChain, func, pred0d, pred, sampling, newChains, splitted_chains); }else{ newChains.push_back(currentChain); @@ -729,6 +872,7 @@ void Operators::recursiveSplit(UnaryFunction0D& func, UnaryPredicate0D& if (!_current_chains_set.empty()) _current_set = &_current_chains_set; + return 0; } // Internal class class PredicateWrapper @@ -740,7 +884,9 @@ public: } inline bool operator()(Interface1D* i1, Interface1D* i2) { - return (*_pred)(*i1, *i2); + if ((*_pred)(*i1, *i2) < 0) + throw std::runtime_error("comparison failed"); + return _pred->result; } private: @@ -748,10 +894,18 @@ private: BinaryPredicate1D* _pred; }; -void Operators::sort(BinaryPredicate1D& pred) { +int Operators::sort(BinaryPredicate1D& pred) { if (!_current_set) - return; - std::sort(_current_set->begin(), _current_set->end(), PredicateWrapper(pred)); + 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; } Stroke* createStroke(Interface1D& inter) { @@ -813,31 +967,39 @@ Stroke* createStroke(Interface1D& inter) { } -inline void applyShading(Stroke& stroke, vector& shaders) { - for (vector::iterator it = shaders.begin(); it != shaders.end(); ++it) - (*it)->shade(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; + } + } + return 0; } -void Operators::create(UnaryPredicate1D& pred, vector shaders) { +int Operators::create(UnaryPredicate1D& pred, vector shaders) { Canvas* canvas = Canvas::getInstance(); if (!_current_set) { cerr << "Warning: current set empty" << endl; - return; + return 0; } for (Operators::I1DContainer::iterator it = _current_set->begin(); it != _current_set->end(); ++it) { - if (!pred(**it)) + if (pred(**it) < 0) + return -1; + if (!pred.result) continue; Stroke* stroke = createStroke(**it); if (stroke) { - applyShading(*stroke, shaders); + if (applyShading(*stroke, shaders) < 0) + return -1; //canvas->RenderStroke(stroke); _current_strokes_set.push_back(stroke); } } + return 0; } diff --git a/source/blender/freestyle/intern/stroke/Operators.h b/source/blender/freestyle/intern/stroke/Operators.h index 804ee4d7056..cff9e120c1a 100755 --- a/source/blender/freestyle/intern/stroke/Operators.h +++ b/source/blender/freestyle/intern/stroke/Operators.h @@ -64,7 +64,7 @@ public: * a specified condition. * \param pred The predicate expressing this condition */ - static void select(UnaryPredicate1D& pred); + 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 @@ -83,7 +83,7 @@ public: * is used to modify the processed ViewEdge state (the timestamp * incrementation is a typical illustration of such a modifier) */ - static void chain(ViewEdgeInternal::ViewEdgeIterator& it, + static int chain(ViewEdgeInternal::ViewEdgeIterator& it, UnaryPredicate1D& pred, UnaryFunction1D_void& modifier); @@ -103,7 +103,7 @@ public: * The predicate on the ViewEdge that expresses the stopping * condition. */ - static void chain(ViewEdgeInternal::ViewEdgeIterator& it, + static int chain(ViewEdgeInternal::ViewEdgeIterator& it, UnaryPredicate1D& pred); /*! Builds a set of chains from the current set of ViewEdges. @@ -126,7 +126,7 @@ public: * The predicate on the ViewEdge that expresses the stopping * condition. */ - static void bidirectionalChain(ChainingIterator& it, UnaryPredicate1D& pred); + 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 @@ -149,7 +149,7 @@ public: * The ChainingIterator on the ViewEdges of the ViewMap. It contains * the chaining rule. */ - static void bidirectionalChain(ChainingIterator& it); + 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. @@ -170,7 +170,7 @@ public: * evaluation. (The chain is not actually resampled, a virtual point * only progresses along the curve using this resolution) */ - static void sequentialSplit(UnaryPredicate0D& startingPred, UnaryPredicate0D& stoppingPred, + static int sequentialSplit(UnaryPredicate0D& startingPred, UnaryPredicate0D& stoppingPred, float sampling = 0.f); /*! Splits each chain of the current set of chains in a sequential way. @@ -185,7 +185,7 @@ public: * evaluation. (The chain is not actually resampled, a virtual point * only progresses along the curve using this resolution) */ - static void sequentialSplit(UnaryPredicate0D& pred, + static int sequentialSplit(UnaryPredicate0D& pred, float sampling = 0.f); /*! Splits the current set of chains in a recursive way. @@ -206,7 +206,7 @@ public: * evaluation. (The chain is not actually resampled, a virtual point * only progresses along the curve using this resolution) */ - static void recursiveSplit(UnaryFunction0D& func, UnaryPredicate1D& pred, float sampling = 0); + 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 @@ -238,14 +238,14 @@ public: * only progresses along the curve using this resolution) * */ - static void recursiveSplit(UnaryFunction0D& func, UnaryPredicate0D& pred0d, UnaryPredicate1D& pred, float sampling = 0); + 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 void sort(BinaryPredicate1D& pred); + 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 @@ -256,7 +256,7 @@ public: * \param shaders * The list of shaders used to shade the strokes */ - static void create(UnaryPredicate1D& pred, vector shaders); + static int create(UnaryPredicate1D& pred, vector shaders); // // Data access diff --git a/source/blender/freestyle/intern/stroke/Predicates0D.h b/source/blender/freestyle/intern/stroke/Predicates0D.h index 0318c1742ec..58aa3e5c86c 100755 --- a/source/blender/freestyle/intern/stroke/Predicates0D.h +++ b/source/blender/freestyle/intern/stroke/Predicates0D.h @@ -51,6 +51,7 @@ class UnaryPredicate0D { public: + bool result; PyObject *py_up0D; /*! Default constructor. */ @@ -72,15 +73,19 @@ public: * \return true if the condition is satisfied, * false otherwise. */ - virtual bool operator()(Interface0DIterator& it) { + virtual int operator()(Interface0DIterator& it) { string name( py_up0D ? PyString_AsString(PyObject_CallMethod(py_up0D, "getName", "")) : getName() ); if( py_up0D && PyObject_HasAttrString(py_up0D, "__call__") ) { - return Director_BPy_UnaryPredicate0D___call__(py_up0D, it); + int res = Director_BPy_UnaryPredicate0D___call__(py_up0D, it); + if (res < 0) + return -1; + result = (res == 1); } else { cerr << "Warning: " << name << " operator() not implemented" << endl; - return false; + result = false; } + return 0; } }; @@ -101,6 +106,7 @@ class BinaryPredicate0D { public: + bool result; PyObject *py_bp0D; /*! Default constructor. */ @@ -122,15 +128,19 @@ public: * The second Interface0D. * \return true or false. */ - virtual bool operator()(Interface0D& inter1, Interface0D& inter2) { + virtual int operator()(Interface0D& inter1, Interface0D& inter2) { string name( py_bp0D ? PyString_AsString(PyObject_CallMethod(py_bp0D, "getName", "")) : getName() ); if( py_bp0D && PyObject_HasAttrString(py_bp0D, "__call__") ) { - return Director_BPy_BinaryPredicate0D___call__(py_bp0D, inter1, inter2); + int res = Director_BPy_BinaryPredicate0D___call__(py_bp0D, inter1, inter2); + if (res < 0) + return -1; + result = (res == 1); } else { cerr << "Warning: " << name << " operator() not implemented" << endl; - return false; + result = false; } + return 0; } }; @@ -155,8 +165,9 @@ namespace Predicates0D { return "TrueUP0D"; } /*! The () operator. */ - bool operator()(Interface0DIterator&) { - return true; + int operator()(Interface0DIterator&) { + result = true; + return 0; } }; @@ -172,8 +183,9 @@ namespace Predicates0D { return "FalseUP0D"; } /*! The () operator. */ - bool operator()(Interface0DIterator&) { - return false; + int operator()(Interface0DIterator&) { + result = false; + return 0; } }; diff --git a/source/blender/freestyle/intern/stroke/Predicates1D.h b/source/blender/freestyle/intern/stroke/Predicates1D.h index 014d5a1130e..6e7ab04783b 100755 --- a/source/blender/freestyle/intern/stroke/Predicates1D.h +++ b/source/blender/freestyle/intern/stroke/Predicates1D.h @@ -55,6 +55,7 @@ class UnaryPredicate1D { public: + bool result; PyObject *py_up1D; /*! Default constructor. */ @@ -75,15 +76,19 @@ public: * \return true if the condition is satisfied, * false otherwise. */ - virtual bool operator()(Interface1D& inter) { + virtual int operator()(Interface1D& inter) { string name( py_up1D ? PyString_AsString(PyObject_CallMethod(py_up1D, "getName", "")) : getName() ); if( py_up1D && PyObject_HasAttrString(py_up1D, "__call__")) { - return Director_BPy_UnaryPredicate1D___call__(py_up1D, inter); + int res = Director_BPy_UnaryPredicate1D___call__(py_up1D, inter); + if (res < 0) + return -1; + result = (res == 1); } else { cerr << "Warning: " << name << " operator() not implemented" << endl; - return false; + result = false; } + return 0; } }; @@ -104,6 +109,7 @@ class BinaryPredicate1D { public: + bool result; PyObject *py_bp1D; /*! Default constructor. */ @@ -124,15 +130,19 @@ public: * The second Interface1D. * \return true or false. */ - virtual bool operator()(Interface1D& inter1, Interface1D& inter2) { + virtual int operator()(Interface1D& inter1, Interface1D& inter2) { string name( py_bp1D ? PyString_AsString(PyObject_CallMethod(py_bp1D, "getName", "")) : getName() ); if( py_bp1D && PyObject_HasAttrString(py_bp1D, "__call__") ) { - return Director_BPy_BinaryPredicate1D___call__(py_bp1D, inter1, inter2); + int res = Director_BPy_BinaryPredicate1D___call__(py_bp1D, inter1, inter2); + if (res < 0) + return -1; + result = (res == 1); } else { cerr << "Warning: " << name << " operator() not implemented" << endl; - return false; + result = false; } + return 0; } }; @@ -157,8 +167,9 @@ namespace Predicates1D { return "TrueUP1D"; } /*! the () operator */ - bool operator()(Interface1D&) { - return true; + int operator()(Interface1D&) { + result = true; + return 0; } }; @@ -174,8 +185,9 @@ namespace Predicates1D { return "FalseUP1D"; } /*! the () operator */ - bool operator()(Interface1D&) { - return false; + int operator()(Interface1D&) { + result = false; + return 0; } }; @@ -198,9 +210,12 @@ namespace Predicates1D { return "QuantitativeInvisibilityUP1D"; } /*! the () operator */ - bool operator()(Interface1D& inter) { + int operator()(Interface1D& inter) { Functions1D::QuantitativeInvisibilityF1D func; - return (func(inter) == _qi); + if (func(inter) < 0) + return -1; + result = (func.result == _qi); + return 0; } private: unsigned _qi; @@ -221,15 +236,20 @@ namespace Predicates1D { return "ContourUP1D"; } /*! The () operator. */ - bool operator()(Interface1D& inter) { - if((_getNature(inter) & Nature::SILHOUETTE) || (_getNature(inter) & Nature::BORDER)){ + 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)) - return true; + if(Functions0D::getOccludeeF0D(it) != Functions0D::getShapeF0D(it)) { + result = true; + return 0; + } } } - return false; + result = false; + return 0; } }; @@ -248,18 +268,23 @@ namespace Predicates1D { return "ExternalContourUP1D"; } /*! The () operator. */ - bool operator()(Interface1D& inter) { - if((_getNature(inter) & Nature::SILHOUETTE) || (_getNature(inter) & Nature::BORDER)){ + 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) - return true; + if((*os) == 0) { + result = true; + return 0; + } } } - return false; + result = false; + return 0; } }; @@ -280,8 +305,9 @@ namespace Predicates1D { return "EqualToTimeStampUP1D"; } /*! The () operator. */ - bool operator()(Interface1D& inter) { - return (inter.getTimeStamp() == _timeStamp); + int operator()(Interface1D& inter) { + result = (inter.getTimeStamp() == _timeStamp); + return 0; } }; @@ -302,11 +328,14 @@ namespace Predicates1D { return "EqualToChainingTimeStampUP1D"; } /*! The () operator. */ - bool operator()(Interface1D& inter) { + int operator()(Interface1D& inter) { ViewEdge* edge = dynamic_cast(&inter); - if (!edge) - return false; - return (edge->getChainingTimeStamp() >= _timeStamp); + if (!edge) { + result = false; + return 0; + } + result = (edge->getChainingTimeStamp() >= _timeStamp); + return 0; } }; @@ -335,16 +364,19 @@ namespace Predicates1D { return "ShapeUP1D"; } /*! The () operator. */ - bool operator()(Interface1D& inter) { + 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) - return true; - } - return false; + if((*s)->getId() == _id) { + result = true; + return 0; + } + } + result = false; + return 0; } }; @@ -363,8 +395,9 @@ namespace Predicates1D { return "TrueBP1D"; } /*! The () operator. */ - bool operator()(Interface1D& i1, Interface1D& i2) { - return true; + int operator()(Interface1D& i1, Interface1D& i2) { + result = true; + return 0; } }; @@ -378,8 +411,9 @@ namespace Predicates1D { return "FalseBP1D"; } /*! The () operator. */ - bool operator()(Interface1D& i1, Interface1D& i2) { - return false; + int operator()(Interface1D& i1, Interface1D& i2) { + result = false; + return 0; } }; @@ -395,8 +429,9 @@ namespace Predicates1D { return "Length2DBP1D"; } /*! The () operator. */ - bool operator()(Interface1D& i1, Interface1D& i2) { - return (i1.getLength2D() > i2.getLength2D()); + int operator()(Interface1D& i1, Interface1D& i2) { + result = (i1.getLength2D() > i2.getLength2D()); + return 0; } }; @@ -412,7 +447,7 @@ namespace Predicates1D { return "SameShapeIdBP1D"; } /*! The () operator. */ - bool operator()(Interface1D& i1, Interface1D& i2) { + int operator()(Interface1D& i1, Interface1D& i2) { set shapes1; Functions1D::getShapeF1D(i1, shapes1); set shapes2; @@ -425,11 +460,14 @@ namespace Predicates1D { for(set::iterator s2=shapes2.begin(), s2end=shapes2.end(); s2!=s2end; ++s2){ - if((*s2)->getId() == current) - return true; + if((*s2)->getId() == current) { + result = true; + return 0; + } } - } - return false; + } + result = false; + return 0; } }; @@ -451,8 +489,15 @@ namespace Predicates1D { return "ViewMapGradientNormBP1D"; } /*! The () operator. */ - bool operator()(Interface1D& i1, Interface1D& i2) { - return (_func(i1) > _func(i2)); + 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 diff --git a/source/blender/freestyle/intern/stroke/StrokeIterators.h b/source/blender/freestyle/intern/stroke/StrokeIterators.h index 9cc08a0532a..b51189f3990 100755 --- a/source/blender/freestyle/intern/stroke/StrokeIterators.h +++ b/source/blender/freestyle/intern/stroke/StrokeIterators.h @@ -158,13 +158,15 @@ namespace StrokeInternal { } /*! Increments. */ - virtual void increment() { + virtual int increment() { ++_it; + return 0; } /*! Decrements. */ - virtual void decrement() { + virtual int decrement() { --_it; + return 0; } /*! Returns true if the pointed StrokeVertex is the diff --git a/source/blender/freestyle/intern/stroke/StrokeShader.h b/source/blender/freestyle/intern/stroke/StrokeShader.h index cb7ceeca09f..031b7cc8acb 100755 --- a/source/blender/freestyle/intern/stroke/StrokeShader.h +++ b/source/blender/freestyle/intern/stroke/StrokeShader.h @@ -115,14 +115,17 @@ public: * modifies the Stroke's attribute's values such * as Color, Thickness, Geometry...) */ - virtual void shade(Stroke& ioStroke) const { + virtual int shade(Stroke& ioStroke) const { string name( py_ss ? PyString_AsString(PyObject_CallMethod(py_ss, "getName", "")) : getName() ); if( py_ss && PyObject_HasAttrString(py_ss, "shade") ) { - Director_BPy_StrokeShader_shade(py_ss, ioStroke); + if (Director_BPy_StrokeShader_shade(py_ss, ioStroke) < 0) { + return -1; + } } else { - cerr << "Warning: " << name << " method shade() not implemented" << endl; + cerr << "Warning: " << name << " shade() method not implemented" << endl; } + return 0; } }; -- cgit v1.2.3