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

#include <kis_experiment_paintop.h>

+ Inheritance diagram for KisExperimentPaintOp:

Public Member Functions

 KisExperimentPaintOp (const KisPaintOpSettingsSP settings, KisPainter *painter, KisNodeSP node, KisImageSP image)
 
void paintLine (const KisPaintInformation &pi1, const KisPaintInformation &pi2, KisDistanceInformation *currentDistance) override
 
 ~KisExperimentPaintOp () override
 
- Public Member Functions inherited from KisPaintOp
virtual bool canPaint () const
 
virtual std::pair< int, bool > doAsynchronousUpdate (QVector< KisRunnableStrokeJobData * > &jobs)
 
 KisPaintOp (KisPainter *painter)
 
void paintAt (const KisPaintInformation &info, KisDistanceInformation *currentDistance)
 
virtual void paintBezierCurve (const KisPaintInformation &pi1, const QPointF &control1, const QPointF &control2, const KisPaintInformation &pi2, KisDistanceInformation *currentDistance)
 
 Private (KisPaintOp *_q)
 
void updateSpacing (const KisPaintInformation &info, KisDistanceInformation &currentDistance) const
 
void updateTiming (const KisPaintInformation &info, KisDistanceInformation &currentDistance) const
 
virtual ~KisPaintOp ()
 
- Public Member Functions inherited from Private
 Private (KisCanvas2 *c)
 
- Public Member Functions inherited from KisShared
bool deref ()
 
bool ref ()
 
int refCount ()
 
QAtomicInt * sharedWeakReference ()
 

Protected Member Functions

KisSpacingInformation paintAt (const KisPaintInformation &info) override
 
KisSpacingInformation updateSpacingImpl (const KisPaintInformation &info) const override
 
- Protected Member Functions inherited from KisPaintOp
KisFixedPaintDeviceSP cachedDab ()
 
KisFixedPaintDeviceSP cachedDab (const KoColorSpace *cs)
 
KisPainterpainter () const
 
KisPaintDeviceSP source () const
 
virtual KisTimingInformation updateTimingImpl (const KisPaintInformation &info) const
 
- Protected Member Functions inherited from KisShared
 KisShared ()
 
 ~KisShared ()
 

Private Member Functions

void paintRegion (const KisRegion &changedRegion)
 
QPointF speedCorrectedPosition (const KisPaintInformation &pi1, const KisPaintInformation &pi2)
 

Static Private Member Functions

static QPainterPath applyDisplace (const QPainterPath &path, int speed)
 
static QPointF getAngle (const QPointF &p1, const QPointF &p2, qreal distance)
 
static qreal simplifyThreshold (const QRectF &bounds)
 

Private Attributes

QPointF m_center
 
int m_displaceCoeff {0}
 
bool m_displaceEnabled {false}
 
KisExperimentOpOptionData m_experimentOption
 
KisPainter::FillStyle m_fillStyle {KisPainter::FillStyleNone}
 
bool m_firstRun {true}
 
bool m_hardEdge {false}
 
QPainterPath m_lastPaintedPath
 
int m_lastPaintTime {0}
 
KisPaintDeviceSP m_originalDevice
 
KisPainterm_originalPainter {0}
 
QPainterPath m_path
 
QVector< QPointF > m_savedPoints
 
int m_savedSmoothingDistance {1}
 
QPointF m_savedSmoothingPoint
 
qreal m_savedSpeedCoeff {1.0}
 
QPointF m_savedSpeedPoint
 
int m_savedUpdateDistance {1}
 
bool m_smoothingEnabled {false}
 
int m_smoothingThreshold {1}
 
bool m_speedEnabled {false}
 
int m_speedMultiplier {1}
 
bool m_useMirroring {false}
 
bool m_windingFill {false}
 

Additional Inherited Members

- Static Public Member Functions inherited from KisPaintOp
static void splitCoordinate (qreal coordinate, qint32 *whole, qreal *fraction)
 
- Public Attributes inherited from KisPaintOp
KisFixedPaintDeviceSP dab
 
bool fanCornersEnabled {false}
 
qreal fanCornersStep {1.0}
 
KisPainterpainter {nullptr}
 
KisPaintOpq {nullptr}
 
- Public Attributes inherited from Private
KisCanvas2canvas
 
int displayedFrame
 
int intendedFrame
 

Detailed Description

Definition at line 25 of file kis_experiment_paintop.h.

Constructor & Destructor Documentation

◆ KisExperimentPaintOp()

KisExperimentPaintOp::KisExperimentPaintOp ( const KisPaintOpSettingsSP settings,
KisPainter * painter,
KisNodeSP node,
KisImageSP image )

Definition at line 26 of file kis_experiment_paintop.cpp.

28{
29 Q_UNUSED(image);
30 Q_UNUSED(node);
31
32 m_firstRun = true;
33
34 m_experimentOption.read(settings.data());
35
37 m_displaceCoeff = (m_experimentOption.displacement * 0.01 * 14) + 1; // 1..15 [7 default according alchemy]
38
40 m_speedMultiplier = (m_experimentOption.speed * 0.01 * 35); // 0..35 [15 default according alchemy]
43
47
48 //Sets the brush to pattern or foregroundColor
51 } else {
53 }
54
55 // Mirror options set with appropriate color, pattern, and fillStyle
56 if (m_useMirroring) {
63
64 }
65 else {
67 }
68}
const QString COMPOSITE_COPY
KisPaintDeviceSP m_originalDevice
KisPainter::FillStyle m_fillStyle
KisExperimentOpOptionData m_experimentOption
KisPaintDeviceSP createCompositionSourceDevice() const
@ FillStyleForegroundColor
bool hasMirroring() const
KoColor paintColor
void setFillStyle(FillStyle fillStyle)
Set the current style with which to fill.
void setPattern(const KoPatternSP pattern)
Set the current pattern.
void setPaintColor(const KoColor &color)
void setCompositeOpId(const KoCompositeOp *op)
KoPatternSP pattern
bool read(const KisPropertiesConfiguration *setting)
KisPainter * painter
KisPaintOp(KisPainter *painter)
KisPaintDeviceSP source() const

References COMPOSITE_COPY, KisPaintDevice::createCompositionSourceDevice(), KisSharedPtr< T >::data(), KisExperimentOpOptionData::displacement, KisPainter::FillStyleForegroundColor, KisPainter::FillStylePattern, KisExperimentOpOptionData::fillType, KisExperimentOpOptionData::hardEdge, KisPainter::hasMirroring(), KisExperimentOpOptionData::isDisplacementEnabled, KisExperimentOpOptionData::isSmoothingEnabled, KisExperimentOpOptionData::isSpeedEnabled, m_displaceCoeff, m_displaceEnabled, m_experimentOption, m_fillStyle, m_firstRun, m_hardEdge, m_originalDevice, m_originalPainter, m_smoothingEnabled, m_smoothingThreshold, m_speedEnabled, m_speedMultiplier, m_useMirroring, m_windingFill, KisPainter::paintColor, KisPaintOp::painter, KisPainter::pattern, Pattern, KisExperimentOpOptionData::read(), KisPainter::setCompositeOpId(), KisPainter::setFillStyle(), KisPainter::setPaintColor(), KisPainter::setPattern(), KisExperimentOpOptionData::smoothing, KisPaintOp::source(), KisExperimentOpOptionData::speed, and KisExperimentOpOptionData::windingFill.

◆ ~KisExperimentPaintOp()

KisExperimentPaintOp::~KisExperimentPaintOp ( )
override

Definition at line 70 of file kis_experiment_paintop.cpp.

71{
72 delete m_originalPainter;
73}

References m_originalPainter.

Member Function Documentation

◆ applyDisplace()

QPainterPath KisExperimentPaintOp::applyDisplace ( const QPainterPath & path,
int speed )
staticprivate

Definition at line 301 of file kis_experiment_paintop.cpp.

302{
303 QPointF lastPoint = path.currentPosition();
304
305 QPainterPath newPath;
306 int count = path.elementCount();
307 int curveElementCounter = 0;
308 QPointF ctrl1;
309 QPointF ctrl2;
310 QPointF endPoint;
311 for (int i = 0; i < count; i++) {
312 QPainterPath::Element e = path.elementAt(i);
313 switch (e.type) {
314 case QPainterPath::MoveToElement: {
315 newPath.moveTo(getAngle(QPointF(e.x, e.y), lastPoint, speed));
316 break;
317 }
318 case QPainterPath::LineToElement: {
319 newPath.lineTo(getAngle(QPointF(e.x, e.y), lastPoint, speed));
320 break;
321 }
322 case QPainterPath::CurveToElement: {
323 curveElementCounter = 0;
324 endPoint = getAngle(QPointF(e.x, e.y), lastPoint, speed);
325 break;
326 }
327 case QPainterPath::CurveToDataElement: {
328 curveElementCounter++;
329
330 if (curveElementCounter == 1) {
331 ctrl1 = getAngle(QPointF(e.x, e.y), lastPoint, speed);
332 }
333 else if (curveElementCounter == 2) {
334 ctrl2 = getAngle(QPointF(e.x, e.y), lastPoint, speed);
335 newPath.cubicTo(ctrl1, ctrl2, endPoint);
336 }
337 break;
338 }
339 }
340
341 }// for
342
343 return newPath;
344}
static QPointF getAngle(const QPointF &p1, const QPointF &p2, qreal distance)

References getAngle().

◆ getAngle()

QPointF KisExperimentPaintOp::getAngle ( const QPointF & p1,
const QPointF & p2,
qreal distance )
staticprivate

Definition at line 294 of file kis_experiment_paintop.cpp.

295{
296 QPointF diff = p1 - p2;
297 qreal realLength = sqrt(diff.x() * diff.x() + diff.y() * diff.y());
298 return realLength > 0.5 ? p1 + diff * distance / realLength : p1;
299}
QPointF p2
QPointF p1
qreal distance(const QPointF &p1, const QPointF &p2)

References distance(), p1, and p2.

◆ paintAt()

KisSpacingInformation KisExperimentPaintOp::paintAt ( const KisPaintInformation & info)
overrideprotectedvirtual

The implementation of painting of a dab and updating spacing. This does NOT need to update the timing information.

Implements KisPaintOp.

Definition at line 250 of file kis_experiment_paintop.cpp.

251{
252 return updateSpacingImpl(info);
253}
KisSpacingInformation updateSpacingImpl(const KisPaintInformation &info) const override

References updateSpacingImpl().

◆ paintLine()

void KisExperimentPaintOp::paintLine ( const KisPaintInformation & pi1,
const KisPaintInformation & pi2,
KisDistanceInformation * currentDistance )
overridevirtual

Draw a line between pos1 and pos2 using the currently set brush and color. If savedDist is less than zero, the brush is painted at pos1 before being painted along the line using the spacing setting.

Returns
the drag distance, that is the remains of the distance between p1 and p2 not covered because the currently set brush has a spacing greater than that distance.

Refresh rate at least 25fps

Rendering the path with diff'ed rects is up to two times more efficient for really huge shapes (tested on 2000+ px shapes), however for smaller ones doing paths arithmetics eats too much time. That's why we choose the method on the base of the size of the shape.

Reimplemented from KisPaintOp.

Definition at line 121 of file kis_experiment_paintop.cpp.

122{
123 Q_UNUSED(currentDistance);
124 if (!painter()) return;
125
126 if (m_firstRun) {
127 m_firstRun = false;
128
129 m_path.moveTo(pi1.pos());
130 m_path.lineTo(pi2.pos());
131
132 m_center = pi1.pos();
133
135 m_lastPaintTime = 0;
136
139
142
143 }
144 else {
145
146 const QPointF pos1 = pi1.pos();
147 QPointF pos2 = pi2.pos();
148
149 if (m_speedEnabled) {
150 pos2 = speedCorrectedPosition(pi1, pi2);
151 }
152
153 int length = (pos2 - pos1).manhattanLength();
155
156 if (m_smoothingEnabled) {
158
160 QPointF pt = (m_savedSmoothingPoint + pos2) * 0.5;
161
162 // for updates approximate curve with two lines
163 m_savedPoints << m_path.currentPosition();
166 m_savedPoints << pt;
167
168 m_path.quadTo(m_savedSmoothingPoint, pt);
170
172 }
173 }
174 else {
175 m_path.lineTo(pos2);
176 m_savedPoints << pos1;
177 m_savedPoints << pos2;
178 }
179
180 if (m_displaceEnabled) {
181 if (m_path.elementCount() % 16 == 0) {
182 QRectF bounds = m_path.boundingRect();
184 bounds |= m_path.boundingRect();
185
186 qreal threshold = simplifyThreshold(bounds);
188 }
189 else {
191 }
192 }
193
197 const int timeThreshold = 40;
198 const int elapsedTime = pi2.currentTime() - m_lastPaintTime;
199
200 QRect pathBounds = m_path.boundingRect().toRect();
201 int distanceMetric = qMax(pathBounds.width(), pathBounds.height());
202
203 if (elapsedTime > timeThreshold ||
205 m_savedUpdateDistance > distanceMetric / 8)) {
206
207 if (m_displaceEnabled) {
216 const int pathSizeThreshold = 128;
217
218 KisRegion changedRegion;
219 if (distanceMetric < pathSizeThreshold) {
220
221 QRectF changedRect = m_path.boundingRect().toRect() |
222 m_lastPaintedPath.boundingRect().toRect();
223 changedRect.adjust(-1, -1, 1, 1);
224
225 changedRegion = changedRect.toRect();
226 }
227 else {
228 QPainterPath diff1 = m_path - m_lastPaintedPath;
229 QPainterPath diff2 = m_lastPaintedPath - m_path;
230
231 changedRegion = KritaUtils::splitPath(diff1 | diff2);
232 }
233
234 paintRegion(changedRegion);
236 }
237 else if (!m_savedPoints.isEmpty()) {
239 paintRegion(changedRegion);
240 }
241
242 m_savedPoints.clear();
245 }
246 }
247}
qreal length(const QPointF &vec)
Definition Ellipse.cc:82
QVector< QPointF > m_savedPoints
QPointF speedCorrectedPosition(const KisPaintInformation &pi1, const KisPaintInformation &pi2)
static qreal simplifyThreshold(const QRectF &bounds)
void paintRegion(const KisRegion &changedRegion)
static QPainterPath applyDisplace(const QPainterPath &path, int speed)
const QPointF & pos() const
qreal currentTime() const
Number of ms since the beginning of the stroke.
QRect boundingRect() const
#define bounds(x, a, b)
QPainterPath trySimplifyPath(const QPainterPath &path, qreal lengthThreshold)
KisRegion splitPath(const QPainterPath &path)
KisRegion splitTriangles(const QPointF &center, const QVector< QPointF > &points)

References applyDisplace(), KisRegion::boundingRect(), bounds, KisPaintInformation::currentTime(), length(), m_center, m_displaceCoeff, m_displaceEnabled, m_firstRun, m_lastPaintedPath, m_lastPaintTime, m_path, m_savedPoints, m_savedSmoothingDistance, m_savedSmoothingPoint, m_savedSpeedCoeff, m_savedSpeedPoint, m_savedUpdateDistance, m_smoothingEnabled, m_smoothingThreshold, m_speedEnabled, KisPaintOp::painter, paintRegion(), KisPaintInformation::pos(), simplifyThreshold(), speedCorrectedPosition(), KritaUtils::splitPath(), KritaUtils::splitTriangles(), and KritaUtils::trySimplifyPath().

◆ paintRegion()

void KisExperimentPaintOp::paintRegion ( const KisRegion & changedRegion)
private

Definition at line 75 of file kis_experiment_paintop.cpp.

76{
77 if (m_windingFill) {
78 m_path.setFillRule(Qt::WindingFill);
79 }
80
81 if (m_useMirroring) {
83
84 Q_FOREACH (const QRect & rect, changedRegion.rects()) {
87
88 }
89 }
90 else {
91 //Sets options when mirror is not selected
93
96
97 Q_FOREACH (const QRect & rect, changedRegion.rects()) {
99 }
100 }
101}
void renderDabWithMirroringNonIncremental(QRect rc, KisPaintDeviceSP dab)
void fillPainterPath(const QPainterPath &path)
void setAntiAliasPolygonFill(bool antiAliasPolygonFill)
Set whether a polygon's filled area should be anti-aliased or not. The default is true.
QVector< QRect > rects() const

References COMPOSITE_COPY, KisPainter::fillPainterPath(), m_fillStyle, m_hardEdge, m_originalDevice, m_originalPainter, m_path, m_useMirroring, m_windingFill, KisPaintOp::painter, KisRegion::rects(), KisPainter::renderDabWithMirroringNonIncremental(), KisPainter::setAntiAliasPolygonFill(), KisPainter::setCompositeOpId(), and KisPainter::setFillStyle().

◆ simplifyThreshold()

qreal KisExperimentPaintOp::simplifyThreshold ( const QRectF & bounds)
staticprivate

Definition at line 288 of file kis_experiment_paintop.cpp.

289{
290 qreal maxDimension = qMax(bounds.width(), bounds.height());
291 return qMax(0.01 * maxDimension, 1.0);
292}
auto maxDimension(Size size) -> decltype(size.width())

References bounds.

◆ speedCorrectedPosition()

QPointF KisExperimentPaintOp::speedCorrectedPosition ( const KisPaintInformation & pi1,
const KisPaintInformation & pi2 )
private

Definition at line 103 of file kis_experiment_paintop.cpp.

105{
106 const qreal fadeFactor = 0.6;
107
108 QPointF diff = pi2.pos() - pi1.pos();
109 qreal realLength = sqrt(diff.x() * diff.x() + diff.y() * diff.y());
110
111 if (realLength < 0.1) return pi2.pos();
112
113 qreal coeff = 0.5 * realLength * m_speedMultiplier;
114 m_savedSpeedCoeff = fadeFactor * m_savedSpeedCoeff + (1 - fadeFactor) * coeff;
115 QPointF newPoint = pi1.pos() + diff * m_savedSpeedCoeff / realLength;
116 m_savedSpeedPoint = fadeFactor * m_savedSpeedPoint + (1 - fadeFactor) * newPoint;
117
118 return m_savedSpeedPoint;
119}

References m_savedSpeedCoeff, m_savedSpeedPoint, m_speedMultiplier, and KisPaintInformation::pos().

◆ updateSpacingImpl()

KisSpacingInformation KisExperimentPaintOp::updateSpacingImpl ( const KisPaintInformation & info) const
overrideprotectedvirtual

Implementation of a spacing update

Implements KisPaintOp.

Definition at line 255 of file kis_experiment_paintop.cpp.

256{
257 Q_UNUSED(info);
258 return KisSpacingInformation(1.0);
259}

Member Data Documentation

◆ m_center

QPointF KisExperimentPaintOp::m_center
private

Definition at line 73 of file kis_experiment_paintop.h.

◆ m_displaceCoeff

int KisExperimentPaintOp::m_displaceCoeff {0}
private

Definition at line 52 of file kis_experiment_paintop.h.

52{0};

◆ m_displaceEnabled

bool KisExperimentPaintOp::m_displaceEnabled {false}
private

Definition at line 51 of file kis_experiment_paintop.h.

51{false};

◆ m_experimentOption

KisExperimentOpOptionData KisExperimentPaintOp::m_experimentOption
private

Definition at line 76 of file kis_experiment_paintop.h.

◆ m_fillStyle

KisPainter::FillStyle KisExperimentPaintOp::m_fillStyle {KisPainter::FillStyleNone}
private

Definition at line 82 of file kis_experiment_paintop.h.

◆ m_firstRun

bool KisExperimentPaintOp::m_firstRun {true}
private

Definition at line 72 of file kis_experiment_paintop.h.

72{true};

◆ m_hardEdge

bool KisExperimentPaintOp::m_hardEdge {false}
private

Definition at line 56 of file kis_experiment_paintop.h.

56{false};

◆ m_lastPaintedPath

QPainterPath KisExperimentPaintOp::m_lastPaintedPath
private

Definition at line 53 of file kis_experiment_paintop.h.

◆ m_lastPaintTime

int KisExperimentPaintOp::m_lastPaintTime {0}
private

Definition at line 70 of file kis_experiment_paintop.h.

70{0};

◆ m_originalDevice

KisPaintDeviceSP KisExperimentPaintOp::m_originalDevice
private

Definition at line 80 of file kis_experiment_paintop.h.

◆ m_originalPainter

KisPainter* KisExperimentPaintOp::m_originalPainter {0}
private

Definition at line 79 of file kis_experiment_paintop.h.

79{0};

◆ m_path

QPainterPath KisExperimentPaintOp::m_path
private

Definition at line 75 of file kis_experiment_paintop.h.

◆ m_savedPoints

QVector<QPointF> KisExperimentPaintOp::m_savedPoints
private

Definition at line 69 of file kis_experiment_paintop.h.

◆ m_savedSmoothingDistance

int KisExperimentPaintOp::m_savedSmoothingDistance {1}
private

Definition at line 66 of file kis_experiment_paintop.h.

66{1};

◆ m_savedSmoothingPoint

QPointF KisExperimentPaintOp::m_savedSmoothingPoint
private

Definition at line 65 of file kis_experiment_paintop.h.

◆ m_savedSpeedCoeff

qreal KisExperimentPaintOp::m_savedSpeedCoeff {1.0}
private

Definition at line 60 of file kis_experiment_paintop.h.

60{1.0};

◆ m_savedSpeedPoint

QPointF KisExperimentPaintOp::m_savedSpeedPoint
private

Definition at line 61 of file kis_experiment_paintop.h.

◆ m_savedUpdateDistance

int KisExperimentPaintOp::m_savedUpdateDistance {1}
private

Definition at line 68 of file kis_experiment_paintop.h.

68{1};

◆ m_smoothingEnabled

bool KisExperimentPaintOp::m_smoothingEnabled {false}
private

Definition at line 63 of file kis_experiment_paintop.h.

63{false};

◆ m_smoothingThreshold

int KisExperimentPaintOp::m_smoothingThreshold {1}
private

Definition at line 64 of file kis_experiment_paintop.h.

64{1};

◆ m_speedEnabled

bool KisExperimentPaintOp::m_speedEnabled {false}
private

Definition at line 58 of file kis_experiment_paintop.h.

58{false};

◆ m_speedMultiplier

int KisExperimentPaintOp::m_speedMultiplier {1}
private

Definition at line 59 of file kis_experiment_paintop.h.

59{1};

◆ m_useMirroring

bool KisExperimentPaintOp::m_useMirroring {false}
private

Definition at line 78 of file kis_experiment_paintop.h.

78{false};

◆ m_windingFill

bool KisExperimentPaintOp::m_windingFill {false}
private

Definition at line 55 of file kis_experiment_paintop.h.

55{false};

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