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