File indexing completed on 2024-06-23 04:28:32
0001 /* 0002 * tool_transform_args.h - part of Krita 0003 * 0004 * SPDX-FileCopyrightText: 2010 Marc Pegon <pe.marc@free.fr> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #ifndef TOOL_TRANSFORM_ARGS_H_ 0010 #define TOOL_TRANSFORM_ARGS_H_ 0011 0012 #include <QPointF> 0013 #include <QVector3D> 0014 #include <kis_warptransform_worker.h> 0015 #include <kis_filter_strategy.h> 0016 #include "kis_liquify_properties.h" 0017 #include "kritatooltransform_export.h" 0018 #include "kis_global.h" 0019 #include "KisToolChangesTrackerData.h" 0020 #include "KisBezierTransformMesh.h" 0021 #include "kis_paint_device.h" 0022 0023 #include <QScopedPointer> 0024 class KisLiquifyTransformWorker; 0025 class QDomElement; 0026 0027 /** 0028 * Class used to store the parameters of a transformation. 0029 * Some parameters are specific to free transform mode, and 0030 * others to warp mode : maybe add a union to save a little more 0031 * memory. 0032 */ 0033 0034 class KRITATOOLTRANSFORM_EXPORT ToolTransformArgs : public KisToolChangesTrackerData 0035 { 0036 public: 0037 enum TransformMode {FREE_TRANSFORM = 0, 0038 WARP, 0039 CAGE, 0040 LIQUIFY, 0041 PERSPECTIVE_4POINT, 0042 MESH, 0043 N_MODES}; 0044 0045 /** 0046 * Initializes the parameters for an identity transformation, 0047 * with mode set to free transform. 0048 */ 0049 ToolTransformArgs(); 0050 0051 /** 0052 * The object return will be a copy of args. 0053 */ 0054 ToolTransformArgs(const ToolTransformArgs& args); 0055 0056 KisToolChangesTrackerData *clone() const override; 0057 0058 /** 0059 * If mode is warp, original and transformed vector points will be of size 0. 0060 * Use setPoints method to set those vectors. 0061 */ 0062 ToolTransformArgs(TransformMode mode, 0063 QPointF transformedCenter, 0064 QPointF originalCenter, 0065 QPointF rotationCenterOffset, bool transformAroundRotationCenter, 0066 double aX, double aY, double aZ, 0067 double scaleX, double scaleY, 0068 double shearX, double shearY, 0069 KisWarpTransformWorker::WarpType warpType, 0070 double alpha, 0071 bool defaultPoints, 0072 const QString &filterId, 0073 int pixelPrecision, int previewPixelPrecision, 0074 KisPaintDeviceSP externalSource); 0075 ~ToolTransformArgs(); 0076 ToolTransformArgs& operator=(const ToolTransformArgs& args); 0077 0078 bool operator==(const ToolTransformArgs& other) const; 0079 bool isSameMode(const ToolTransformArgs& other) const; 0080 0081 inline TransformMode mode() const { 0082 return m_mode; 0083 } 0084 inline void setMode(TransformMode mode) { 0085 m_mode = mode; 0086 } 0087 0088 inline int pixelPrecision() const { 0089 return m_pixelPrecision; 0090 } 0091 0092 inline void setPixelPrecision(int precision) { 0093 m_pixelPrecision = precision; 0094 } 0095 0096 inline int previewPixelPrecision() const { 0097 return m_previewPixelPrecision; 0098 } 0099 0100 inline void setPreviewPixelPrecision(int precision) { 0101 m_previewPixelPrecision = precision; 0102 } 0103 0104 inline KisPaintDeviceSP externalSource() const { 0105 return m_externalSource; 0106 } 0107 0108 inline void setExternalSource(KisPaintDeviceSP externalSource) { 0109 m_externalSource = externalSource; 0110 } 0111 0112 //warp-related 0113 inline int numPoints() const { 0114 KIS_ASSERT_RECOVER_NOOP(m_origPoints.size() == m_transfPoints.size()); 0115 return m_origPoints.size(); 0116 } 0117 inline QPointF &origPoint(int i) { 0118 return m_origPoints[i]; 0119 } 0120 inline QPointF &transfPoint(int i) { 0121 return m_transfPoints[i]; 0122 } 0123 inline const QVector<QPointF> &origPoints() const { 0124 return m_origPoints; 0125 } 0126 inline const QVector<QPointF> &transfPoints() const { 0127 return m_transfPoints; 0128 } 0129 0130 inline QVector<QPointF> &refOriginalPoints() { 0131 return m_origPoints; 0132 } 0133 inline QVector<QPointF> &refTransformedPoints() { 0134 return m_transfPoints; 0135 } 0136 0137 inline KisWarpTransformWorker::WarpType warpType() const { 0138 return m_warpType; 0139 } 0140 inline double alpha() const { 0141 return m_alpha; 0142 } 0143 inline bool defaultPoints() const { 0144 return m_defaultPoints; 0145 } 0146 inline void setPoints(QVector<QPointF> origPoints, QVector<QPointF> transfPoints) { 0147 m_origPoints = QVector<QPointF>(origPoints); 0148 m_transfPoints = QVector<QPointF>(transfPoints); 0149 } 0150 inline void setWarpType(KisWarpTransformWorker::WarpType warpType) { 0151 m_warpType = warpType; 0152 } 0153 inline void setWarpCalculation(KisWarpTransformWorker::WarpCalculation warpCalc) { 0154 m_warpCalculation = warpCalc; 0155 } 0156 inline KisWarpTransformWorker::WarpCalculation warpCalculation() { 0157 return m_warpCalculation; 0158 } 0159 0160 inline void setAlpha(double alpha) { 0161 m_alpha = alpha; 0162 } 0163 inline void setDefaultPoints(bool defaultPoints) { 0164 m_defaultPoints = defaultPoints; 0165 } 0166 0167 //"free transform"-related 0168 inline QPointF transformedCenter() const { 0169 return m_transformedCenter; 0170 } 0171 inline QPointF originalCenter() const { 0172 return m_originalCenter; 0173 } 0174 inline QPointF rotationCenterOffset() const { 0175 return m_rotationCenterOffset; 0176 } 0177 inline bool transformAroundRotationCenter() const { 0178 return m_transformAroundRotationCenter; 0179 } 0180 inline double aX() const { 0181 return m_aX; 0182 } 0183 inline double aY() const { 0184 return m_aY; 0185 } 0186 inline double aZ() const { 0187 return m_aZ; 0188 } 0189 inline QVector3D cameraPos() const { 0190 return m_cameraPos; 0191 } 0192 inline double scaleX() const { 0193 return m_scaleX; 0194 } 0195 inline double scaleY() const { 0196 return m_scaleY; 0197 } 0198 inline bool keepAspectRatio() const { 0199 return m_keepAspectRatio; 0200 } 0201 inline double shearX() const { 0202 return m_shearX; 0203 } 0204 inline double shearY() const { 0205 return m_shearY; 0206 } 0207 0208 inline void setTransformedCenter(QPointF transformedCenter) { 0209 m_transformedCenter = transformedCenter; 0210 } 0211 inline void setOriginalCenter(QPointF originalCenter) { 0212 m_originalCenter = originalCenter; 0213 } 0214 inline void setRotationCenterOffset(QPointF rotationCenterOffset) { 0215 m_rotationCenterOffset = rotationCenterOffset; 0216 } 0217 void setTransformAroundRotationCenter(bool value); 0218 0219 inline void setAX(double aX) { 0220 m_aX = aX; 0221 } 0222 inline void setAY(double aY) { 0223 m_aY = aY; 0224 } 0225 inline void setAZ(double aZ) { 0226 m_aZ = aZ; 0227 } 0228 inline void setCameraPos(const QVector3D &pos) { 0229 m_cameraPos = pos; 0230 } 0231 inline void setScaleX(double scaleX) { 0232 m_scaleX = scaleX; 0233 } 0234 inline void setScaleY(double scaleY) { 0235 m_scaleY = scaleY; 0236 } 0237 inline void setKeepAspectRatio(bool value) { 0238 m_keepAspectRatio = value; 0239 } 0240 inline void setShearX(double shearX) { 0241 m_shearX = shearX; 0242 } 0243 inline void setShearY(double shearY) { 0244 m_shearY = shearY; 0245 } 0246 0247 inline QString filterId() const { 0248 return m_filter->id(); 0249 } 0250 0251 void setFilterId(const QString &id); 0252 0253 inline KisFilterStrategy* filter() const { 0254 return m_filter; 0255 } 0256 0257 // True if the transformation does not differ from the initial one. The 0258 // target device may still need changing if we are placing an external source. 0259 bool isIdentity() const; 0260 0261 // True if the target device does not need changing as a result of this 0262 // transformation, because the transformation does not differ from the initial 0263 // one and the source image is not external. 0264 bool isUnchanging() const; 0265 0266 inline QTransform flattenedPerspectiveTransform() const { 0267 return m_flattenedPerspectiveTransform; 0268 } 0269 0270 inline void setFlattenedPerspectiveTransform(const QTransform &value) { 0271 m_flattenedPerspectiveTransform = value; 0272 } 0273 0274 bool isEditingTransformPoints() const { 0275 return m_editTransformPoints; 0276 } 0277 0278 void setEditingTransformPoints(bool value) { 0279 m_editTransformPoints = value; 0280 } 0281 0282 const KisLiquifyProperties* liquifyProperties() const { 0283 return m_liquifyProperties.data(); 0284 } 0285 0286 KisLiquifyProperties* liquifyProperties() { 0287 return m_liquifyProperties.data(); 0288 } 0289 0290 void initLiquifyTransformMode(const QRect &srcRect); 0291 void saveLiquifyTransformMode() const; 0292 0293 KisLiquifyTransformWorker* liquifyWorker() const { 0294 return m_liquifyWorker.data(); 0295 } 0296 0297 void toXML(QDomElement *e) const; 0298 static ToolTransformArgs fromXML(const QDomElement &e); 0299 0300 void translateSrcAndDst(const QPointF &offset); 0301 void transformSrcAndDst(const QTransform &t); 0302 void translateDstSpace(const QPointF &offset); 0303 0304 void saveContinuedState(); 0305 void restoreContinuedState(); 0306 const ToolTransformArgs* continuedTransform() const; 0307 0308 const KisBezierTransformMesh* meshTransform() const; 0309 KisBezierTransformMesh* meshTransform(); 0310 0311 bool meshShowHandles() const; 0312 void setMeshShowHandles(bool value); 0313 0314 bool meshSymmetricalHandles() const; 0315 void setMeshSymmetricalHandles(bool meshSymmetricalHandles); 0316 0317 bool meshScaleHandles() const; 0318 void setMeshScaleHandles(bool meshScaleHandles); 0319 0320 void scale3dSrcAndDst(qreal scale); 0321 0322 private: 0323 void clear(); 0324 void init(const ToolTransformArgs& args); 0325 TransformMode m_mode {ToolTransformArgs::TransformMode::FREE_TRANSFORM}; 0326 0327 // warp-related arguments 0328 // these are basically the arguments taken by the warp transform worker 0329 bool m_defaultPoints {true}; // true : the original points are set to make a grid 0330 // which density is given by numPoints() 0331 QVector<QPointF> m_origPoints; 0332 QVector<QPointF> m_transfPoints; 0333 KisWarpTransformWorker::WarpType m_warpType {KisWarpTransformWorker::WarpType_::RIGID_TRANSFORM}; 0334 KisWarpTransformWorker::WarpCalculation m_warpCalculation {KisWarpTransformWorker::WarpCalculation::DRAW}; // DRAW or GRID 0335 double m_alpha {1.0}; 0336 0337 //'free transform'-related 0338 // basically the arguments taken by the transform worker 0339 QPointF m_transformedCenter; 0340 QPointF m_originalCenter; 0341 QPointF m_rotationCenterOffset; // the position of the rotation center relative to 0342 // the original top left corner of the selection 0343 // before any transformation 0344 bool m_transformAroundRotationCenter {false}; // In freehand mode makes the scaling and other transformations 0345 // be anchored to the rotation center point. 0346 0347 double m_aX {0}; 0348 double m_aY {0}; 0349 double m_aZ {0}; 0350 QVector3D m_cameraPos {QVector3D(0,0,1024)}; 0351 double m_scaleX {1.0}; 0352 double m_scaleY {1.0}; 0353 double m_shearX {0.0}; 0354 double m_shearY {0.0}; 0355 bool m_keepAspectRatio {false}; 0356 0357 // perspective transform related 0358 QTransform m_flattenedPerspectiveTransform; 0359 0360 KisFilterStrategy *m_filter {0}; 0361 bool m_editTransformPoints {false}; 0362 QSharedPointer<KisLiquifyProperties> m_liquifyProperties; 0363 QScopedPointer<KisLiquifyTransformWorker> m_liquifyWorker; 0364 0365 KisBezierTransformMesh m_meshTransform; 0366 bool m_meshShowHandles = true; 0367 bool m_meshSymmetricalHandles = true; 0368 bool m_meshScaleHandles = false; 0369 0370 /** 0371 * When we continue a transformation, m_continuedTransformation 0372 * stores the initial step of our transform. All cancel and revert 0373 * operations should revert to it. 0374 */ 0375 QScopedPointer<ToolTransformArgs> m_continuedTransformation; 0376 0377 //PixelPrecision should always be in powers of 2 0378 int m_pixelPrecision {8}; 0379 int m_previewPixelPrecision {16}; 0380 0381 /** 0382 * Optional external image, for example from the clipboard, that 0383 * can be transformed directly over an existing paint layer or mask. 0384 */ 0385 KisPaintDeviceSP m_externalSource; 0386 }; 0387 0388 #endif // TOOL_TRANSFORM_ARGS_H_