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

#include <PerspectiveAssistant.h>

+ Inheritance diagram for PerspectiveAssistant:

Public Member Functions

void adjustLine (QPointF &point, QPointF &strokeBegin) override
 
QPointF adjustPosition (const QPointF &point, const QPointF &strokeBegin, const bool snapToAny, qreal moveThresholdPt) override
 
KisPaintingAssistantSP clone (QMap< KisPaintingAssistantHandleSP, KisPaintingAssistantHandleSP > &handleMap) const override
 
bool contains (const QPointF &point) const override
 
qreal distance (const QPointF &point) const override
 
void drawAssistant (QPainter &gc, const QRectF &updateRect, const KisCoordinatesConverter *converter, bool cached=true, KisCanvas2 *canvas=0, bool assistantVisible=true, bool previewVisible=true) override
 
void endStroke () override
 
QPointF getDefaultEditorPosition () const override
 
bool isActive () const override
 
bool isAssistantComplete () const override
 
bool loadCustomXml (QXmlStreamReader *xml) override
 
int numHandles () const override
 
 PerspectiveAssistant (QObject *parent=0)
 
void saveCustomXml (QXmlStreamWriter *xml) override
 
void setSubdivisions (int subdivisions)
 
int subdivisions () const
 
- Public Member Functions inherited from KisAbstractPerspectiveGrid
 KisAbstractPerspectiveGrid (QObject *parent=0)
 
 ~KisAbstractPerspectiveGrid () override
 
- Public Member Functions inherited from KisPaintingAssistant
void addHandle (KisPaintingAssistantHandleSP handle, HandleType type)
 
bool areTwoPointsClose (const QPointF &pointOne, const QPointF &pointTwo)
 
QColor assistantCustomColor ()
 
KisPaintingAssistantHandleSP bottomLeft ()
 
const KisPaintingAssistantHandleSP bottomLeft () const
 
KisPaintingAssistantHandleSP bottomMiddle ()
 
const KisPaintingAssistantHandleSP bottomMiddle () const
 
KisPaintingAssistantHandleSP bottomRight ()
 
const KisPaintingAssistantHandleSP bottomRight () const
 
virtual bool canBeLocal () const
 canBeLocal
 
KisPaintingAssistantHandleSP closestCornerHandleFromPoint (QPointF point)
 
void copySharedData (KisPaintingAssistantSP assistant)
 
void drawError (QPainter &painter, const QPainterPath &path)
 
void drawPath (QPainter &painter, const QPainterPath &path, bool drawActive=true)
 
void drawPreview (QPainter &painter, const QPainterPath &path)
 
void drawX (QPainter &painter, const QPointF &pt)
 
QPointF editorWidgetOffset ()
 
QColor effectiveAssistantColor () const
 
void findPerspectiveAssistantHandleLocation ()
 
virtual QPointF getEditorPosition () const
 
QList< KisPaintingAssistantHandleSPhandles ()
 
const QList< KisPaintingAssistantHandleSP > & handles () const
 
const QString & id () const
 
bool isDuplicating ()
 isDuplicating
 
bool isLocal () const
 isLocal
 
bool isLocked ()
 isLocked
 
bool isSnappingActive () const
 
 KisPaintingAssistant (const QString &id, const QString &name)
 
KisPaintingAssistantHandleSP leftMiddle ()
 
const KisPaintingAssistantHandleSP leftMiddle () const
 
void loadXml (KoStore *store, QMap< int, KisPaintingAssistantHandleSP > &handleMap, QString path)
 
const QString & name () const
 
KisPaintingAssistantHandleSP oppHandleOne ()
 
void replaceHandle (KisPaintingAssistantHandleSP _handle, KisPaintingAssistantHandleSP _with)
 
KisPaintingAssistantHandleSP rightMiddle ()
 
const KisPaintingAssistantHandleSP rightMiddle () const
 
QByteArray saveXml (QMap< KisPaintingAssistantHandleSP, int > &handleMap)
 
void saveXmlList (QDomDocument &doc, QDomElement &assistantsElement, int count)
 
virtual void setAdjustedBrushPosition (const QPointF position)
 
void setAssistantCustomColor (QColor color)
 
void setAssistantGlobalColorCache (const QColor &color)
 
void setDecorationThickness (int thickness)
 
void setDuplicating (bool value)
 setDuplicating
 
void setEditorWidgetOffset (QPointF offset)
 
virtual void setFollowBrushPosition (bool follow)
 
void setLocal (bool value)
 setLocal
 
void setLocked (bool value)
 setLocked
 
void setSnappingActive (bool set)
 
void setUseCustomColor (bool useCustomColor)
 
QList< KisPaintingAssistantHandleSPsideHandles ()
 
const QList< KisPaintingAssistantHandleSP > & sideHandles () const
 
KisPaintingAssistantHandleSP topLeft ()
 
const KisPaintingAssistantHandleSP topLeft () const
 
KisPaintingAssistantHandleSP topMiddle ()
 
const KisPaintingAssistantHandleSP topMiddle () const
 
KisPaintingAssistantHandleSP topRight ()
 
const KisPaintingAssistantHandleSP topRight () const
 
virtual void transform (const QTransform &transform)
 
void uncache ()
 
bool useCustomColor ()
 
QPointF viewportConstrainedEditorPosition (const KisCoordinatesConverter *converter, const QSize editorSize)
 
virtual ~KisPaintingAssistant ()
 

Protected Member Functions

void drawCache (QPainter &gc, const KisCoordinatesConverter *converter, bool assistantVisible=true) override
 performance layer where the graphics can be drawn from a cache instead of generated every render update
 
- Protected Member Functions inherited from KisPaintingAssistant
virtual QRect boundingRect () const
 
QPointF effectiveBrushPosition (const KisCoordinatesConverter *converter, KisCanvas2 *canvas) const
 Query the effective brush position to be used for preview lines. This is intended to be used for painting the dynamic preview lines for assistants that feature them. Affected by setAdjustedBrushPosition() and setFollowBrushPosition().
 
virtual KisPaintingAssistantHandleSP firstLocalHandle () const
 firstLocalHandle Note: this doesn't guarantee it will be the topleft corner! For that, use getLocalRect().topLeft() The only purpose of those functions to exist is to be able to put getLocalRect() function in the KisPaintingAssistant instead of reimplementing it in every specific assistant.
 
QRectF getLocalRect () const
 getLocalRect The function deals with local handles not being topLeft and bottomRight gracefully and returns a correct rectangle. Thanks to that the user can place handles in a "wrong" order or move them around but the local rectangle will still be correct.
 
void initHandles (QList< KisPaintingAssistantHandleSP > _handles)
 
 KisPaintingAssistant (const KisPaintingAssistant &rhs, QMap< KisPaintingAssistantHandleSP, KisPaintingAssistantHandleSP > &handleMap)
 
QPointF pixelToView (const QPoint pixelCoords) const
 
virtual KisPaintingAssistantHandleSP secondLocalHandle () const
 secondLocalHandle Note: this doesn't guarantee it will be the bottomRight corner! For that, use getLocalRect().bottomRight() (and remember that for QRect bottomRight() works differently than for QRectF, so don't convert to QRect before accessing the corner)
 

Private Member Functions

bool getTransform (QPolygonF &polyOut, QTransform &transformOut) const
 
 PerspectiveAssistant (const PerspectiveAssistant &rhs, QMap< KisPaintingAssistantHandleSP, KisPaintingAssistantHandleSP > &handleMap)
 
QPointF project (const QPointF &pt, const QPointF &strokeBegin, const bool snapToAnyDirection, qreal moveThresholdPt)
 

Private Attributes

PerspectiveBasedAssistantHelper::CacheData m_cache
 
QPointF m_cachedPoints [4]
 
QPolygonF m_cachedPolygon
 
QTransform m_cachedTransform
 
bool m_cacheValid {false}
 
QLineF m_snapLine
 
int m_subdivisions {8}
 

Additional Inherited Members

- Static Public Member Functions inherited from KisPaintingAssistant
static QList< KisPaintingAssistantSPcloneAssistantList (const QList< KisPaintingAssistantSP > &list)
 
static double norm2 (const QPointF &p)
 
- Protected Attributes inherited from KisPaintingAssistant
QList< KisPaintingAssistantHandleSPm_handles
 
bool m_hasBeenInsideLocalRect {false}
 

Detailed Description

Definition at line 21 of file PerspectiveAssistant.h.

Constructor & Destructor Documentation

◆ PerspectiveAssistant() [1/2]

PerspectiveAssistant::PerspectiveAssistant ( QObject * parent = 0)

Definition at line 29 of file PerspectiveAssistant.cc.

31 , KisPaintingAssistant("perspective", i18n("Perspective assistant"))
32{
33}
KisPaintingAssistant(const QString &id, const QString &name)

◆ PerspectiveAssistant() [2/2]

PerspectiveAssistant::PerspectiveAssistant ( const PerspectiveAssistant & rhs,
QMap< KisPaintingAssistantHandleSP, KisPaintingAssistantHandleSP > & handleMap )
explicitprivate

Definition at line 35 of file PerspectiveAssistant.cc.

36 : KisAbstractPerspectiveGrid(rhs.parent())
37 , KisPaintingAssistant(rhs, handleMap)
43 , m_cache(rhs.m_cache)
44{
45 for (int i = 0; i < 4; ++i) {
47 }
48}
PerspectiveBasedAssistantHelper::CacheData m_cache

References m_cachedPoints.

Member Function Documentation

◆ adjustLine()

void PerspectiveAssistant::adjustLine ( QPointF & point,
QPointF & strokeBegin )
overridevirtual

Implements KisPaintingAssistant.

Definition at line 113 of file PerspectiveAssistant.cc.

114{
115 point = project(point, strokeBegin, true, 0.0);
116}
QPointF project(const QPointF &pt, const QPointF &strokeBegin, const bool snapToAnyDirection, qreal moveThresholdPt)

References project().

◆ adjustPosition()

QPointF PerspectiveAssistant::adjustPosition ( const QPointF & point,
const QPointF & strokeBegin,
const bool snapToAny,
qreal moveThresholdPt )
overridevirtual

Adjust the position given in parameter.

Parameters
pointthe coordinates in point in the document reference
strokeBeginthe coordinates of the beginning of the stroke
snapToAnybecause now assistants can be composited out of multiple inside assistants. snapToAny true means that you can use any of the inside assistant, while it being false means you should use the last used one. The logic determining when it happens (first stroke etc.) is in the decoration, so those two options are enough.
moveThresholdPtthe threshold for the "move" of the cursor measured in pt (usually equals to 2px in screen coordinates converted to pt)

Implements KisPaintingAssistant.

Definition at line 108 of file PerspectiveAssistant.cc.

109{
110 return project(pt, strokeBegin, snapToAny, moveThresholdPt);
111}

References project().

◆ clone()

KisPaintingAssistantSP PerspectiveAssistant::clone ( QMap< KisPaintingAssistantHandleSP, KisPaintingAssistantHandleSP > & handleMap) const
overridevirtual

Implements KisPaintingAssistant.

Definition at line 50 of file PerspectiveAssistant.cc.

51{
52 return KisPaintingAssistantSP(new PerspectiveAssistant(*this, handleMap));
53}
PerspectiveAssistant(QObject *parent=0)
QSharedPointer< KisPaintingAssistant > KisPaintingAssistantSP
Definition kis_types.h:189

References PerspectiveAssistant().

◆ contains()

bool PerspectiveAssistant::contains ( const QPointF & point) const
overridevirtual

Implements KisAbstractPerspectiveGrid.

Definition at line 124 of file PerspectiveAssistant.cc.

125{
126 QPolygonF poly;
128 return poly.containsPoint(pt, Qt::OddEvenFill);
129}
const QList< KisPaintingAssistantHandleSP > & handles() const
bool isAssistantComplete() const override
static bool getTetragon(const QList< KisPaintingAssistantHandleSP > &handles, bool isAssistantComplete, QPolygonF &outPolygon)

References PerspectiveBasedAssistantHelper::getTetragon(), KisPaintingAssistant::handles(), and isAssistantComplete().

◆ distance()

qreal PerspectiveAssistant::distance ( const QPointF & pt) const
overridevirtual

Returns the reciprocal of the distance from the given point to the 'observer', in the range [0, 1] where 0 = infinite distance and 1 = closest.

Implements KisAbstractPerspectiveGrid.

Definition at line 131 of file PerspectiveAssistant.cc.

132{
135}
static qreal distanceInGrid(const QList< KisPaintingAssistantHandleSP > &handles, bool isAssistantComplete, const QPointF &point)
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130

References PerspectiveBasedAssistantHelper::distanceInGrid(), KIS_SAFE_ASSERT_RECOVER_NOOP, m_cache, and m_cacheValid.

◆ drawAssistant()

void PerspectiveAssistant::drawAssistant ( QPainter & gc,
const QRectF & updateRect,
const KisCoordinatesConverter * converter,
bool cached = true,
KisCanvas2 * canvas = 0,
bool assistantVisible = true,
bool previewVisible = true )
overridevirtual

Reimplemented from KisPaintingAssistant.

Definition at line 142 of file PerspectiveAssistant.cc.

143{
144 gc.save();
145 gc.resetTransform();
146 QTransform initialTransform = converter->documentToWidgetTransform();
147 //QTransform reverseTransform = converter->widgetToDocument();
148 QPolygonF poly;
149 QTransform transform; // unused, but computed for caching purposes
150 if (getTransform(poly, transform) && assistantVisible==true) {
151 // draw vanishing points
153 drawX(gc, initialTransform.map(m_cache.vanishingPoint1.get()));
154 }
156 drawX(gc, initialTransform.map(m_cache.vanishingPoint2.get()));
157 }
158 }
159
160 if (isSnappingActive() && getTransform(poly, transform) && previewVisible==true){
161 //find vanishing point, find mouse, draw line between both.
162 QPainterPath path2;
163 QPointF intersection(0, 0);//this is the position of the vanishing point.
164 QPointF mousePos = effectiveBrushPosition(converter, canvas);
165 QLineF snapLine;
166 QRect viewport= gc.viewport();
167 QRect bounds;
168
169 //figure out if point is in the perspective grid
170 QPointF intersectTransformed(0, 0); // dummy for holding transformed intersection so the code is more readable.
171
172 if (poly.containsPoint(initialTransform.inverted().map(mousePos), Qt::OddEvenFill)==true){
173 // check if the lines aren't parallel to each other to avoid calculation errors in the intersection calculation (bug 345754)//
174 if (fmod(QLineF(poly[0], poly[1]).angle(), 180.0)>=fmod(QLineF(poly[2], poly[3]).angle(), 180.0)+2.0 || fmod(QLineF(poly[0], poly[1]).angle(), 180.0)<=fmod(QLineF(poly[2], poly[3]).angle(), 180.0)-2.0) {
175 if (QLineF(poly[0], poly[1]).intersects(QLineF(poly[2], poly[3]), &intersection) != QLineF::NoIntersection) {
176 intersectTransformed = initialTransform.map(intersection);
177 snapLine = QLineF(intersectTransformed, mousePos);
178 KisAlgebra2D::intersectLineRect(snapLine, viewport, true);
179 bounds= QRect(snapLine.p1().toPoint(), snapLine.p2().toPoint());
180
181 if (bounds.contains(intersectTransformed.toPoint())){
182 path2.moveTo(intersectTransformed);
183 path2.lineTo(snapLine.p2());
184 }
185 else {
186 path2.moveTo(snapLine.p1());
187 path2.lineTo(snapLine.p2());
188 }
189 }
190 }
191 if (fmod(QLineF(poly[1], poly[2]).angle(), 180.0)>=fmod(QLineF(poly[3], poly[0]).angle(), 180.0)+2.0 || fmod(QLineF(poly[1], poly[2]).angle(), 180.0)<=fmod(QLineF(poly[3], poly[0]).angle(), 180.0)-2.0){
192 if (QLineF(poly[1], poly[2]).intersects(QLineF(poly[3], poly[0]), &intersection) != QLineF::NoIntersection) {
193 intersectTransformed = initialTransform.map(intersection);
194 snapLine = QLineF(intersectTransformed, mousePos);
195 KisAlgebra2D::intersectLineRect(snapLine, viewport, true);
196 bounds= QRect(snapLine.p1().toPoint(), snapLine.p2().toPoint());
197 QPainterPath path;
198
199 if (bounds.contains(intersectTransformed.toPoint())){
200 path2.moveTo(intersectTransformed);
201 path2.lineTo(snapLine.p2());
202 }
203 else {
204 path2.moveTo(snapLine.p1());
205 path2.lineTo(snapLine.p2());
206 }
207 }
208 }
209 drawPreview(gc, path2);
210 }
211 }
212
213
214
215 // draw the grid lines themselves
216 gc.setTransform(converter->documentToWidgetTransform());
217
218 if (assistantVisible) {
219 // getTransform was checked before but what if the preview wasn't visible etc., and we need a return value here too
220 if (!getTransform(poly, transform)) {
221 // color red for an invalid transform, but not for an incomplete one
222 if(isAssistantComplete()) {
223 QPainterPath path;
224 // that will create a triangle with a point inside connected to all vertices of the triangle
226 drawError(gc, path);
227 } else {
228 QPainterPath path;
229 path.addPolygon(poly);
230 drawPath(gc, path, isSnappingActive());
231 }
232 } else {
233 gc.setPen(QColor(0, 0, 0, 125));
234 gc.setTransform(transform, true);
235 QPainterPath path;
236 qreal step = 1.0 / subdivisions();
237
238 for (int y = 0; y <= subdivisions(); ++y)
239 {
240 QLineF line = QLineF(QPointF(0.0, y * step), QPointF(1.0, y * step));
241 KisAlgebra2D::cropLineToRect(line, gc.window(), false, false);
242 path.moveTo(line.p1());
243 path.lineTo(line.p2());
244 }
245 for (int x = 0; x <= subdivisions(); ++x)
246 {
247 QLineF line = QLineF(QPointF(x * step, 0.0), QPointF(x * step, 1.0));
248 KisAlgebra2D::cropLineToRect(line, gc.window(), false, false);
249 path.moveTo(line.p1());
250 path.lineTo(line.p2());
251 }
252
253 drawPath(gc, path, isSnappingActive());
254 }
255 }
256 //
257
258
259 gc.restore();
260
261 KisPaintingAssistant::drawAssistant(gc, updateRect, converter, cached,canvas, assistantVisible, previewVisible);
262}
void drawX(QPainter &painter, const QPointF &pt)
QPointF effectiveBrushPosition(const KisCoordinatesConverter *converter, KisCanvas2 *canvas) const
Query the effective brush position to be used for preview lines. This is intended to be used for pain...
void drawError(QPainter &painter, const QPainterPath &path)
void drawPath(QPainter &painter, const QPainterPath &path, bool drawActive=true)
void drawPreview(QPainter &painter, const QPainterPath &path)
virtual void transform(const QTransform &transform)
virtual void drawAssistant(QPainter &gc, const QRectF &updateRect, const KisCoordinatesConverter *converter, bool cached, KisCanvas2 *canvas=0, bool assistantVisible=true, bool previewVisible=true)
bool getTransform(QPolygonF &polyOut, QTransform &transformOut) const
static QPolygonF getAllConnectedTetragon(const QList< KisPaintingAssistantHandleSP > &handles)
#define bounds(x, a, b)
void cropLineToRect(QLineF &line, const QRect rect, bool extendFirst, bool extendSecond)
bool intersectLineRect(QLineF &line, const QRect rect, bool extend)

References bounds, KisAlgebra2D::cropLineToRect(), KisCoordinatesConverter::documentToWidgetTransform(), KisPaintingAssistant::drawAssistant(), KisPaintingAssistant::drawError(), KisPaintingAssistant::drawPath(), KisPaintingAssistant::drawPreview(), KisPaintingAssistant::drawX(), KisPaintingAssistant::effectiveBrushPosition(), PerspectiveBasedAssistantHelper::getAllConnectedTetragon(), getTransform(), KisPaintingAssistant::handles(), KisAlgebra2D::intersectLineRect(), isAssistantComplete(), KisPaintingAssistant::isSnappingActive(), m_cache, subdivisions(), KisPaintingAssistant::transform(), PerspectiveBasedAssistantHelper::CacheData::vanishingPoint1, and PerspectiveBasedAssistantHelper::CacheData::vanishingPoint2.

◆ drawCache()

void PerspectiveAssistant::drawCache ( QPainter & gc,
const KisCoordinatesConverter * converter,
bool assistantVisible = true )
overrideprotectedvirtual

performance layer where the graphics can be drawn from a cache instead of generated every render update

Implements KisPaintingAssistant.

Definition at line 264 of file PerspectiveAssistant.cc.

265{
266 Q_UNUSED(gc);
267 Q_UNUSED(converter);
268 Q_UNUSED(assistantVisible);
269}

◆ endStroke()

void PerspectiveAssistant::endStroke ( )
overridevirtual

Reimplemented from KisPaintingAssistant.

Definition at line 118 of file PerspectiveAssistant.cc.

119{
120 m_snapLine = QLineF();
122}

References KisPaintingAssistant::endStroke(), and m_snapLine.

◆ getDefaultEditorPosition()

QPointF PerspectiveAssistant::getDefaultEditorPosition ( ) const
overridevirtual

Implements KisPaintingAssistant.

Definition at line 271 of file PerspectiveAssistant.cc.

272{
273 QPointF centroid(0, 0);
274 for (int i = 0; i < 4; ++i) {
275 centroid += *handles()[i];
276 }
277
278 return centroid * 0.25;
279}

References KisPaintingAssistant::handles().

◆ getTransform()

bool PerspectiveAssistant::getTransform ( QPolygonF & polyOut,
QTransform & transformOut ) const
private

Definition at line 281 of file PerspectiveAssistant.cc.

282{
283 if (m_cachedPolygon.size() != 0 && isAssistantComplete()) {
284 for (int i = 0; i <= 4; ++i) {
285 if (i == 4) {
286 poly = m_cachedPolygon;
288 return m_cacheValid;
289 }
290 if (m_cachedPoints[i] != *handles()[i]) break;
291 }
292 }
293
294 m_cachedPolygon.clear();
295 m_cacheValid = false;
296
298 m_cachedPolygon = poly;
299 return false;
300 }
301
302 if (!QTransform::squareToQuad(poly, transform)) {
303 qWarning("Failed to create perspective mapping");
304 return false;
305 }
306
307 for (int i = 0; i < 4; ++i) {
308 m_cachedPoints[i] = *handles()[i];
309 }
310
311 m_cachedPolygon = poly;
314 m_cacheValid = true;
315 return true;
316}
static void updateCacheData(CacheData &cache, const QPolygonF &poly)

References PerspectiveBasedAssistantHelper::getTetragon(), KisPaintingAssistant::handles(), isAssistantComplete(), m_cache, m_cachedPoints, m_cachedPolygon, m_cachedTransform, m_cacheValid, KisPaintingAssistant::transform(), and PerspectiveBasedAssistantHelper::updateCacheData().

◆ isActive()

bool PerspectiveAssistant::isActive ( ) const
overridevirtual

Implements KisAbstractPerspectiveGrid.

Definition at line 137 of file PerspectiveAssistant.cc.

138{
139 return isSnappingActive();
140}

References KisPaintingAssistant::isSnappingActive().

◆ isAssistantComplete()

bool PerspectiveAssistant::isAssistantComplete ( ) const
overridevirtual

determines if the assistant has enough handles to be considered created new assistants get in a "creation" phase where they are currently being made on the canvas it will return false if we are in the middle of creating the assistant.

Reimplemented from KisPaintingAssistant.

Definition at line 318 of file PerspectiveAssistant.cc.

319{
320 return handles().size() >= 4; // specify 4 corners to make assistant complete
321}

References KisPaintingAssistant::handles().

◆ loadCustomXml()

bool PerspectiveAssistant::loadCustomXml ( QXmlStreamReader * xml)
overridevirtual

Reimplemented from KisPaintingAssistant.

Definition at line 340 of file PerspectiveAssistant.cc.

340 {
341 if (xml && xml->name() == "subdivisions") {
342 setSubdivisions(KisDomUtils::toInt(xml->attributes().value("value").toString()));
343 }
344 return true;
345}
void setSubdivisions(int subdivisions)
int toInt(const QString &str, bool *ok=nullptr)

References setSubdivisions(), and KisDomUtils::toInt().

◆ numHandles()

int PerspectiveAssistant::numHandles ( ) const
inlineoverridevirtual

Implements KisPaintingAssistant.

Definition at line 33 of file PerspectiveAssistant.h.

33{ return 4; }

◆ project()

QPointF PerspectiveAssistant::project ( const QPointF & pt,
const QPointF & strokeBegin,
const bool snapToAnyDirection,
qreal moveThresholdPt )
private

Definition at line 55 of file PerspectiveAssistant.cc.

56{
57 const static QPointF nullPoint(std::numeric_limits<qreal>::quiet_NaN(), std::numeric_limits<qreal>::quiet_NaN());
58
59 Q_ASSERT(isAssistantComplete());
60
61 if (snapToAnyDirection || m_snapLine.isNull()) {
62 QPolygonF poly;
63 QTransform transform;
64
65 if (!getTransform(poly, transform)) {
66 return nullPoint;
67 }
68
69 if (!poly.containsPoint(strokeBegin, Qt::OddEvenFill)) {
70 return nullPoint; // avoid problems with multiple assistants: only snap if starting in the grid
71 }
72
73 if (KisAlgebra2D::norm(pt - strokeBegin) < moveThresholdPt) {
74 return strokeBegin; // allow some movement before snapping
75 }
76
77 // construct transformation
78 bool invertible;
79 const QTransform inverse = transform.inverted(&invertible);
80 if (!invertible) {
81 return nullPoint; // shouldn't happen
82 }
83
84
85 // figure out which direction to go
86 const QPointF start = inverse.map(strokeBegin);
87 const QLineF verticalLine = QLineF(strokeBegin, transform.map(start + QPointF(0, 1)));
88 const QLineF horizontalLine = QLineF(strokeBegin, transform.map(start + QPointF(1, 0)));
89
90 // determine whether the horizontal or vertical line is closer to the point
91 m_snapLine = KisAlgebra2D::pointToLineDistSquared(pt, verticalLine) < KisAlgebra2D::pointToLineDistSquared(pt, horizontalLine) ? verticalLine : horizontalLine;
92 }
93
94 // snap to line
95 const qreal
96 dx = m_snapLine.dx(),
97 dy = m_snapLine.dy(),
98 dx2 = dx * dx,
99 dy2 = dy * dy,
100 invsqrlen = 1.0 / (dx2 + dy2);
101 QPointF r(dx2 * pt.x() + dy2 * m_snapLine.x1() + dx * dy * (pt.y() - m_snapLine.y1()),
102 dx2 * m_snapLine.y1() + dy2 * pt.y() + dx * dy * (pt.x() - m_snapLine.x1()));
103
104 r *= invsqrlen;
105 return r;
106}
qreal pointToLineDistSquared(const QPointF &pt, const QLineF &line)
qreal norm(const T &a)

References getTransform(), isAssistantComplete(), m_snapLine, KisAlgebra2D::norm(), KisAlgebra2D::pointToLineDistSquared(), and KisPaintingAssistant::transform().

◆ saveCustomXml()

void PerspectiveAssistant::saveCustomXml ( QXmlStreamWriter * xml)
overridevirtual

Reimplemented from KisPaintingAssistant.

Definition at line 332 of file PerspectiveAssistant.cc.

332 {
333 if (xml) {
334 xml->writeStartElement("subdivisions");
335 xml->writeAttribute("value", KisDomUtils::toString(subdivisions()));
336 xml->writeEndElement();
337 }
338}
QString toString(const QString &value)

References subdivisions(), and KisDomUtils::toString().

◆ setSubdivisions()

void PerspectiveAssistant::setSubdivisions ( int subdivisions)

Definition at line 327 of file PerspectiveAssistant.cc.

327 {
328 if (subdivisions < 1) m_subdivisions = 1;
330}

References m_subdivisions, and subdivisions().

◆ subdivisions()

int PerspectiveAssistant::subdivisions ( ) const

Definition at line 323 of file PerspectiveAssistant.cc.

323 {
324 return m_subdivisions;
325}

References m_subdivisions.

Member Data Documentation

◆ m_cache

PerspectiveBasedAssistantHelper::CacheData PerspectiveAssistant::m_cache
mutableprivate

Definition at line 67 of file PerspectiveAssistant.h.

◆ m_cachedPoints

QPointF PerspectiveAssistant::m_cachedPoints[4]
mutableprivate

Definition at line 64 of file PerspectiveAssistant.h.

◆ m_cachedPolygon

QPolygonF PerspectiveAssistant::m_cachedPolygon
mutableprivate

Definition at line 63 of file PerspectiveAssistant.h.

◆ m_cachedTransform

QTransform PerspectiveAssistant::m_cachedTransform
mutableprivate

Definition at line 62 of file PerspectiveAssistant.h.

◆ m_cacheValid

bool PerspectiveAssistant::m_cacheValid {false}
mutableprivate

Definition at line 65 of file PerspectiveAssistant.h.

65{false};

◆ m_snapLine

QLineF PerspectiveAssistant::m_snapLine
private

Definition at line 60 of file PerspectiveAssistant.h.

◆ m_subdivisions

int PerspectiveAssistant::m_subdivisions {8}
private

Definition at line 58 of file PerspectiveAssistant.h.

58{8};

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