Commit e4db0858 authored by Dmitry Kazakov's avatar Dmitry Kazakov

Cage Transform is ready for testing (implemented the last bit: extrapolation)

That was a tough task. The points outside of the outline of the cage
are not defined in green coordinates, so we would either need to:

- chop the grid into smaller chunks near the outline, which would make
  the grid non-uniform with lots of inherited complications

- extrapolate the points near the outline of the cage based on the
  internal points which lay inside the cage polygon.

I chose the latter approach. It is much easier to implement, but has one
small drawback. Sometimes, if your cage is too narrow (e.g. 8-16px wide),
the interpolator may not find the points suitable for a base. In such a case
the corresponding cell of the grind will be dropped from the processing
and you may see an empty cell.

The cell sizes:

1) Preview: 16 px
2) Real transform: 8 px

So when creating the cage, just ensure you are not creating the cage
polygons more narrow than 8 px. This limitation applies only to the
non-deformed grid. The deformed one can have arbitrary configuration.

CCMAIL:kimageshop@kde.org
parent 90a070f5
This diff is collapsed.
......@@ -28,6 +28,11 @@
#include "kis_iterator_ng.h"
#include "kis_random_sub_accessor.h"
//#define DEBUG_PAINTING_POLYGONS
#ifdef DEBUG_PAINTING_POLYGONS
#include <QPainter>
#endif /* DEBUG_PAINTING_POLYGONS */
namespace GridIterationTools {
......@@ -167,7 +172,11 @@ struct PaintDevicePolygonOp
: m_srcDev(srcDev), m_dstDev(dstDev) {}
void operator() (const QPolygonF &srcPolygon, const QPolygonF &dstPolygon) {
QRect boundRect = dstPolygon.boundingRect().toAlignedRect();
this->operator() (srcPolygon, dstPolygon, dstPolygon);
}
void operator() (const QPolygonF &srcPolygon, const QPolygonF &dstPolygon, const QPolygonF &clipDstPolygon) {
QRect boundRect = clipDstPolygon.boundingRect().toAlignedRect();
KisSequentialIterator dstIt(m_dstDev, boundRect);
KisRandomSubAccessorSP srcAcc = m_srcDev->createRandomSubAccessor();
......@@ -186,7 +195,7 @@ struct PaintDevicePolygonOp
QPointF srcPoint(dstIt.x(), y);
if (dstPolygon.containsPoint(srcPoint, Qt::OddEvenFill)) {
if (clipDstPolygon.containsPoint(srcPoint, Qt::OddEvenFill)) {
interp.setX(srcPoint.x());
QPointF dstPoint = interp.getValue();
......@@ -224,7 +233,11 @@ struct QImagePolygonOp
}
void operator() (const QPolygonF &srcPolygon, const QPolygonF &dstPolygon) {
QRect boundRect = dstPolygon.boundingRect().toAlignedRect();
this->operator() (srcPolygon, dstPolygon, dstPolygon);
}
void operator() (const QPolygonF &srcPolygon, const QPolygonF &dstPolygon, const QPolygonF &clipDstPolygon) {
QRect boundRect = clipDstPolygon.boundingRect().toAlignedRect();
KisFourPointInterpolatorBackward interp(srcPolygon, dstPolygon);
for (int y = boundRect.top(); y <= boundRect.bottom(); y++) {
......@@ -232,7 +245,7 @@ struct QImagePolygonOp
for (int x = boundRect.left(); x <= boundRect.right(); x++) {
QPointF srcPoint(x, y);
if (dstPolygon.containsPoint(srcPoint, Qt::OddEvenFill)) {
if (clipDstPolygon.containsPoint(srcPoint, Qt::OddEvenFill)) {
interp.setX(srcPoint.x());
QPointF dstPoint = interp.getValue();
......@@ -255,6 +268,20 @@ struct QImagePolygonOp
}
}
}
#ifdef DEBUG_PAINTING_POLYGONS
QPainter gc(&m_dstImage);
gc.setPen(Qt::red);
gc.setOpacity(0.5);
gc.setBrush(Qt::green);
gc.drawPolygon(clipDstPolygon.translated(-m_dstImageOffset));
gc.setBrush(Qt::blue);
//gc.drawPolygon(dstPolygon.translated(-m_dstImageOffset));
#endif /* DEBUG_PAINTING_POLYGONS */
}
const QImage &m_srcImage;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment