KiCad PCB EDA Suite
Loading...
Searching...
No Matches
drc_test_provider_track_segment_length.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 (C) 2004-2023 KiCad Developers.
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, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include <core/thread_pool.h>
25#include <pcb_track.h>
26#include <drc/drc_engine.h>
27#include <drc/drc_item.h>
28#include <drc/drc_rule.h>
30
31
32/*
33 Track segment length test. As the name says, checks segment length of the tracks (including segments and arcs)
34 Errors generated:
35 - DRCE_TRACK_SEGMENT_LENGTH
36*/
37
39{
40public:
42 {}
43
45 {}
46
47 virtual bool Run() override;
48
49 virtual const wxString GetName() const override
50 {
51 return wxT( "segment_length" );
52 };
53
54 virtual const wxString GetDescription() const override
55 {
56 return wxT( "Tests track segment lengths" );
57 }
58};
59
60
62{
64 {
65 reportAux( wxT( "Track segment length violations ignored. Tests not run." ) );
66 return true; // continue with other tests
67 }
68
70 {
71 reportAux( wxT( "No track segment length constraints found. Tests not run." ) );
72 return true; // continue with other tests
73 }
74
75 if( !reportPhase( _( "Checking track segment lengths..." ) ) )
76 return false; // DRC cancelled
77
78 auto checkTrackSegmentLength =
79 [&]( BOARD_ITEM* item ) -> bool
80 {
82 return false;
83
84 int actual;
85 VECTOR2I p0;
86
87 if( item->Type() == PCB_ARC_T )
88 {
89 PCB_ARC* arc = static_cast<PCB_ARC*>( item );
90
91 actual = arc->GetLength();
92 p0 = arc->GetStart();
93 }
94 else if( item->Type() == PCB_TRACE_T )
95 {
96 PCB_TRACK* track = static_cast<PCB_TRACK*>( item );
97
98 actual = track->GetLength();
99 p0 = ( track->GetStart() + track->GetEnd() ) / 2;
100 }
101 else
102 {
103 return true;
104 }
105
106 auto constraint = m_drcEngine->EvalRules( TRACK_SEGMENT_LENGTH_CONSTRAINT, item, nullptr,
107 item->GetLayer() );
108 bool fail_min = false;
109 bool fail_max = false;
110 int constraintLength = 0;
111
112 if( constraint.GetSeverity() != RPT_SEVERITY_IGNORE )
113 {
114 if( constraint.Value().HasMin() && actual < constraint.Value().Min() )
115 {
116 fail_min = true;
117 constraintLength = constraint.Value().Min();
118 }
119
120 if( constraint.Value().HasMax() && actual > constraint.Value().Max() )
121 {
122 fail_max = true;
123 constraintLength = constraint.Value().Max();
124 }
125 }
126
127 if( fail_min || fail_max )
128 {
129 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_TRACK_SEGMENT_LENGTH );
130 wxString constraintName = constraint.GetName();
131 wxString msg;
132
133 if( fail_min )
134 {
135 if( constraint.m_ImplicitMin )
136 constraintName = _( "board setup constraints" );
137
138 msg = formatMsg( _( "(%s min length %s; actual %s)" ),
139 constraintName,
140 constraintLength,
141 actual );
142 }
143 else
144 {
145 msg = formatMsg( _( "(%s max length %s; actual %s)" ),
146 constraintName,
147 constraintLength,
148 actual );
149 }
150
151 drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
152 drcItem->SetItems( item );
153 drcItem->SetViolatingRule( constraint.GetParentRule() );
154
155 reportViolation( drcItem, p0, item->GetLayer() );
156 }
157
158 return true;
159 };
160
161 const int progressDelta = 250;
162 int ii = 0;
163
165 std::vector<std::future<bool>> returns;
166
167 returns.reserve( m_drcEngine->GetBoard()->Tracks().size() );
168
169 for( PCB_TRACK* item : m_drcEngine->GetBoard()->Tracks() )
170 {
171 returns.emplace_back( tp.submit( checkTrackSegmentLength, item ) );
172 }
173
174 for( std::future<bool>& ret : returns )
175 {
176 std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
177
178 while( status != std::future_status::ready )
179 {
180 reportProgress( ii++, m_drcEngine->GetBoard()->Tracks().size(), progressDelta );
181 status = ret.wait_for( std::chrono::milliseconds( 250 ) );
182 }
183 }
184
186
187 return !m_drcEngine->IsCancelled();
188}
189
190
191namespace detail
192{
194}
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:79
const TRACKS & Tracks() const
Definition: board.h:329
MINOPTMAX< int > & Value()
Definition: drc_rule.h:153
BOARD * GetBoard() const
Definition: drc_engine.h:99
bool HasRulesForConstraintType(DRC_CONSTRAINT_T constraintID)
bool IsErrorLimitExceeded(int error_code)
DRC_CONSTRAINT EvalRules(DRC_CONSTRAINT_T aConstraintType, const BOARD_ITEM *a, const BOARD_ITEM *b, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
Definition: drc_engine.cpp:679
bool IsCancelled() const
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
Definition: drc_item.cpp:372
virtual const wxString GetDescription() const override
virtual bool Run() override
Run this provider against the given PCB with configured options (if any).
Represent a DRC "provider" which runs some DRC functions over a BOARD and spits out DRC_ITEM and posi...
wxString formatMsg(const wxString &aFormatString, const wxString &aSource, double aConstraint, double aActual)
virtual bool reportPhase(const wxString &aStageName)
virtual void reportViolation(std::shared_ptr< DRC_ITEM > &item, const VECTOR2I &aMarkerPos, int aMarkerLayer)
DRC_ENGINE * m_drcEngine
void reportAux(const wxString &aMsg)
virtual void reportRuleStatistics()
virtual bool reportProgress(size_t aCount, size_t aSize, size_t aDelta=1)
T Min() const
Definition: minoptmax.h:33
virtual double GetLength() const override
Return the length of the arc track.
Definition: pcb_track.h:333
virtual double GetLength() const
Get the length of the track using the hypotenuse calculation.
Definition: pcb_track.cpp:725
const VECTOR2I & GetStart() const
Definition: pcb_track.h:122
const VECTOR2I & GetEnd() const
Definition: pcb_track.h:119
@ DRCE_TRACK_SEGMENT_LENGTH
Definition: drc_item.h:57
@ TRACK_SEGMENT_LENGTH_CONSTRAINT
Definition: drc_rule.h:60
#define _(s)
static DRC_REGISTER_TEST_PROVIDER< DRC_TEST_PROVIDER_ANNULAR_WIDTH > dummy
@ RPT_SEVERITY_IGNORE
static thread_pool * tp
Definition: thread_pool.cpp:30
BS::thread_pool thread_pool
Definition: thread_pool.h:30
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
Definition: thread_pool.cpp:32
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:96