Krita Source Code Documentation
Loading...
Searching...
No Matches
KisRainDropsFilter Class Reference

#include <kis_raindrops_filter.h>

+ Inheritance diagram for KisRainDropsFilter:

Public Member Functions

KisConfigWidgetcreateConfigurationWidget (QWidget *parent, const KisPaintDeviceSP dev, bool useForMasks) const override
 
KisFilterConfigurationSP defaultConfiguration (KisResourcesInterfaceSP resourcesInterface) const override
 
 KisRainDropsFilter ()
 
void processImpl (KisPaintDeviceSP device, const QRect &applyRect, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const override
 
- Public Member Functions inherited from KisFilter
virtual QRect changedRect (const QRect &rect, const KisFilterConfigurationSP config, int lod) const
 
virtual bool configurationAllowedForMask (KisFilterConfigurationSP config) const
 
virtual void fixLoadedFilterConfigurationForMasks (KisFilterConfigurationSP config) const
 
 KisFilter (const KoID &id, const KoID &category, const QString &entry)
 
virtual QRect neededRect (const QRect &rect, const KisFilterConfigurationSP config, int lod) const
 
virtual bool needsTransparentPixels (const KisFilterConfigurationSP config, const KoColorSpace *cs) const
 
void process (const KisPaintDeviceSP src, KisPaintDeviceSP dst, KisSelectionSP selection, const QRect &applyRect, const KisFilterConfigurationSP config, KoUpdater *progressUpdater=0) const
 
void process (KisPaintDeviceSP device, const QRect &applyRect, const KisFilterConfigurationSP config, KoUpdater *progressUpdater=0) const
 
virtual bool supportsLevelOfDetail (const KisFilterConfigurationSP config, int lod) const
 
 ~KisFilter () override
 
- Public Member Functions inherited from KisBaseProcessor
KisBookmarkedConfigurationManagerbookmarkManager ()
 
const KisBookmarkedConfigurationManagerbookmarkManager () const
 
ColorSpaceIndependence colorSpaceIndependence () const
 
virtual KisFilterConfigurationSP factoryConfiguration (KisResourcesInterfaceSP resourcesInterface) const
 
QString id () const
 
 KisBaseProcessor (const KoID &id, const KoID &category, const QString &entry)
 
KoID menuCategory () const
 
QString menuEntry () const
 
QString name () const
 
 Private ()
 
QKeySequence shortcut () const
 
bool showConfigurationWidget ()
 If true, the filter wants to show a configuration widget.
 
bool supportsAdjustmentLayers () const
 This filter can be used in adjustment layers.
 
bool supportsPainting () const
 
bool supportsThreading () const
 
virtual ~KisBaseProcessor ()
 
- Public Member Functions inherited from Private
 Private (KisCanvas2 *c)
 
- Public Member Functions inherited from KisShared
bool deref ()
 
bool ref ()
 
int refCount ()
 
QAtomicInt * sharedWeakReference ()
 

Static Public Member Functions

static KoID id ()
 

Private Member Functions

bool ** CreateBoolArray (uint Columns, uint Rows) const
 
void FreeBoolArray (bool **lpbArray, uint Columns) const
 
uchar LimitValues (int ColorValue) const
 

Additional Inherited Members

- Public Attributes inherited from KisBaseProcessor
KisBookmarkedConfigurationManagerbookmarkManager
 
KoID category
 
ColorSpaceIndependence colorSpaceIndependence
 
QString entry
 
KoID id
 
QKeySequence shortcut
 
bool showConfigurationWidget
 
bool supportsAdjustmentLayers
 
bool supportsPainting
 
bool supportsThreading
 
- Public Attributes inherited from Private
KisCanvas2canvas
 
int displayedFrame
 
int intendedFrame
 
- Protected Member Functions inherited from KisFilter
QString configEntryGroup () const
 
void setSupportsLevelOfDetail (bool value)
 
- Protected Member Functions inherited from KisBaseProcessor
void init (const QString &configEntryGroup)
 
void setColorSpaceIndependence (ColorSpaceIndependence v)
 
void setShortcut (const QKeySequence &shortcut)
 
void setShowConfigurationWidget (bool v)
 
void setSupportsAdjustmentLayers (bool v)
 
void setSupportsPainting (bool v)
 
void setSupportsThreading (bool v)
 
- Protected Member Functions inherited from KisShared
 KisShared ()
 
 ~KisShared ()
 

Detailed Description

Definition at line 16 of file kis_raindrops_filter.h.

Constructor & Destructor Documentation

◆ KisRainDropsFilter()

KisRainDropsFilter::KisRainDropsFilter ( )

Definition at line 46 of file kis_raindrops_filter.cpp.

47 : KisFilter(id(), FiltersCategoryArtisticId, i18n("&Raindrops..."))
48{
52}
KisFilter(const KoID &id, const KoID &category, const QString &entry)
Definition kis_filter.cc:22
const KoID FiltersCategoryArtisticId("artistic_filters", ki18nc("The category of artistic filters, like raindrops. Adjective.", "Artistic"))
void setSupportsThreading(bool v)
void setSupportsAdjustmentLayers(bool v)
void setSupportsPainting(bool v)

References KisBaseProcessor::setSupportsAdjustmentLayers(), KisBaseProcessor::setSupportsPainting(), and KisBaseProcessor::setSupportsThreading().

Member Function Documentation

◆ CreateBoolArray()

bool ** KisRainDropsFilter::CreateBoolArray ( uint Columns,
uint Rows ) const
private

Definition at line 340 of file kis_raindrops_filter.cpp.

341{
342 bool** lpbArray = 0;
343 lpbArray = (bool**) malloc(Columns * sizeof(bool*));
344
345 if (lpbArray == 0)
346 return (0);
347
348 for (uint i = 0; i < Columns; ++i) {
349 lpbArray[i] = (bool*) malloc(Rows * sizeof(bool));
350 if (lpbArray[i] == 0) {
351 FreeBoolArray(lpbArray, Columns);
352 return (0);
353 }
354 }
355
356 return (lpbArray);
357}
unsigned int uint
void FreeBoolArray(bool **lpbArray, uint Columns) const

References FreeBoolArray().

◆ createConfigurationWidget()

KisConfigWidget * KisRainDropsFilter::createConfigurationWidget ( QWidget * parent,
const KisPaintDeviceSP dev,
bool useForMasks ) const
overridevirtual

Create the configuration widget for this processor.

Parameters
parentthe Qt owner widget of this widget
devthe paintdevice this filter will act on
useForMasksshown if the filer is going to be used in a mask. Some filters may provide limited options when applied as a mask (e.g. Gaussian Blur)

Reimplemented from KisBaseProcessor.

Definition at line 379 of file kis_raindrops_filter.cpp.

380{
382 param.push_back(KisIntegerWidgetParam(1, 200, 80, i18n("Drop size"), "dropsize"));
383 param.push_back(KisIntegerWidgetParam(1, 500, 80, i18n("Number of drops"), "number"));
384 param.push_back(KisIntegerWidgetParam(1, 100, 30, i18n("Fish eyes"), "fishEyes"));
385 KisMultiIntegerFilterWidget * w = new KisMultiIntegerFilterWidget(id().id(), parent, id().id(), param);
387 return w;
388}
static KisResourcesInterfaceSP instance()
KisFilterConfigurationSP defaultConfiguration(KisResourcesInterfaceSP resourcesInterface) const override
std::vector< KisIntegerWidgetParam > vKisIntegerWidgetParam

References defaultConfiguration(), and KisGlobalResourcesInterface::instance().

◆ defaultConfiguration()

KisFilterConfigurationSP KisRainDropsFilter::defaultConfiguration ( KisResourcesInterfaceSP resourcesInterface) const
overridevirtual

Return the configuration set as the default by the user or the default configuration from the filter writer as returned by factoryConfiguration.

This configuration is used by default for the configuration widget and given to the process function if there is no configuration widget.

Returns
the default configuration of this widget

Reimplemented from KisBaseProcessor.

Definition at line 390 of file kis_raindrops_filter.cpp.

391{
392 KisFilterConfigurationSP config = factoryConfiguration(resourcesInterface);
393 config->setProperty("dropsize", 80);
394 config->setProperty("number", 80);
395 config->setProperty("fishEyes", 30);
396 config->setProperty("seed", QTime::currentTime().msec());
397
398
399 return config;
400}
virtual KisFilterConfigurationSP factoryConfiguration(KisResourcesInterfaceSP resourcesInterface) const

References KisBaseProcessor::factoryConfiguration().

◆ FreeBoolArray()

void KisRainDropsFilter::FreeBoolArray ( bool ** lpbArray,
uint Columns ) const
private

Definition at line 324 of file kis_raindrops_filter.cpp.

325{
326 for (uint i = 0; i < Columns; ++i)
327 free(lpbArray[i]);
328
329 free(lpbArray);
330}

◆ id()

static KoID KisRainDropsFilter::id ( )
inlinestatic

Definition at line 26 of file kis_raindrops_filter.h.

26 {
27 return KoID("raindrops", i18n("Raindrops"));
28 }
Definition KoID.h:30

◆ LimitValues()

uchar KisRainDropsFilter::LimitValues ( int ColorValue) const
private

Definition at line 370 of file kis_raindrops_filter.cpp.

371{
372 if (ColorValue > 255) // MAX = 255
373 ColorValue = 255;
374 if (ColorValue < 0) // MIN = 0
375 ColorValue = 0;
376 return ((uchar) ColorValue);
377}

◆ processImpl()

void KisRainDropsFilter::processImpl ( KisPaintDeviceSP device,
const QRect & applyRect,
const KisFilterConfigurationSP config,
KoUpdater * progressUpdater ) const
overridevirtual

Override this function with the implementation of your filter.

This is a low level function that expects all the conditions for the

Parameters
devicebe met. Use usual process() methods instead.
devicethe paint device to filter
applyRectthe rectangle where the filter is applied
configthe parameters of the filter
progressUpdaterto pass on the progress the filter is making

This case should be filtered out at the higher level, in KisFilter::process() or in KisFilterStrokeStrategy

Implements KisFilter.

Definition at line 74 of file kis_raindrops_filter.cpp.

78{
83 KIS_SAFE_ASSERT_RECOVER_RETURN(!applyRect.isEmpty());
84
85 QPoint srcTopLeft = applyRect.topLeft();
86 Q_ASSERT(device);
87
88 //read the filter configuration values from the KisFilterConfiguration object
89 quint32 DropSize = config->getInt("dropSize", 80);
90 quint32 number = config->getInt("number", 80);
91 quint32 fishEyes = config->getInt("fishEyes", 30);
92 QRandomGenerator rng(config->getInt("seed"));
93
94 if (fishEyes <= 0) fishEyes = 1;
95
96 if (fishEyes > 100) fishEyes = 100;
97
98 int Width = applyRect.width();
99 int Height = applyRect.height();
100
101 bool** BoolMatrix = CreateBoolArray(Width, Height);
102
103 int i, j, k, l, m, n; // loop variables
104 int Bright; // Bright value for shadows and highlights
105 int x, y; // center coordinates
106 int Counter = 0; // Counter (duh !)
107 int NewSize; // Size of current raindrop
108 int halfSize; // Half of the current raindrop
109 int Radius; // Maximum radius for raindrop
110 int BlurRadius; // Blur Radius
111 int BlurPixels;
112
113 double r, a; // polar coordinates
114 double OldRadius; // Radius before processing
115 double NewfishEyes = (double)fishEyes * 0.01; // FishEye Coefficients
116 double s;
117 double R, G, B;
118
119 bool FindAnother = false; // To search for good coordinates
120
121 const KoColorSpace * cs = device->colorSpace();
122
123 // Init boolean Matrix.
124
125 for (i = 0 ; i < Width; ++i) {
126 for (j = 0 ; j < Height; ++j) {
127 BoolMatrix[i][j] = false;
128 }
129 }
130
131 progressUpdater->setRange(0, number);
132 KisRandomAccessorSP dstAccessor = device->createRandomAccessorNG();
133
134 for (uint NumBlurs = 0; NumBlurs <= number; ++NumBlurs) {
135 NewSize = 5 + static_cast<int>(rng.bounded(1.0) * (DropSize - 5));
136 halfSize = NewSize / 2;
137 Radius = halfSize;
138 s = Radius / log(NewfishEyes * Radius + 1);
139
140 Counter = 0;
141
142 do {
143 FindAnother = false;
144 y = static_cast<int>(rng.bounded(static_cast<double>(Width - 1)));
145 x = static_cast<int>(rng.bounded(static_cast<double>(Height - 1)));
146
147 if (BoolMatrix[y][x])
148 FindAnother = true;
149 else
150 for (i = x - halfSize ; i <= x + halfSize; i++)
151 for (j = y - halfSize ; j <= y + halfSize; j++)
152 if ((i >= 0) && (i < Height) && (j >= 0) && (j < Width))
153 if (BoolMatrix[j][i])
154 FindAnother = true;
155
156 Counter++;
157 } while (FindAnother && Counter < 10000);
158
159 if (Counter >= 10000) {
160 NumBlurs = number;
161 break;
162 }
163
164 for (i = -1 * halfSize ; i < NewSize - halfSize; i++) {
165 for (j = -1 * halfSize ; j < NewSize - halfSize; j++) {
166 r = sqrt((double)i * i + j * j);
167 a = atan2(static_cast<double>(i), static_cast<double>(j));
168
169 if (r <= Radius) {
170 OldRadius = r;
171 r = (exp(r / s) - 1) / NewfishEyes;
172
173 k = x + (int)(r * sin(a));
174 l = y + (int)(r * cos(a));
175
176 m = x + i;
177 n = y + j;
178
179 if ((k >= 0) && (k < Height) && (l >= 0) && (l < Width)) {
180 if ((m >= 0) && (m < Height) && (n >= 0) && (n < Width)) {
181 Bright = 0;
182
183 if (OldRadius >= 0.9 * Radius) {
184 if ((a <= 0) && (a > -2.25))
185 Bright = -80;
186 else if ((a <= -2.25) && (a > -2.5))
187 Bright = -40;
188 else if ((a <= 0.25) && (a > 0))
189 Bright = -40;
190 }
191
192 else if (OldRadius >= 0.8 * Radius) {
193 if ((a <= -0.75) && (a > -1.50))
194 Bright = -40;
195 else if ((a <= 0.10) && (a > -0.75))
196 Bright = -30;
197 else if ((a <= -1.50) && (a > -2.35))
198 Bright = -30;
199 }
200
201 else if (OldRadius >= 0.7 * Radius) {
202 if ((a <= -0.10) && (a > -2.0))
203 Bright = -20;
204 else if ((a <= 2.50) && (a > 1.90))
205 Bright = 60;
206 }
207
208 else if (OldRadius >= 0.6 * Radius) {
209 if ((a <= -0.50) && (a > -1.75))
210 Bright = -20;
211 else if ((a <= 0) && (a > -0.25))
212 Bright = 20;
213 else if ((a <= -2.0) && (a > -2.25))
214 Bright = 20;
215 }
216
217 else if (OldRadius >= 0.5 * Radius) {
218 if ((a <= -0.25) && (a > -0.50))
219 Bright = 30;
220 else if ((a <= -1.75) && (a > -2.0))
221 Bright = 30;
222 }
223
224 else if (OldRadius >= 0.4 * Radius) {
225 if ((a <= -0.5) && (a > -1.75))
226 Bright = 40;
227 }
228
229 else if (OldRadius >= 0.3 * Radius) {
230 if ((a <= 0) && (a > -2.25))
231 Bright = 30;
232 }
233
234 else if (OldRadius >= 0.2 * Radius) {
235 if ((a <= -0.5) && (a > -1.75))
236 Bright = 20;
237 }
238
239 BoolMatrix[n][m] = true;
240
241 QColor originalColor;
242
243 dstAccessor->moveTo(srcTopLeft.x() + l, srcTopLeft.y() + k);
244 cs->toQColor(dstAccessor->oldRawData(), &originalColor);
245
246 int newRed = CLAMP(originalColor.red() + Bright, 0, quint8_MAX);
247 int newGreen = CLAMP(originalColor.green() + Bright, 0, quint8_MAX);
248 int newBlue = CLAMP(originalColor.blue() + Bright, 0, quint8_MAX);
249
250 QColor newColor;
251 newColor.setRgb(newRed, newGreen, newBlue);
252
253 dstAccessor->moveTo(srcTopLeft.x() + n, srcTopLeft.y() + m);
254 cs->fromQColor(newColor, dstAccessor->rawData());
255 }
256 }
257 }
258 }
259 }
260
261 BlurRadius = NewSize / 25 + 1;
262
263 for (i = -1 * halfSize - BlurRadius ; i < NewSize - halfSize + BlurRadius; i++) {
264 for (j = -1 * halfSize - BlurRadius; j < NewSize - halfSize + BlurRadius; ++j) {
265 r = sqrt((double)i * i + j * j);
266
267 if (r <= Radius * 1.1) {
268 R = G = B = 0;
269 BlurPixels = 0;
270
271 for (k = -1 * BlurRadius; k < BlurRadius + 1; k++)
272 for (l = -1 * BlurRadius; l < BlurRadius + 1; l++) {
273 m = x + i + k;
274 n = y + j + l;
275
276 if ((m >= 0) && (m < Height) && (n >= 0) && (n < Width)) {
277 QColor color;
278 dstAccessor->moveTo(srcTopLeft.x() + n, srcTopLeft.y() + m);
279 cs->toQColor(dstAccessor->rawData(), &color);
280
281 R += color.red();
282 G += color.green();
283 B += color.blue();
284 BlurPixels++;
285 }
286 }
287
288 m = x + i;
289 n = y + j;
290
291 if ((m >= 0) && (m < Height) && (n >= 0) && (n < Width)) {
292 QColor color;
293
294 if (BlurPixels == 0) {
295 // Coverity complains that it *is* possible
296 // for BlurPixels to be 0, so let's make sure
297 // Krita doesn't crash here
298 BlurPixels = 1;
299 }
300
301 color.setRgb((int)(R / BlurPixels), (int)(G / BlurPixels), (int)(B / BlurPixels));
302 dstAccessor->moveTo(srcTopLeft.x() + n, srcTopLeft.y() + m);
303 cs->fromQColor(color, dstAccessor->rawData());
304 }
305 }
306 }
307 }
308
309 progressUpdater->setValue(NumBlurs);
310 }
311
312 FreeBoolArray(BoolMatrix, Width);
313}
Eigen::Matrix< double, 4, 2 > R
virtual quint8 * rawData()=0
virtual const quint8 * oldRawData() const =0
const KoColorSpace * colorSpace() const
KisRandomAccessorSP createRandomAccessorNG()
bool ** CreateBoolArray(uint Columns, uint Rows) const
virtual void moveTo(qint32 x, qint32 y)=0
virtual void toQColor(const quint8 *src, QColor *c) const =0
virtual void fromQColor(const QColor &color, quint8 *dst) const =0
void setValue(int value) override
Definition KoUpdater.cpp:64
void setRange(int minimum, int maximum) override
Definition KoUpdater.cpp:79
#define CLAMP(x, l, h)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
const quint8 quint8_MAX
Definition kis_global.h:24
KRITAIMAGE_EXPORT qreal atan2(qreal y, qreal x)
atan2 replacement

References B, CLAMP, KisPaintDevice::colorSpace(), CreateBoolArray(), KisPaintDevice::createRandomAccessorNG(), FreeBoolArray(), KoColorSpace::fromQColor(), G, KIS_SAFE_ASSERT_RECOVER_RETURN, KisRandomConstAccessorNG::moveTo(), KisBaseConstAccessor::oldRawData(), quint8_MAX, R, KisBaseAccessor::rawData(), KoUpdater::setRange(), KoUpdater::setValue(), and KoColorSpace::toQColor().


The documentation for this class was generated from the following files: