File indexing completed on 2024-06-16 04:17:19
0001 /* 0002 * SPDX-FileCopyrightText: 2008, 2010 Lukáš Tvrdý <lukast.dev@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef _DEFORM_BRUSH_H_ 0008 #define _DEFORM_BRUSH_H_ 0009 0010 #include <kis_paint_device.h> 0011 #include <brushengine/kis_paint_information.h> 0012 0013 #include "KisBrushSizeOptionData.h" 0014 #include "KisDeformOptionData.h" 0015 #include "kis_algebra_2d.h" 0016 0017 #include <time.h> 0018 0019 #if defined(_WIN32) || defined(_WIN64) 0020 #define srand48 srand 0021 inline double drand48() 0022 { 0023 return double(rand()) / RAND_MAX; 0024 } 0025 #endif 0026 0027 0028 class DeformBase 0029 { 0030 public: 0031 DeformBase() {} 0032 virtual ~DeformBase() {} 0033 virtual void transform(qreal * x, qreal * y, qreal distance, KisRandomSourceSP randomSource) { 0034 Q_UNUSED(x); 0035 Q_UNUSED(y); 0036 Q_UNUSED(distance); 0037 Q_UNUSED(randomSource); 0038 } 0039 }; 0040 0041 /// Inverse weighted inverse scaling - grow&shrink 0042 class DeformScale : public DeformBase 0043 { 0044 0045 public: 0046 void setFactor(qreal factor) { 0047 m_factor = factor; 0048 } 0049 qreal factor() { 0050 return m_factor; 0051 } 0052 void transform(qreal* x, qreal* y, qreal distance, KisRandomSourceSP randomSource) override { 0053 Q_UNUSED(randomSource); 0054 qreal scaleFactor = KisAlgebra2D::signPZ(m_factor) * (qAbs((1.0 - distance) * m_factor) + distance); 0055 *x = *x / scaleFactor; 0056 *y = *y / scaleFactor; 0057 } 0058 0059 private: 0060 qreal m_factor {0.0}; 0061 }; 0062 0063 /// Inverse weighted rotation - swirlCW&&swirlCWW 0064 class DeformRotation : public DeformBase 0065 { 0066 0067 public: 0068 void setAlpha(qreal alpha) { 0069 m_alpha = alpha; 0070 } 0071 void transform(qreal* maskX, qreal* maskY, qreal distance, KisRandomSourceSP randomSource) override { 0072 Q_UNUSED(randomSource); 0073 distance = 1.0 - distance; 0074 qreal rotX = cos(-m_alpha * distance) * (*maskX) - sin(-m_alpha * distance) * (*maskY); 0075 qreal rotY = sin(-m_alpha * distance) * (*maskX) + cos(-m_alpha * distance) * (*maskY); 0076 0077 *maskX = rotX; 0078 *maskY = rotY; 0079 } 0080 0081 private: 0082 qreal m_alpha {0.0}; 0083 }; 0084 0085 /// Inverse move 0086 class DeformMove : public DeformBase 0087 { 0088 public: 0089 void setFactor(qreal factor) { 0090 m_factor = factor; 0091 } 0092 void setDistance(qreal dx, qreal dy) { 0093 m_dx = dx; 0094 m_dy = dy; 0095 } 0096 void transform(qreal* maskX, qreal* maskY, qreal distance, KisRandomSourceSP randomSource) override { 0097 Q_UNUSED(randomSource); 0098 *maskX -= m_dx * m_factor * (1.0 - distance); 0099 *maskY -= m_dy * m_factor * (1.0 - distance); 0100 } 0101 0102 private: 0103 qreal m_dx {0.0}; 0104 qreal m_dy {0.0}; 0105 qreal m_factor {0.0}; 0106 }; 0107 0108 /// Inverse lens distortion 0109 class DeformLens : public DeformBase 0110 { 0111 public: 0112 void setLensFactor(qreal k1, qreal k2) { 0113 m_k1 = k1; 0114 m_k2 = k2; 0115 } 0116 void setMaxDistance(qreal maxX, qreal maxY) { 0117 m_maxX = maxX; 0118 m_maxY = maxY; 0119 } 0120 void setMode(bool out) { 0121 m_out = out; 0122 } 0123 0124 void transform(qreal* maskX, qreal* maskY, qreal distance, KisRandomSourceSP randomSource) override { 0125 Q_UNUSED(distance); 0126 Q_UNUSED(randomSource); 0127 //normalize 0128 qreal normX = *maskX / m_maxX; 0129 qreal normY = *maskY / m_maxY; 0130 0131 qreal radius_2 = normX * normX + normY * normY; 0132 qreal radius_4 = radius_2 * radius_2; 0133 0134 if (m_out) { 0135 *maskX = normX * (1.0 + m_k1 * radius_2 + m_k2 * radius_4); 0136 *maskY = normY * (1.0 + m_k1 * radius_2 + m_k2 * radius_4); 0137 } 0138 else { 0139 *maskX = normX / (1.0 + m_k1 * radius_2 + m_k2 * radius_4); 0140 *maskY = normY / (1.0 + m_k1 * radius_2 + m_k2 * radius_4); 0141 } 0142 0143 *maskX = m_maxX * (*maskX); 0144 *maskY = m_maxY * (*maskY); 0145 } 0146 0147 private: 0148 qreal m_k1 {0.0}, m_k2 {0.0}; 0149 qreal m_maxX {0.0}, m_maxY {0.0}; 0150 bool m_out {false}; 0151 }; 0152 0153 /// Randomly disturb the pixels 0154 class DeformColor : public DeformBase 0155 { 0156 public: 0157 DeformColor() { 0158 } 0159 0160 void setFactor(qreal factor) { 0161 m_factor = factor; 0162 } 0163 void transform(qreal* x, qreal* y, qreal distance, KisRandomSourceSP randomSource) override { 0164 Q_UNUSED(distance); 0165 qreal randomX = m_factor * ((randomSource->generateNormalized() * 2.0) - 1.0); 0166 qreal randomY = m_factor * ((randomSource->generateNormalized() * 2.0) - 1.0); 0167 *x += randomX; 0168 *y += randomY; 0169 } 0170 0171 private: 0172 qreal m_factor {0.0}; 0173 }; 0174 0175 0176 0177 0178 0179 class DeformBrush 0180 { 0181 0182 public: 0183 DeformBrush(); 0184 ~DeformBrush(); 0185 0186 KisFixedPaintDeviceSP paintMask(KisFixedPaintDeviceSP dab, KisPaintDeviceSP layer, KisRandomSourceSP randomSource, 0187 qreal scale, qreal rotation, QPointF pos, 0188 qreal subPixelX, qreal subPixelY, int dabX, int dabY); 0189 0190 void setSizeProperties(KisBrushSizeOptionData * properties) { 0191 m_sizeProperties = properties; 0192 } 0193 void setProperties(KisDeformOptionData * properties) { 0194 m_properties = properties; 0195 } 0196 void initDeformAction(); 0197 QPointF hotSpot(qreal scale, qreal rotation); 0198 0199 private: 0200 // return true if can paint 0201 bool setupAction( 0202 DeformModes mode, const QPointF& pos, QTransform const& rotation); 0203 void debugColor(const quint8* data, KoColorSpace * cs); 0204 0205 qreal maskWidth(qreal scale) { 0206 return m_sizeProperties->brushDiameter * scale; 0207 } 0208 0209 qreal maskHeight(qreal scale) { 0210 return m_sizeProperties->brushDiameter * m_sizeProperties->brushAspect * scale; 0211 } 0212 0213 inline qreal norme(qreal x, qreal y) { 0214 return x * x + y * y; 0215 } 0216 0217 0218 private: 0219 KisRandomSubAccessorSP m_srcAcc; 0220 bool m_firstPaint {false}; 0221 qreal m_prevX {0.0}, m_prevY {0.0}; 0222 int m_counter {1}; // taken from the constructor 0223 0224 QRectF m_maskRect; 0225 0226 DeformBase * m_deformAction {0}; 0227 0228 KisDeformOptionData * m_properties {0}; 0229 KisBrushSizeOptionData * m_sizeProperties {0}; 0230 }; 0231 0232 0233 #endif