LibrePCB Developers Documentation
Loading...
Searching...
No Matches
path.h
Go to the documentation of this file.
1/*
2 * LibrePCB - Professional EDA for everyone!
3 * Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors.
4 * https://librepcb.org/
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifndef LIBREPCB_CORE_PATH_H
21#define LIBREPCB_CORE_PATH_H
22
23/*******************************************************************************
24 * Includes
25 ******************************************************************************/
26#include "../exceptions.h"
27#include "vertex.h"
28
29#include <type_safe/constrained_type.hpp>
30
31#include <QtCore>
32#include <QtGui>
33
34#include <optional>
35
36/*******************************************************************************
37 * Namespace / Forward Declarations
38 ******************************************************************************/
39namespace librepcb {
40
41/*******************************************************************************
42 * Class Path
43 ******************************************************************************/
44
59class Path final {
60 Q_DECLARE_TR_FUNCTIONS(Path)
61
62public:
63 // Constructors / Destructor
64 Path() noexcept : mVertices(), mPainterPathPx() {}
65 Path(const Path& other) noexcept;
66 explicit Path(const QVector<Vertex>& vertices) noexcept
67 : mVertices(vertices) {}
68 explicit Path(const SExpression& node);
69 ~Path() noexcept {}
70
71 // Getters
72 bool isClosed() const noexcept;
73 bool isCurved() const noexcept;
74 bool isZeroLength() const noexcept;
75 bool isOnGrid(const PositiveLength& gridInterval) const noexcept;
76 QVector<Vertex>& getVertices() noexcept {
78 return mVertices;
79 }
80 const QVector<Vertex>& getVertices() const noexcept { return mVertices; }
82 qreal calcAreaOfStraightSegments() const noexcept;
83 Point calcNearestPointBetweenVertices(const Point& p) const noexcept;
84 Path cleaned() const noexcept;
85 Path toClosedPath() const noexcept;
86 Path toOpenPath() const noexcept;
87 QVector<Path> toOutlineStrokes(const PositiveLength& width) const noexcept;
88 const QPainterPath& toQPainterPathPx() const noexcept;
89 QString toSvgPathMm() const noexcept;
90
91 // Transformations
92 Path& translate(const Point& offset) noexcept;
93 Path translated(const Point& offset) const noexcept;
94 Path& mapToGrid(const PositiveLength& gridInterval) noexcept;
95 Path mappedToGrid(const PositiveLength& gridInterval) const noexcept;
96 Path& rotate(const Angle& angle, const Point& center = Point(0, 0)) noexcept;
97 Path rotated(const Angle& angle,
98 const Point& center = Point(0, 0)) const noexcept;
99 Path& mirror(Qt::Orientation orientation,
100 const Point& center = Point(0, 0)) noexcept;
101 Path mirrored(Qt::Orientation orientation,
102 const Point& center = Point(0, 0)) const noexcept;
103 Path& reverse() noexcept;
104 Path reversed() const noexcept;
105 Path& flattenArcs(const PositiveLength& maxTolerance) noexcept;
106 Path flattenedArcs(const PositiveLength& maxTolerance) const noexcept;
107
108 // General Methods
109 void addVertex(const Vertex& vertex) noexcept;
110 void addVertex(const Point& pos, const Angle& angle = Angle::deg0()) noexcept;
111 void insertVertex(int index, const Vertex& vertex) noexcept;
112 void insertVertex(int index, const Point& pos,
113 const Angle& angle = Angle::deg0()) noexcept;
114 bool clean() noexcept;
115 bool close() noexcept;
116 bool open() noexcept;
117
123 void serialize(SExpression& root) const;
124
125 // Operator Overloadings
126 Path& operator=(const Path& rhs) noexcept;
127 bool operator==(const Path& rhs) const noexcept {
128 return mVertices == rhs.mVertices;
129 }
130 bool operator!=(const Path& rhs) const noexcept { return !(*this == rhs); }
131
142 bool operator<(const Path& rhs) const noexcept;
143
144 // Static Methods
145 static Path line(const Point& p1, const Point& p2,
146 const Angle& angle = Angle::deg0()) noexcept;
147 static Path circle(const PositiveLength& diameter) noexcept;
148 static Path donut(const PositiveLength& outerDiameter,
149 const PositiveLength& innerDiameter) noexcept;
150 static Path obround(const PositiveLength& width,
151 const PositiveLength& height) noexcept;
152 static Path obround(const Point& p1, const Point& p2,
153 const PositiveLength& width) noexcept;
154 static Path arcObround(const Point& p1, const Point& p2, const Angle& angle,
155 const PositiveLength& width) noexcept;
156 static std::optional<Path> flatCapLine(const Point& p1, const Point& p2,
157 const Angle& angle,
158 const PositiveLength& width) noexcept;
159 static Path rect(const Point& p1, const Point& p2) noexcept;
160 static Path centeredRect(
161 const PositiveLength& width, const PositiveLength& height,
162 const UnsignedLength& cornerRadius = UnsignedLength(0)) noexcept;
163 static Path chamferedRect(const PositiveLength& width,
164 const PositiveLength& height,
165 const UnsignedLength& chamferSize, bool topLeft,
166 bool topRight, bool bottomLeft,
167 bool bottomRight) noexcept;
168 static Path trapezoid(const PositiveLength& width,
169 const PositiveLength& height, const Length& dw,
170 const Length dh) noexcept;
171 static Path octagon(
172 const PositiveLength& width, const PositiveLength& height,
173 const UnsignedLength& cornerRadius = UnsignedLength(0)) noexcept;
174 static Path flatArc(const Point& p1, const Point& p2, const Angle& angle,
175 const PositiveLength& maxTolerance) noexcept;
176
187 static QPainterPath toQPainterPathPx(const QVector<Path>& paths,
188 bool area) noexcept;
189
190private: // Methods
191 void invalidatePainterPath() const noexcept {
192 mPainterPathPx = QPainterPath();
193 }
194
195private: // Data
196 QVector<Vertex> mVertices;
197 mutable QPainterPath mPainterPathPx; // cached path for #toQPainterPathPx()
198};
199
200/*******************************************************************************
201 * Non-Member Functions
202 ******************************************************************************/
203
204inline std::size_t qHash(const Path& key, std::size_t seed = 0) noexcept {
205 return qHashRange(key.getVertices().begin(), key.getVertices().end(), seed);
206}
207
208/*******************************************************************************
209 * Class NonEmptyPath
210 ******************************************************************************/
211
213 template <typename Value, typename Predicate>
214 static constexpr auto verify(Value&& val, const Predicate& p) ->
215 typename std::decay<Value>::type {
216 return p(val)
217 ? std::forward<Value>(val)
218 : (throw RuntimeError(__FILE__, __LINE__,
219 Path::tr("Path doesn't contain vertices!")),
220 std::forward<Value>(val));
221 }
222};
223
225 bool operator()(const Path& p) const noexcept {
226 return p.getVertices().count() > 0;
227 }
228};
229
237using NonEmptyPath = type_safe::constrained_type<Path, NonEmptyPathConstraint,
239
240inline std::size_t qHash(const NonEmptyPath& key,
241 std::size_t seed = 0) noexcept {
242 return ::qHash(*key, seed);
243}
244
245inline NonEmptyPath makeNonEmptyPath(const Point& pos) noexcept {
246 return NonEmptyPath(Path({Vertex(pos)}));
247}
248
249/*******************************************************************************
250 * Class StraightAreaPath
251 ******************************************************************************/
252
254 template <typename Value, typename Predicate>
255 static constexpr auto verify(Value&& val, const Predicate& p) ->
256 typename std::decay<Value>::type {
257 return p(val) ? std::forward<Value>(val)
258 : (throw RuntimeError(
259 __FILE__, __LINE__,
260 Path::tr("Path is not fillable or contains arcs!")),
261 std::forward<Value>(val));
262 }
263};
264
266 bool operator()(const Path& p) const noexcept {
267 return (p.getVertices().count() >= 4) && p.isClosed() && (!p.isCurved());
268 }
269};
270
280 type_safe::constrained_type<Path, StraightAreaPathConstraint,
282
283inline std::size_t qHash(const StraightAreaPath& key,
284 std::size_t seed = 0) noexcept {
285 return ::qHash(*key, seed);
286}
287
288/*******************************************************************************
289 * End of File
290 ******************************************************************************/
291
292} // namespace librepcb
293
294Q_DECLARE_METATYPE(librepcb::Path)
295
296#endif
The Angle class is used to represent an angle (for example 12.75 degrees)
Definition angle.h:76
static Angle deg0() noexcept
0 degrees
Definition angle.h:349
The Length class is used to represent a length (for example 12.75 millimeters)
Definition length.h:82
The Path class represents a list of vertices connected by straight lines or circular arc segments.
Definition path.h:59
Path reversed() const noexcept
Definition path.cpp:309
Path toOpenPath() const noexcept
Definition path.cpp:152
static Path trapezoid(const PositiveLength &width, const PositiveLength &height, const Length &dw, const Length dh) noexcept
Definition path.cpp:625
QVector< Path > toOutlineStrokes(const PositiveLength &width) const noexcept
Definition path.cpp:158
Path & mirror(Qt::Orientation orientation, const Point &center=Point(0, 0)) noexcept
Definition path.cpp:283
Path flattenedArcs(const PositiveLength &maxTolerance) const noexcept
Definition path.cpp:333
const QPainterPath & toQPainterPathPx() const noexcept
Definition path.cpp:178
static Path octagon(const PositiveLength &width, const PositiveLength &height, const UnsignedLength &cornerRadius=UnsignedLength(0)) noexcept
Definition path.cpp:645
const QVector< Vertex > & getVertices() const noexcept
Definition path.h:80
Path & reverse() noexcept
Definition path.cpp:297
static Path donut(const PositiveLength &outerDiameter, const PositiveLength &innerDiameter) noexcept
Definition path.cpp:426
QVector< Vertex > & getVertices() noexcept
Definition path.h:76
bool operator<(const Path &rhs) const noexcept
The "<" operator to compare two librepcb::Path objects.
Definition path.cpp:410
QVector< Vertex > mVertices
Definition path.h:196
static Path rect(const Point &p1, const Point &p2) noexcept
Definition path.cpp:547
Path translated(const Point &offset) const noexcept
Definition path.cpp:255
Path & flattenArcs(const PositiveLength &maxTolerance) noexcept
Definition path.cpp:313
Path mirrored(Qt::Orientation orientation, const Point &center=Point(0, 0)) const noexcept
Definition path.cpp:292
static Path arcObround(const Point &p1, const Point &p2, const Angle &angle, const PositiveLength &width) noexcept
Definition path.cpp:478
bool clean() noexcept
Definition path.cpp:360
bool close() noexcept
Definition path.cpp:373
Path & mapToGrid(const PositiveLength &gridInterval) noexcept
Definition path.cpp:259
static Path chamferedRect(const PositiveLength &width, const PositiveLength &height, const UnsignedLength &chamferSize, bool topLeft, bool topRight, bool bottomLeft, bool bottomRight) noexcept
Definition path.cpp:587
static Path centeredRect(const PositiveLength &width, const PositiveLength &height, const UnsignedLength &cornerRadius=UnsignedLength(0)) noexcept
Definition path.cpp:557
Path cleaned() const noexcept
Definition path.cpp:140
void insertVertex(int index, const Vertex &vertex) noexcept
Definition path.cpp:350
static Path flatArc(const Point &p1, const Point &p2, const Angle &angle, const PositiveLength &maxTolerance) noexcept
Definition path.cpp:696
Point calcNearestPointBetweenVertices(const Point &p) const noexcept
Definition path.cpp:123
static std::optional< Path > flatCapLine(const Point &p1, const Point &p2, const Angle &angle, const PositiveLength &width) noexcept
Definition path.cpp:513
bool isZeroLength() const noexcept
Definition path.cpp:73
Path mappedToGrid(const PositiveLength &gridInterval) const noexcept
Definition path.cpp:267
QString toSvgPathMm() const noexcept
Definition path.cpp:208
Path() noexcept
Definition path.h:64
static Path circle(const PositiveLength &diameter) noexcept
Definition path.cpp:422
Path(const QVector< Vertex > &vertices) noexcept
Definition path.h:66
static Path line(const Point &p1, const Point &p2, const Angle &angle=Angle::deg0()) noexcept
Definition path.cpp:418
void invalidatePainterPath() const noexcept
Definition path.h:191
qreal calcAreaOfStraightSegments() const noexcept
Definition path.cpp:108
Path & rotate(const Angle &angle, const Point &center=Point(0, 0)) noexcept
Definition path.cpp:271
QPainterPath mPainterPathPx
Definition path.h:197
static Path obround(const PositiveLength &width, const PositiveLength &height) noexcept
Definition path.cpp:443
void addVertex(const Vertex &vertex) noexcept
Definition path.cpp:341
~Path() noexcept
Definition path.h:69
Path rotated(const Angle &angle, const Point &center=Point(0, 0)) const noexcept
Definition path.cpp:279
void serialize(SExpression &root) const
Serialize into librepcb::SExpression node.
Definition path.cpp:392
bool isOnGrid(const PositiveLength &gridInterval) const noexcept
Definition path.cpp:86
Path & translate(const Point &offset) noexcept
Definition path.cpp:247
bool isCurved() const noexcept
Definition path.cpp:63
UnsignedLength getTotalStraightLength() const noexcept
Definition path.cpp:95
bool open() noexcept
Definition path.cpp:383
bool operator!=(const Path &rhs) const noexcept
Definition path.h:130
bool isClosed() const noexcept
Definition path.cpp:55
Path toClosedPath() const noexcept
Definition path.cpp:146
The Point class is used to represent a point/coordinate/vector, for example (1.2mm; 5....
Definition point.h:78
The RuntimeError class.
Definition exceptions.h:218
The SExpression class.
Definition sexpression.h:69
The Vertex class.
Definition vertex.h:43
Definition occmodel.cpp:77
std::size_t qHash(const AttributeKey &key, std::size_t seed=0) noexcept
Definition attributekey.h:113
type_safe::constrained_type< Length, PositiveLengthConstraint, PositiveLengthVerifier > PositiveLength
Definition length.h:810
type_safe::constrained_type< Path, NonEmptyPathConstraint, NonEmptyPathVerifier > NonEmptyPath
Definition path.h:238
type_safe::constrained_type< Length, UnsignedLengthConstraint, UnsignedLengthVerifier > UnsignedLength
Definition length.h:694
type_safe::constrained_type< Path, StraightAreaPathConstraint, StraightAreaPathVerifier > StraightAreaPath
Definition path.h:281
NonEmptyPath makeNonEmptyPath(const Point &pos) noexcept
Definition path.h:245
Definition uuid.h:186
bool operator()(const Path &p) const noexcept
Definition path.h:225
Definition path.h:212
static constexpr auto verify(Value &&val, const Predicate &p) -> typename std::decay< Value >::type
Definition path.h:214
bool operator()(const Path &p) const noexcept
Definition path.h:266
static constexpr auto verify(Value &&val, const Predicate &p) -> typename std::decay< Value >::type
Definition path.h:255