diff options
Diffstat (limited to 'source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp')
-rw-r--r-- | source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp | 483 |
1 files changed, 254 insertions, 229 deletions
diff --git a/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp index 247fde9a9c0..a7883187066 100644 --- a/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp +++ b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp @@ -33,46 +33,49 @@ namespace Freestyle { // ///////////////////////////////////////// -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; } 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<StrokeVertex*>(&(*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; + 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<StrokeVertex *>(&(*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; } ///////////////////////////////////////// @@ -83,64 +86,65 @@ int 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 { - 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<StrokeVertex*>(&(*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<StrokeVertex*>(&(*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; - } - - ioStroke.UpdateLength(); - - 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<StrokeVertex *>(&(*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<StrokeVertex *>(&(*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; + } + + ioStroke.UpdateLength(); + + return 0; } ///////////////////////////////////////// @@ -149,29 +153,40 @@ int SpatialNoiseShader::shade(Stroke &ioStroke) const // ///////////////////////////////////////// -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 { - // cerr << " Smoothing a stroke " << endl; - - Smoother smoother(ioStroke); - smoother.smooth(_nbIterations, _factorPoint, _factorCurvature, _factorCurvatureDifference, _anisoPoint, - _anisoNormal, _anisoCurvature, _carricatureFactor); - return 0; + // cerr << " Smoothing a stroke " << endl; + + Smoother smoother(ioStroke); + smoother.smooth(_nbIterations, + _factorPoint, + _factorCurvature, + _factorCurvatureDifference, + _anisoPoint, + _anisoNormal, + _anisoCurvature, + _carricatureFactor); + return 0; } // SMOOTHER @@ -179,152 +194,162 @@ int SmoothingShader::shade(Stroke &ioStroke) const Smoother::Smoother(Stroke &ioStroke) { - _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); + _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); } Smoother::~Smoother() { - delete[] _vertex; - delete[] _curvature; - delete[] _normal; + delete[] _vertex; + delete[] _curvature; + delete[] _normal; } -void Smoother::smooth(int nbIteration, real iFactorPoint, real ifactorCurvature, real iFactorCurvatureDifference, - real iAnisoPoint, real iAnisoNormal, real iAnisoCurvature, real iCarricatureFactor) +void Smoother::smooth(int nbIteration, + real iFactorPoint, + real ifactorCurvature, + real iFactorCurvatureDifference, + 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 < nbIteration; ++i) - iteration (); - copyVertices(); + _factorCurvature = ifactorCurvature; + _factorCurvatureDifference = iFactorCurvatureDifference; + _anisoNormal = iAnisoNormal; + _anisoCurvature = iAnisoCurvature; + _carricatureFactor = iCarricatureFactor; + _factorPoint = iFactorPoint; + _anisoPoint = iAnisoPoint; + + for (int i = 0; i < nbIteration; ++i) + iteration(); + copyVertices(); } static real edgeStopping(real x, real sigma) { - if (sigma == 0.0) - return 1.0; - return exp(-x * x / (sigma * sigma)); + if (sigma == 0.0) + return 1.0; + return exp(-x * x / (sigma * sigma)); } void Smoother::iteration() { - computeCurvature(); - for (int i = 1; i < (_nbVertices - 1); ++i) { - real motionNormal = _factorCurvature * _curvature[i] * edgeStopping(_curvature[i], _anisoNormal); - - real diffC1 = _curvature[i] - _curvature[i - 1]; - real diffC2 = _curvature[i] - _curvature[i + 1]; - real motionCurvature = edgeStopping(diffC1, _anisoCurvature) * diffC1 + - edgeStopping(diffC2, _anisoCurvature) * diffC2; //_factorCurvatureDifference; - motionCurvature *= _factorCurvatureDifference; - //motionCurvature = _factorCurvatureDifference * (diffC1 + diffC2); - if (_safeTest) - _vertex[i] = Vec2r(_vertex[i] + (motionNormal + motionCurvature) * _normal[i]); - Vec2r v1(_vertex[i - 1] - _vertex[i]); - Vec2r v2(_vertex[i + 1] - _vertex[i]); - real d1 = v1.norm(); - real d2 = v2.norm(); - _vertex[i] = Vec2r(_vertex[i] + - _factorPoint * edgeStopping(d2, _anisoPoint) * (_vertex[i - 1] - _vertex[i]) + - _factorPoint * edgeStopping(d1, _anisoPoint) * (_vertex[i + 1] - _vertex[i])); - } - - if (_isClosedCurve) { - real motionNormal = _factorCurvature * _curvature[0] * edgeStopping(_curvature[0], _anisoNormal); - - real diffC1 = _curvature[0] - _curvature[_nbVertices - 2]; - real diffC2 = _curvature[0] - _curvature[1]; - real motionCurvature = edgeStopping(diffC1, _anisoCurvature) * diffC1 + - edgeStopping(diffC2, _anisoCurvature) * diffC2; //_factorCurvatureDifference; - motionCurvature *= _factorCurvatureDifference; - //motionCurvature = _factorCurvatureDifference * (diffC1 + diffC2); - _vertex[0] = Vec2r(_vertex[0] + (motionNormal + motionCurvature) * _normal[0]); - _vertex[_nbVertices - 1] = _vertex[0]; - } + computeCurvature(); + for (int i = 1; i < (_nbVertices - 1); ++i) { + real motionNormal = _factorCurvature * _curvature[i] * + edgeStopping(_curvature[i], _anisoNormal); + + real diffC1 = _curvature[i] - _curvature[i - 1]; + real diffC2 = _curvature[i] - _curvature[i + 1]; + real motionCurvature = edgeStopping(diffC1, _anisoCurvature) * diffC1 + + edgeStopping(diffC2, _anisoCurvature) * + diffC2; //_factorCurvatureDifference; + motionCurvature *= _factorCurvatureDifference; + //motionCurvature = _factorCurvatureDifference * (diffC1 + diffC2); + if (_safeTest) + _vertex[i] = Vec2r(_vertex[i] + (motionNormal + motionCurvature) * _normal[i]); + Vec2r v1(_vertex[i - 1] - _vertex[i]); + Vec2r v2(_vertex[i + 1] - _vertex[i]); + real d1 = v1.norm(); + real d2 = v2.norm(); + _vertex[i] = Vec2r( + _vertex[i] + _factorPoint * edgeStopping(d2, _anisoPoint) * (_vertex[i - 1] - _vertex[i]) + + _factorPoint * edgeStopping(d1, _anisoPoint) * (_vertex[i + 1] - _vertex[i])); + } + + if (_isClosedCurve) { + real motionNormal = _factorCurvature * _curvature[0] * + edgeStopping(_curvature[0], _anisoNormal); + + real diffC1 = _curvature[0] - _curvature[_nbVertices - 2]; + real diffC2 = _curvature[0] - _curvature[1]; + real motionCurvature = edgeStopping(diffC1, _anisoCurvature) * diffC1 + + edgeStopping(diffC2, _anisoCurvature) * + diffC2; //_factorCurvatureDifference; + motionCurvature *= _factorCurvatureDifference; + //motionCurvature = _factorCurvatureDifference * (diffC1 + diffC2); + _vertex[0] = Vec2r(_vertex[0] + (motionNormal + motionCurvature) * _normal[0]); + _vertex[_nbVertices - 1] = _vertex[0]; + } } - void Smoother::computeCurvature() { - 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]; - } + 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() { - 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; - } - _stroke->UpdateLength(); + 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; + } + _stroke->UpdateLength(); } } /* namespace Freestyle */ |