Krita Source Code Documentation
Loading...
Searching...
No Matches
GridIterationTools Namespace Reference

Namespaces

namespace  Private
 

Classes

struct  AlwaysCompletePolygonPolicy
 
struct  CellOp
 
struct  IncompletePolygonPolicy
 
struct  PaintDevicePolygonOp
 
struct  QImagePolygonOp
 
struct  RegularGridIndexesOp
 

Functions

void adjustAlignedPolygon (QPolygonF &polygon)
 
int calcGridDimension (int start, int end, const int pixelPrecision)
 
QSize calcGridSize (const QRect &srcBounds, const int pixelPrecision)
 
QVector< int > calculateCellIndexes (int col, int row, const QSize &gridSize)
 
template<class IndexesOp >
bool getOrthogonalPointApproximation (const QPoint &cellPt, const QVector< QPointF > &originalPoints, const QVector< QPointF > &transformedPoints, IndexesOp indexesOp, QPointF *srcPoint, QPointF *dstPoint)
 
template<template< class PolygonOp, class IndexesOp > class IncompletePolygonPolicy, class PolygonOp , class IndexesOp >
void iterateThroughGrid (PolygonOp &polygonOp, IndexesOp &indexesOp, const QSize &gridSize, const QVector< QPointF > &originalPoints, const QVector< QPointF > &transformedPoints)
 
int pointToIndex (const QPoint &cellPt, const QSize &gridSize)
 
template<class ProcessCell >
void processGrid (ProcessCell &cellOp, const QRect &srcBounds, const int pixelPrecision)
 
template<class ProcessPolygon , class ForwardTransform >
void processGrid (ProcessPolygon &polygonOp, ForwardTransform &transformOp, const QRect &srcBounds, const int pixelPrecision)
 

Function Documentation

◆ adjustAlignedPolygon()

void GridIterationTools::adjustAlignedPolygon ( QPolygonF & polygon)
inline

There is a weird problem in fetching correct bounds of the polygon. If the rightmost (bottommost) point of the polygon is integral, then QRectF() will end exactly on it, but when converting into QRect the last point will not be taken into account. It happens due to the difference between center-point/topleft-point point representation. In many cases the latter is expected, but we don't work with it in Qt/Krita.

Definition at line 586 of file kis_grid_interpolation_tools.h.

587{
588 static const qreal eps = 1e-5;
589 static const QPointF p1(eps, 0.0);
590 static const QPointF p2(eps, eps);
591 static const QPointF p3(0.0, eps);
592
593 polygon[1] += p1;
594 polygon[2] += p2;
595 polygon[3] += p3;
596}
QPointF p2
QPointF p3
QPointF p1
const qreal eps

References eps, p1, p2, and p3.

◆ calcGridDimension()

int GridIterationTools::calcGridDimension ( int start,
int end,
const int pixelPrecision )
inline

Definition at line 29 of file kis_grid_interpolation_tools.h.

30{
31 const int alignmentMask = ~(pixelPrecision - 1);
32
33 int alignedStart = (start + pixelPrecision - 1) & alignmentMask;
34 int alignedEnd = end & alignmentMask;
35
36 int size = 0;
37
38 if (alignedEnd > alignedStart) {
39 size = (alignedEnd - alignedStart) / pixelPrecision + 1;
40 size += alignedStart != start;
41 size += alignedEnd != end;
42 } else {
43 size = 2 + (end - start >= pixelPrecision);
44 }
45
46 return size;
47}
int size(const Forest< T > &forest)
Definition KisForest.h:1232

◆ calcGridSize()

QSize GridIterationTools::calcGridSize ( const QRect & srcBounds,
const int pixelPrecision )
inline

Definition at line 49 of file kis_grid_interpolation_tools.h.

49 {
50 return QSize(calcGridDimension(srcBounds.x(), srcBounds.right(), pixelPrecision),
51 calcGridDimension(srcBounds.y(), srcBounds.bottom(), pixelPrecision));
52}
int calcGridDimension(int start, int end, const int pixelPrecision)

References calcGridDimension().

◆ calculateCellIndexes()

QVector< int > GridIterationTools::calculateCellIndexes ( int col,
int row,
const QSize & gridSize )
inline

A--—B The polygons will be in the following order: | | | | polygon << A << B << D << C; C--—D

Definition at line 319 of file kis_grid_interpolation_tools.h.

320{
321 const int tl = col + row * gridSize.width();
322 const int tr = tl + 1;
323 const int bl = tl + gridSize.width();
324 const int br = bl + 1;
325
326 QVector<int> cellIndexes;
327 cellIndexes << tl;
328 cellIndexes << tr;
329 cellIndexes << br;
330 cellIndexes << bl;
331
332 return cellIndexes;
333}

◆ getOrthogonalPointApproximation()

template<class IndexesOp >
bool GridIterationTools::getOrthogonalPointApproximation ( const QPoint & cellPt,
const QVector< QPointF > & originalPoints,
const QVector< QPointF > & transformedPoints,
IndexesOp indexesOp,
QPointF * srcPoint,
QPointF * dstPoint )

Definition at line 362 of file kis_grid_interpolation_tools.h.

368{
369 QVector<Private::PointExtension> extensionPoints;
371
372 // left
373 if ((ext.near = indexesOp.tryGetValidIndex(cellPt + QPoint(-1, 0))) >= 0 &&
374 (ext.far = indexesOp.tryGetValidIndex(cellPt + QPoint(-2, 0))) >= 0) {
375
376 extensionPoints << ext;
377 }
378 // top
379 if ((ext.near = indexesOp.tryGetValidIndex(cellPt + QPoint(0, -1))) >= 0 &&
380 (ext.far = indexesOp.tryGetValidIndex(cellPt + QPoint(0, -2))) >= 0) {
381
382 extensionPoints << ext;
383 }
384 // right
385 if ((ext.near = indexesOp.tryGetValidIndex(cellPt + QPoint(1, 0))) >= 0 &&
386 (ext.far = indexesOp.tryGetValidIndex(cellPt + QPoint(2, 0))) >= 0) {
387
388 extensionPoints << ext;
389 }
390 // bottom
391 if ((ext.near = indexesOp.tryGetValidIndex(cellPt + QPoint(0, 1))) >= 0 &&
392 (ext.far = indexesOp.tryGetValidIndex(cellPt + QPoint(0, 2))) >= 0) {
393
394 extensionPoints << ext;
395 }
396
397 if (extensionPoints.isEmpty()) {
398 // top-left
399 if ((ext.near = indexesOp.tryGetValidIndex(cellPt + QPoint(-1, -1))) >= 0 &&
400 (ext.far = indexesOp.tryGetValidIndex(cellPt + QPoint(-2, -2))) >= 0) {
401
402 extensionPoints << ext;
403 }
404 // top-right
405 if ((ext.near = indexesOp.tryGetValidIndex(cellPt + QPoint(1, -1))) >= 0 &&
406 (ext.far = indexesOp.tryGetValidIndex(cellPt + QPoint(2, -2))) >= 0) {
407
408 extensionPoints << ext;
409 }
410 // bottom-right
411 if ((ext.near = indexesOp.tryGetValidIndex(cellPt + QPoint(1, 1))) >= 0 &&
412 (ext.far = indexesOp.tryGetValidIndex(cellPt + QPoint(2, 2))) >= 0) {
413
414 extensionPoints << ext;
415 }
416 // bottom-left
417 if ((ext.near = indexesOp.tryGetValidIndex(cellPt + QPoint(-1, 1))) >= 0 &&
418 (ext.far = indexesOp.tryGetValidIndex(cellPt + QPoint(-2, 2))) >= 0) {
419
420 extensionPoints << ext;
421 }
422 }
423
424 if (extensionPoints.isEmpty()) {
425 return false;
426 }
427
428 int numResultPoints = 0;
429 *srcPoint = indexesOp.getSrcPointForce(cellPt);
430 *dstPoint = QPointF();
431
432 Q_FOREACH (const Private::PointExtension &ext, extensionPoints) {
433 QPointF near = transformedPoints[ext.near];
434 QPointF far = transformedPoints[ext.far];
435
436 QPointF nearSrc = originalPoints[ext.near];
437 QPointF farSrc = originalPoints[ext.far];
438
439 QPointF base1 = nearSrc - farSrc;
440 QPointF base2 = near - far;
441
442 QPointF pt = near +
443 KisAlgebra2D::transformAsBase(*srcPoint - nearSrc, base1, base2);
444
445 *dstPoint += pt;
446 numResultPoints++;
447 }
448
449 *dstPoint /= numResultPoints;
450
451 return true;
452}
QPointF dstPoint
QPointF transformAsBase(const QPointF &pt, const QPointF &base1, const QPointF &base2)

References dstPoint, GridIterationTools::Private::PointExtension::far, GridIterationTools::Private::PointExtension::near, and KisAlgebra2D::transformAsBase().

◆ iterateThroughGrid()

template<template< class PolygonOp, class IndexesOp > class IncompletePolygonPolicy, class PolygonOp , class IndexesOp >
void GridIterationTools::iterateThroughGrid ( PolygonOp & polygonOp,
IndexesOp & indexesOp,
const QSize & gridSize,
const QVector< QPointF > & originalPoints,
const QVector< QPointF > & transformedPoints )

Definition at line 601 of file kis_grid_interpolation_tools.h.

606{
607 QVector<int> polygonPoints(4);
608
609 for (int row = 0; row < gridSize.height() - 1; row++) {
610 for (int col = 0; col < gridSize.width() - 1; col++) {
611 int numExistingPoints = 0;
612
613 polygonPoints = indexesOp.calculateMappedIndexes(col, row, &numExistingPoints);
614
616 tryProcessPolygon(col, row,
617 numExistingPoints,
618 polygonOp,
619 indexesOp,
620 polygonPoints,
621 originalPoints,
622 transformedPoints)) {
623
624 QPolygonF srcPolygon;
625 QPolygonF dstPolygon;
626
627 for (int i = 0; i < 4; i++) {
628 const int index = polygonPoints[i];
629 srcPolygon << originalPoints[index];
630 dstPolygon << transformedPoints[index];
631 }
632
633 adjustAlignedPolygon(srcPolygon);
634 adjustAlignedPolygon(dstPolygon);
635
636 polygonOp(srcPolygon, dstPolygon);
637 }
638 }
639 }
640}

References adjustAlignedPolygon().

◆ pointToIndex()

int GridIterationTools::pointToIndex ( const QPoint & cellPt,
const QSize & gridSize )
inline

Definition at line 335 of file kis_grid_interpolation_tools.h.

336{
337 return cellPt.x() +
338 cellPt.y() * gridSize.width();
339}

◆ processGrid() [1/2]

template<class ProcessCell >
void GridIterationTools::processGrid ( ProcessCell & cellOp,
const QRect & srcBounds,
const int pixelPrecision )

Definition at line 106 of file kis_grid_interpolation_tools.h.

109{
110 if (srcBounds.isEmpty()) return;
111
112 const int alignmentMask = ~(pixelPrecision - 1);
113
114 int prevRow = std::numeric_limits<int>::max();
115 int prevCol = std::numeric_limits<int>::max();
116
117 int rowIndex = 0;
118 int colIndex = 0;
119
120 for (int row = srcBounds.top(); row <= srcBounds.bottom();) {
121 for (int col = srcBounds.left(); col <= srcBounds.right();) {
122
123 cellOp.processPoint(col, row,
124 prevCol, prevRow,
125 colIndex, rowIndex);
126
127 prevCol = col;
128 col += pixelPrecision;
129 colIndex++;
130
131 if (col > srcBounds.right() &&
132 col <= srcBounds.right() + pixelPrecision - 1) {
133
134 col = srcBounds.right();
135 } else {
136 col &= alignmentMask;
137 }
138 }
139
140 cellOp.nextLine();
141 colIndex = 0;
142
143 prevRow = row;
144 row += pixelPrecision;
145 rowIndex++;
146
147 if (row > srcBounds.bottom() &&
148 row <= srcBounds.bottom() + pixelPrecision - 1) {
149
150 row = srcBounds.bottom();
151 } else {
152 row &= alignmentMask;
153 }
154 }
155}

◆ processGrid() [2/2]

template<class ProcessPolygon , class ForwardTransform >
void GridIterationTools::processGrid ( ProcessPolygon & polygonOp,
ForwardTransform & transformOp,
const QRect & srcBounds,
const int pixelPrecision )

Definition at line 158 of file kis_grid_interpolation_tools.h.

160{
161 CellOp<ProcessPolygon, ForwardTransform> cellOp(polygonOp, transformOp);
162 processGrid(cellOp, srcBounds, pixelPrecision);
163}
void processGrid(ProcessCell &cellOp, const QRect &srcBounds, const int pixelPrecision)

References processGrid().