KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_drc_creepage_issue24523.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
34
37
38#include <board.h>
40#include <layer_ids.h>
41#include <drc/drc_item.h>
42#include <drc/drc_engine.h>
43#include <footprint.h>
44#include <pad.h>
45#include <pcb_marker.h>
48
49
51{
53
55 {
56 if( m_board && m_board->GetDesignSettings().m_DRCEngine )
57 m_board->GetDesignSettings().m_DRCEngine->ClearViolationHandler();
58
59 if( m_board )
60 {
61 m_board->SetProject( nullptr );
62 m_board = nullptr;
63 }
64 }
65
67 std::unique_ptr<BOARD> m_board;
68};
69
70
72{
73 KI_TEST::LoadBoard( m_settingsManager, "issue24523/issue24523", m_board );
74
75 BOOST_REQUIRE_MESSAGE( m_board, "Failed to load board issue24523" );
76
77 struct ViolationInfo
78 {
79 std::shared_ptr<DRC_ITEM> item;
80 VECTOR2I pos;
81 std::vector<PCB_SHAPE> pathShapes;
82 int layer = 0;
83 double reportedActual = -1.0;
84 };
85
86 std::vector<ViolationInfo> violations;
87 BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
88
89 BOOST_REQUIRE_MESSAGE( bds.m_DRCEngine, "DRC engine not initialized" );
90
91 for( int ii = DRCE_FIRST; ii <= DRCE_LAST; ++ii )
93
95
96 auto parseActual =
97 []( const wxString& aMsg ) -> double
98 {
99 int actualPos = aMsg.Find( wxT( "actual " ) );
100
101 if( actualPos == wxNOT_FOUND )
102 return -1.0;
103
104 wxString tail = aMsg.Mid( actualPos + 7 );
105 int spacePos = tail.Find( ' ' );
106
107 if( spacePos != wxNOT_FOUND )
108 tail = tail.Left( spacePos );
109
110 double value = -1.0;
111 tail.ToDouble( &value );
112 return value;
113 };
114
116 [&]( const std::shared_ptr<DRC_ITEM>& aItem, const VECTOR2I& aPos, int aLayer,
117 const std::function<void( PCB_MARKER* )>& aPathGenerator )
118 {
119 if( bds.GetSeverity( aItem->GetErrorCode() ) != SEVERITY::RPT_SEVERITY_ERROR )
120 return;
121
122 ViolationInfo vi;
123 vi.item = aItem;
124 vi.pos = aPos;
125 vi.layer = aLayer;
126 vi.reportedActual = parseActual( aItem->GetErrorMessage( false ) );
127
128 if( aPathGenerator )
129 {
130 PCB_MARKER marker( aItem, aPos, aLayer );
131 aPathGenerator( &marker );
132 vi.pathShapes = marker.GetPath();
133 }
134
135 violations.push_back( vi );
136 } );
137
138 bds.m_DRCEngine->RunTests( EDA_UNITS::MM, true, false );
139
141
142 BOOST_TEST_MESSAGE( wxString::Format( "Found %d creepage violations",
143 (int) violations.size() ) );
144
145 double shortestActual = std::numeric_limits<double>::max();
146
147 for( const ViolationInfo& vi : violations )
148 {
149 BOOST_TEST_MESSAGE( wxString::Format( " layer=%d arrow=(%.4f,%.4f) shapes=%d actual=%.4f",
150 vi.layer, vi.pos.x / 1e6, vi.pos.y / 1e6,
151 (int) vi.pathShapes.size(), vi.reportedActual ) );
152
153 if( vi.reportedActual >= 0.0 )
154 shortestActual = std::min( shortestActual, vi.reportedActual );
155 }
156
157 // The two nets violate the 5 mm rule because the true surface path that winds
158 // around the two NPTH slots is only ~3 mm. The path search must find it.
159 BOOST_REQUIRE_MESSAGE( !violations.empty(),
160 "No creepage violation reported; the path search failed to find the ~3 mm route "
161 "winding around the two NPTH slots and overestimated the creepage distance." );
162
163 BOOST_TEST_MESSAGE( wxString::Format( "Shortest reported creepage actual: %.4f mm",
164 shortestActual ) );
165
166 // A violation is only emitted when the computed distance is below the 5 mm rule, so any
167 // reported actual is already < 5 mm. Guard against a future regression that lets a grossly
168 // overestimated (but still sub-5 mm) path through: the real path is ~3 mm.
169 BOOST_CHECK_MESSAGE( shortestActual < 4.0,
170 wxString::Format( "Shortest reported creepage %.4f mm is far longer than the true "
171 "~3 mm winding path, indicating the search is still missing the "
172 "shortest route around the two slots.", shortestActual ) );
173}
Container for design settings for a BOARD object.
std::map< int, SEVERITY > m_DRCSeverities
std::shared_ptr< DRC_ENGINE > m_DRCEngine
SEVERITY GetSeverity(int aDRCErrorCode)
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 ClearViolationHandler()
Definition drc_engine.h:169
const std::vector< PCB_SHAPE > & GetPath() const
Definition pcb_marker.h:158
@ DRCE_CREEPAGE
Definition drc_item.h:41
@ DRCE_FIRST
Definition drc_item.h:35
@ DRCE_LAST
Definition drc_item.h:121
void LoadBoard(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< BOARD > &aBoard)
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_IGNORE
BOOST_FIXTURE_TEST_CASE(CreepageTwoNPTHSlotsIssue24523, DRC_CREEPAGE_TWO_SLOTS_FIXTURE)
BOOST_CHECK_MESSAGE(totalMismatches==0, std::to_string(totalMismatches)+" board(s) with strategy disagreements")
BOOST_TEST_MESSAGE("\n=== Real-World Polygon PIP Benchmark ===\n"<< formatTable(table))
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683