PCB Environment 2
Loading...
Searching...
No Matches
Track.hpp
1#ifndef GYM_PCB_TRACK_H
2#define GYM_PCB_TRACK_H
3
4#include "AShape.hpp"
5#include "Path.hpp"
6#include "Via.hpp"
7
8class NavGrid;
9class Connection;
10
11enum class ContactType
12{
13 NONE = 0,
14 END_TO_START = 1,
15 END_TO_END = 2,
16 START_TO_END = 3,
17 START_TO_START = 4
18};
19
20class Track
21{
22public:
23 Track(const Point_25 &start) : mStart(start), mEnd(start) { }
24
25 const Point_25& start() const { return mStart; }
26 const Point_25& end() const { return mEnd; }
27
28 bool empty() const { return mSegments.empty() && mVias.empty(); }
29
30 const WideSegment_25& getSegment(uint i) const { assert(i < mSegments.size()); return mSegments[i]; }
31 const std::vector<WideSegment_25>& getSegments() const { return mSegments; }
32 uint numSegments() const { return mSegments.size(); }
33 bool hasSegments() const { return !mSegments.empty(); }
34 void setSegments(const std::vector<Segment_25>&);
35 void setSegments(const std::vector<WideSegment_25>&);
36 void setSegments(std::vector<WideSegment_25>&&);
37
38 const Via& getVia(uint i) const { assert(i < mVias.size()); return mVias[i]; }
39 const std::vector<Via>& getVias() const { return mVias; }
40 uint numVias() const { return mVias.size(); }
41 bool hasVias() const { return !mVias.empty(); }
42 bool startsWithVia() const;
43 bool endsWithVia() const;
44 bool inferStartsWithVia() const;
45 bool inferEndsWithVia() const;
46
47 ContactType canAttach(const Track&) const;
48 bool touchesEndToStart(const Track&) const;
49 bool touchesEndToEnd(const Track&) const;
50 bool touchesStartToStart(const Track&) const;
51 bool touchesStartToEnd(const Track&) const;
52
53 void setStart(const Point_25&);
54 void setEnd(const Point_25&);
55 void _setEnd(const Point_25 &v);
56 void moveStartTo(const Point_25&);
57 void moveEndTo(const Point_25&);
58 void _setEndLayer(uint);
59 void _setEndLayer(const Point_25&);
60 void inferStart();
61 void inferEnd();
62 void inferEndpoints();
63
64 void setPath(const Path&, bool updateStart = false);
65 void _setPath(const Path&);
66 void getPath(Path&) const;
67 void setVias(const std::vector<Via> &vias) { setModified(); mVias = vias; }
68 void setVias(std::vector<Via> &&vias) { setModified(); mVias = std::move(vias); }
69 void autocreateVias(const Point_25 &end);
70
71 void setModified() { mCacheDirty = true; }
72
73 void append(const Track&);
74 void appendMove(Track *);
75 void append(const WideSegment_25&);
76 void appendSegment(const Point_25&, const Point_25&);
77 void append(const Via&);
78 void appendVia(const Point_2&, uint z0, uint z1, Real r = std::numeric_limits<Real>::quiet_NaN());
79 void prepend(const Via&);
80 Via popVia();
81 WideSegment_25 popSegment();
82 void popSafe();
83 void _append(const WideSegment_25&);
84 void _append(const Segment_25&);
85 void _appendVia(const Point_2&, uint z0, uint z1, Real r);
86
87 void extendTo(const Point_25&, uint viaLocation);
88 void _extendTo(const Point_25&);
89 void extendToLayer(uint z);
90
91 bool isContiguous() const;
92 bool hasValidEnds() const;
93
94 void clear();
95 Real reduceBy_cells(Real len_cells, const Real len_perLayer, const Real tolerance);
96 Real reduceSegmentsBy_cells(Real len_cells, const Real tolerance);
97 Real reduceViaBy_cells(Real len_cells, const Real len_perLayer, const Real tolerance);
98
99 void reverse();
100 static void _reverseSegments(std::vector<WideSegment_25>&);
101
102 Real defaultWidth() const { return mWidth; }
103 Real defaultViaDiameter() const { return mViaDiameter; }
104 Real defaultViaRadius() const { return mViaDiameter * 0.5; }
105
106 void setDefaultWidth(float w) { mWidth = w; }
107 void setDefaultViaDiameter(Real d) { mViaDiameter = d; }
108
109 Real length() const { return mLength; }
110 void computeLength();
111
112 void setSegmentCapsMask(uint8_t m) { mSegmentCapsMask = m; }
113 bool hasStartCap() const { return mSegmentCapsMask & 0x1; }
114 bool hasEndCap() const { return mSegmentCapsMask & 0x2; }
115 bool hasSegmentJoints() const { return mSegmentCapsMask & 0x4; }
116
118 Bbox_2 bbox(Real clearance, int z = -1) const;
119
120 bool snapToStart(Point_25&, const Point_25&, Real maxDistance = 0.0) const;
121 bool snapToEnd(Point_25&, const Point_25&, Real maxDistance = 0.0) const;
122 int snapToEndpoint(Point_25&, const Point_25&, Real maxDistance = 0.0) const;
123
124 void determineForks(std::vector<uint> &indices, const Connection&);
125 Real shortcutBetween(uint sourcePos, uint targetPos);
126
128 bool violatesClearance(const Pin&, Real clearance, Point_25 * = 0) const;
129 bool violatesClearance(const Track&, Real clearance, Point_25 * = 0) const;
130 bool violatesClearance2D(const Track&, Real clearance, Point_25 * = 0) const;
131 bool violatesClearance(const Via&, Real clearance, Point_25 * = 0) const;
132 bool violatesClearance(const WideSegment_25&, Real clearance, Point_25 * = 0) const;
133 bool intersects(const Bbox_2&, uint zmin, uint zmax) const;
134
135 bool isRasterized() const { return mRasterizedCount > 0; }
136 void resetRasterizedCount() { mRasterizedCount = 0; }
137 void addRasterizedCount(int count) const;
138 bool checkRasterization(const NavGrid&) const;
139
140 bool updateForRemovedLayers(uint zmin, uint zmax);
141
142 std::string str() const;
143 void setPy(PyObject *);
144 PyObject *getViasPy() const;
145 PyObject *getViasNumpy() const;
146 PyObject *getSegmentsPy() const;
147 PyObject *getSegmentsNumpy() const;
148 PyObject *getPathPy() const;
149 PyObject *getPathNumpy() const;
150 PyObject *getPy(bool asNumpy) const;
151private:
152 std::vector<WideSegment_25> mSegments;
153 std::vector<Via> mVias;
154 Point_25 mStart;
155 Point_25 mEnd;
156 Real mWidth{0.0};
157 Real mViaDiameter{0.0};
158 Real mLength{0.0};
159 mutable Bbox_2 mCachedBbox;
160 mutable bool mCacheDirty{true};
161 uint8_t mSegmentCapsMask{0x7}; // 0x4|0x2|0x1 for joints|track end|track start
162private:
163 mutable int mRasterizedCount{0};
164};
165
166inline Via Track::popVia()
167{
168 assert(endsWithVia());
169 setModified();
170 const auto via = mVias.back();
171 mVias.pop_back();
172 mEnd = hasSegments() ? mSegments.back().target() : mStart;
173 return via;
174}
175inline WideSegment_25 Track::popSegment()
176{
177 assert(hasSegments() && !endsWithVia());
178 setModified();
179 const auto s = mSegments.back();
180 mSegments.pop_back();
181 inferEnd();
182 mLength -= s.base().length();
183 return s;
184}
185inline void Track::popSafe()
186{
187 if (endsWithVia())
188 popVia();
189 else if (hasSegments())
190 popSegment();
191}
192
193inline void Track::appendMove(Track *T)
194{
195 append(*T);
196 T->clear();
197}
198
199inline void Track::prepend(const Via &v)
200{
201 assert(v.contains(mStart));
202 setModified();
203 mVias.insert(mVias.begin(), v);
204}
205
206inline bool Track::startsWithVia() const
207{
208 const bool rv = hasSegments() ? (mStart.z() != mSegments.front().z()) : hasVias();
209 assert(!rv || (hasVias() && mVias.front().contains(mStart)));
210 return rv;
211}
212inline bool Track::endsWithVia() const
213{
214 const bool rv = hasSegments() ? (mEnd.z() != mSegments.back().z()) : hasVias();
215 assert(!rv || (hasVias() && mVias.back().contains(mEnd)));
216 return rv;
217}
218
219inline void Track::_setEnd(const Point_25 &v)
220{
221 mEnd = v;
222}
223inline void Track::_setEndLayer(uint z)
224{
225 mEnd = Point_25(mEnd.xy(), z);
226}
227inline void Track::_setEndLayer(const Point_25 &v)
228{
229 if (mEnd.xy() != v.xy())
230 throw std::runtime_error("track end does not match specified endpoint");
231 _setEndLayer(v.z());
232}
233
234inline void Track::appendSegment(const Point_25 &v0, const Point_25 &v1)
235{
236 if (v0.z() == v1.z())
237 throw std::invalid_argument("segment points must be on the same layer");
238 append(WideSegment_25(v0.xy(), v1.xy(), v0.z(), mWidth * 0.5));
239}
240
241inline void Track::_append(const WideSegment_25 &s)
242{
243 setModified();
244 mSegments.emplace_back(s);
245}
246inline void Track::_append(const Segment_25 &s)
247{
248 setModified();
249 mSegments.emplace_back(s, mWidth * 0.5);
250}
251inline void Track::_appendVia(const Point_2 &c, uint z0, uint z1, Real r)
252{
253 setModified();
254 mVias.emplace_back(c, z0, z1, r);
255}
256
257#endif // GYM_PCB_TRACK_H
Definition Connection.hpp:17
The grid-representation of the board.
Definition NavGrid.hpp:61
Definition Path.hpp:13
Definition Pin.hpp:18
Definition Geometry.hpp:131
Definition Geometry.hpp:155
Definition Track.hpp:21
bool violatesClearance(const Pin &, Real clearance, Point_25 *=0) const
Check whether the other item comes within @clearance distance of this one.
Bbox_2 bbox(Real clearance, int z=-1) const
@z < 0 means all layers.
Definition Via.hpp:10
Definition AShape.hpp:332