[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [calligra/krita-chili-kazakov] krita: Implemented preview of the Cage Transform
From: Dmitry Kazakov <dimula73 () gmail ! com>
Date: 2014-09-19 9:28:25
Message-ID: E1XUuUL-0006MY-EP () scm ! kde ! org
[Download RAW message or body]
Git commit ff9a841fe1fc7906da7fd071cbbb63748ac4deaf by Dmitry Kazakov.
Committed on 19/09/2014 at 09:28.
Pushed by dkazakov into branch 'krita-chili-kazakov'.
Implemented preview of the Cage Transform
Still in TODO list:
1) Fix resetting edit points mode when switching between warp and cage
transforms
2) Add extrapolation at the borders of the cage
3) Fix a random assert in the cage adjusting algorithm
M +11 -5 krita/image/kis_algebra_2d.cpp
M +2 -1 krita/image/kis_algebra_2d.h
M +117 -33 krita/image/kis_cage_transform_worker.cpp
M +8 -0 krita/image/kis_cage_transform_worker.h
M +20 -0 krita/image/kis_global.h
M +2 -2 krita/image/kis_grid_interpolation_tools.h
M +5 -5 krita/image/kis_warptransform_worker.cc
M +40 -12 krita/image/tests/kis_cage_transform_worker_test.cpp
M +1 -0 krita/image/tests/kis_cage_transform_worker_test.h
M +20 -0 krita/plugins/tools/tool_transform2/kis_cage_transform_strategy.cpp
M +7 -0 krita/plugins/tools/tool_transform2/kis_cage_transform_strategy.h
M +21 -7 krita/plugins/tools/tool_transform2/kis_warp_transform_strategy.cpp
M +7 -0 krita/plugins/tools/tool_transform2/kis_warp_transform_strategy.h
http://commits.kde.org/calligra/ff9a841fe1fc7906da7fd071cbbb63748ac4deaf
diff --git a/krita/image/kis_algebra_2d.cpp b/krita/image/kis_algebra_2d.cpp
index ed6d15a..cbc9791 100644
--- a/krita/image/kis_algebra_2d.cpp
+++ b/krita/image/kis_algebra_2d.cpp
@@ -19,11 +19,10 @@
#include "kis_algebra_2d.h"
#include <kis_debug.h>
-#include <QPolygonF>
namespace KisAlgebra2D {
-void KRITAIMAGE_EXPORT adjustIfOnPolygonBoundary(const QVector<QPointF> &poly, int \
polygonDirection, QPointF *pt) +void KRITAIMAGE_EXPORT \
adjustIfOnPolygonBoundary(const QPolygonF &poly, int polygonDirection, QPointF *pt) \
{ const int numPoints = poly.size();
for (int i = 0; i < numPoints; i++) {
@@ -44,10 +43,17 @@ void KRITAIMAGE_EXPORT adjustIfOnPolygonBoundary(const \
QVector<QPointF> &poly, i isInRange(pt->x(), p0.x(), p1.x()) &&
isInRange(pt->y(), p0.y(), p1.y())) {
- QPointF salt = 1.0e-4 * inwardUnitNormal(edge, polygonDirection);
- *pt += salt;
+ QPointF salt = 1.0e-3 * inwardUnitNormal(edge, polygonDirection);
- KIS_ASSERT_RECOVER_NOOP(QPolygonF(poly).containsPoint(*pt, \
Qt::OddEvenFill)); + QPointF t1 = *pt + salt;
+ QPointF t2 = *pt - salt;
+
+ if (poly.contains(t1)) {
+ *pt = t1;
+ } else {
+ KIS_ASSERT_RECOVER_NOOP(poly.containsPoint(t2, Qt::OddEvenFill));
+ *pt = t2;
+ }
}
}
}
diff --git a/krita/image/kis_algebra_2d.h b/krita/image/kis_algebra_2d.h
index d2ce332..5c0b370 100644
--- a/krita/image/kis_algebra_2d.h
+++ b/krita/image/kis_algebra_2d.h
@@ -22,6 +22,7 @@
#include <QPoint>
#include <QPointF>
#include <QVector>
+#include <QPolygonF>
#include <cmath>
#include <kis_global.h>
@@ -118,7 +119,7 @@ bool isInRange(T x, T a, T b) {
return qAbs(x - a) <= length && qAbs(x - b) <= length;
}
-void KRITAIMAGE_EXPORT adjustIfOnPolygonBoundary(const QVector<QPointF> &poly, int \
polygonDirection, QPointF *pt); +void KRITAIMAGE_EXPORT \
adjustIfOnPolygonBoundary(const QPolygonF &poly, int polygonDirection, QPointF *pt); \
}
diff --git a/krita/image/kis_cage_transform_worker.cpp \
b/krita/image/kis_cage_transform_worker.cpp index 6c39354..984e063 100644
--- a/krita/image/kis_cage_transform_worker.cpp
+++ b/krita/image/kis_cage_transform_worker.cpp
@@ -22,6 +22,8 @@
#include "kis_green_coordinates_math.h"
#include "kis_algebra_2d.h"
+#include <QPainter>
+
#include "KoColor.h"
#include "kis_selection.h"
#include "kis_painter.h"
@@ -41,6 +43,10 @@ struct KisCageTransformWorker::Private
}
KisPaintDeviceSP dev;
+
+ QImage srcImage;
+ QPointF srcImageOffset;
+
QVector<QPointF> origCage;
QVector<QPointF> transfCage;
KoUpdater *progress;
@@ -52,6 +58,12 @@ struct KisCageTransformWorker::Private
KisGreenCoordinatesMath cage;
QSize gridSize;
+
+ QVector<QPointF> calculateTransformedPoints();
+
+ template <class PolygonOp>
+ void iterateThroughGrid(PolygonOp polygonOp,
+ const QVector<QPointF> &transformedPoints);
};
KisCageTransformWorker::KisCageTransformWorker(KisPaintDeviceSP dev,
@@ -62,6 +74,17 @@ KisCageTransformWorker::KisCageTransformWorker(KisPaintDeviceSP \
dev, {
}
+KisCageTransformWorker::KisCageTransformWorker(const QImage &srcImage,
+ const QPointF &srcImageOffset,
+ const QVector<QPointF> &origCage,
+ KoUpdater *progress,
+ int pixelPrecision)
+ : m_d(new Private(0, origCage, progress, pixelPrecision))
+{
+ m_d->srcImage = srcImage;
+ m_d->srcImageOffset = srcImageOffset;
+}
+
KisCageTransformWorker::~KisCageTransformWorker()
{
}
@@ -123,8 +146,10 @@ void KisCageTransformWorker::prepareTransform()
if (m_d->origCage.size() < 3) return;
const QPolygonF srcPolygon(m_d->origCage);
- const QRect srcBounds = m_d->dev->region().boundingRect() &
- srcPolygon.boundingRect().toAlignedRect();
+
+ QRect srcBounds = m_d->dev ? m_d->dev->region().boundingRect() :
+ QRectF(m_d->srcImageOffset, m_d->srcImage.size()).toAlignedRect();
+ srcBounds &= srcPolygon.boundingRect().toAlignedRect();
m_d->gridSize =
GridIterationTools::calcGridSize(srcBounds, m_d->pixelPrecision);
@@ -158,20 +183,61 @@ void KisCageTransformWorker::prepareTransform()
m_d->cage.precalculateGreenCoordinates(m_d->origCage, m_d->validPoints);
}
-void KisCageTransformWorker::run()
+QVector<QPointF> KisCageTransformWorker::Private::calculateTransformedPoints()
{
- KIS_ASSERT_RECOVER_RETURN(m_d->origCage.size() == m_d->transfCage.size());
-
- m_d->cage.generateTransformedCageNormals(m_d->transfCage);
+ cage.generateTransformedCageNormals(transfCage);
- const int numValidPoints = m_d->validPoints.size();
+ const int numValidPoints = validPoints.size();
QVector<QPointF> transformedPoints(numValidPoints);
for (int i = 0; i < numValidPoints; i++) {
- transformedPoints[i] = m_d->cage.transformedPoint(i, m_d->transfCage);
+ transformedPoints[i] = cage.transformedPoint(i, transfCage);
}
- // here the cage is not needed anymore
+ return transformedPoints;
+}
+
+template <class PolygonOp>
+void KisCageTransformWorker::Private::
+iterateThroughGrid(PolygonOp polygonOp,
+ const QVector<QPointF> &transformedPoints)
+{
+ QVector<int> polygonPoints(4);
+
+ for (int row = 0; row < gridSize.height() - 1; row++) {
+ for (int col = 0; col < gridSize.width() - 1; col++) {
+ polygonPoints[0] = allToValidPointsMap[col + row * gridSize.width()];
+ if (polygonPoints[0] < 0) continue;
+ polygonPoints[1] = allToValidPointsMap[col + 1 + row * \
gridSize.width()]; + if (polygonPoints[1] < 0) continue;
+ polygonPoints[2] = allToValidPointsMap[col + 1 + (row + 1) * \
gridSize.width()]; + if (polygonPoints[2] < 0) continue;
+ polygonPoints[3] = allToValidPointsMap[col + (row + 1) * \
gridSize.width()]; + if (polygonPoints[3] < 0) continue;
+
+ QPolygonF srcPolygon;
+ QPolygonF dstPolygon;
+
+ for (int i = 0; i < 4; i++) {
+ const int index = polygonPoints[i];
+ srcPolygon << validPoints[index];
+ dstPolygon << transformedPoints[index];
+ }
+
+ //qDebug() << ppVar(col) << ppVar(row);
+ //qDebug() << ppVar(srcPolygon);
+ //qDebug() << ppVar(dstPolygon);
+
+ polygonOp(srcPolygon, dstPolygon);
+ }
+ }
+}
+
+void KisCageTransformWorker::run()
+{
+ KIS_ASSERT_RECOVER_RETURN(m_d->origCage.size() == m_d->transfCage.size());
+
+ QVector<QPointF> transformedPoints = m_d->calculateTransformedPoints();
KisPaintDeviceSP srcDev = new KisPaintDevice(*m_d->dev.data());
@@ -190,34 +256,52 @@ void KisCageTransformWorker::run()
}
GridIterationTools::PaintDevicePolygonOp polygonOp(srcDev, m_d->dev);
+ m_d->iterateThroughGrid(polygonOp, transformedPoints);
+}
- QVector<int> polygonPoints(4);
-
- for (int row = 0; row < m_d->gridSize.height() - 1; row++) {
- for (int col = 0; col < m_d->gridSize.width() - 1; col++) {
- polygonPoints[0] = m_d->allToValidPointsMap[col + row * \
m_d->gridSize.width()];
- if (polygonPoints[0] < 0) continue;
- polygonPoints[1] = m_d->allToValidPointsMap[col + 1 + row * \
m_d->gridSize.width()];
- if (polygonPoints[1] < 0) continue;
- polygonPoints[2] = m_d->allToValidPointsMap[col + 1 + (row + 1) * \
m_d->gridSize.width()];
- if (polygonPoints[2] < 0) continue;
- polygonPoints[3] = m_d->allToValidPointsMap[col + (row + 1) * \
m_d->gridSize.width()];
- if (polygonPoints[3] < 0) continue;
+QImage KisCageTransformWorker::runOnQImage(QPointF *newOffset)
+{
+ KIS_ASSERT_RECOVER(m_d->origCage.size() == m_d->transfCage.size()) {
+ return QImage();
+ }
- QPolygonF srcPolygon;
- QPolygonF dstPolygon;
+ KIS_ASSERT_RECOVER(!m_d->srcImage.isNull()) {
+ return QImage();
+ }
- for (int i = 0; i < 4; i++) {
- const int index = polygonPoints[i];
- srcPolygon << m_d->validPoints[index];
- dstPolygon << transformedPoints[index];
- }
+ KIS_ASSERT_RECOVER(m_d->srcImage.format() == QImage::Format_ARGB32) {
+ return QImage();
+ }
- //qDebug() << ppVar(col) << ppVar(row);
- //qDebug() << ppVar(srcPolygon);
- //qDebug() << ppVar(dstPolygon);
+ QVector<QPointF> transformedPoints = m_d->calculateTransformedPoints();
- polygonOp(srcPolygon, dstPolygon);
- }
+ QRectF dstBounds;
+ foreach (const QPointF &pt, transformedPoints) {
+ kisAccumulateBounds(pt, &dstBounds);
}
+
+ const QRectF srcBounds(m_d->srcImageOffset, m_d->srcImage.size());
+ dstBounds |= srcBounds;
+
+ QPointF dstQImageOffset = dstBounds.topLeft();
+ *newOffset = dstQImageOffset;
+
+ QRect dstBoundsI = dstBounds.toAlignedRect();
+
+
+ QImage dstImage(dstBoundsI.size(), m_d->srcImage.format());
+ dstImage.fill(0);
+
+ QPainter gc(&dstImage);
+ gc.drawImage(-dstQImageOffset + m_d->srcImageOffset, m_d->srcImage);
+ gc.setBrush(Qt::black);
+ gc.setPen(Qt::black);
+ gc.setCompositionMode(QPainter::CompositionMode_Clear);
+ gc.drawPolygon(QPolygonF(m_d->origCage).translated(-dstQImageOffset));
+
+ GridIterationTools::QImagePolygonOp polygonOp(m_d->srcImage, dstImage, \
m_d->srcImageOffset, dstQImageOffset); + m_d->iterateThroughGrid(polygonOp, \
transformedPoints); +
+ return dstImage;
}
+
diff --git a/krita/image/kis_cage_transform_worker.h \
b/krita/image/kis_cage_transform_worker.h index 3de21fc..2097d1c 100644
--- a/krita/image/kis_cage_transform_worker.h
+++ b/krita/image/kis_cage_transform_worker.h
@@ -33,12 +33,20 @@ public:
KoUpdater *progress,
int pixelPrecision = 8);
+ KisCageTransformWorker(const QImage &srcImage,
+ const QPointF &srcImageOffset,
+ const QVector<QPointF> &origCage,
+ KoUpdater *progress,
+ int pixelPrecision = 8);
+
~KisCageTransformWorker();
void prepareTransform();
void setTransformedCage(const QVector<QPointF> &transformedCage);
void run();
+ QImage runOnQImage(QPointF *newOffset);
+
private:
struct Private;
const QScopedPointer<Private> m_d;
diff --git a/krita/image/kis_global.h b/krita/image/kis_global.h
index 7060919..0dc3aae 100644
--- a/krita/image/kis_global.h
+++ b/krita/image/kis_global.h
@@ -199,5 +199,25 @@ inline QRect kisEnsureInRect(QRect rc, const QRect &bounds)
return rc;
}
+template <class Point, class Rect>
+inline void kisAccumulateBounds(const Point &pt, Rect *bounds)
+{
+ if (pt.x() > bounds->right()) {
+ bounds->setRight(pt.x());
+ }
+
+ if (pt.x() < bounds->left()) {
+ bounds->setLeft(pt.x());
+ }
+
+ if (pt.y() > bounds->bottom()) {
+ bounds->setBottom(pt.y());
+ }
+
+ if (pt.y() < bounds->top()) {
+ bounds->setTop(pt.y());
+ }
+}
+
#endif // KISGLOBAL_H_
diff --git a/krita/image/kis_grid_interpolation_tools.h \
b/krita/image/kis_grid_interpolation_tools.h index d781ae4..a9d4936 100644
--- a/krita/image/kis_grid_interpolation_tools.h
+++ b/krita/image/kis_grid_interpolation_tools.h
@@ -128,7 +128,7 @@ void processGrid(ProcessCell &cellOp,
colIndex++;
if (col > srcBounds.right() &&
- col < srcBounds.right() + pixelPrecision - 1) {
+ col <= srcBounds.right() + pixelPrecision - 1) {
col = srcBounds.right();
} else {
@@ -144,7 +144,7 @@ void processGrid(ProcessCell &cellOp,
rowIndex++;
if (row > srcBounds.bottom() &&
- row < srcBounds.bottom() + pixelPrecision - 1) {
+ row <= srcBounds.bottom() + pixelPrecision - 1) {
row = srcBounds.bottom();
} else {
diff --git a/krita/image/kis_warptransform_worker.cc \
b/krita/image/kis_warptransform_worker.cc index 3051ead..af6f295 100644
--- a/krita/image/kis_warptransform_worker.cc
+++ b/krita/image/kis_warptransform_worker.cc
@@ -303,7 +303,7 @@ QImage KisWarpTransformWorker::transformQImage(WarpType warpType,
FunctionTransformOp functionOp(warpMathFunction, origPoint, transfPoint, alpha);
- const QRect srcBounds = srcImage.rect();
+ const QRectF srcBounds = QRectF(srcQImageOffset, srcImage.size());
QRectF dstBounds;
{
@@ -332,15 +332,15 @@ QImage KisWarpTransformWorker::transformQImage(WarpType \
warpType, }
QPointF dstQImageOffset = dstBounds.topLeft();
- *newOffset = srcQImageOffset + dstQImageOffset;
+ *newOffset = dstQImageOffset;
QRect dstBoundsI = dstBounds.toAlignedRect();
QImage dstImage(dstBoundsI.size(), srcImage.format());
- dstImage.fill(128);
+ dstImage.fill(0);
const int pixelPrecision = 32;
- GridIterationTools::QImagePolygonOp polygonOp(srcImage, dstImage, QPointF(), \
dstQImageOffset);
- GridIterationTools::processGrid(polygonOp, functionOp, srcBounds, \
pixelPrecision); + GridIterationTools::QImagePolygonOp polygonOp(srcImage, \
dstImage, srcQImageOffset, dstQImageOffset); + \
GridIterationTools::processGrid(polygonOp, functionOp, srcBounds.toAlignedRect(), \
pixelPrecision);
return dstImage;
}
diff --git a/krita/image/tests/kis_cage_transform_worker_test.cpp \
b/krita/image/tests/kis_cage_transform_worker_test.cpp index 958e358..5d66b5c 100644
--- a/krita/image/tests/kis_cage_transform_worker_test.cpp
+++ b/krita/image/tests/kis_cage_transform_worker_test.cpp
@@ -27,7 +27,7 @@
#include <kis_cage_transform_worker.h>
#include <algorithm>
-void testCage(bool clockwise, bool unityTransform, bool benchmarkPrepareOnly = \
false, int pixelPrecision = 8) +void testCage(bool clockwise, bool unityTransform, \
bool benchmarkPrepareOnly = false, int pixelPrecision = 8, bool testQImage = false) \
{ TestUtil::TestProgressBar bar;
KoProgressUpdater pu(&bar);
@@ -77,23 +77,46 @@ void testCage(bool clockwise, bool unityTransform, bool \
benchmarkPrepareOnly = f updater,
pixelPrecision);
- QBENCHMARK_ONCE {
- worker.prepareTransform();
+ QImage result;
+ QPointF srcQImageOffset(0, 0);
+ QPointF dstQImageOffset;
- if (!benchmarkPrepareOnly) {
- worker.setTransformedCage(transfPoints);
- worker.run();
+ QBENCHMARK_ONCE {
+ if (!testQImage) {
+ worker.prepareTransform();
+ if (!benchmarkPrepareOnly) {
+ worker.setTransformedCage(transfPoints);
+ worker.run();
+
+ }
+ } else {
+ QImage srcImage(image);
+ image = QImage(image.size(), QImage::Format_ARGB32);
+ QPainter gc(&image);
+ gc.drawImage(QPoint(), srcImage);
+
+ image.convertToFormat(QImage::Format_ARGB32);
+
+ KisCageTransformWorker qimageWorker(image,
+ srcQImageOffset,
+ origPoints,
+ updater,
+ pixelPrecision);
+ qimageWorker.prepareTransform();
+ qimageWorker.setTransformedCage(transfPoints);
+ result = qimageWorker.runOnQImage(&dstQImageOffset);
}
}
- if (!benchmarkPrepareOnly && pixelPrecision == 8) {
-
- QImage result = dev->convertToQImage(0);
+ QString testName = QString("%1_%2")
+ .arg(clockwise ? "clk" : "cclk")
+ .arg(unityTransform ? "unity" : "normal");
- QString testName = QString("%1_%2")
- .arg(clockwise ? "clk" : "cclk")
- .arg(unityTransform ? "unity" : "normal");
+ if (testQImage) {
+ QVERIFY(TestUtil::checkQImage(result, "cage_transform_test", "cage_qimage", \
testName)); + } else if (!benchmarkPrepareOnly && pixelPrecision == 8) {
+ result = dev->convertToQImage(0);
QVERIFY(TestUtil::checkQImage(result, "cage_transform_test", "cage", \
testName)); }
}
@@ -113,6 +136,11 @@ void \
KisCageTransformWorkerTest::testCageClockwisePixePrecision4() testCage(true, false, \
false, 4); }
+void KisCageTransformWorkerTest::testCageClockwisePixePrecision8QImage()
+{
+ testCage(true, false, false, 8, true);
+}
+
void KisCageTransformWorkerTest::testCageCounterclockwise()
{
testCage(false, false);
diff --git a/krita/image/tests/kis_cage_transform_worker_test.h \
b/krita/image/tests/kis_cage_transform_worker_test.h index 11e5cfc..6c60855 100644
--- a/krita/image/tests/kis_cage_transform_worker_test.h
+++ b/krita/image/tests/kis_cage_transform_worker_test.h
@@ -28,6 +28,7 @@ private slots:
void testCageClockwise();
void testCageClockwisePrepareOnly();
void testCageClockwisePixePrecision4();
+ void testCageClockwisePixePrecision8QImage();
void testCageCounterclockwise();
void testCageClockwiseUnity();
void testCageCounterclockwiseUnity();
diff --git a/krita/plugins/tools/tool_transform2/kis_cage_transform_strategy.cpp \
b/krita/plugins/tools/tool_transform2/kis_cage_transform_strategy.cpp index \
caa965f..97b6836 100644
--- a/krita/plugins/tools/tool_transform2/kis_cage_transform_strategy.cpp
+++ b/krita/plugins/tools/tool_transform2/kis_cage_transform_strategy.cpp
@@ -23,6 +23,7 @@
#include "krita_utils.h"
#include "kis_cursor.h"
+#include <kis_cage_transform_worker.h>
struct KisCageTransformStrategy::Private
@@ -76,3 +77,22 @@ void KisCageTransformStrategy::drawConnectionLines(QPainter &gc,
gc.drawLine(transfPoints[prevIdx], transfPoints[idx]);
}
}
+
+QImage KisCageTransformStrategy::calculateTransformedImage(ToolTransformArgs \
¤tArgs, + const \
QImage &srcImage, + const \
QVector<QPointF> &origPoints, + \
const QVector<QPointF> &transfPoints, + \
const QPointF &srcOffset, + \
QPointF *dstOffset) +{
+ Q_UNUSED(currentArgs);
+
+ KisCageTransformWorker worker(srcImage,
+ srcOffset,
+ origPoints,
+ 0,
+ 16);
+ worker.prepareTransform();
+ worker.setTransformedCage(transfPoints);
+ return worker.runOnQImage(dstOffset);
+}
diff --git a/krita/plugins/tools/tool_transform2/kis_cage_transform_strategy.h \
b/krita/plugins/tools/tool_transform2/kis_cage_transform_strategy.h index \
e1cb98e..59b77ed 100644
--- a/krita/plugins/tools/tool_transform2/kis_cage_transform_strategy.h
+++ b/krita/plugins/tools/tool_transform2/kis_cage_transform_strategy.h
@@ -49,6 +49,13 @@ protected:
const QVector<QPointF> &transfPoints,
bool isEditingPoints);
+ QImage calculateTransformedImage(ToolTransformArgs ¤tArgs,
+ const QImage &srcImage,
+ const QVector<QPointF> &origPoints,
+ const QVector<QPointF> &transfPoints,
+ const QPointF &srcOffset,
+ QPointF *dstOffset);
+
private:
class Private;
const QScopedPointer<Private> m_d;
diff --git a/krita/plugins/tools/tool_transform2/kis_warp_transform_strategy.cpp \
b/krita/plugins/tools/tool_transform2/kis_warp_transform_strategy.cpp index \
8fd0665..c27272b 100644
--- a/krita/plugins/tools/tool_transform2/kis_warp_transform_strategy.cpp
+++ b/krita/plugins/tools/tool_transform2/kis_warp_transform_strategy.cpp
@@ -376,13 +376,12 @@ void \
KisWarpTransformStrategy::Private::recalculateTransformations()
}
- transformedImage =
- KisWarpTransformWorker::transformQImage(
- currentArgs.warpType(),
- thumbOrigPoints, thumbTransfPoints,
- currentArgs.alpha(),
- transformedImage,
- origTLInFlake, &paintingOffset);
+ transformedImage = q->calculateTransformedImage(currentArgs,
+ transformedImage,
+ thumbOrigPoints,
+ thumbTransfPoints,
+ origTLInFlake,
+ &paintingOffset);
} else {
transformedImage = q->originalImage();
paintingOffset = imageToThumb(transaction.originalTopLeft(), false);
@@ -391,3 +390,18 @@ void \
KisWarpTransformStrategy::Private::recalculateTransformations()
handlesTransform = scaleTransform;
}
+
+QImage KisWarpTransformStrategy::calculateTransformedImage(ToolTransformArgs \
¤tArgs, + const \
QImage &srcImage, + const \
QVector<QPointF> &origPoints, + \
const QVector<QPointF> &transfPoints, + \
const QPointF &srcOffset, + \
QPointF *dstOffset) +{
+ return KisWarpTransformWorker::transformQImage(
+ currentArgs.warpType(),
+ origPoints, transfPoints,
+ currentArgs.alpha(),
+ srcImage,
+ srcOffset, dstOffset);
+}
diff --git a/krita/plugins/tools/tool_transform2/kis_warp_transform_strategy.h \
b/krita/plugins/tools/tool_transform2/kis_warp_transform_strategy.h index \
bc0e690..655bea4 100644
--- a/krita/plugins/tools/tool_transform2/kis_warp_transform_strategy.h
+++ b/krita/plugins/tools/tool_transform2/kis_warp_transform_strategy.h
@@ -72,6 +72,13 @@ protected:
const QVector<QPointF> &origPoints,
const QVector<QPointF> &transfPoints,
bool isEditingPoints);
+
+ virtual QImage calculateTransformedImage(ToolTransformArgs ¤tArgs,
+ const QImage &srcImage,
+ const QVector<QPointF> &origPoints,
+ const QVector<QPointF> &transfPoints,
+ const QPointF &srcOffset,
+ QPointF *dstOffset);
private:
class Private;
const QScopedPointer<Private> m_d;
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic