File indexing completed on 2024-12-22 04:16:59
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 #include "tool_transform_args.h" 0010 0011 #include <QDomElement> 0012 0013 #include <ksharedconfig.h> 0014 #include <kconfig.h> 0015 #include <kconfiggroup.h> 0016 0017 #include "kis_liquify_transform_worker.h" 0018 #include "kis_dom_utils.h" 0019 #include <QMatrix4x4> 0020 0021 0022 ToolTransformArgs::ToolTransformArgs() 0023 : m_liquifyProperties(new KisLiquifyProperties()) 0024 { 0025 KConfigGroup configGroup = KSharedConfig::openConfig()->group("KisToolTransform"); 0026 QString savedFilterId = configGroup.readEntry("filterId", "Bicubic"); 0027 setFilterId(savedFilterId); 0028 m_transformAroundRotationCenter = configGroup.readEntry("transformAroundRotationCenter", "0").toInt(); 0029 m_meshShowHandles = configGroup.readEntry("meshShowHandles", true); 0030 m_meshSymmetricalHandles = configGroup.readEntry("meshSymmetricalHandles", true); 0031 m_meshScaleHandles = configGroup.readEntry("meshScaleHandles", false); 0032 } 0033 0034 void ToolTransformArgs::setFilterId(const QString &id) { 0035 m_filter = KisFilterStrategyRegistry::instance()->value(id); 0036 0037 if (m_filter) { 0038 KConfigGroup configGroup = KSharedConfig::openConfig()->group("KisToolTransform"); 0039 configGroup.writeEntry("filterId", id); 0040 } 0041 } 0042 0043 void ToolTransformArgs::setTransformAroundRotationCenter(bool value) 0044 { 0045 m_transformAroundRotationCenter = value; 0046 0047 KConfigGroup configGroup = KSharedConfig::openConfig()->group("KisToolTransform"); 0048 configGroup.writeEntry("transformAroundRotationCenter", int(value)); 0049 } 0050 0051 void ToolTransformArgs::init(const ToolTransformArgs& args) 0052 { 0053 m_mode = args.mode(); 0054 m_transformedCenter = args.transformedCenter(); 0055 m_originalCenter = args.originalCenter(); 0056 m_rotationCenterOffset = args.rotationCenterOffset(); 0057 m_transformAroundRotationCenter = args.transformAroundRotationCenter(); 0058 m_cameraPos = args.m_cameraPos; 0059 m_aX = args.aX(); 0060 m_aY = args.aY(); 0061 m_aZ = args.aZ(); 0062 m_scaleX = args.scaleX(); 0063 m_scaleY = args.scaleY(); 0064 m_shearX = args.shearX(); 0065 m_shearY = args.shearY(); 0066 m_origPoints = args.origPoints(); //it's a copy 0067 m_transfPoints = args.transfPoints(); 0068 m_warpType = args.warpType(); 0069 m_alpha = args.alpha(); 0070 m_defaultPoints = args.defaultPoints(); 0071 m_keepAspectRatio = args.keepAspectRatio(); 0072 m_filter = args.m_filter; 0073 m_flattenedPerspectiveTransform = args.m_flattenedPerspectiveTransform; 0074 m_editTransformPoints = args.m_editTransformPoints; 0075 m_pixelPrecision = args.pixelPrecision(); 0076 m_previewPixelPrecision = args.previewPixelPrecision(); 0077 m_externalSource = args.externalSource(); 0078 0079 if (args.m_liquifyWorker) { 0080 m_liquifyWorker.reset(new KisLiquifyTransformWorker(*args.m_liquifyWorker.data())); 0081 } 0082 0083 m_meshTransform = args.m_meshTransform; 0084 m_meshShowHandles = args.m_meshShowHandles; 0085 m_meshSymmetricalHandles = args.m_meshSymmetricalHandles; 0086 m_meshScaleHandles = args.m_meshScaleHandles; 0087 0088 m_continuedTransformation.reset(args.m_continuedTransformation ? new ToolTransformArgs(*args.m_continuedTransformation) : 0); 0089 } 0090 0091 bool ToolTransformArgs::meshScaleHandles() const 0092 { 0093 return m_meshScaleHandles; 0094 } 0095 0096 void ToolTransformArgs::setMeshScaleHandles(bool meshScaleHandles) 0097 { 0098 m_meshScaleHandles = meshScaleHandles; 0099 0100 KConfigGroup configGroup = KSharedConfig::openConfig()->group("KisToolTransform"); 0101 configGroup.writeEntry("meshScaleHandles", meshScaleHandles); 0102 } 0103 0104 void ToolTransformArgs::clear() 0105 { 0106 m_origPoints.clear(); 0107 m_transfPoints.clear(); 0108 m_meshTransform = KisBezierTransformMesh(); 0109 } 0110 0111 ToolTransformArgs::ToolTransformArgs(const ToolTransformArgs& args) 0112 : m_liquifyProperties(new KisLiquifyProperties(*args.m_liquifyProperties.data())) 0113 { 0114 init(args); 0115 } 0116 0117 KisToolChangesTrackerData *ToolTransformArgs::clone() const 0118 { 0119 return new ToolTransformArgs(*this); 0120 } 0121 0122 ToolTransformArgs& ToolTransformArgs::operator=(const ToolTransformArgs& args) 0123 { 0124 if (this == &args) return *this; 0125 0126 clear(); 0127 0128 m_liquifyProperties.reset(new KisLiquifyProperties(*args.m_liquifyProperties.data())); 0129 init(args); 0130 0131 return *this; 0132 } 0133 0134 bool ToolTransformArgs::operator==(const ToolTransformArgs& other) const 0135 { 0136 return 0137 m_mode == other.m_mode && 0138 m_defaultPoints == other.m_defaultPoints && 0139 m_origPoints == other.m_origPoints && 0140 m_transfPoints == other.m_transfPoints && 0141 m_warpType == other.m_warpType && 0142 m_alpha == other.m_alpha && 0143 m_transformedCenter == other.m_transformedCenter && 0144 m_originalCenter == other.m_originalCenter && 0145 m_rotationCenterOffset == other.m_rotationCenterOffset && 0146 m_transformAroundRotationCenter == other.m_transformAroundRotationCenter && 0147 m_aX == other.m_aX && 0148 m_aY == other.m_aY && 0149 m_aZ == other.m_aZ && 0150 m_cameraPos == other.m_cameraPos && 0151 m_scaleX == other.m_scaleX && 0152 m_scaleY == other.m_scaleY && 0153 m_shearX == other.m_shearX && 0154 m_shearY == other.m_shearY && 0155 m_keepAspectRatio == other.m_keepAspectRatio && 0156 m_flattenedPerspectiveTransform == other.m_flattenedPerspectiveTransform && 0157 m_editTransformPoints == other.m_editTransformPoints && 0158 (m_liquifyProperties == other.m_liquifyProperties || 0159 *m_liquifyProperties == *other.m_liquifyProperties) && 0160 m_meshTransform == other.m_meshTransform && 0161 0162 // pointer types 0163 0164 m_externalSource == other.m_externalSource && 0165 0166 ((m_filter && other.m_filter && 0167 m_filter->id() == other.m_filter->id()) 0168 || m_filter == other.m_filter) && 0169 0170 ((m_liquifyWorker && other.m_liquifyWorker && 0171 *m_liquifyWorker == *other.m_liquifyWorker) 0172 || m_liquifyWorker == other.m_liquifyWorker) && 0173 m_pixelPrecision == other.m_pixelPrecision && 0174 m_previewPixelPrecision == other.m_previewPixelPrecision; 0175 } 0176 0177 bool ToolTransformArgs::isSameMode(const ToolTransformArgs& other) const 0178 { 0179 if (m_mode != other.m_mode) return false; 0180 0181 bool result = true; 0182 0183 if (m_mode == FREE_TRANSFORM) { 0184 result &= m_transformedCenter == other.m_transformedCenter; 0185 result &= m_originalCenter == other.m_originalCenter; 0186 result &= m_scaleX == other.m_scaleX; 0187 result &= m_scaleY == other.m_scaleY; 0188 result &= m_shearX == other.m_shearX; 0189 result &= m_shearY == other.m_shearY; 0190 result &= m_aX == other.m_aX; 0191 result &= m_aY == other.m_aY; 0192 result &= m_aZ == other.m_aZ; 0193 0194 } else if (m_mode == PERSPECTIVE_4POINT) { 0195 result &= m_transformedCenter == other.m_transformedCenter; 0196 result &= m_originalCenter == other.m_originalCenter; 0197 result &= m_scaleX == other.m_scaleX; 0198 result &= m_scaleY == other.m_scaleY; 0199 result &= m_shearX == other.m_shearX; 0200 result &= m_shearY == other.m_shearY; 0201 result &= m_flattenedPerspectiveTransform == other.m_flattenedPerspectiveTransform; 0202 0203 } else if(m_mode == WARP || m_mode == CAGE) { 0204 result &= m_origPoints == other.m_origPoints; 0205 result &= m_transfPoints == other.m_transfPoints; 0206 0207 } else if (m_mode == LIQUIFY) { 0208 result &= m_liquifyProperties && 0209 (m_liquifyProperties == other.m_liquifyProperties || 0210 *m_liquifyProperties == *other.m_liquifyProperties); 0211 0212 result &= 0213 (m_liquifyWorker && other.m_liquifyWorker && 0214 *m_liquifyWorker == *other.m_liquifyWorker) 0215 || m_liquifyWorker == other.m_liquifyWorker; 0216 0217 } else if (m_mode == MESH) { 0218 result &= m_meshTransform == other.m_meshTransform; 0219 } else { 0220 KIS_SAFE_ASSERT_RECOVER_NOOP(0 && "unknown transform mode"); 0221 } 0222 0223 return result; 0224 } 0225 0226 ToolTransformArgs::ToolTransformArgs(TransformMode mode, 0227 QPointF transformedCenter, 0228 QPointF originalCenter, 0229 QPointF rotationCenterOffset, 0230 bool transformAroundRotationCenter, 0231 double aX, double aY, double aZ, 0232 double scaleX, double scaleY, 0233 double shearX, double shearY, 0234 KisWarpTransformWorker::WarpType warpType, 0235 double alpha, 0236 bool defaultPoints, 0237 const QString &filterId, 0238 int pixelPrecision, int previewPixelPrecision, 0239 KisPaintDeviceSP externalSource) 0240 : m_mode(mode) 0241 , m_defaultPoints(defaultPoints) 0242 , m_origPoints {QVector<QPointF>()} 0243 , m_transfPoints {QVector<QPointF>()} 0244 , m_warpType(warpType) 0245 , m_alpha(alpha) 0246 , m_transformedCenter(transformedCenter) 0247 , m_originalCenter(originalCenter) 0248 , m_rotationCenterOffset(rotationCenterOffset) 0249 , m_transformAroundRotationCenter(transformAroundRotationCenter) 0250 , m_aX(aX) 0251 , m_aY(aY) 0252 , m_aZ(aZ) 0253 , m_scaleX(scaleX) 0254 , m_scaleY(scaleY) 0255 , m_shearX(shearX) 0256 , m_shearY(shearY) 0257 , m_liquifyProperties(new KisLiquifyProperties()) 0258 , m_pixelPrecision(pixelPrecision) 0259 , m_previewPixelPrecision(previewPixelPrecision) 0260 , m_externalSource(externalSource) 0261 { 0262 setFilterId(filterId); 0263 } 0264 0265 0266 ToolTransformArgs::~ToolTransformArgs() 0267 { 0268 clear(); 0269 } 0270 0271 void ToolTransformArgs::translateSrcAndDst(const QPointF &offset) 0272 { 0273 transformSrcAndDst(QTransform::fromTranslate(offset.x(), offset.y())); 0274 } 0275 0276 void ToolTransformArgs::transformSrcAndDst(const QTransform &t) 0277 { 0278 if (m_mode == FREE_TRANSFORM ) { 0279 m_originalCenter = t.map(m_originalCenter); 0280 m_transformedCenter = t.map(m_transformedCenter); 0281 0282 QMatrix4x4 m(t); 0283 m_cameraPos = m * m_cameraPos; 0284 } else if (m_mode == PERSPECTIVE_4POINT) { 0285 m_originalCenter = t.map(m_originalCenter); 0286 m_transformedCenter = t.map(m_transformedCenter); 0287 0288 m_flattenedPerspectiveTransform = t.inverted() * m_flattenedPerspectiveTransform * t; 0289 0290 } else if(m_mode == WARP || m_mode == CAGE) { 0291 for (auto &pt : m_origPoints) { 0292 pt = t.map(pt); 0293 } 0294 0295 for (auto &pt : m_transfPoints) { 0296 pt = t.map(pt); 0297 } 0298 } else if (m_mode == LIQUIFY) { 0299 KIS_ASSERT_RECOVER_RETURN(m_liquifyWorker); 0300 m_liquifyWorker->transformSrcAndDst(t); 0301 } else if (m_mode == MESH) { 0302 m_meshTransform.transformSrcAndDst(t); 0303 } else { 0304 KIS_ASSERT_RECOVER_NOOP(0 && "unknown transform mode"); 0305 } 0306 } 0307 0308 void ToolTransformArgs::translateDstSpace(const QPointF &offset) 0309 { 0310 if (m_mode == FREE_TRANSFORM || m_mode == PERSPECTIVE_4POINT) { 0311 m_transformedCenter += offset; 0312 } else if(m_mode == WARP || m_mode == CAGE) { 0313 for (auto &pt : m_transfPoints) { 0314 pt += offset; 0315 } 0316 } else if (m_mode == LIQUIFY) { 0317 KIS_ASSERT_RECOVER_RETURN(m_liquifyWorker); 0318 m_liquifyWorker->translateDstSpace(offset); 0319 } else if (m_mode == MESH) { 0320 m_meshTransform.translate(offset); 0321 } else { 0322 KIS_ASSERT_RECOVER_NOOP(0 && "unknown transform mode"); 0323 } 0324 } 0325 0326 bool ToolTransformArgs::isIdentity() const 0327 { 0328 if (m_mode == FREE_TRANSFORM) { 0329 return (m_transformedCenter == m_originalCenter && m_scaleX == 1 0330 && m_scaleY == 1 && m_shearX == 0 && m_shearY == 0 0331 && m_aX == 0 && m_aY == 0 && m_aZ == 0); 0332 } else if (m_mode == PERSPECTIVE_4POINT) { 0333 return (m_transformedCenter == m_originalCenter && m_scaleX == 1 0334 && m_scaleY == 1 && m_shearX == 0 && m_shearY == 0 0335 && m_flattenedPerspectiveTransform.isIdentity()); 0336 } else if(m_mode == WARP || m_mode == CAGE) { 0337 for (int i = 0; i < m_origPoints.size(); ++i) 0338 if (m_origPoints[i] != m_transfPoints[i]) 0339 return false; 0340 0341 return true; 0342 } else if (m_mode == LIQUIFY) { 0343 return !m_liquifyWorker || m_liquifyWorker->isIdentity(); 0344 } else if (m_mode == MESH) { 0345 return m_meshTransform.isIdentity(); 0346 } else { 0347 KIS_ASSERT_RECOVER_NOOP(0 && "unknown transform mode"); 0348 return true; 0349 } 0350 } 0351 0352 bool ToolTransformArgs::isUnchanging() const 0353 { 0354 return !m_externalSource && isIdentity(); 0355 } 0356 0357 void ToolTransformArgs::initLiquifyTransformMode(const QRect &srcRect) 0358 { 0359 m_liquifyWorker.reset(new KisLiquifyTransformWorker(srcRect, 0, 8)); 0360 m_liquifyProperties->loadAndResetMode(); 0361 } 0362 0363 void ToolTransformArgs::saveLiquifyTransformMode() const 0364 { 0365 m_liquifyProperties->saveMode(); 0366 } 0367 0368 void ToolTransformArgs::toXML(QDomElement *e) const 0369 { 0370 e->setAttribute("mode", (int) m_mode); 0371 0372 QDomDocument doc = e->ownerDocument(); 0373 0374 if (m_mode == FREE_TRANSFORM || m_mode == PERSPECTIVE_4POINT) { 0375 0376 QDomElement freeEl = doc.createElement("free_transform"); 0377 e->appendChild(freeEl); 0378 0379 KisDomUtils::saveValue(&freeEl, "transformedCenter", m_transformedCenter); 0380 KisDomUtils::saveValue(&freeEl, "originalCenter", m_originalCenter); 0381 KisDomUtils::saveValue(&freeEl, "rotationCenterOffset", m_rotationCenterOffset); 0382 KisDomUtils::saveValue(&freeEl, "transformAroundRotationCenter", m_transformAroundRotationCenter); 0383 0384 KisDomUtils::saveValue(&freeEl, "aX", m_aX); 0385 KisDomUtils::saveValue(&freeEl, "aY", m_aY); 0386 KisDomUtils::saveValue(&freeEl, "aZ", m_aZ); 0387 0388 KisDomUtils::saveValue(&freeEl, "cameraPos", m_cameraPos); 0389 0390 KisDomUtils::saveValue(&freeEl, "scaleX", m_scaleX); 0391 KisDomUtils::saveValue(&freeEl, "scaleY", m_scaleY); 0392 0393 KisDomUtils::saveValue(&freeEl, "shearX", m_shearX); 0394 KisDomUtils::saveValue(&freeEl, "shearY", m_shearY); 0395 0396 KisDomUtils::saveValue(&freeEl, "keepAspectRatio", m_keepAspectRatio); 0397 KisDomUtils::saveValue(&freeEl, "flattenedPerspectiveTransform", m_flattenedPerspectiveTransform); 0398 0399 KisDomUtils::saveValue(&freeEl, "filterId", m_filter->id()); 0400 0401 } else if (m_mode == WARP || m_mode == CAGE) { 0402 QDomElement warpEl = doc.createElement("warp_transform"); 0403 e->appendChild(warpEl); 0404 0405 KisDomUtils::saveValue(&warpEl, "defaultPoints", m_defaultPoints); 0406 KisDomUtils::saveValue(&warpEl, "originalPoints", m_origPoints); 0407 KisDomUtils::saveValue(&warpEl, "transformedPoints", m_transfPoints); 0408 0409 KisDomUtils::saveValue(&warpEl, "warpType", (int)m_warpType); // limited! 0410 KisDomUtils::saveValue(&warpEl, "alpha", m_alpha); 0411 0412 if(m_mode == CAGE){ 0413 KisDomUtils::saveValue(&warpEl,"pixelPrecision",m_pixelPrecision); 0414 KisDomUtils::saveValue(&warpEl,"previewPixelPrecision",m_previewPixelPrecision); 0415 } 0416 0417 } else if (m_mode == LIQUIFY) { 0418 QDomElement liqEl = doc.createElement("liquify_transform"); 0419 e->appendChild(liqEl); 0420 0421 m_liquifyProperties->toXML(&liqEl); 0422 m_liquifyWorker->toXML(&liqEl); 0423 } else if (m_mode == MESH) { 0424 QDomElement meshEl = doc.createElement("mesh_transform"); 0425 e->appendChild(meshEl); 0426 0427 KisDomUtils::saveValue(&meshEl, "mesh", m_meshTransform); 0428 } else { 0429 KIS_ASSERT_RECOVER_RETURN(0 && "Unknown transform mode"); 0430 } 0431 0432 // m_editTransformPoints should not be saved since it is reset explicitly 0433 } 0434 0435 ToolTransformArgs ToolTransformArgs::fromXML(const QDomElement &e) 0436 { 0437 ToolTransformArgs args; 0438 0439 int newMode = e.attribute("mode", "0").toInt(); 0440 if (newMode < 0 || newMode >= N_MODES) return ToolTransformArgs(); 0441 0442 args.m_mode = (TransformMode) newMode; 0443 0444 // reset explicitly 0445 args.m_editTransformPoints = false; 0446 0447 bool result = false; 0448 0449 if (args.m_mode == FREE_TRANSFORM || args.m_mode == PERSPECTIVE_4POINT) { 0450 0451 QDomElement freeEl; 0452 0453 QString filterId; 0454 0455 result = 0456 KisDomUtils::findOnlyElement(e, "free_transform", &freeEl) && 0457 0458 KisDomUtils::loadValue(freeEl, "transformedCenter", &args.m_transformedCenter) && 0459 KisDomUtils::loadValue(freeEl, "originalCenter", &args.m_originalCenter) && 0460 KisDomUtils::loadValue(freeEl, "rotationCenterOffset", &args.m_rotationCenterOffset) && 0461 0462 KisDomUtils::loadValue(freeEl, "aX", &args.m_aX) && 0463 KisDomUtils::loadValue(freeEl, "aY", &args.m_aY) && 0464 KisDomUtils::loadValue(freeEl, "aZ", &args.m_aZ) && 0465 0466 KisDomUtils::loadValue(freeEl, "cameraPos", &args.m_cameraPos) && 0467 0468 KisDomUtils::loadValue(freeEl, "scaleX", &args.m_scaleX) && 0469 KisDomUtils::loadValue(freeEl, "scaleY", &args.m_scaleY) && 0470 0471 KisDomUtils::loadValue(freeEl, "shearX", &args.m_shearX) && 0472 KisDomUtils::loadValue(freeEl, "shearY", &args.m_shearY) && 0473 0474 KisDomUtils::loadValue(freeEl, "keepAspectRatio", &args.m_keepAspectRatio) && 0475 KisDomUtils::loadValue(freeEl, "flattenedPerspectiveTransform", &args.m_flattenedPerspectiveTransform) && 0476 KisDomUtils::loadValue(freeEl, "filterId", &filterId); 0477 0478 // transformAroundRotationCenter is a new parameter introduced in Krita 4.0, 0479 // so it might be not present in older transform masks 0480 if (!KisDomUtils::loadValue(freeEl, "transformAroundRotationCenter", &args.m_transformAroundRotationCenter)) { 0481 args.m_transformAroundRotationCenter = false; 0482 } 0483 0484 if (result) { 0485 args.m_filter = KisFilterStrategyRegistry::instance()->value(filterId); 0486 result = (bool) args.m_filter; 0487 } 0488 0489 } else if (args.m_mode == WARP || args.m_mode == CAGE) { 0490 QDomElement warpEl; 0491 0492 int warpType = 0; 0493 0494 result = 0495 KisDomUtils::findOnlyElement(e, "warp_transform", &warpEl) && 0496 0497 KisDomUtils::loadValue(warpEl, "defaultPoints", &args.m_defaultPoints) && 0498 0499 KisDomUtils::loadValue(warpEl, "originalPoints", &args.m_origPoints) && 0500 KisDomUtils::loadValue(warpEl, "transformedPoints", &args.m_transfPoints) && 0501 0502 KisDomUtils::loadValue(warpEl, "warpType", &warpType) && 0503 KisDomUtils::loadValue(warpEl, "alpha", &args.m_alpha); 0504 0505 if(args.m_mode == CAGE){ 0506 // Pixel precision is a parameter introduced in Krita 4.2, so we should 0507 // expect it not being present in older files. In case it is not found, 0508 // just use the default value initialized by c-tor (that is, do nothing). 0509 0510 (void) KisDomUtils::loadValue(warpEl, "pixelPrecision", &args.m_pixelPrecision); 0511 (void) KisDomUtils::loadValue(warpEl, "previewPixelPrecision", &args.m_previewPixelPrecision); 0512 } 0513 0514 if (result && warpType >= 0 && warpType < KisWarpTransformWorker::N_MODES) { 0515 args.m_warpType = (KisWarpTransformWorker::WarpType_) warpType; 0516 } else { 0517 result = false; 0518 } 0519 0520 } else if (args.m_mode == LIQUIFY) { 0521 QDomElement liquifyEl; 0522 0523 result = 0524 KisDomUtils::findOnlyElement(e, "liquify_transform", &liquifyEl); 0525 0526 *args.m_liquifyProperties = KisLiquifyProperties::fromXML(e); 0527 args.m_liquifyWorker.reset(KisLiquifyTransformWorker::fromXML(e)); 0528 } else if (args.m_mode == MESH) { 0529 QDomElement meshEl; 0530 0531 result = 0532 KisDomUtils::findOnlyElement(e, "mesh_transform", &meshEl); 0533 0534 result &= KisDomUtils::loadValue(meshEl, "mesh", &args.m_meshTransform); 0535 0536 } else { 0537 KIS_ASSERT_RECOVER_NOOP(0 && "Unknown transform mode"); 0538 } 0539 0540 KIS_SAFE_ASSERT_RECOVER(result) { 0541 args = ToolTransformArgs(); 0542 } 0543 0544 return args; 0545 } 0546 0547 void ToolTransformArgs::saveContinuedState() 0548 { 0549 m_continuedTransformation.reset(); 0550 m_continuedTransformation.reset(new ToolTransformArgs(*this)); 0551 } 0552 0553 void ToolTransformArgs::restoreContinuedState() 0554 { 0555 QScopedPointer<ToolTransformArgs> tempTransformation( 0556 new ToolTransformArgs(*m_continuedTransformation)); 0557 0558 *this = *tempTransformation; 0559 m_continuedTransformation.swap(tempTransformation); 0560 } 0561 0562 const ToolTransformArgs* ToolTransformArgs::continuedTransform() const 0563 { 0564 return m_continuedTransformation.data(); 0565 } 0566 0567 const KisBezierTransformMesh *ToolTransformArgs::meshTransform() const 0568 { 0569 return &m_meshTransform; 0570 } 0571 0572 KisBezierTransformMesh *ToolTransformArgs::meshTransform() 0573 { 0574 return &m_meshTransform; 0575 } 0576 0577 bool ToolTransformArgs::meshShowHandles() const 0578 { 0579 return m_meshShowHandles; 0580 } 0581 0582 void ToolTransformArgs::setMeshShowHandles(bool value) 0583 { 0584 m_meshShowHandles = value; 0585 0586 KConfigGroup configGroup = KSharedConfig::openConfig()->group("KisToolTransform"); 0587 configGroup.writeEntry("meshShowHandles", value); 0588 } 0589 0590 bool ToolTransformArgs::meshSymmetricalHandles() const 0591 { 0592 return m_meshSymmetricalHandles; 0593 } 0594 0595 void ToolTransformArgs::setMeshSymmetricalHandles(bool value) 0596 { 0597 m_meshSymmetricalHandles = value; 0598 0599 KConfigGroup configGroup = KSharedConfig::openConfig()->group("KisToolTransform"); 0600 configGroup.writeEntry("meshSymmetricalHandles", value); 0601 } 0602 0603 void ToolTransformArgs::scale3dSrcAndDst(qreal scale) 0604 { 0605 const QTransform t = QTransform::fromScale(scale, scale); 0606 0607 if (m_mode == FREE_TRANSFORM ) { 0608 m_originalCenter = t.map(m_originalCenter); 0609 m_transformedCenter = t.map(m_transformedCenter); 0610 0611 // we need to scale Z-coordinate of the camera pos as well, 0612 // so we cannot just do `QMatrix4x4 m(t)`. 0613 QMatrix4x4 m; 0614 m.scale(scale); 0615 m_cameraPos = m * m_cameraPos; 0616 } else { 0617 transformSrcAndDst(t); 0618 } 0619 }