KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_junction_helpers.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.TXT for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 3
9 * of the License, or (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 <https://www.gnu.org/licenses/>.
18 */
19
21
22#include <junction_helpers.h>
23
24#include <sch_bus_entry.h>
25#include <sch_line.h>
26#include <sch_sheet.h>
27#include <sch_sheet_pin.h>
28
29using namespace JUNCTION_HELPERS;
30
31static constexpr int BE_SIZE = 25400;
32
37
38static SCH_LINE* make_wire( const VECTOR2I& aStart, const VECTOR2I& aEnd )
39{
40 SCH_LINE* const line = new SCH_LINE{ aStart, LAYER_WIRE };
41 line->SetEndPoint( aEnd );
42 return line;
43}
44
45static SCH_LINE* make_bus( const VECTOR2I& aStart, const VECTOR2I& aEnd )
46{
47 SCH_LINE* const line = new SCH_LINE{ aStart, LAYER_BUS };
48 line->SetEndPoint( aEnd );
49 return line;
50}
51
52BOOST_FIXTURE_TEST_SUITE( JunctionHelpers, JUNCTION_HELPER_FIXTURE )
53
54
58{
59 const POINT_INFO info = AnalyzePoint( items, { 0, 0 }, false );
60
61 BOOST_CHECK( !info.isJunction );
62}
63
64BOOST_AUTO_TEST_CASE( SingleWireEnd )
65{
66 /*
67 * not a junction
68 * V
69 * -----------
70 */
71 items.insert( make_wire( { 0, 0 }, { 0, 100 } ) );
72
73 const POINT_INFO info = AnalyzePoint( items, { 0, 0 }, false );
74
75 BOOST_CHECK( !info.isJunction );
76}
77
79{
80 /*
81 * |
82 * |_____
83 * ^
84 * not a junction
85 */
86 items.insert( make_wire( { 0, 0 }, { 100, 0 } ) );
87 items.insert( make_wire( { 0, 0 }, { 0, 100 } ) );
88
89 const POINT_INFO info = AnalyzePoint( items, { 0, 0 }, false );
90
91 BOOST_CHECK( !info.isJunction );
92}
93
95{
96 /*
97 * | /-- junction in the middle
98 * | /
99 * -----O------
100 */
101 items.insert( make_wire( { 0, 0 }, { 100, 0 } ) );
102 items.insert( make_wire( { 0, 0 }, { -100, 0 } ) );
103 items.insert( make_wire( { 0, 0 }, { 0, 100 } ) );
104
105 const POINT_INFO info = AnalyzePoint( items, { 0, 0 }, false );
106
107 BOOST_CHECK( info.isJunction );
108 BOOST_CHECK( !info.hasBusEntry );
109 BOOST_CHECK( !info.hasBusEntryToMultipleWires );
110}
111
112BOOST_AUTO_TEST_CASE( BusEntryOnBus )
113{
114 /*
115 * || <-- not a junction (it is a connection!)
116 * ||\
117 * || \
118 * || \ <-- also not a junction
119 */
120
121 items.insert( make_bus( { 0, 0 }, { 0, BE_SIZE } ) );
122
123 SCH_BUS_WIRE_ENTRY* const busEntry = new SCH_BUS_WIRE_ENTRY( { 0, 0 }, false );
124
125 // Make sure the BE is where we think it is
126 BOOST_REQUIRE_EQUAL( busEntry->GetPosition(), VECTOR2I( 0, 0 ) );
127 BOOST_REQUIRE_EQUAL( busEntry->GetEnd(), VECTOR2I( BE_SIZE, BE_SIZE ) );
128
129 items.insert( busEntry );
130
131 // BE-bus point
132 const POINT_INFO info_start = AnalyzePoint( items, { 0, 0 }, false );
133 BOOST_CHECK( !info_start.isJunction );
134 BOOST_CHECK( info_start.hasBusEntry );
135
136 // Dangling end of the bus entry
137 const POINT_INFO info_end = AnalyzePoint( items, { BE_SIZE, BE_SIZE }, false );
138 BOOST_CHECK( !info_end.isJunction );
139 BOOST_CHECK( info_end.hasBusEntry );
140 // There is no wire here
141 BOOST_CHECK( !info_end.hasBusEntryToMultipleWires );
142}
143
144BOOST_AUTO_TEST_CASE( BusEntryToWire )
145{
146 /*
147 * \
148 * \ /--- <-- not a junction
149 * \V________________
150 */
151 SCH_BUS_WIRE_ENTRY* const busEntry = new SCH_BUS_WIRE_ENTRY( { 0, 0 }, false );
152 items.insert( busEntry );
153 items.insert( make_wire( { BE_SIZE, BE_SIZE }, { 2 * BE_SIZE, BE_SIZE } ) );
154
155 const POINT_INFO info = AnalyzePoint( items, { BE_SIZE, BE_SIZE }, false );
156 BOOST_CHECK( !info.isJunction );
157 BOOST_CHECK( info.hasBusEntry );
158 // This is a single wire to a bus entry, not multiple
159 BOOST_CHECK( !info.hasBusEntryToMultipleWires );
160}
161
162BOOST_AUTO_TEST_CASE( WireDirectToBus )
163{
164 /*
165 * || /--- <-- not a junction
166 * ||______________
167 */
168 items.insert( make_bus( { 0, 0 }, { 0, BE_SIZE } ) );
169 items.insert( make_wire( { 0, 0 }, { BE_SIZE, 0 } ) );
170
171 const POINT_INFO info = AnalyzePoint( items, { 0, 0 }, false );
172 BOOST_CHECK( !info.isJunction );
173 BOOST_CHECK( !info.hasBusEntry );
174 // It's a single wire, and not a bus entry
175 BOOST_CHECK( !info.hasBusEntryToMultipleWires );
176}
177
178BOOST_AUTO_TEST_CASE( WireCrossingBus )
179{
180 /* || __ not a junction
181 * || /
182 * ______________________
183 * ||
184 * ||
185 */
186 items.insert( make_bus( { 0, 0 }, { 0, -BE_SIZE } ) );
187 items.insert( make_bus( { 0, 0 }, { 0, BE_SIZE } ) );
188 items.insert( make_wire( { 0, 0 }, { BE_SIZE, 0 } ) );
189 items.insert( make_wire( { 0, 0 }, { -BE_SIZE, 0 } ) );
190
191 const POINT_INFO info = AnalyzePoint( items, { 0, 0 }, false );
192 // Two wires and two buses meet, which isn't a junction
193 BOOST_CHECK( !info.isJunction );
194 BOOST_CHECK( !info.hasBusEntry );
195 BOOST_CHECK( !info.hasBusEntryToMultipleWires );
196}
197
198BOOST_AUTO_TEST_CASE( WireToBusEntryRoot )
199{
200 /*
201 * /--- <-- not a junction
202 * _____________
203 * ||\
204 * || \
205 * || \
206 */
207 items.insert( make_bus( { 0, 0 }, { 0, BE_SIZE } ) );
208 items.insert( make_wire( { 0, 0 }, { BE_SIZE, 0 } ) );
209 items.insert( new SCH_BUS_WIRE_ENTRY( { 0, 0 }, false ) );
210
211 const POINT_INFO info = AnalyzePoint( items, { 0, 0 }, false );
212 BOOST_CHECK( !info.isJunction );
213 BOOST_CHECK( info.hasBusEntry );
214 // The bus/bus-entry point isn't valid
215 BOOST_CHECK( !info.hasBusEntryToMultipleWires );
216}
217
218BOOST_AUTO_TEST_CASE( WireCrossingBusEntryRoot )
219{
220 /* ||
221 * || /--- <-- it's a junction, but the client can choose not
222 * || to put a dot here
223 * ______________________
224 * ||\
225 * || \
226 * || \
227 */
228 items.insert( make_bus( { 0, 0 }, { 0, -BE_SIZE } ) );
229 items.insert( make_bus( { 0, 0 }, { 0, BE_SIZE } ) );
230 items.insert( make_wire( { 0, 0 }, { BE_SIZE, 0 } ) );
231 items.insert( make_wire( { 0, 0 }, { -BE_SIZE, 0 } ) );
232 items.insert( new SCH_BUS_WIRE_ENTRY( { 0, 0 }, false ) );
233
234 const POINT_INFO info = AnalyzePoint( items, { 0, 0 }, false );
235 // Three buses meet here, so this is a junction
236 BOOST_CHECK( info.isJunction );
237 BOOST_CHECK( info.hasBusEntry );
238 // There are multiple wires but they don't count here
239 BOOST_CHECK( !info.hasBusEntryToMultipleWires );
240}
241
242BOOST_AUTO_TEST_CASE( WireCornerToBusEntry )
243{
244 /*
245 * ||
246 * ||
247 * ||
248 * \ /--- junction here
249 * \ |
250 * O-------------
251 * |
252 * |
253 */
254 items.insert( make_bus( { 0, 0 }, { 0, BE_SIZE } ) );
255 items.insert( make_wire( { BE_SIZE, BE_SIZE }, { 2 * BE_SIZE, BE_SIZE } ) );
256 items.insert( make_wire( { BE_SIZE, BE_SIZE }, { BE_SIZE, 2 * BE_SIZE } ) );
257 items.insert( new SCH_BUS_WIRE_ENTRY( { 0, 0 }, false ) );
258
259 const POINT_INFO info = AnalyzePoint( items, { BE_SIZE, BE_SIZE }, false );
260 BOOST_CHECK( info.isJunction );
261 BOOST_CHECK( info.hasBusEntry );
262 BOOST_CHECK( info.hasBusEntryToMultipleWires );
263}
264
265BOOST_AUTO_TEST_CASE( WireTeeToBusEntry )
266{
267 /*
268 * ||
269 * ||
270 * || |
271 * \ | /--- junction here
272 * \| /
273 * O-------------
274 * |
275 * |
276 */
277 items.insert( make_bus( { 0, 0 }, { 0, BE_SIZE } ) );
278 items.insert( make_wire( { BE_SIZE, BE_SIZE }, { 2 * BE_SIZE, BE_SIZE } ) ); // right
279 items.insert( make_wire( { BE_SIZE, BE_SIZE }, { BE_SIZE, 0 } ) ); //up
280 items.insert( make_wire( { BE_SIZE, BE_SIZE }, { BE_SIZE, 2 * BE_SIZE } ) ); // down
281 items.insert( new SCH_BUS_WIRE_ENTRY( { 0, 0 }, false ) );
282
283 const POINT_INFO info = AnalyzePoint( items, { BE_SIZE, BE_SIZE }, false );
284 BOOST_CHECK( info.isJunction );
285 BOOST_CHECK( info.hasBusEntry );
286 BOOST_CHECK( info.hasBusEntryToMultipleWires );
287}
288
289BOOST_AUTO_TEST_CASE( SheetPinToOneWire )
290{
291 /*
292 * ---+ ___not a junction
293 * |/
294 * |=>|---------
295 * |
296 * --+
297 */
298
299 // The point of interest is at (0, 0)
300
301 items.insert( make_wire( { 0, 0 }, { BE_SIZE, 0 } ) ); // right
302
303 SCH_SHEET* const sheet = new SCH_SHEET( nullptr, { -10 * BE_SIZE, -10 * BE_SIZE },
304 { 10 * BE_SIZE, 20 * BE_SIZE } );
305 SCH_SHEET_PIN* const pin = new SCH_SHEET_PIN( sheet, { 0, 0 }, "Pin Name" );
306 pin->SetSide( SHEET_SIDE::RIGHT );
307
308 sheet->AddPin( pin );
309 items.insert( sheet );
310
311 // This test won't make sense if the pin isn't where we think it is!
312 BOOST_REQUIRE( sheet->IsConnected( { 0, 0 } ) );
313
314 const POINT_INFO info = AnalyzePoint( items, { 0, 0 }, false );
315 BOOST_CHECK( !info.isJunction );
316 BOOST_CHECK( !info.hasBusEntry );
317}
318
319BOOST_AUTO_TEST_CASE( SheetPinToTwoWires )
320{
321 /*
322 * A sheet pin counts as a wire, so this is a junction
323 *
324 * ---+ ___this is a junction
325 * |/
326 * |=>O---------
327 * |\
328 * | \
329 * | \
330 * --+
331 */
332 // The point of interest is at (0, 0)
333
334 items.insert( make_wire( { 0, 0 }, { BE_SIZE, 0 } ) ); // right
335 items.insert( make_wire( { 0, 0 }, { BE_SIZE, BE_SIZE } ) ); // right and down
336
337 SCH_SHEET* const sheet = new SCH_SHEET( nullptr, { -10 * BE_SIZE, -10 * BE_SIZE },
338 { 10 * BE_SIZE, 20 * BE_SIZE } );
339 SCH_SHEET_PIN* const pin = new SCH_SHEET_PIN( sheet, { 0, 0 }, "Pin Name" );
340 pin->SetSide( SHEET_SIDE::RIGHT );
341
342 sheet->AddPin( pin );
343 items.insert( sheet );
344
345 BOOST_REQUIRE( sheet->IsConnected( { 0, 0 } ) );
346
347 const POINT_INFO info = AnalyzePoint( items, { 0, 0 }, false );
348 BOOST_CHECK( info.isJunction );
349 BOOST_CHECK( !info.hasBusEntry );
350}
351
Implement an R-tree for fast spatial and type indexing of schematic items.
Definition sch_rtree.h:34
VECTOR2I GetPosition() const override
VECTOR2I GetEnd() const
Class for a wire to bus entry.
bool IsConnected(const VECTOR2I &aPoint) const
Test the item to see if it is connected to aPoint.
Definition sch_item.cpp:478
Segment description base class to describe items which have 2 end points (track, wire,...
Definition sch_line.h:38
void SetEndPoint(const VECTOR2I &aPosition)
Definition sch_line.h:145
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:44
void AddPin(SCH_SHEET_PIN *aSheetPin)
Add aSheetPin to the sheet.
@ LAYER_WIRE
Definition layer_ids.h:450
@ LAYER_BUS
Definition layer_ids.h:451
POINT_INFO AnalyzePoint(const EE_RTREE &aItem, const VECTOR2I &aPosition, bool aBreakCrossings)
Check a tree of items for a confluence at a given point and work out what kind of junction it is,...
A selection of information about a point in the schematic that might be eligible for turning into a j...
bool hasBusEntryToMultipleWires
True if there is a bus entry at the point and it connects to more than one wire.
bool isJunction
True if the point has 3+ wires and/or 3+ buses meeting there.
bool hasBusEntry
True if there is a bus entry at the point (either end)
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
static SCH_LINE * make_wire(const VECTOR2I &aStart, const VECTOR2I &aEnd)
BOOST_AUTO_TEST_CASE(Empty)
Check that we can get the basic properties out as expected.
static constexpr int BE_SIZE
static SCH_LINE * make_bus(const VECTOR2I &aStart, const VECTOR2I &aEnd)
KIBIS_PIN * pin
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683