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 27 of file kis_experiment_paintop.cpp.

29{
30 Q_UNUSED(image);
31 Q_UNUSED(node);
32
33 m_firstRun = true;
34
35 m_experimentOption.read(settings.data());
36
38 m_displaceCoeff = (m_experimentOption.displacement * 0.01 * 14) + 1; // 1..15 [7 default according alchemy]
39
41 m_speedMultiplier = (m_experimentOption.speed * 0.01 * 35); // 0..35 [15 default according alchemy]
44
48
49 //Sets the brush to pattern or foregroundColor
52 } else {
54 }
55
56 // Mirror options set with appropriate color, pattern, and fillStyle
57 if (m_useMirroring) {
64
65 }
66 else {
68 }
69}
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 71 of file kis_experiment_paintop.cpp.

72{
73 delete m_originalPainter;
74}

References m_originalPainter.

Member Function Documentation

◆ applyDisplace()

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

Definition at line 302 of file kis_experiment_paintop.cpp.

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

296{
297 QPointF diff = p1 - p2;
298 qreal realLength = sqrt(diff.x() * diff.x() + diff.y() * diff.y());
299 return realLength > 0.5 ? p1 + diff * distance / realLength : p1;
300}
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 251 of file kis_experiment_paintop.cpp.

252{
253 return updateSpacingImpl(info);
254}
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 122 of file kis_experiment_paintop.cpp.

123{
124 Q_UNUSED(currentDistance);
125 if (!painter()) return;
126
127 if (m_firstRun) {
128 m_firstRun = false;
129
130 m_path.moveTo(pi1.pos());
131 m_path.lineTo(pi2.pos());
132
133 m_center = pi1.pos();
134
136 m_lastPaintTime = 0;
137
140
143
144 }
145 else {
146
147 const QPointF pos1 = pi1.pos();
148 QPointF pos2 = pi2.pos();
149
150 if (m_speedEnabled) {
151 pos2 = speedCorrectedPosition(pi1, pi2);
152 }
153
154 int length = (pos2 - pos1).manhattanLength();
156
157 if (m_smoothingEnabled) {
159
161 QPointF pt = (m_savedSmoothingPoint + pos2) * 0.5;
162
163 // for updates approximate curve with two lines
164 m_savedPoints << m_path.currentPosition();
167 m_savedPoints << pt;
168
169 m_path.quadTo(m_savedSmoothingPoint, pt);
171
173 }
174 }
175 else {
176 m_path.lineTo(pos2);
177 m_savedPoints << pos1;
178 m_savedPoints << pos2;
179 }
180
181 if (m_displaceEnabled) {
182 if (m_path.elementCount() % 16 == 0) {
183 QRectF bounds = m_path.boundingRect();
185 bounds |= m_path.boundingRect();
186
187 qreal threshold = simplifyThreshold(bounds);
189 }
190 else {
192 }
193 }
194
198 const int timeThreshold = 40;
199 const int elapsedTime = pi2.currentTime() - m_lastPaintTime;
200
201 QRect pathBounds = m_path.boundingRect().toRect();
202 int distanceMetric = qMax(pathBounds.width(), pathBounds.height());
203
204 if (elapsedTime > timeThreshold ||
206 m_savedUpdateDistance > distanceMetric / 8)) {
207
208 if (m_displaceEnabled) {
217 const int pathSizeThreshold = 128;
218
219 KisRegion changedRegion;
220 if (distanceMetric < pathSizeThreshold) {
221
222 QRectF changedRect = m_path.boundingRect().toRect() |
223 m_lastPaintedPath.boundingRect().toRect();
224 changedRect.adjust(-1, -1, 1, 1);
225
226 changedRegion = changedRect.toRect();
227 }
228 else {
229 QPainterPath diff1 = m_path - m_lastPaintedPath;
230 QPainterPath diff2 = m_lastPaintedPath - m_path;
231
232 changedRegion = KritaUtils::splitPath(diff1 | diff2);
233 }
234
235 paintRegion(changedRegion);
237 }
238 else if (!m_savedPoints.isEmpty()) {
240 paintRegion(changedRegion);
241 }
242
243 m_savedPoints.clear();
246 }
247 }
248}
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)
trySimplifyPath Tries to simplify a QPainterPath
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 KisAlgebra2D::trySimplifyPath().

◆ paintRegion()

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

Definition at line 76 of file kis_experiment_paintop.cpp.

77{
78 if (m_windingFill) {
79 m_path.setFillRule(Qt::WindingFill);
80 }
81
82 if (m_useMirroring) {
84
85 Q_FOREACH (const QRect & rect, changedRegion.rects()) {
88
89 }
90 }
91 else {
92 //Sets options when mirror is not selected
94
97
98 Q_FOREACH (const QRect & rect, changedRegion.rects()) {
100 }
101 }
102}
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 289 of file kis_experiment_paintop.cpp.

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

References bounds.

◆ speedCorrectedPosition()

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

Definition at line 104 of file kis_experiment_paintop.cpp.

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

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 256 of file kis_experiment_paintop.cpp.

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

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: