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

#include <multigridpatterngenerator.h>

+ Inheritance diagram for KisMultigridPatternGenerator:

Public Types

enum  Connector {
  None , Acute , Obtuse , Cross ,
  CenterDot , CornerDot
}
 

Public Member Functions

virtual bool allowsSplittingIntoPatches () const override
 
KisConfigWidgetcreateConfigurationWidget (QWidget *parent, const KisPaintDeviceSP dev, bool useForMasks) const override
 
KisFilterConfigurationSP defaultConfiguration (KisResourcesInterfaceSP resourcesInterface) const override
 
virtual void generate (KisProcessingInformation dst, const QSize &size, const KisFilterConfigurationSP config) const
 
void generate (KisProcessingInformation dst, const QSize &size, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const override
 
virtual void generate (KisProcessingInformation dst, const QSize &size, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const=0
 
 KisMultigridPatternGenerator ()
 
- Public Member Functions inherited from KisGenerator
virtual QRect generatedRect (QRect _imageArea, const KisFilterConfigurationSP=0) const
 
 KisGenerator (const KoID &id, const KoID &category, const QString &entry)
 
 ~KisGenerator () 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

QList< KisMultiGridRhombgenerateRhombs (int lines, int divisions, qreal offset) const
 
QList< int > getIndicesFromPoint (QPointF point, QList< qreal > angles, qreal offset) const
 
QPointF getVertice (QList< int > indices, QList< qreal > angles) 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 KisGenerator
QString configEntryGroup () const
 
- 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 45 of file multigridpatterngenerator.h.

Member Enumeration Documentation

◆ Connector

Constructor & Destructor Documentation

◆ KisMultigridPatternGenerator()

KisMultigridPatternGenerator::KisMultigridPatternGenerator ( )

Definition at line 51 of file multigridpatterngenerator.cpp.

51 : KisGenerator(id(), KoID("basic"), i18n("&Multigrid Pattern..."))
52{
55}
@ FULLY_INDEPENDENT
KisGenerator(const KoID &id, const KoID &category, const QString &entry)
Definition KoID.h:30
void setSupportsPainting(bool v)
void setColorSpaceIndependence(ColorSpaceIndependence v)

References FULLY_INDEPENDENT, KisBaseProcessor::setColorSpaceIndependence(), and KisBaseProcessor::setSupportsPainting().

Member Function Documentation

◆ allowsSplittingIntoPatches()

virtual bool KisMultigridPatternGenerator::allowsSplittingIntoPatches ( ) const
inlineoverridevirtual

Reports whether this generator can run properly while tiling the image into patches (as opposed to over the whole image in one single pass).

Generators that are known to not work properly should override this function and return false.

Reimplemented from KisGenerator.

Definition at line 76 of file multigridpatterngenerator.h.

76{ return false; }

◆ createConfigurationWidget()

KisConfigWidget * KisMultigridPatternGenerator::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 92 of file multigridpatterngenerator.cpp.

93{
94 Q_UNUSED(dev);
95 return new KisWdgMultigridPattern(parent);
96}

◆ defaultConfiguration()

KisFilterConfigurationSP KisMultigridPatternGenerator::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 57 of file multigridpatterngenerator.cpp.

58{
59 KisFilterConfigurationSP config = factoryConfiguration(resourcesInterface);
60
61 QLinearGradient gradient;
62 gradient.setColorAt(0, Qt::green);
63 gradient.setColorAt(1.0, Qt::blue);
65 if (grad) {
66 QDomDocument doc;
67 QDomElement elt = doc.createElement("gradient");
68 grad->toXML(doc, elt);
69 doc.appendChild(elt);
70 config->setProperty("gradientXML", doc.toString());
71 }
72
73 QVariant v;
74 KoColor c;
75 v.setValue(c);
76 config->setProperty("lineColor", v);
77 config->setProperty("divisions", 5);
78 config->setProperty("lineWidth", 1);
79 config->setProperty("dimensions", 5);
80 config->setProperty("offset", .2);
81
82 config->setProperty("colorRatio", 1.0);
83 config->setProperty("colorIndex", 0.0);
84 config->setProperty("colorIntersect", 0.0);
85
86 config->setProperty("connectorColor", v);
87 config->setProperty("connectorType", Connector::None);
88 config->setProperty("connectorWidth", 1);
89 return config;
90}
qreal v
static QSharedPointer< KoStopGradient > fromQGradient(const QGradient *gradient)
Creates KoStopGradient from a QGradient.
virtual KisFilterConfigurationSP factoryConfiguration(KisResourcesInterfaceSP resourcesInterface) const

References KisBaseProcessor::factoryConfiguration(), KoStopGradient::fromQGradient(), None, and v.

◆ generate() [1/3]

void KisGenerator::generate ( KisProcessingInformation dst,
const QSize & size,
const KisFilterConfigurationSP config ) const
virtual

Provided for convenience when no progress reporting is needed.

Reimplemented from KisGenerator.

Definition at line 59 of file kis_generator.cpp.

33{
34 generate(dst, size, config, 0);
35}
void generate(KisProcessingInformation dst, const QSize &size, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const override

◆ generate() [2/3]

void KisMultigridPatternGenerator::generate ( KisProcessingInformation dst,
const QSize & size,
const KisFilterConfigurationSP config,
KoUpdater * progressUpdater ) const
overridevirtual

Override this function with the implementation of your generator.

Parameters
dstthe destination paint device
sizethe size of the area that is to be filled
configthe parameters of the filter
progressUpdaterthe progress updater

Implements KisGenerator.

Definition at line 98 of file multigridpatterngenerator.cpp.

102{
103 KisPaintDeviceSP dst = dstInfo.paintDevice();
104
105 Q_ASSERT(!dst.isNull());
106 Q_ASSERT(config);
107
108 if (config) {
109
110 QLinearGradient gradient;
111 gradient.setColorAt(0, Qt::green);
112 gradient.setColorAt(1.0, Qt::blue);
114 if (config->hasProperty("gradientXML")) {
115 QDomDocument doc;
116 doc.setContent(config->getString("gradientXML", ""));
117 KoStopGradient gradient = KoStopGradient::fromXML(doc.firstChildElement());
118 if (gradient.stops().size() > 0) {
119 grad->setStops(gradient.stops());
120 }
121 }
122
123 int divisions = config->getInt("divisions", 1);
124 int dimensions = config->getInt("dimensions", 5);
125 qreal offset = config->getFloat("offset", .2);
126 QRectF bounds(QPoint(), size);
127
128 KoColor lineColor = config->getColor("lineColor");
129 lineColor.setOpacity(1.0);
130 int lineWidth = config->getInt("lineWidth", 1);
131
132 qreal colorRatio = config->getFloat("colorRatio", 1.0);
133 qreal colorIndex = config->getFloat("colorIndex", 0.0);
134 qreal colorIntersect = config->getFloat("colorIntersect", 0.0);
135
136 qreal diameter = QLineF(bounds.topLeft(), bounds.bottomRight()).length();
137 qreal scale = diameter/2/divisions;
138
139 QList<KisMultiGridRhomb> rhombs = generateRhombs(dimensions, divisions, offset);
140
141 KisProgressUpdateHelper progress(progressUpdater, 100, rhombs.size());
142
143
144 KisPainter gc(dst);
145 gc.setChannelFlags(config->channelFlags());
146 gc.setOpacityToUnit();
148 gc.setStrokeStyle(KisPainter::StrokeStyleBrush);
149 gc.setSelection(dstInfo.selection());
150
151 gc.fill(bounds.left(), bounds.top(), bounds.right(), bounds.bottom(), lineColor);
152
153 QTransform tf;
154 tf.translate(bounds.center().x(), bounds.center().y());
155 tf.scale(scale, scale);
156 if (dimensions%2>0) {
157 tf.rotateRadians((M_PI/dimensions)*0.5);
158 }
159 KoColor c = grad->stops()[0].color;
160 for (int i= 0; i < rhombs.size(); i++){
161 KisMultiGridRhomb rhomb = rhombs.at(i);
162 QPolygonF shape = tf.map(rhomb.shape);
163
164 QPointF center = shape.at(0)+shape.at(1)+shape.at(2)+shape.at(3);
165 center.setX(center.x()/4.0);
166 center.setY(center.y()/4.0);
167
168 QTransform lineWidthTransform;
169
170 qreal scaleForLineWidth = qMax(1-(qreal(lineWidth)/scale), 0.0);
171 lineWidthTransform.scale(scaleForLineWidth, scaleForLineWidth);
172 QPointF scaledCenter = lineWidthTransform.map(center);
173 lineWidthTransform.reset();
174
175 lineWidthTransform.translate(center.x()-scaledCenter.x(), center.y()-scaledCenter.y());
176 lineWidthTransform.scale(scaleForLineWidth, scaleForLineWidth);
177
178 shape = lineWidthTransform.map(shape);
179 if (shape.intersects(bounds) && shape.boundingRect().width()>0) {
180 QPainterPath p;
181 p.addPolygon(lineWidthTransform.map(shape));
182
183 qreal gradientPos = 1;
184
185 qreal w1 = QLineF (shape.at(0), shape.at(2)).length();
186 qreal w2 = QLineF (shape.at(1), shape.at(3)).length();
187 qreal shapeRatio = qMin(w1, w2)/qMax(w1, w2);
188
189 qreal intersectRatio = qreal(rhomb.line1)/qreal(dimensions);
190 intersectRatio += qreal(rhomb.line2)/qreal(dimensions);
191 intersectRatio *= 0.5;
192
193 qreal indexRatio = 1-abs(qreal(rhomb.parallel1)/qreal(divisions/2.0));
194 indexRatio *= 1-abs(qreal(rhomb.parallel2)/qreal(divisions/2.0));
195
196 if (colorRatio>=0) {
197 gradientPos *= 1-(shapeRatio*colorRatio);
198 } else {
199 gradientPos *= 1-((1-shapeRatio)*abs(colorRatio));
200 }
201 if (colorIntersect>=0) {
202 gradientPos *= 1-(intersectRatio*colorIntersect);
203 } else {
204 gradientPos *= 1-((1-intersectRatio)*abs(colorIntersect));
205 }
206 if (colorIndex>=0) {
207 gradientPos *= 1-(indexRatio*colorIndex);
208 } else {
209 gradientPos *= 1-((1-indexRatio)*abs(colorIndex));
210 }
211
212 grad->colorAt(c, gradientPos);
213 gc.setBackgroundColor(c);
214
215 gc.fillPainterPath(p, p.boundingRect().adjusted(-2, -2, 2, 2).toRect());
216
217 int connectorType = config->getInt("connectorType", Connector::None);
218
219 if (connectorType != Connector::None) {
220 gc.setBackgroundColor(config->getColor("connectorColor"));
221 qreal connectorWidth = qreal(config->getInt("connectorWidth", 1))*.5;
222 QPainterPath pConnect;
223 qreal lower = connectorWidth/scale;
224
225 if (connectorType == Connector::Cross) {
226 QPointF cl = QLineF(shape.at(0), shape.at(1)).pointAt(0.5-lower);
227 pConnect.moveTo(cl);
228 cl = QLineF(shape.at(0), shape.at(1)).pointAt(0.5+lower);
229 pConnect.lineTo(cl);
230 cl = QLineF(shape.at(2), shape.at(3)).pointAt(0.5-lower);
231 pConnect.lineTo(cl);
232 cl = QLineF(shape.at(2), shape.at(3)).pointAt(0.5+lower);
233 pConnect.lineTo(cl);
234 pConnect.closeSubpath();
235
236 cl = QLineF(shape.at(1), shape.at(2)).pointAt(0.5-lower);
237 pConnect.moveTo(cl);
238 cl = QLineF(shape.at(1), shape.at(2)).pointAt(0.5+lower);
239 pConnect.lineTo(cl);
240 cl = QLineF(shape.at(3), shape.at(0)).pointAt(0.5-lower);
241 pConnect.lineTo(cl);
242 cl = QLineF(shape.at(3), shape.at(0)).pointAt(0.5+lower);
243 pConnect.lineTo(cl);
244 pConnect.closeSubpath();
245
246 } else if (connectorType == Connector::CornerDot) {
247 QPointF cW(connectorWidth, connectorWidth);
248
249 QRectF dot (shape.at(0)-cW, shape.at(0)+cW);
250 pConnect.addEllipse(dot);
251 dot = QRectF(shape.at(1)-cW, shape.at(1)+cW);
252 pConnect.addEllipse(dot);
253 dot = QRectF(shape.at(2)-cW, shape.at(2)+cW);
254 pConnect.addEllipse(dot);
255 dot = QRectF(shape.at(3)-cW, shape.at(3)+cW);
256 pConnect.addEllipse(dot);
257 pConnect = pConnect.intersected(p);
258
259 } else if (connectorType == Connector::CenterDot) {
260
261 QRectF dot (center-QPointF(connectorWidth, connectorWidth), center+QPointF(connectorWidth, connectorWidth));
262 pConnect.addEllipse(dot);
263
264 } else {
265 for (int i=1; i<shape.size(); i++) {
266 QPainterPath pAngle;
267 QPointF curPoint = shape.at(i);
268 QLineF l1(curPoint, shape.at(i-1));
269 QPointF np;
270 if (i==4) {
271 np = shape.at(1);
272 } else {
273 np = shape.at(i+1);
274 }
275 QLineF l2(curPoint, np);
276 qreal angleDiff = abs(fmod(abs(l1.angle()-l2.angle())+180, 360)-180);
277
278 if (round(angleDiff) == 90) {
279 continue;
280 }
281 if (angleDiff > 90 && connectorType == Connector::Acute) {
282 continue;
283 }
284 if (angleDiff < 90 && connectorType == Connector::Obtuse) {
285 continue;
286 }
287
288 qreal length = (l1.length()*0.5)-connectorWidth;
289 QRectF sweep(curPoint-QPointF(length, length), curPoint+QPointF(length, length));
290 length = (l1.length()*0.5)+connectorWidth;
291 QRectF sweep2(curPoint-QPointF(length, length), curPoint+QPointF(length, length));
292
293 pAngle.moveTo(shape.at(i));
294 pAngle.addEllipse(sweep2);
295 pAngle.addEllipse(sweep);
296 pAngle = pAngle.intersected(p);
297 pAngle.closeSubpath();
298 pConnect.addPath(pAngle);
299 }
300 pConnect.closeSubpath();
301
302 }
303 pConnect.setFillRule(Qt::WindingFill);
304 gc.fillPainterPath(pConnect);
305
306 }
307
308 progress.step();
309 }
310 }
311
312 gc.end();
313 }
314}
qreal length(const QPointF &vec)
Definition Ellipse.cc:82
const Params2D p
QList< KisMultiGridRhomb > generateRhombs(int lines, int divisions, qreal offset) const
@ FillStyleBackgroundColor
bool isNull() const
void setOpacity(quint8 alpha)
Definition KoColor.cpp:333
static KoStopGradient fromXML(const QDomElement &elt)
fromXML convert a gradient from xml.
QList< KoGradientStop > stops() const
#define bounds(x, a, b)
#define M_PI
Definition kis_global.h:111
Point abs(const Point &pt)

References Acute, bounds, CenterDot, CornerDot, Cross, KisPainter::end(), KisPainter::fill(), KisPainter::fillPainterPath(), KisPainter::FillStyleBackgroundColor, KoStopGradient::fromQGradient(), KoStopGradient::fromXML(), generateRhombs(), KisSharedPtr< T >::isNull(), length(), KisMultiGridRhomb::line1, KisMultiGridRhomb::line2, M_PI, None, Obtuse, p, KisProcessingInformation::paintDevice(), KisMultiGridRhomb::parallel1, KisMultiGridRhomb::parallel2, KisConstProcessingInformation::selection, KisPainter::setBackgroundColor(), KisPainter::setChannelFlags(), KisPainter::setFillStyle(), KoColor::setOpacity(), KisPainter::setOpacityToUnit(), KisPainter::setSelection(), KisPainter::setStrokeStyle(), KisMultiGridRhomb::shape, KisProgressUpdateHelper::step(), KoStopGradient::stops(), and KisPainter::StrokeStyleBrush.

◆ generate() [3/3]

virtual void KisGenerator::generate ( KisProcessingInformation dst,
const QSize & size,
const KisFilterConfigurationSP config,
KoUpdater * progressUpdater ) const
virtual

Override this function with the implementation of your generator.

Parameters
dstthe destination paint device
sizethe size of the area that is to be filled
configthe parameters of the filter
progressUpdaterthe progress updater

Implements KisGenerator.

◆ generateRhombs()

QList< KisMultiGridRhomb > KisMultigridPatternGenerator::generateRhombs ( int lines,
int divisions,
qreal offset ) const
private

Definition at line 316 of file multigridpatterngenerator.cpp.

317{
319 QList<QLineF> parallelLines;
320 QList<qreal> angles;
321
322 int halfLines = divisions;
323 int totalLines = (halfLines*2) +1;
324
325 //setup our imaginary lines...
326 int dimensions = lines;
327 for (int i = 0; i< dimensions; i++) {
328 qreal angle = 2*(M_PI/lines)*i;
329 angles.append(angle);
330 }
331
332
333 for (int i = 0; i <angles.size(); i++ ) {
334 qreal angle1 = angles.at(i);
335 QPointF p1(totalLines*cos(angle1), -totalLines*sin(angle1));
336 QPointF p2 = -p1;
337
338
339 for (int parallel1 = 0; parallel1 < totalLines; parallel1++) {
340 int index1 = halfLines-parallel1;
341
342 QPointF offset1((index1+offset)*sin(angle1), (index1+offset)*cos(angle1));
343 QLineF l1(p1, p2);
344 l1.translate(offset1);
345
346 for (int k = i+1; k <angles.size(); k++ ) {
347 qreal angle2 = angles.at(k);
348 QPointF p3(totalLines*cos(angle2), -totalLines*sin(angle2));
349 QPointF p4 = -p3;
350
351
352 for (int parallel2 = 0; parallel2 < totalLines; parallel2++) {
353 int index2 = halfLines-parallel2;
354
355 QPointF offset2((index2+offset)*sin(angle2), (index2+offset)*cos(angle2));
356 QLineF l2(p3, p4);
357 l2.translate(offset2);
358
359
360 QPointF intersect;
361 if (l1.intersects(l2, &intersect) == QLineF::BoundedIntersection) {
362
363 QList<int> indices = getIndicesFromPoint(intersect, angles, offset );
364
365 QPolygonF shape;
366 indices[i] = index1+1;
367 indices[k] = index2+1;
368 shape << getVertice(indices, angles);
369 indices[i] = index1;
370 indices[k] = index2+1;
371 shape << getVertice(indices, angles);
372 indices[i] = index1;
373 indices[k] = index2;
374 shape << getVertice(indices, angles);
375 indices[i] = index1+1;
376 indices[k] = index2;
377 shape << getVertice(indices, angles);
378 indices[i] = index1+1;
379 indices[k] = index2+1;
380 shape << getVertice(indices, angles);
381
382 KisMultiGridRhomb rhomb;
383 rhomb.shape = shape;
384 rhomb.parallel1 = index1;
385 rhomb.parallel2 = index2;
386 rhomb.line1 = i;
387 rhomb.line2 = k;
388
389 rhombs.append(rhomb);
390 }
391
392 }
393 }
394 }
395 }
396
397
398 return rhombs;
399}
QPointF p2
QPointF p3
QPointF p1
QPointF getVertice(QList< int > indices, QList< qreal > angles) const
QList< int > getIndicesFromPoint(QPointF point, QList< qreal > angles, qreal offset) const

References getIndicesFromPoint(), getVertice(), KisMultiGridRhomb::line1, KisMultiGridRhomb::line2, M_PI, p1, p2, p3, KisMultiGridRhomb::parallel1, KisMultiGridRhomb::parallel2, and KisMultiGridRhomb::shape.

◆ getIndicesFromPoint()

QList< int > KisMultigridPatternGenerator::getIndicesFromPoint ( QPointF point,
QList< qreal > angles,
qreal offset ) const
private

Definition at line 401 of file multigridpatterngenerator.cpp.

402{
403 QList<int> indices;
404
405 for (int a=0; a< angles.size(); a++) {
406
407 QPointF p = point;
408
409 qreal index = p.x() * sin(angles.at(a)) + (p.y()) * cos(angles.at(a));
410 indices.append(floor(index-offset+1));
411 }
412 return indices;
413}

References p.

◆ getVertice()

QPointF KisMultigridPatternGenerator::getVertice ( QList< int > indices,
QList< qreal > angles ) const
private

Projects the 5d vertice to a point.

Definition at line 415 of file multigridpatterngenerator.cpp.

416{
417 if (indices.isEmpty() || angles.isEmpty()) {
418 qDebug() << "error";
419 return QPointF();
420 }
421 qreal x = 0;
422 qreal y = 0;
423
424 for (int i=0; i<indices.size(); i++) {
425 x += indices.at(i)*cos(angles.at(i));
426 y += indices.at(i)*sin(angles.at(i));
427 }
428
429 return QPointF(x, y);
430}

◆ id()

static KoID KisMultigridPatternGenerator::id ( )
inlinestatic

Definition at line 68 of file multigridpatterngenerator.h.

68 {
69 return KoID("multigrid", i18n("Multigrid"));
70 }

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