Krita Source Code Documentation
Loading...
Searching...
No Matches
KisCageTransformWorker Class Reference

#include <kis_cage_transform_worker.h>

+ Inheritance diagram for KisCageTransformWorker:

Public Member Functions

QRect approxChangeRect (const QRect &rc)
 
QRect approxNeedRect (const QRect &rc, const QRect &fullBounds)
 
QVector< int > calculateMappedIndexes (int col, int row, int *numExistingPoints)
 
QVector< QPointF > calculateTransformedPoints ()
 
bool isGridEmpty () const
 
 KisCageTransformWorker (const QImage &srcImage, const QPointF &srcImageOffset, const QVector< QPointF > &origCage, KoUpdater *progress, int pixelPrecision=8)
 
 KisCageTransformWorker (const QRect &deviceNonDefaultRegion, const QVector< QPointF > &origCage, KoUpdater *progress, int pixelPrecision=8)
 
void prepareTransform ()
 
 Private (const QVector< QPointF > &_origCage, KoUpdater *_progress, int _pixelPrecision)
 
void run (KisPaintDeviceSP srcDevice, KisPaintDeviceSP dstDevice)
 
QImage runOnQImage (QPointF *newOffset)
 
void setTransformedCage (const QVector< QPointF > &transformedCage)
 
int tryGetValidIndex (const QPoint &cellPt)
 
 ~KisCageTransformWorker ()
 
- Public Member Functions inherited from Private
 Private (KisCanvas2 *c)
 

Public Attributes

QVector< QPointF > allSrcPoints
 
QVector< int > allToValidPointsMap
 
KisGreenCoordinatesMath cage
 
QSize gridSize
 
QVector< QPointF > origCage
 
int pixelPrecision
 
KoUpdaterprogress
 
QRect srcBounds
 
QImage srcImage
 
QPointF srcImageOffset
 
QVector< QPointF > transfCage
 
QVector< QPointF > validPoints
 
- Public Attributes inherited from Private
KisCanvas2canvas
 
int displayedFrame
 
int intendedFrame
 

Private Attributes

const QScopedPointer< Privatem_d
 

Detailed Description

Definition at line 22 of file kis_cage_transform_worker.cpp.

Constructor & Destructor Documentation

◆ KisCageTransformWorker() [1/2]

KisCageTransformWorker::KisCageTransformWorker ( const QRect & deviceNonDefaultRegion,
const QVector< QPointF > & origCage,
KoUpdater * progress,
int pixelPrecision = 8 )

Definition at line 71 of file kis_cage_transform_worker.cpp.

76{
77 m_d->srcBounds = deviceNonDefaultRegion;
78}
const QScopedPointer< Private > m_d

References m_d.

◆ KisCageTransformWorker() [2/2]

KisCageTransformWorker::KisCageTransformWorker ( const QImage & srcImage,
const QPointF & srcImageOffset,
const QVector< QPointF > & origCage,
KoUpdater * progress,
int pixelPrecision = 8 )

Definition at line 80 of file kis_cage_transform_worker.cpp.

86{
87 m_d->srcImage = srcImage;
88 m_d->srcImageOffset = srcImageOffset;
89 m_d->srcBounds = QRectF(m_d->srcImageOffset, m_d->srcImage.size()).toAlignedRect();
90}

References m_d, srcImage, and srcImageOffset.

◆ ~KisCageTransformWorker()

KisCageTransformWorker::~KisCageTransformWorker ( )

Definition at line 92 of file kis_cage_transform_worker.cpp.

93{
94}

Member Function Documentation

◆ approxChangeRect()

QRect KisCageTransformWorker::approxChangeRect ( const QRect & rc)

Definition at line 272 of file kis_cage_transform_worker.cpp.

273{
274 const qreal margin = 0.30;
275
276 QVector<QPointF> cageSamplePoints;
277
278 const int minStep = 3;
279 const int maxSamples = 200;
280
281 const int totalPixels = rc.width() * rc.height();
282 const int realStep = qMax(minStep, totalPixels / maxSamples);
283 const QPolygonF cagePolygon(m_d->origCage);
284
285 for (int i = 0; i < totalPixels; i += realStep) {
286 const int x = rc.x() + i % rc.width();
287 const int y = rc.y() + i / rc.width();
288
289 const QPointF pt(x, y);
290 if (cagePolygon.containsPoint(pt, Qt::OddEvenFill)) {
291 cageSamplePoints << pt;
292 }
293 }
294
295 if (cageSamplePoints.isEmpty()) {
296 return rc;
297 }
298
300 cage.precalculateGreenCoordinates(m_d->origCage, cageSamplePoints);
302
303 const int numValidPoints = cageSamplePoints.size();
304 QVector<QPointF> transformedPoints(numValidPoints);
305
306 int failedPoints = 0;
307
308 for (int i = 0; i < numValidPoints; i++) {
309 transformedPoints[i] = cage.transformedPoint(i, m_d->transfCage);
310
311 if (qIsNaN(transformedPoints[i].x()) ||
312 qIsNaN(transformedPoints[i].y())) {
313
314 transformedPoints[i] = cageSamplePoints[i];
315 failedPoints++;
316 }
317 }
318
319 QRect resultRect =
320 KisAlgebra2D::approximateRectFromPoints(transformedPoints).toAlignedRect();
321
322 return KisAlgebra2D::blowRect(resultRect | rc, margin);
323}
Rect blowRect(const Rect &rect, qreal coeff)
QRect approximateRectFromPoints(const QVector< QPoint > &points)
void generateTransformedCageNormals(const QVector< QPointF > &transformedCage)
QPointF transformedPoint(int pointIndex, const QVector< QPointF > &transformedCage)
void precalculateGreenCoordinates(const QVector< QPointF > &originalCage, const QVector< QPointF > &points)

References KisAlgebra2D::approximateRectFromPoints(), KisAlgebra2D::blowRect(), cage, KisGreenCoordinatesMath::generateTransformedCageNormals(), m_d, KisGreenCoordinatesMath::precalculateGreenCoordinates(), and KisGreenCoordinatesMath::transformedPoint().

◆ approxNeedRect()

QRect KisCageTransformWorker::approxNeedRect ( const QRect & rc,
const QRect & fullBounds )

Definition at line 325 of file kis_cage_transform_worker.cpp.

326{
327 Q_UNUSED(rc);
328 return fullBounds;
329}

◆ calculateMappedIndexes()

QVector< int > KisCageTransformWorker::calculateMappedIndexes ( int col,
int row,
int * numExistingPoints )
inline

◆ calculateTransformedPoints()

QVector< QPointF > KisCageTransformWorker::calculateTransformedPoints ( )

◆ isGridEmpty()

bool KisCageTransformWorker::isGridEmpty ( ) const
inline

Definition at line 56 of file kis_cage_transform_worker.cpp.

56 {
57 return allSrcPoints.isEmpty();
58 }

◆ prepareTransform()

void KisCageTransformWorker::prepareTransform ( )

Definition at line 143 of file kis_cage_transform_worker.cpp.

144{
145 if (m_d->origCage.size() < 3) return;
146
147 const QPolygonF srcPolygon(m_d->origCage);
148
149 QRect srcBounds = m_d->srcBounds;
150 srcBounds &= srcPolygon.boundingRect().toAlignedRect();
151
152 // no need to process empty devices
153 if (srcBounds.isEmpty()) return;
154 m_d->gridSize =
156
157 PointsFetcherOp pointsOp(srcPolygon);
158 GridIterationTools::processGrid(pointsOp, srcBounds, m_d->pixelPrecision);
159
160 const int numPoints = pointsOp.m_points.size();
161 KIS_ASSERT_RECOVER_RETURN(numPoints == m_d->gridSize.width() * m_d->gridSize.height());
162
163 m_d->allSrcPoints = pointsOp.m_points;
164 m_d->allToValidPointsMap.resize(pointsOp.m_points.size());
165 m_d->validPoints.resize(pointsOp.m_numValidPoints);
166
167 {
168 int validIdx = 0;
169 for (int i = 0; i < numPoints; i++) {
170 const QPointF &pt = pointsOp.m_points[i];
171 const bool pointValid = pointsOp.m_pointValid[i];
172
173 if (pointValid) {
174 m_d->validPoints[validIdx] = pt;
175 m_d->allToValidPointsMap[i] = validIdx;
176 validIdx++;
177 } else {
178 m_d->allToValidPointsMap[i] = -1;
179 }
180 }
181 KIS_ASSERT_RECOVER_NOOP(validIdx == m_d->validPoints.size());
182 }
183
184 m_d->cage.precalculateGreenCoordinates(m_d->origCage, m_d->validPoints);
185}
#define KIS_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:75
#define KIS_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:97
void processGrid(ProcessCell &cellOp, const QRect &srcBounds, const int pixelPrecision)
QSize calcGridSize(const QRect &srcBounds, const int pixelPrecision)

References GridIterationTools::calcGridSize(), KIS_ASSERT_RECOVER_NOOP, KIS_ASSERT_RECOVER_RETURN, m_d, PointsFetcherOp::m_numValidPoints, PointsFetcherOp::m_points, PointsFetcherOp::m_pointValid, GridIterationTools::processGrid(), and srcBounds.

◆ Private()

KisCageTransformWorker::Private ( const QVector< QPointF > & _origCage,
KoUpdater * _progress,
int _pixelPrecision )
inline

Definition at line 24 of file kis_cage_transform_worker.cpp.

27 : origCage(_origCage),
28 progress(_progress),
29 pixelPrecision(_pixelPrecision)
30 {
31 }

◆ run()

void KisCageTransformWorker::run ( KisPaintDeviceSP srcDevice,
KisPaintDeviceSP dstDevice )

Definition at line 331 of file kis_cage_transform_worker.cpp.

332{
333 if (m_d->isGridEmpty()) return;
334
335 KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->origCage.size() >= 3);
336 KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->origCage.size() == m_d->transfCage.size());
337 KIS_SAFE_ASSERT_RECOVER_RETURN(*srcDevice->colorSpace() == *dstDevice->colorSpace());
338
339 QVector<QPointF> transformedPoints = m_d->calculateTransformedPoints();
340
341 KisPaintDeviceSP tempDevice = new KisPaintDevice(dstDevice->colorSpace());
342
343 {
344 KisSelectionSP selection = new KisSelection();
345
346 KisPainter painter(selection->pixelSelection());
347 painter.setPaintColor(KoColor(Qt::black, selection->pixelSelection()->colorSpace()));
348 painter.setAntiAliasPolygonFill(true);
349 painter.setFillStyle(KisPainter::FillStyleForegroundColor);
350 painter.setStrokeStyle(KisPainter::StrokeStyleNone);
351
352 painter.paintPolygon(m_d->origCage);
353
354 dstDevice->clearSelection(selection);
355 }
356
357 GridIterationTools::PaintDevicePolygonOp polygonOp(srcDevice, tempDevice);
358 Private::MapIndexesOp indexesOp(m_d.data());
360 <GridIterationTools::IncompletePolygonPolicy>(polygonOp, indexesOp,
361 m_d->gridSize,
362 m_d->validPoints,
363 transformedPoints);
364
365 QRect rect = tempDevice->extent();
366 KisPainter gc(dstDevice);
367 gc.bitBlt(rect.topLeft(), tempDevice, rect);
368}
QRect extent() const
const KoColorSpace * colorSpace() const
void clearSelection(KisSelectionSP selection)
@ FillStyleForegroundColor
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
void iterateThroughGrid(PolygonOp &polygonOp, IndexesOp &indexesOp, const QSize &gridSize, const QVector< QPointF > &originalPoints, const QVector< QPointF > &transformedPoints)
KisPixelSelectionSP pixelSelection

References KisPainter::bitBlt(), KisPaintDevice::clearSelection(), KisPaintDevice::colorSpace(), KisPaintDevice::extent(), KisPainter::FillStyleForegroundColor, GridIterationTools::iterateThroughGrid(), KIS_SAFE_ASSERT_RECOVER_RETURN, m_d, KisPainter::paintPolygon(), KisSelection::pixelSelection, KisPainter::setAntiAliasPolygonFill(), KisPainter::setFillStyle(), KisPainter::setPaintColor(), KisPainter::setStrokeStyle(), and KisPainter::StrokeStyleNone.

◆ runOnQImage()

QImage KisCageTransformWorker::runOnQImage ( QPointF * newOffset)

Definition at line 370 of file kis_cage_transform_worker.cpp.

371{
372 if (m_d->isGridEmpty()) return QImage();
373
374 KIS_ASSERT_RECOVER(m_d->origCage.size() >= 3 &&
375 m_d->origCage.size() == m_d->transfCage.size()) {
376 return QImage();
377 }
378
379 KIS_ASSERT_RECOVER(!m_d->srcImage.isNull()) {
380 return QImage();
381 }
382
383 KIS_ASSERT_RECOVER(m_d->srcImage.format() == QImage::Format_ARGB32) {
384 return QImage();
385 }
386
387 QVector<QPointF> transformedPoints = m_d->calculateTransformedPoints();
388
389 QRectF dstBounds;
390 Q_FOREACH (const QPointF &pt, transformedPoints) {
391 KisAlgebra2D::accumulateBounds(pt, &dstBounds);
392 }
393
394 const QRectF srcBounds(m_d->srcImageOffset, m_d->srcImage.size());
395 dstBounds |= srcBounds;
396
397 QPointF dstQImageOffset = dstBounds.topLeft();
398 *newOffset = dstQImageOffset;
399
400 QRect dstBoundsI = dstBounds.toAlignedRect();
401
402
403 QImage dstImage(dstBoundsI.size(), m_d->srcImage.format());
404 dstImage.fill(0);
405
406 QImage tempImage(dstImage);
407
408 {
409 // we shouldn't create too many painters
410 QPainter gc(&dstImage);
411 gc.drawImage(-dstQImageOffset + m_d->srcImageOffset, m_d->srcImage);
412 gc.setBrush(Qt::black);
413 gc.setPen(Qt::black);
414 gc.setCompositionMode(QPainter::CompositionMode_Clear);
415 gc.drawPolygon(QPolygonF(m_d->origCage).translated(-dstQImageOffset));
416 gc.end();
417 }
418
419 GridIterationTools::QImagePolygonOp polygonOp(m_d->srcImage, tempImage, m_d->srcImageOffset, dstQImageOffset);
420 Private::MapIndexesOp indexesOp(m_d.data());
422 <GridIterationTools::IncompletePolygonPolicy>(polygonOp, indexesOp,
423 m_d->gridSize,
424 m_d->validPoints,
425 transformedPoints);
426
427 {
428 QPainter gc(&dstImage);
429 gc.drawImage(QPoint(), tempImage);
430 }
431
432 return dstImage;
433}
#define KIS_ASSERT_RECOVER(cond)
Definition kis_assert.h:55
void accumulateBounds(const Point &pt, Rect *bounds)

References KisAlgebra2D::accumulateBounds(), GridIterationTools::iterateThroughGrid(), KIS_ASSERT_RECOVER, m_d, and srcBounds.

◆ setTransformedCage()

void KisCageTransformWorker::setTransformedCage ( const QVector< QPointF > & transformedCage)

Definition at line 96 of file kis_cage_transform_worker.cpp.

97{
98 m_d->transfCage = transformedCage;
99}

References m_d.

◆ tryGetValidIndex()

int KisCageTransformWorker::tryGetValidIndex ( const QPoint & cellPt)

Member Data Documentation

◆ allSrcPoints

QVector<QPointF> KisCageTransformWorker::allSrcPoints

Contains all points of the grid including non-defined points (the ones which are placed outside the cage).

Definition at line 50 of file kis_cage_transform_worker.cpp.

◆ allToValidPointsMap

QVector<int> KisCageTransformWorker::allToValidPointsMap

Definition at line 43 of file kis_cage_transform_worker.cpp.

◆ cage

KisGreenCoordinatesMath KisCageTransformWorker::cage

Definition at line 52 of file kis_cage_transform_worker.cpp.

◆ gridSize

QSize KisCageTransformWorker::gridSize

Definition at line 54 of file kis_cage_transform_worker.cpp.

◆ m_d

const QScopedPointer<Private> KisCageTransformWorker::m_d
private

Definition at line 43 of file kis_cage_transform_worker.h.

◆ origCage

QVector<QPointF> KisCageTransformWorker::origCage

Definition at line 38 of file kis_cage_transform_worker.cpp.

◆ pixelPrecision

int KisCageTransformWorker::pixelPrecision

Definition at line 41 of file kis_cage_transform_worker.cpp.

◆ progress

KoUpdater* KisCageTransformWorker::progress

Definition at line 40 of file kis_cage_transform_worker.cpp.

◆ srcBounds

QRect KisCageTransformWorker::srcBounds

Definition at line 33 of file kis_cage_transform_worker.cpp.

◆ srcImage

QImage KisCageTransformWorker::srcImage

Definition at line 35 of file kis_cage_transform_worker.cpp.

◆ srcImageOffset

QPointF KisCageTransformWorker::srcImageOffset

Definition at line 36 of file kis_cage_transform_worker.cpp.

◆ transfCage

QVector<QPointF> KisCageTransformWorker::transfCage

Definition at line 39 of file kis_cage_transform_worker.cpp.

◆ validPoints

QVector<QPointF> KisCageTransformWorker::validPoints

Definition at line 44 of file kis_cage_transform_worker.cpp.


The documentation for this class was generated from the following files: