LibrePCB Developers Documentation
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 "../qtcompat.h"
28#include "vertex.h"
29
30#include <type_safe/constrained_type.hpp>
31
32#include <QtCore>
33#include <QtGui>
34
35/*******************************************************************************
36 * Namespace / Forward Declarations
37 ******************************************************************************/
38namespace librepcb {
39
40/*******************************************************************************
41 * Class Path
42 ******************************************************************************/
43
58class Path final {
59 Q_DECLARE_TR_FUNCTIONS(Path)
60
61public:
62 // Constructors / Destructor
63 Path() noexcept : mVertices(), mPainterPathPx() {}
64 Path(const Path& other) noexcept;
65 explicit Path(const QVector<Vertex>& vertices) noexcept
66 : mVertices(vertices) {}
67 explicit Path(const SExpression& node);
68 ~Path() noexcept {}
69
70 // Getters
71 bool isClosed() const noexcept;
72 bool isCurved() const noexcept;
73 bool isZeroLength() const noexcept;
74 QVector<Vertex>& getVertices() noexcept {
76 return mVertices;
77 }
78 const QVector<Vertex>& getVertices() const noexcept { return mVertices; }
80 qreal calcAreaOfStraightSegments() const noexcept;
81 Point calcNearestPointBetweenVertices(const Point& p) const noexcept;
82 Path cleaned() const noexcept;
83 Path toClosedPath() const noexcept;
84 Path toOpenPath() const noexcept;
85 QVector<Path> toOutlineStrokes(const PositiveLength& width) const noexcept;
86 const QPainterPath& toQPainterPathPx() const noexcept;
87
88 // Transformations
89 Path& translate(const Point& offset) noexcept;
90 Path translated(const Point& offset) const noexcept;
91 Path& mapToGrid(const PositiveLength& gridInterval) noexcept;
92 Path mappedToGrid(const PositiveLength& gridInterval) const noexcept;
93 Path& rotate(const Angle& angle, const Point& center = Point(0, 0)) noexcept;
94 Path rotated(const Angle& angle,
95 const Point& center = Point(0, 0)) const noexcept;
96 Path& mirror(Qt::Orientation orientation,
97 const Point& center = Point(0, 0)) noexcept;
98 Path mirrored(Qt::Orientation orientation,
99 const Point& center = Point(0, 0)) const noexcept;
100 Path& reverse() noexcept;
101 Path reversed() const noexcept;
102 Path& flattenArcs(const PositiveLength& maxTolerance) noexcept;
103 Path flattenedArcs(const PositiveLength& maxTolerance) const noexcept;
104
105 // General Methods
106 void addVertex(const Vertex& vertex) noexcept;
107 void addVertex(const Point& pos, const Angle& angle = Angle::deg0()) noexcept;
108 void insertVertex(int index, const Vertex& vertex) noexcept;
109 void insertVertex(int index, const Point& pos,
110 const Angle& angle = Angle::deg0()) noexcept;
111 bool clean() noexcept;
112 bool close() noexcept;
113 bool open() noexcept;
114
120 void serialize(SExpression& root) const;
121
122 // Operator Overloadings
123 Path& operator=(const Path& rhs) noexcept;
124 bool operator==(const Path& rhs) const noexcept {
125 return mVertices == rhs.mVertices;
126 }
127 bool operator!=(const Path& rhs) const noexcept { return !(*this == rhs); }
128
139 bool operator<(const Path& rhs) const noexcept;
140
141 // Static Methods
142 static Path line(const Point& p1, const Point& p2,
143 const Angle& angle = Angle::deg0()) noexcept;
144 static Path circle(const PositiveLength& diameter) noexcept;
145 static Path obround(const PositiveLength& width,
146 const PositiveLength& height) noexcept;
147 static Path obround(const Point& p1, const Point& p2,
148 const PositiveLength& width) noexcept;
149 static Path arcObround(const Point& p1, const Point& p2, const Angle& angle,
150 const PositiveLength& width) noexcept;
151 static Path rect(const Point& p1, const Point& p2) noexcept;
152 static Path centeredRect(
153 const PositiveLength& width, const PositiveLength& height,
154 const UnsignedLength& cornerRadius = UnsignedLength(0)) noexcept;
155 static Path octagon(
156 const PositiveLength& width, const PositiveLength& height,
157 const UnsignedLength& cornerRadius = UnsignedLength(0)) noexcept;
158 static Path flatArc(const Point& p1, const Point& p2, const Angle& angle,
159 const PositiveLength& maxTolerance) noexcept;
160
171 static QPainterPath toQPainterPathPx(const QVector<Path>& paths,
172 bool area) noexcept;
173
174private: // Methods
175 void invalidatePainterPath() const noexcept {
176 mPainterPathPx = QPainterPath();
177 }
178
179private: // Data
180 QVector<Vertex> mVertices;
181 mutable QPainterPath mPainterPathPx; // cached path for #toQPainterPathPx()
182};
183
184/*******************************************************************************
185 * Non-Member Functions
186 ******************************************************************************/
187
188inline QtCompat::Hash qHash(const Path& key, QtCompat::Hash seed = 0) noexcept {
189 return qHashRange(key.getVertices().begin(), key.getVertices().end(), seed);
190}
191
192/*******************************************************************************
193 * Class NonEmptyPath
194 ******************************************************************************/
195
197 template <typename Value, typename Predicate>
198 static constexpr auto verify(Value&& val, const Predicate& p) ->
199 typename std::decay<Value>::type {
200 return p(val)
201 ? std::forward<Value>(val)
202 : (throw RuntimeError(__FILE__, __LINE__,
203 Path::tr("Path doesn't contain vertices!")),
204 std::forward<Value>(val));
205 }
206};
207
209 bool operator()(const Path& p) const noexcept {
210 return p.getVertices().count() > 0;
211 }
212};
213
221using NonEmptyPath = type_safe::constrained_type<Path, NonEmptyPathConstraint,
223
225 QtCompat::Hash seed = 0) noexcept {
226 return ::qHash(*key, seed);
227}
228
229inline NonEmptyPath makeNonEmptyPath(const Point& pos) noexcept {
230 return NonEmptyPath(Path({Vertex(pos)}));
231}
232
233/*******************************************************************************
234 * Class StraightAreaPath
235 ******************************************************************************/
236
238 template <typename Value, typename Predicate>
239 static constexpr auto verify(Value&& val, const Predicate& p) ->
240 typename std::decay<Value>::type {
241 return p(val) ? std::forward<Value>(val)
242 : (throw RuntimeError(
243 __FILE__, __LINE__,
244 Path::tr("Path is not fillable or contains arcs!")),
245 std::forward<Value>(val));
246 }
247};
248
250 bool operator()(const Path& p) const noexcept {
251 return (p.getVertices().count() >= 4) && p.isClosed() && (!p.isCurved());
252 }
253};
254
264 type_safe::constrained_type<Path, StraightAreaPathConstraint,
266
268 QtCompat::Hash seed = 0) noexcept {
269 return ::qHash(*key, seed);
270}
271
272/*******************************************************************************
273 * End of File
274 ******************************************************************************/
275
276} // namespace librepcb
277
278Q_DECLARE_METATYPE(librepcb::Path)
279
280#endif
The Angle class is used to represent an angle (for example 12.75 degrees)
Definition: angle.h:78
static Angle deg0() noexcept
0 degrees
Definition: angle.h:351
The Path class represents a list of vertices connected by straight lines or circular arc segments.
Definition: path.h:58
Path reversed() const noexcept
Definition: path.cpp:265
Path toOpenPath() const noexcept
Definition: path.cpp:143
QVector< Path > toOutlineStrokes(const PositiveLength &width) const noexcept
Definition: path.cpp:149
Path & mirror(Qt::Orientation orientation, const Point &center=Point(0, 0)) noexcept
Definition: path.cpp:239
Path flattenedArcs(const PositiveLength &maxTolerance) const noexcept
Definition: path.cpp:289
const QPainterPath & toQPainterPathPx() const noexcept
Definition: path.cpp:169
static Path octagon(const PositiveLength &width, const PositiveLength &height, const UnsignedLength &cornerRadius=UnsignedLength(0)) noexcept
Definition: path.cpp:492
const QVector< Vertex > & getVertices() const noexcept
Definition: path.h:78
Path & reverse() noexcept
Definition: path.cpp:253
QVector< Vertex > & getVertices() noexcept
Definition: path.h:74
bool operator<(const Path &rhs) const noexcept
The "<" operator to compare two librepcb::Path objects.
Definition: path.cpp:366
QVector< Vertex > mVertices
Definition: path.h:180
static Path rect(const Point &p1, const Point &p2) noexcept
Definition: path.cpp:452
Path translated(const Point &offset) const noexcept
Definition: path.cpp:211
Path & flattenArcs(const PositiveLength &maxTolerance) noexcept
Definition: path.cpp:269
Path mirrored(Qt::Orientation orientation, const Point &center=Point(0, 0)) const noexcept
Definition: path.cpp:248
static Path arcObround(const Point &p1, const Point &p2, const Angle &angle, const PositiveLength &width) noexcept
Definition: path.cpp:417
bool clean() noexcept
Definition: path.cpp:316
bool close() noexcept
Definition: path.cpp:329
Path & mapToGrid(const PositiveLength &gridInterval) noexcept
Definition: path.cpp:215
static Path centeredRect(const PositiveLength &width, const PositiveLength &height, const UnsignedLength &cornerRadius=UnsignedLength(0)) noexcept
Definition: path.cpp:462
Path cleaned() const noexcept
Definition: path.cpp:131
void insertVertex(int index, const Vertex &vertex) noexcept
Definition: path.cpp:306
static Path flatArc(const Point &p1, const Point &p2, const Angle &angle, const PositiveLength &maxTolerance) noexcept
Definition: path.cpp:543
Point calcNearestPointBetweenVertices(const Point &p) const noexcept
Definition: path.cpp:114
bool isZeroLength() const noexcept
Definition: path.cpp:73
Path mappedToGrid(const PositiveLength &gridInterval) const noexcept
Definition: path.cpp:223
Path() noexcept
Definition: path.h:63
static Path circle(const PositiveLength &diameter) noexcept
Definition: path.cpp:378
Path(const QVector< Vertex > &vertices) noexcept
Definition: path.h:65
static Path line(const Point &p1, const Point &p2, const Angle &angle=Angle::deg0()) noexcept
Definition: path.cpp:374
void invalidatePainterPath() const noexcept
Definition: path.h:175
qreal calcAreaOfStraightSegments() const noexcept
Definition: path.cpp:99
Path & rotate(const Angle &angle, const Point &center=Point(0, 0)) noexcept
Definition: path.cpp:227
QPainterPath mPainterPathPx
Definition: path.h:181
static Path obround(const PositiveLength &width, const PositiveLength &height) noexcept
Definition: path.cpp:382
void addVertex(const Vertex &vertex) noexcept
Definition: path.cpp:297
~Path() noexcept
Definition: path.h:68
Path rotated(const Angle &angle, const Point &center=Point(0, 0)) const noexcept
Definition: path.cpp:235
void serialize(SExpression &root) const
Serialize into librepcb::SExpression node.
Definition: path.cpp:348
Path & translate(const Point &offset) noexcept
Definition: path.cpp:203
bool isCurved() const noexcept
Definition: path.cpp:63
UnsignedLength getTotalStraightLength() const noexcept
Definition: path.cpp:86
bool open() noexcept
Definition: path.cpp:339
bool operator!=(const Path &rhs) const noexcept
Definition: path.h:127
bool isClosed() const noexcept
Definition: path.cpp:55
Path toClosedPath() const noexcept
Definition: path.cpp:137
The Point class is used to represent a point/coordinate/vector, for example (1.2mm; 5....
Definition: point.h:79
uint Hash
Return type of Qt's qHash() function.
Definition: qtcompat.h:58
The RuntimeError class.
Definition: exceptions.h:218
The SExpression class.
Definition: sexpression.h:69
The Vertex class.
Definition: vertex.h:44
Definition: occmodel.cpp:77
type_safe::constrained_type< Length, PositiveLengthConstraint, PositiveLengthVerifier > PositiveLength
Definition: length.h:812
type_safe::constrained_type< Path, NonEmptyPathConstraint, NonEmptyPathVerifier > NonEmptyPath
Definition: path.h:222
QtCompat::Hash qHash(const AttributeKey &key, QtCompat::Hash seed=0) noexcept
Definition: attributekey.h:119
type_safe::constrained_type< Length, UnsignedLengthConstraint, UnsignedLengthVerifier > UnsignedLength
Definition: length.h:696
type_safe::constrained_type< Path, StraightAreaPathConstraint, StraightAreaPathVerifier > StraightAreaPath
Definition: path.h:265
NonEmptyPath makeNonEmptyPath(const Point &pos) noexcept
Definition: path.h:229
QtCompat::Hash qHash(const StraightAreaPath &key, QtCompat::Hash seed=0) noexcept
Definition: path.h:267
Definition: path.h:208
bool operator()(const Path &p) const noexcept
Definition: path.h:209
Definition: path.h:196
static constexpr auto verify(Value &&val, const Predicate &p) -> typename std::decay< Value >::type
Definition: path.h:198
bool operator()(const Path &p) const noexcept
Definition: path.h:250
static constexpr auto verify(Value &&val, const Predicate &p) -> typename std::decay< Value >::type
Definition: path.h:239