Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_deform_paintop.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2008-2010 Lukáš Tvrdý <lukast.dev@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
9
10#include <cmath>
11
12#include <QtGlobal>
13#include <QRect>
14
15#include <kis_image.h>
16#include <kis_debug.h>
17
18#include "kis_global.h"
19#include "kis_paint_device.h"
20#include "kis_painter.h"
21#include "kis_selection.h"
23#include "kis_lod_transform.h"
24
26
27#include "KisDeformOptionData.h"
31#include <KoCompositeOp.h>
32
33#ifdef Q_OS_WIN
34// quoting DRAND48(3) man-page:
35// These functions are declared obsolete by SVID 3,
36// which states that rand(3) should be used instead.
37#define drand48() (static_cast<double>(qrand()) / static_cast<double>(RAND_MAX))
38#endif
39
41 : KisPaintOp(painter)
42 , m_sizeOption(settings.data())
43 , m_opacityOption(settings.data(), node)
44 , m_rotationOption(settings.data())
45 , m_rateOption(settings.data())
46{
47 Q_UNUSED(image);
48 Q_UNUSED(node);
49 Q_ASSERT(settings);
50
51 m_brushSizeData.read(settings.data());
52 m_deformData.read(settings.data());
53 m_airbrushData.read(settings.data());
54
57
59
60 m_dev = source();
61
62 if ((m_brushSizeData.brushDiameter * 0.5) > 1) {
64 }
65 else {
66 m_ySpacing = m_xSpacing = 1.0;
67 }
69
70
71
72}
73
77
79{
82
83 KisFixedPaintDeviceSP dab = cachedDab(source()->compositionSourceColorSpace());
84
85 qint32 x;
86 qreal subPixelX;
87 qint32 y;
88 qreal subPixelY;
89
90 QPointF pt = info.pos();
94 }
95
96 qreal rotation = m_rotationOption.apply(info);
97
98 // Deform Brush is capable of working with zero scale,
99 // so no additional checks for 'zero'ness are needed
100 qreal scale = m_sizeOption.apply(info);
101
102
103 rotation += m_brushSizeData.brushRotation;
105
106 QPointF pos = pt - m_deformBrush.hotSpot(scale, rotation);
107
108 splitCoordinate(pos.x(), &x, &subPixelX);
109 splitCoordinate(pos.y(), &y, &subPixelY);
110
112 scale, rotation,
113 info.pos(),
114 subPixelX, subPixelY,
115 x, y
116 );
117
118 // this happens for the first dab of the move mode, we need more information for being able to move
119 if (!mask) {
120 return updateSpacingImpl(info);
121 }
122
124 painter()->bltFixedWithFixedSelection(x, y, dab, mask, mask->bounds().width() , mask->bounds().height());
125 painter()->renderMirrorMask(QRect(QPoint(x, y), QSize(mask->bounds().width() , mask->bounds().height())), dab, mask);
126
127 return updateSpacingImpl(info);
128}
129
131{
132 return KisPaintOpPluginUtils::effectiveSpacing(1.0, 1.0, true, 0.0, false, m_spacing, false,
133 1.0,
135 &m_airbrushData, nullptr, info);
136}
137
void initDeformAction()
KisFixedPaintDeviceSP paintMask(KisFixedPaintDeviceSP dab, KisPaintDeviceSP layer, KisRandomSourceSP randomSource, qreal scale, qreal rotation, QPointF pos, qreal subPixelX, qreal subPixelY, int dabX, int dabY)
void setSizeProperties(KisBrushSizeOptionData *properties)
void setProperties(KisDeformOptionData *properties)
QPointF hotSpot(qreal scale, qreal rotation)
KisRateOption m_rateOption
KisBrushSizeOptionData m_brushSizeData
KisPaintDeviceSP m_dev
KisDeformPaintOp(const KisPaintOpSettingsSP settings, KisPainter *painter, KisNodeSP node, KisImageSP image)
DeformBrush m_deformBrush
KisOpacityOption m_opacityOption
KisAirbrushOptionData m_airbrushData
KisTimingInformation updateTimingImpl(const KisPaintInformation &info) const override
KisDeformOptionData m_deformData
KisSpacingInformation paintAt(const KisPaintInformation &info) override
KisSpacingInformation updateSpacingImpl(const KisPaintInformation &info) const override
KisRotationOption m_rotationOption
KisSizeOption m_sizeOption
static qreal lodToScale(int levelOfDetail)
void apply(KisPainter *painter, const KisPaintInformation &info) const
KisRandomSourceSP randomSource() const
const QPointF & pos() const
void bltFixedWithFixedSelection(qint32 dstX, qint32 dstY, const KisFixedPaintDeviceSP srcDev, const KisFixedPaintDeviceSP selection, qint32 selX, qint32 selY, qint32 srcX, qint32 srcY, quint32 srcWidth, quint32 srcHeight)
void renderMirrorMask(QRect rc, KisFixedPaintDeviceSP dab)
qreal generateNormalized() const
qreal apply(const KisPaintInformation &info) const
qreal apply(const KisPaintInformation &info) const
KisSpacingInformation effectiveSpacing(qreal dabWidth, qreal dabHeight, bool isotropicSpacing, qreal rotation, bool axesFlipped, qreal spacingVal, bool autoSpacingActive, qreal autoSpacingCoeff, qreal lodScale, const KisAirbrushOptionData *airbrushOption, const KisSpacingOption *spacingOption, const KisPaintInformation &pi)
KisTimingInformation effectiveTiming(const KisAirbrushOptionData *airbrushOption, const KisRateOption *rateOption, const KisPaintInformation &pi)
bool read(const KisPropertiesConfiguration *setting)
bool read(const KisPropertiesConfiguration *setting)
bool read(const KisPropertiesConfiguration *setting)
KisPainter * painter
KisFixedPaintDeviceSP dab
KisPaintDeviceSP source() const
KisFixedPaintDeviceSP cachedDab()
static void splitCoordinate(qreal coordinate, qint32 *whole, qreal *fraction)