diff --git a/libs/image/kis_brush_mask_applicator_factories.cpp b/libs/image/kis_brush_mask_applicator_factories.cpp index 4a19684cdf..b2df3472a9 100644 --- a/libs/image/kis_brush_mask_applicator_factories.cpp +++ b/libs/image/kis_brush_mask_applicator_factories.cpp @@ -1,226 +1,231 @@ /* * Copyright (c) 2012 Dmitry Kazakov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_brush_mask_applicator_factories.h" #include "kis_circle_mask_generator.h" #include "kis_circle_mask_generator_p.h" #include "kis_gauss_circle_mask_generator_p.h" #include "kis_brush_mask_applicators.h" #include "kis_brush_mask_applicator_base.h" #define a(_s) #_s #define b(_s) a(_s) template<> template<> MaskApplicatorFactory::ReturnType MaskApplicatorFactory::create(ParamType maskGenerator) { return new KisBrushMaskScalarApplicator(maskGenerator); } template<> template<> MaskApplicatorFactory::ReturnType MaskApplicatorFactory::create(ParamType maskGenerator) { return new KisBrushMaskVectorApplicator(maskGenerator); } template<> template<> MaskApplicatorFactory::ReturnType MaskApplicatorFactory::create(ParamType maskGenerator) { return new KisBrushMaskVectorApplicator(maskGenerator); } #if defined HAVE_VC struct KisCircleMaskGenerator::FastRowProcessor { FastRowProcessor(KisCircleMaskGenerator *maskGenerator) : d(maskGenerator->d.data()) {} template void process(float* buffer, int width, float y, float cosa, float sina, float centerX, float centerY); KisCircleMaskGenerator::Private *d; }; template<> void KisCircleMaskGenerator:: FastRowProcessor::process(float* buffer, int width, float y, float cosa, float sina, float centerX, float centerY) { const bool useSmoothing = d->copyOfAntialiasEdges; const bool noFading = d->noFading; float y_ = y - centerY; float sinay_ = sina * y_; float cosay_ = cosa * y_; float* bufferPointer = buffer; Vc::float_v currentIndices = Vc::float_v::IndexesFromZero(); Vc::float_v increment((float)Vc::float_v::size()); Vc::float_v vCenterX(centerX); Vc::float_v vCosa(cosa); Vc::float_v vSina(sina); Vc::float_v vCosaY_(cosay_); Vc::float_v vSinaY_(sinay_); Vc::float_v vXCoeff(d->xcoef); Vc::float_v vYCoeff(d->ycoef); Vc::float_v vTransformedFadeX(d->transformedFadeX); Vc::float_v vTransformedFadeY(d->transformedFadeY); Vc::float_v vOne(Vc::One); for (int i=0; i < width; i+= Vc::float_v::size()){ Vc::float_v x_ = currentIndices - vCenterX; Vc::float_v xr = x_ * vCosa - vSinaY_; Vc::float_v yr = x_ * vSina + vCosaY_; Vc::float_v n = pow2(xr * vXCoeff) + pow2(yr * vYCoeff); Vc::float_m outsideMask = n > vOne; if (!outsideMask.isFull()) { if (noFading) { Vc::float_v vFade(Vc::Zero); vFade(outsideMask) = vOne; vFade.store(bufferPointer, Vc::Aligned); } else { if (useSmoothing) { xr = Vc::abs(xr) + vOne; yr = Vc::abs(yr) + vOne; } Vc::float_v vNormFade = pow2(xr * vTransformedFadeX) + pow2(yr * vTransformedFadeY); //255 * n * (normeFade - 1) / (normeFade - n) Vc::float_v vFade = n * (vNormFade - vOne) / (vNormFade - n); // Mask in the inner circe of the mask Vc::float_m mask = vNormFade < vOne; vFade.setZero(mask); // Mask out the outer circe of the mask vFade(outsideMask) = vOne; vFade.store(bufferPointer, Vc::Aligned); } } else { // Mask out everything outside the circle vOne.store(bufferPointer, Vc::Aligned); } currentIndices = currentIndices + increment; bufferPointer += Vc::float_v::size(); } } struct KisGaussCircleMaskGenerator::FastRowProcessor { FastRowProcessor(KisGaussCircleMaskGenerator *maskGenerator) : d(maskGenerator->d.data()) {} template void process(float* buffer, int width, float y, float cosa, float sina, float centerX, float centerY); KisGaussCircleMaskGenerator::Private *d; }; template<> void KisGaussCircleMaskGenerator:: FastRowProcessor::process(float* buffer, int width, float y, float cosa, float sina, float centerX, float centerY) -{ - float widthHalf = width/2; - - float y_ = (y - widthHalf) / width; +{ + float y_ = y - centerY; float sinay_ = sina * y_; float cosay_ = cosa * y_; - float gStd = .1515 * (d->fade + .30); - float gDen = 1/(2*3.1415 * pow2(gStd)); - float gExpDen = 2 * pow2(gStd); - - float gMax = gDen * std::exp( -0.02/ gExpDen); - float gMin = gDen * std::exp( -0.5/ gExpDen); - - - float* bufferPointer = buffer; - Vc::float_v currentIndices = Vc::float_v::IndexesFromZero() - widthHalf; + Vc::float_v currentIndices = Vc::float_v::IndexesFromZero(); Vc::float_v increment((float)Vc::float_v::size()); Vc::float_v vCenterX(centerX); + Vc::float_v vCenter(d->center); Vc::float_v vCosa(cosa); Vc::float_v vSina(sina); Vc::float_v vCosaY_(cosay_); Vc::float_v vSinaY_(sinay_); Vc::float_v vYCoeff(d->ycoef); + Vc::float_v vDistfactor(d->distfactor); + Vc::float_v vAlphafactor(d->alphafactor); Vc::float_v vOne(Vc::One); Vc::float_v vZero(Vc::Zero); for (int i=0; i < width; i+= Vc::float_v::size()){ - Vc::float_v x_ = currentIndices / width; + Vc::float_v x_ = currentIndices - vCenterX; - Vc::float_v xr_ = -(pow2(x_) + pow2(y_)) / gExpDen; - Vc::float_v n = gDen * xr_.apply([](float f) { return std::exp(f); }); - Vc::float_v vNormFade = -(n - gMin)/(gMax - gMin) + 1.1f; + Vc::float_v xr = x_ * vCosa - vSinaY_; + Vc::float_v yr = x_ * vSina + vCosaY_; - Vc::float_m outsideMask = vNormFade > vOne; + Vc::float_v dist = sqrt(pow2(xr) + pow2(yr * vYCoeff)); - if (!outsideMask.isFull()) { +// Vc::float_m fadeMask = d->fadeMaker.needFade + +// Vc::float_m outsideMask = dist > vOne; + +// if (!outsideMask.isFull()) { + Vc::float_v valDist = dist * vDistfactor; + Vc::float_v fullFade = vAlphafactor * ( + (valDist + vCenter).apply([](float f) { return erff(f); }) - + (valDist - vCenter).apply([](float f) { return erff(f); }) ); - Vc::float_v vFade = vNormFade; + //255 * n * (normeFade - 1) / (normeFade - n) + Vc::float_v vFade = (255.f - fullFade) / 255.f; - Vc::float_m mask = vNormFade < vZero; +// for (size_t i = 0; i < Vc::float_v::size(); i++){ +// qDebug() << vFade[i]; +// } +// // Mask in the inner circe of the mask + Vc::float_m mask = vFade < vZero; vFade.setZero(mask); // Mask out the outer circe of the mask - vFade(outsideMask) = vOne; + mask = vFade > vOne; + vFade(mask) = vOne; vFade.store(bufferPointer, Vc::Aligned); - } else { - // Mask out everything outside the circle - vOne.store(bufferPointer, Vc::Aligned); - } - currentIndices = currentIndices + increment; - bufferPointer += Vc::float_v::size(); +// } else { +// vOne.store(bufferPointer, Vc::Aligned); +// } + currentIndices = currentIndices + increment; + + bufferPointer += Vc::float_v::size(); } } #endif /* defined HAVE_VC */