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

#include <KisBezierPatch.h>

+ Inheritance diagram for KisBezierPatch:

Public Types

enum  ControlPointType {
  TL = 0 , TL_HC , TL_VC , TR ,
  TR_HC , TR_VC , BL , BL_HC ,
  BL_VC , BR , BR_HC , BR_VC
}
 

Public Member Functions

QRectF dstBoundingRect () const
 
QPointF globalToLocal (const QPointF &pt) const
 
QPointF localToGlobal (const QPointF &pt) const
 
void sampleRegularGrid (QSize &gridSize, QVector< QPointF > &origPoints, QVector< QPointF > &transfPoints, const QPointF &dstStep) const
 
void sampleRegularGridSVG2 (QSize &gridSize, QVector< QPointF > &origPoints, QVector< QPointF > &transfPoints, const QPointF &dstStep) const
 
QRectF srcBoundingRect () const
 

Public Attributes

QRectF originalRect
 
std::array< QPointF, 12 > points
 

Detailed Description

Definition at line 17 of file KisBezierPatch.h.

Member Enumeration Documentation

◆ ControlPointType

Enumerator
TL 
TL_HC 
TL_VC 
TR 
TR_HC 
TR_VC 
BL 
BL_HC 
BL_VC 
BR 
BR_HC 
BR_VC 

Definition at line 20 of file KisBezierPatch.h.

Member Function Documentation

◆ dstBoundingRect()

QRectF KisBezierPatch::dstBoundingRect ( ) const

Definition at line 15 of file KisBezierPatch.cpp.

15 {
16 QRectF result;
17
18 for (auto it = points.begin(); it != points.end(); ++it) {
20 }
21
22 return result;
23}
std::array< QPointF, 12 > points
void accumulateBounds(const Point &pt, Rect *bounds)

References KisAlgebra2D::accumulateBounds(), and points.

◆ globalToLocal()

QPointF KisBezierPatch::globalToLocal ( const QPointF & pt) const

Definition at line 34 of file KisBezierPatch.cpp.

35{
37}
QPointF calculateLocalPos(const std::array< QPointF, 12 > &points, const QPointF &globalPoint)
calculates local (u,v) coordinates of the patch corresponding to globalPoint

References KisBezierUtils::calculateLocalPos(), and points.

◆ localToGlobal()

QPointF KisBezierPatch::localToGlobal ( const QPointF & pt) const

Definition at line 29 of file KisBezierPatch.cpp.

30{
32}
QPointF calculateGlobalPos(const std::array< QPointF, 12 > &points, const QPointF &localPoint)
calculates global coordinate corresponding to the patch coordinate (u, v)

References KisBezierUtils::calculateGlobalPos(), and points.

◆ sampleRegularGrid()

void KisBezierPatch::sampleRegularGrid ( QSize & gridSize,
QVector< QPointF > & origPoints,
QVector< QPointF > & transfPoints,
const QPointF & dstStep ) const

Definition at line 39 of file KisBezierPatch.cpp.

40{
43
44 const QRectF bounds = dstBoundingRect();
45 gridSize.rwidth() = qCeil(bounds.width() / dstStep.x());
46 gridSize.rheight() = qCeil(bounds.height() / dstStep.y());
47
48 const qreal topLength = KisBezierUtils::curveLength(points[TL], points[TL_HC], points[TR_HC], points[TR], 0.01);
49 const qreal bottomLength = KisBezierUtils::curveLength(points[BL], points[BL_HC], points[BR_HC], points[BR], 0.01);
50
51 const qreal leftLength = KisBezierUtils::curveLength(points[TL], points[TL_VC], points[BL_VC], points[BL], 0.01);
52 const qreal rightLength = KisBezierUtils::curveLength(points[TR], points[TR_VC], points[BR_VC], points[BR], 0.01);
53
54 struct Split {
55 QPointF p0;
56 QPointF relP1;
57 QPointF relP2;
58 QPointF p3;
59 qreal coord1;
60 qreal coord2;
61 qreal proportion;
62 };
63
64 std::vector<Split> verticalSplits;
65 std::vector<Split> horizontalSplits;
66
67 for (int y = 0; y < gridSize.height(); y++) {
68 const qreal yProportion = qreal(y) / (gridSize.height() - 1);
69
70 const qreal yCoord1 = KisBezierUtils::curveLengthAtPoint(points[TL], points[TL_VC], points[BL_VC], points[BL], yProportion, 0.01) / leftLength;
71 const qreal yCoord2 = KisBezierUtils::curveLengthAtPoint(points[TR], points[TR_VC], points[BR_VC], points[BR], yProportion, 0.01) / rightLength;
72
73 const QPointF p0 = bezierCurve(points[TL], points[TL_VC], points[BL_VC], points[BL], yProportion);
74
75 const QPointF relP1 = lerp(points[TL_HC] - points[TL], points[BL_HC] - points[BL], yProportion);
76 const QPointF relP2 = lerp(points[TR_HC] - points[TR], points[BR_HC] - points[BR], yProportion);
77
78 const QPointF p3 = bezierCurve(points[TR], points[TR_VC], points[BR_VC], points[BR], yProportion);
79
80 verticalSplits.push_back({p0, relP1, relP2, p3, yCoord1, yCoord2, yProportion});
81 }
82
83 for (int x = 0; x < gridSize.width(); x++) {
84 const qreal xProportion = qreal(x) / (gridSize.width() - 1);
85
86 const qreal xCoord1 = KisBezierUtils::curveLengthAtPoint(points[TL], points[TL_HC], points[TR_HC], points[TR], xProportion, 0.01) / topLength;
87 const qreal xCoord2 = KisBezierUtils::curveLengthAtPoint(points[BL], points[BL_HC], points[BR_HC], points[BR], xProportion, 0.01) / bottomLength;
88
89 const QPointF q0 = bezierCurve(points[TL], points[TL_HC], points[TR_HC], points[TR], xProportion);
90
91 const QPointF relQ1 = lerp(points[TL_VC] - points[TL], points[TR_VC] - points[TR], xProportion);
92 const QPointF relQ2 = lerp(points[BL_VC] - points[BL], points[BR_VC] - points[BR], xProportion);
93
94 const QPointF q3 = bezierCurve(points[BL], points[BL_HC], points[BR_HC], points[BR], xProportion);
95
96 horizontalSplits.push_back({q0, relQ1, relQ2, q3, xCoord1, xCoord2, xProportion});
97 }
98
99 for (int y = 0; y < gridSize.height(); y++) {
100 for (int x = 0; x < gridSize.width(); x++) {
101 const Split &ySplit = verticalSplits[y];
102 const Split &xSplit = horizontalSplits[x];
103
104 const QPointF transf1 = bezierCurve(ySplit.p0,
105 ySplit.p0 + ySplit.relP1,
106 ySplit.p3 + ySplit.relP2,
107 ySplit.p3,
108 xSplit.proportion);
109
110
111 const QPointF transf2 = bezierCurve(xSplit.p0,
112 xSplit.p0 + xSplit.relP1,
113 xSplit.p3 + xSplit.relP2,
114 xSplit.p3,
115 ySplit.proportion);
116
117
118 const QPointF transf = 0.5 * (transf1 + transf2);
119
120 const QPointF localPt(lerp(xSplit.coord1, xSplit.coord2, ySplit.proportion),
121 lerp(ySplit.coord1, ySplit.coord2, xSplit.proportion));
122 const QPointF orig = KisAlgebra2D::relativeToAbsolute(localPt, originalRect);
123
124 origPoints.append(orig);
125 transfPoints.append(transf);
126 }
127 }
128}
QPointF q0
QPointF p0
QPointF q3
QPointF p3
QPointF lerp(const QPointF &p1, const QPointF &p2, qreal t)
QRectF dstBoundingRect() const
#define bounds(x, a, b)
QPointF relativeToAbsolute(const QPointF &pt, const QRectF &rc)
Point lerp(const Point &pt1, const Point &pt2, qreal t)
qreal curveLengthAtPoint(const QPointF p0, const QPointF p1, const QPointF p2, const QPointF p3, qreal t, const qreal error)
QPointF bezierCurve(const QPointF p0, const QPointF p1, const QPointF p2, const QPointF p3, qreal t)
qreal curveLength(const QPointF p0, const QPointF p1, const QPointF p2, const QPointF p3, const qreal error)

References KisBezierUtils::bezierCurve(), BL, BL_HC, BL_VC, bounds, BR, BR_HC, BR_VC, KisBezierUtils::curveLength(), KisBezierUtils::curveLengthAtPoint(), dstBoundingRect(), KisAlgebra2D::lerp(), lerp(), originalRect, p0, p3, points, q0, q3, KisAlgebra2D::relativeToAbsolute(), TL, TL_HC, TL_VC, TR, TR_HC, and TR_VC.

◆ sampleRegularGridSVG2()

void KisBezierPatch::sampleRegularGridSVG2 ( QSize & gridSize,
QVector< QPointF > & origPoints,
QVector< QPointF > & transfPoints,
const QPointF & dstStep ) const

Definition at line 130 of file KisBezierPatch.cpp.

131{
132 using KisAlgebra2D::lerp;
134
135 const QRectF bounds = dstBoundingRect();
136 gridSize.rwidth() = qCeil(bounds.width() / dstStep.x());
137 gridSize.rheight() = qCeil(bounds.height() / dstStep.y());
138
139 const qreal topLength = KisBezierUtils::curveLength(points[TL], points[TL_HC], points[TR_HC], points[TR], 0.01);
140 const qreal bottomLength = KisBezierUtils::curveLength(points[BL], points[BL_HC], points[BR_HC], points[BR], 0.01);
141
142 const qreal leftLength = KisBezierUtils::curveLength(points[TL], points[TL_VC], points[BL_VC], points[BL], 0.01);
143 const qreal rightLength = KisBezierUtils::curveLength(points[TR], points[TR_VC], points[BR_VC], points[BR], 0.01);
144
145
146 struct Split {
147 QPointF p0;
148 QPointF p3;
149 qreal coord1;
150 qreal coord2;
151 qreal proportion;
152 };
153
154 std::vector<Split> verticalSplits;
155 std::vector<Split> horizontalSplits;
156
157 for (int y = 0; y < gridSize.height(); y++) {
158 const qreal yProportion = qreal(y) / (gridSize.height() - 1);
159
160 const qreal yCoord1 = KisBezierUtils::curveLengthAtPoint(points[TL], points[TL_VC], points[BL_VC], points[BL], yProportion, 0.01) / leftLength;
161 const qreal yCoord2 = KisBezierUtils::curveLengthAtPoint(points[TR], points[TR_VC], points[BR_VC], points[BR], yProportion, 0.01) / rightLength;
162
163 const QPointF p0 = bezierCurve(points[TL], points[TL_VC], points[BL_VC], points[BL], yProportion);
164 const QPointF p3 = bezierCurve(points[TR], points[TR_VC], points[BR_VC], points[BR], yProportion);
165
166 verticalSplits.push_back({p0, p3, yCoord1, yCoord2, yProportion});
167 }
168
169 for (int x = 0; x < gridSize.width(); x++) {
170 const qreal xProportion = qreal(x) / (gridSize.width() - 1);
171
172 const qreal xCoord1 = KisBezierUtils::curveLengthAtPoint(points[TL], points[TL_HC], points[TR_HC], points[TR], xProportion, 0.01) / topLength;
173 const qreal xCoord2 = KisBezierUtils::curveLengthAtPoint(points[BL], points[BL_HC], points[BR_HC], points[BR], xProportion, 0.01) / bottomLength;
174
175 const QPointF q0 = bezierCurve(points[TL], points[TL_HC], points[TR_HC], points[TR], xProportion);
176 const QPointF q3 = bezierCurve(points[BL], points[BL_HC], points[BR_HC], points[BR], xProportion);
177
178 horizontalSplits.push_back({q0, q3, xCoord1, xCoord2, xProportion});
179 }
180
181 for (int y = 0; y < gridSize.height(); y++) {
182 for (int x = 0; x < gridSize.width(); x++) {
183 const Split &ySplit = verticalSplits[y];
184 const Split &xSplit = horizontalSplits[x];
185
186 const QPointF Sc = lerp(xSplit.p0, xSplit.p3, ySplit.proportion);
187 const QPointF Sd = lerp(ySplit.p0, ySplit.p3, xSplit.proportion);
188
189 const QPointF Sb =
190 lerp(lerp(points[TL], points[TR], xSplit.proportion),
191 lerp(points[BL], points[BR], xSplit.proportion),
192 ySplit.proportion);
193
194 const QPointF transf = Sc + Sd - Sb;
195
196 const QPointF localPt(lerp(xSplit.coord1, xSplit.coord2, ySplit.proportion),
197 lerp(ySplit.coord1, ySplit.coord2, xSplit.proportion));
198 const QPointF orig = KisAlgebra2D::relativeToAbsolute(localPt, originalRect);
199
200 origPoints.append(orig);
201 transfPoints.append(transf);
202 }
203 }
204}

References KisBezierUtils::bezierCurve(), BL, BL_HC, BL_VC, bounds, BR, BR_HC, BR_VC, KisBezierUtils::curveLength(), KisBezierUtils::curveLengthAtPoint(), dstBoundingRect(), KisAlgebra2D::lerp(), lerp(), originalRect, p0, p3, points, q0, q3, KisAlgebra2D::relativeToAbsolute(), TL, TL_HC, TL_VC, TR, TR_HC, and TR_VC.

◆ srcBoundingRect()

QRectF KisBezierPatch::srcBoundingRect ( ) const

Definition at line 25 of file KisBezierPatch.cpp.

25 {
26 return originalRect;
27}

References originalRect.

Member Data Documentation

◆ originalRect

QRectF KisBezierPatch::originalRect

Definition at line 35 of file KisBezierPatch.h.

◆ points

std::array<QPointF, 12> KisBezierPatch::points

Definition at line 36 of file KisBezierPatch.h.


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