KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_drc_courtyard_overlap.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 2
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
23#include <board.h>
25#include <footprint.h>
26#include <pcb_marker.h>
27#include <drc/drc_item.h>
28#include <drc/drc_engine.h>
29#include <widgets/ui_common.h>
30
31#include "drc_test_utils.h"
32
33
34/*
35 * Struct holding information about a courtyard collision
36 */
38{
39 // The two colliding parts
40 std::string m_refdes_a;
41 std::string m_refdes_b;
42};
43
44
45std::ostream& operator<<( std::ostream& os, const COURTYARD_COLLISION& aColl )
46{
47 os << "COURTYARD_COLLISION[ " << aColl.m_refdes_a << " -> " << aColl.m_refdes_b << "]";
48 return os;
49}
50
51
57{
58 std::string m_board_name; // Fixture under drc_courtyard/overlap/
59 std::vector<COURTYARD_COLLISION> m_collisions; // The expected collisions
60};
61
62
63BOOST_AUTO_TEST_SUITE( DrcCourtyardOverlap )
64
65// clang-format off
67 {
68 "empty_board",
69 {}, // no collisions
70 },
71 {
72 "single_empty_footprint",
73 {}, // no collisions
74 },
75 {
76 // A single footprint can't overlap itself
77 "single_footprint_single_courtyard",
78 {}, // no collisions
79 },
80 {
81 "two_footprints_no_overlap",
82 {}, // no collisions
83 },
84 {
85 "two_footprints_touching",
86 {}, // Touching means not colliding
87 },
88 {
89 "two_footprints_overlap",
90 {
91 { "U1", "U2" }, // These two collide
92 },
93 },
94 {
95 "two_footprints_overlap_different_sides",
96 {}, // but on different sides
97 },
98 {
99 "two_footprints_multiple_courtyards_overlap",
100 {
101 { "U1", "U2" },
102 },
103 },
104 {
105 // The courtyards do not overlap, but their bounding boxes do
106 "two_footprints_bbox_overlap_only",
107 {},
108 },
109};
110// clang-format on
111
112
116static bool CollisionMatchesExpected( BOARD& aBoard, const PCB_MARKER& aMarker,
117 const COURTYARD_COLLISION& aCollision )
118{
119 auto reporter = std::static_pointer_cast<DRC_ITEM>( aMarker.GetRCItem() );
120
121 const FOOTPRINT* item_a = dynamic_cast<FOOTPRINT*>( aBoard.ResolveItem( reporter->GetMainItemID(), true ) );
122 const FOOTPRINT* item_b = dynamic_cast<FOOTPRINT*>( aBoard.ResolveItem( reporter->GetAuxItemID(), true ) );
123
124 // can't find the items!
125 if( !item_a || !item_b )
126 return false;
127
128 const bool ref_match_aa_bb = ( item_a->GetReference() == aCollision.m_refdes_a )
129 && ( item_b->GetReference() == aCollision.m_refdes_b );
130
131 const bool ref_match_ab_ba = ( item_a->GetReference() == aCollision.m_refdes_b )
132 && ( item_b->GetReference() == aCollision.m_refdes_a );
133
134 // Doesn't matter which way around it is, but both have to match somehow
135 return ref_match_aa_bb || ref_match_ab_ba;
136}
137
138
147 const std::vector<std::unique_ptr<PCB_MARKER>>& aMarkers,
148 const std::vector<COURTYARD_COLLISION>& aExpCollisions )
149{
150 for( const auto& marker : aMarkers )
151 {
154 }
155
156 KI_TEST::CheckUnorderedMatches( aExpCollisions, aMarkers,
157 [&]( const COURTYARD_COLLISION& aColl, const std::unique_ptr<PCB_MARKER>& aMarker )
158 {
159 return CollisionMatchesExpected( aBoard, *aMarker, aColl );
160 } );
161}
162
163
169{
170 const std::string path = KI_TEST::GetPcbnewTestDataDir() + "drc_courtyard/overlap/"
171 + aCase.m_board_name + ".kicad_pcb";
172
173 std::unique_ptr<BOARD> board = KI_TEST::ReadBoardFromFileOrStream( path );
174
175 BOOST_REQUIRE( board );
176
177 BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
178
180
181 // we might not always have courtyards - that's a separate test
183
184 // list of markers to collect
185 std::vector<std::unique_ptr<PCB_MARKER>> markers;
186
187 DRC_ENGINE drcEngine( board.get(), &board->GetDesignSettings() );
188
189 drcEngine.InitEngine( wxFileName() );
190
191 drcEngine.SetViolationHandler(
192 [&]( const std::shared_ptr<DRC_ITEM>& aItem, const VECTOR2I& aPos, int aLayer,
193 const std::function<void( PCB_MARKER* )>& aPathGenerator )
194 {
195 if( aItem->GetErrorCode() == DRCE_OVERLAPPING_FOOTPRINTS
196 || aItem->GetErrorCode() == DRCE_MALFORMED_COURTYARD
197 || aItem->GetErrorCode() == DRCE_MISSING_COURTYARD )
198 {
199 markers.push_back( std::make_unique<PCB_MARKER>( aItem, aPos ) );
200 }
201 } );
202
203 drcEngine.RunTests( EDA_UNITS::MM, true, false );
204
205 CheckCollisionsMatchExpected( *board, markers, aCase.m_collisions );
206}
207
208
209BOOST_AUTO_TEST_CASE( OverlapCases )
210{
211 for( const auto& c : courtyard_cases )
212 {
213 BOOST_TEST_CONTEXT( c.m_board_name )
214 {
216 }
217 }
218}
219
General utilities for PCB file IO for QA programs.
Container for design settings for a BOARD object.
std::map< int, SEVERITY > m_DRCSeverities
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:409
BOARD_ITEM * ResolveItem(const KIID &aID, bool aAllowNullptrReturn=false) const
Definition board.cpp:2116
Design Rule Checker object that performs all the DRC tests.
Definition drc_engine.h:129
void RunTests(EDA_UNITS aUnits, bool aReportAllTrackErrors, bool aTestFootprints, BOARD_COMMIT *aCommit=nullptr)
Run the DRC tests.
void SetViolationHandler(DRC_VIOLATION_HANDLER aHandler)
Set an optional DRC violation handler (receives DRC_ITEMs and positions).
Definition drc_engine.h:164
void InitEngine(const wxFileName &aRulePath)
Initialize the DRC engine.
const wxString & GetReference() const
Definition footprint.h:901
std::shared_ptr< RC_ITEM > GetRCItem() const
@ DRCE_OVERLAPPING_FOOTPRINTS
Definition drc_item.h:68
@ DRCE_MISSING_COURTYARD
Definition drc_item.h:69
@ DRCE_MALFORMED_COURTYARD
Definition drc_item.h:70
General utilities for DRC-related PCB tests.
std::string GetPcbnewTestDataDir()
Utility which returns a path to the data directory where the test board files are stored.
void CheckUnorderedMatches(const EXP_CONT &aExpected, const FOUND_CONT &aFound, MATCH_PRED aMatchPredicate)
Check that a container of "found" objects matches a container of "expected" objects.
std::unique_ptr< BOARD > ReadBoardFromFileOrStream(const std::string &aFilename, std::istream &aFallback)
Read a board from a file, or another stream, as appropriate.
bool IsDrcMarkerOfType(const PCB_MARKER &aMarker, int aErrorCode)
Predicate for testing the type of a DRC marker.
STL namespace.
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_IGNORE
A complete courtyard overlap test case: the board fixture to load and the expected collisions.
std::vector< COURTYARD_COLLISION > m_collisions
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
static bool CollisionMatchesExpected(BOARD &aBoard, const PCB_MARKER &aMarker, const COURTYARD_COLLISION &aCollision)
Check if a PCB_MARKER is described by a particular COURTYARD_COLLISION object.
static void CheckCollisionsMatchExpected(BOARD &aBoard, const std::vector< std::unique_ptr< PCB_MARKER > > &aMarkers, const std::vector< COURTYARD_COLLISION > &aExpCollisions)
Check that the produced markers match the expected.
static void DoCourtyardOverlapTest(const COURTYARD_OVERLAP_TEST_CASE &aCase)
Run a single courtyard overlap testcase.
BOOST_AUTO_TEST_CASE(OverlapCases)
static std::vector< COURTYARD_OVERLAP_TEST_CASE > courtyard_cases
std::ostream & operator<<(std::ostream &os, const COURTYARD_COLLISION &aColl)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
std::string path
IbisParser parser & reporter
BOOST_CHECK_PREDICATE(ArePolylineEndPointsNearCircle,(chain)(c.m_geom.m_center_point)(radius)(accuracy+epsilon))
BOOST_TEST_CONTEXT("Test Clearance")
Functions to provide common constants and other functions to assist in making a consistent UI.
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683