1 /* 2 * tool_transform_args.h - part of Krita 3 * 4 * Copyright (c) 2010 Marc Pegon <pe.marc@free.fr> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 */ 20 21 #ifndef TOOL_TRANSFORM_ARGS_H_ 22 #define TOOL_TRANSFORM_ARGS_H_ 23 24 #include <QPointF> 25 #include <QVector3D> 26 #include <kis_warptransform_worker.h> 27 #include <kis_filter_strategy.h> 28 #include "kis_liquify_properties.h" 29 #include "kritatooltransform_export.h" 30 #include "kis_global.h" 31 #include "KisToolChangesTrackerData.h" 32 #include "KisBezierTransformMesh.h" 33 34 #include <QScopedPointer> 35 class KisLiquifyTransformWorker; 36 class QDomElement; 37 38 /** 39 * Class used to store the parameters of a transformation. 40 * Some parameters are specific to free transform mode, and 41 * others to warp mode : maybe add a union to save a little more 42 * memory. 43 */ 44 45 class KRITATOOLTRANSFORM_EXPORT ToolTransformArgs : public KisToolChangesTrackerData 46 { 47 public: 48 enum TransformMode {FREE_TRANSFORM = 0, 49 WARP, 50 CAGE, 51 LIQUIFY, 52 PERSPECTIVE_4POINT, 53 MESH, 54 N_MODES}; 55 56 /** 57 * Initializes the parameters for an identity transformation, 58 * with mode set to free transform. 59 */ 60 ToolTransformArgs(); 61 62 /** 63 * The object return will be a copy of args. 64 */ 65 ToolTransformArgs(const ToolTransformArgs& args); 66 67 KisToolChangesTrackerData *clone() const; 68 69 /** 70 * If mode is warp, original and transformed vector points will be of size 0. 71 * Use setPoints method to set those vectors. 72 */ 73 ToolTransformArgs(TransformMode mode, 74 QPointF transformedCenter, 75 QPointF originalCenter, 76 QPointF rotationCenterOffset, bool transformAroundRotationCenter, 77 double aX, double aY, double aZ, 78 double scaleX, double scaleY, 79 double shearX, double shearY, 80 KisWarpTransformWorker::WarpType warpType, 81 double alpha, 82 bool defaultPoints, 83 const QString &filterId, 84 int pixelPrecision, int previewPixelPrecision); 85 ~ToolTransformArgs(); 86 ToolTransformArgs& operator=(const ToolTransformArgs& args); 87 88 bool operator==(const ToolTransformArgs& other) const; 89 bool isSameMode(const ToolTransformArgs& other) const; 90 mode()91 inline TransformMode mode() const { 92 return m_mode; 93 } setMode(TransformMode mode)94 inline void setMode(TransformMode mode) { 95 m_mode = mode; 96 } 97 pixelPrecision()98 inline int pixelPrecision() const { 99 return m_pixelPrecision; 100 } 101 setPixelPrecision(int precision)102 inline void setPixelPrecision(int precision) { 103 m_pixelPrecision = precision; 104 } 105 previewPixelPrecision()106 inline int previewPixelPrecision() const { 107 return m_previewPixelPrecision; 108 } 109 setPreviewPixelPrecision(int precision)110 inline void setPreviewPixelPrecision(int precision) { 111 m_previewPixelPrecision = precision; 112 } 113 114 //warp-related numPoints()115 inline int numPoints() const { 116 KIS_ASSERT_RECOVER_NOOP(m_origPoints.size() == m_transfPoints.size()); 117 return m_origPoints.size(); 118 } origPoint(int i)119 inline QPointF &origPoint(int i) { 120 return m_origPoints[i]; 121 } transfPoint(int i)122 inline QPointF &transfPoint(int i) { 123 return m_transfPoints[i]; 124 } origPoints()125 inline const QVector<QPointF> &origPoints() const { 126 return m_origPoints; 127 } transfPoints()128 inline const QVector<QPointF> &transfPoints() const { 129 return m_transfPoints; 130 } 131 refOriginalPoints()132 inline QVector<QPointF> &refOriginalPoints() { 133 return m_origPoints; 134 } refTransformedPoints()135 inline QVector<QPointF> &refTransformedPoints() { 136 return m_transfPoints; 137 } 138 warpType()139 inline KisWarpTransformWorker::WarpType warpType() const { 140 return m_warpType; 141 } alpha()142 inline double alpha() const { 143 return m_alpha; 144 } defaultPoints()145 inline bool defaultPoints() const { 146 return m_defaultPoints; 147 } setPoints(QVector<QPointF> origPoints,QVector<QPointF> transfPoints)148 inline void setPoints(QVector<QPointF> origPoints, QVector<QPointF> transfPoints) { 149 m_origPoints = QVector<QPointF>(origPoints); 150 m_transfPoints = QVector<QPointF>(transfPoints); 151 } setWarpType(KisWarpTransformWorker::WarpType warpType)152 inline void setWarpType(KisWarpTransformWorker::WarpType warpType) { 153 m_warpType = warpType; 154 } setWarpCalculation(KisWarpTransformWorker::WarpCalculation warpCalc)155 inline void setWarpCalculation(KisWarpTransformWorker::WarpCalculation warpCalc) { 156 m_warpCalculation = warpCalc; 157 } warpCalculation()158 inline KisWarpTransformWorker::WarpCalculation warpCalculation() { 159 return m_warpCalculation; 160 } 161 setAlpha(double alpha)162 inline void setAlpha(double alpha) { 163 m_alpha = alpha; 164 } setDefaultPoints(bool defaultPoints)165 inline void setDefaultPoints(bool defaultPoints) { 166 m_defaultPoints = defaultPoints; 167 } 168 169 //"free transform"-related transformedCenter()170 inline QPointF transformedCenter() const { 171 return m_transformedCenter; 172 } originalCenter()173 inline QPointF originalCenter() const { 174 return m_originalCenter; 175 } rotationCenterOffset()176 inline QPointF rotationCenterOffset() const { 177 return m_rotationCenterOffset; 178 } transformAroundRotationCenter()179 inline bool transformAroundRotationCenter() const { 180 return m_transformAroundRotationCenter; 181 } aX()182 inline double aX() const { 183 return m_aX; 184 } aY()185 inline double aY() const { 186 return m_aY; 187 } aZ()188 inline double aZ() const { 189 return m_aZ; 190 } cameraPos()191 inline QVector3D cameraPos() const { 192 return m_cameraPos; 193 } scaleX()194 inline double scaleX() const { 195 return m_scaleX; 196 } scaleY()197 inline double scaleY() const { 198 return m_scaleY; 199 } keepAspectRatio()200 inline bool keepAspectRatio() const { 201 return m_keepAspectRatio; 202 } shearX()203 inline double shearX() const { 204 return m_shearX; 205 } shearY()206 inline double shearY() const { 207 return m_shearY; 208 } 209 setTransformedCenter(QPointF transformedCenter)210 inline void setTransformedCenter(QPointF transformedCenter) { 211 m_transformedCenter = transformedCenter; 212 } setOriginalCenter(QPointF originalCenter)213 inline void setOriginalCenter(QPointF originalCenter) { 214 m_originalCenter = originalCenter; 215 } setRotationCenterOffset(QPointF rotationCenterOffset)216 inline void setRotationCenterOffset(QPointF rotationCenterOffset) { 217 m_rotationCenterOffset = rotationCenterOffset; 218 } 219 void setTransformAroundRotationCenter(bool value); 220 setAX(double aX)221 inline void setAX(double aX) { 222 KIS_SAFE_ASSERT_RECOVER(qFuzzyCompare(aX, normalizeAngle(aX))) { 223 aX = normalizeAngle(aX); 224 } 225 226 m_aX = aX; 227 } setAY(double aY)228 inline void setAY(double aY) { 229 KIS_SAFE_ASSERT_RECOVER(qFuzzyCompare(aY, normalizeAngle(aY))) { 230 aY = normalizeAngle(aY); 231 } 232 233 m_aY = aY; 234 } setAZ(double aZ)235 inline void setAZ(double aZ) { 236 KIS_SAFE_ASSERT_RECOVER(qFuzzyCompare(aZ, normalizeAngle(aZ))) { 237 aZ = normalizeAngle(aZ); 238 } 239 240 m_aZ = aZ; 241 } setCameraPos(const QVector3D & pos)242 inline void setCameraPos(const QVector3D &pos) { 243 m_cameraPos = pos; 244 } setScaleX(double scaleX)245 inline void setScaleX(double scaleX) { 246 m_scaleX = scaleX; 247 } setScaleY(double scaleY)248 inline void setScaleY(double scaleY) { 249 m_scaleY = scaleY; 250 } setKeepAspectRatio(bool value)251 inline void setKeepAspectRatio(bool value) { 252 m_keepAspectRatio = value; 253 } setShearX(double shearX)254 inline void setShearX(double shearX) { 255 m_shearX = shearX; 256 } setShearY(double shearY)257 inline void setShearY(double shearY) { 258 m_shearY = shearY; 259 } 260 filterId()261 inline QString filterId() const { 262 return m_filter->id(); 263 } 264 265 void setFilterId(const QString &id); 266 filter()267 inline KisFilterStrategy* filter() const { 268 return m_filter; 269 } 270 271 bool isIdentity() const; 272 flattenedPerspectiveTransform()273 inline QTransform flattenedPerspectiveTransform() const { 274 return m_flattenedPerspectiveTransform; 275 } 276 setFlattenedPerspectiveTransform(const QTransform & value)277 inline void setFlattenedPerspectiveTransform(const QTransform &value) { 278 m_flattenedPerspectiveTransform = value; 279 } 280 isEditingTransformPoints()281 bool isEditingTransformPoints() const { 282 return m_editTransformPoints; 283 } 284 setEditingTransformPoints(bool value)285 void setEditingTransformPoints(bool value) { 286 m_editTransformPoints = value; 287 } 288 liquifyProperties()289 const KisLiquifyProperties* liquifyProperties() const { 290 return m_liquifyProperties.data(); 291 } 292 liquifyProperties()293 KisLiquifyProperties* liquifyProperties() { 294 return m_liquifyProperties.data(); 295 } 296 297 void initLiquifyTransformMode(const QRect &srcRect); 298 void saveLiquifyTransformMode() const; 299 liquifyWorker()300 KisLiquifyTransformWorker* liquifyWorker() const { 301 return m_liquifyWorker.data(); 302 } 303 304 void toXML(QDomElement *e) const; 305 static ToolTransformArgs fromXML(const QDomElement &e); 306 307 void translate(const QPointF &offset); 308 309 void saveContinuedState(); 310 void restoreContinuedState(); 311 const ToolTransformArgs* continuedTransform() const; 312 313 const KisBezierTransformMesh* meshTransform() const; 314 KisBezierTransformMesh* meshTransform(); 315 316 bool meshShowHandles() const; 317 void setMeshShowHandles(bool value); 318 319 bool meshSymmetricalHandles() const; 320 void setMeshSymmetricalHandles(bool meshSymmetricalHandles); 321 322 bool meshScaleHandles() const; 323 void setMeshScaleHandles(bool meshScaleHandles); 324 325 private: 326 void clear(); 327 void init(const ToolTransformArgs& args); 328 TransformMode m_mode {ToolTransformArgs::TransformMode::FREE_TRANSFORM}; 329 330 // warp-related arguments 331 // these are basically the arguments taken by the warp transform worker 332 bool m_defaultPoints {true}; // true : the original points are set to make a grid 333 // which density is given by numPoints() 334 QVector<QPointF> m_origPoints; 335 QVector<QPointF> m_transfPoints; 336 KisWarpTransformWorker::WarpType m_warpType {KisWarpTransformWorker::WarpType_::RIGID_TRANSFORM}; 337 KisWarpTransformWorker::WarpCalculation m_warpCalculation {KisWarpTransformWorker::WarpCalculation::DRAW}; // DRAW or GRID 338 double m_alpha {1.0}; 339 340 //'free transform'-related 341 // basically the arguments taken by the transform worker 342 QPointF m_transformedCenter; 343 QPointF m_originalCenter; 344 QPointF m_rotationCenterOffset; // the position of the rotation center relative to 345 // the original top left corner of the selection 346 // before any transformation 347 bool m_transformAroundRotationCenter {false}; // In freehand mode makes the scaling and other transformations 348 // be anchored to the rotation center point. 349 350 double m_aX {0}; 351 double m_aY {0}; 352 double m_aZ {0}; 353 QVector3D m_cameraPos {QVector3D(0,0,1024)}; 354 double m_scaleX {1.0}; 355 double m_scaleY {1.0}; 356 double m_shearX {0.0}; 357 double m_shearY {0.0}; 358 bool m_keepAspectRatio {false}; 359 360 // perspective trasform related 361 QTransform m_flattenedPerspectiveTransform; 362 363 KisFilterStrategy *m_filter {0}; 364 bool m_editTransformPoints {false}; 365 QSharedPointer<KisLiquifyProperties> m_liquifyProperties; 366 QScopedPointer<KisLiquifyTransformWorker> m_liquifyWorker; 367 368 KisBezierTransformMesh m_meshTransform; 369 bool m_meshShowHandles = true; 370 bool m_meshSymmetricalHandles = true; 371 bool m_meshScaleHandles = false; 372 373 /** 374 * When we continue a transformation, m_continuedTransformation 375 * stores the initial step of our transform. All cancel and revert 376 * operations should revert to it. 377 */ 378 QScopedPointer<ToolTransformArgs> m_continuedTransformation; 379 380 //PixelPrecision should always be in powers of 2 381 int m_pixelPrecision {8}; 382 int m_previewPixelPrecision {16}; 383 }; 384 385 #endif // TOOL_TRANSFORM_ARGS_H_ 386