KiCad PCB EDA Suite
drc_test_provider_hole_size.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-2020 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 <pad.h>
25 #include <track.h>
26 #include <drc/drc_item.h>
27 #include <drc/drc_rule.h>
29 
30 
31 /*
32  Drilled hole size test. scans vias/through-hole pads and checks for min drill sizes
33  Errors generated:
34  - DRCE_DRILL_OUT_OF_RANGE
35  - DRCE_MICROVIA_DRILL_OUT_OF_RANGE
36 */
37 
39 {
40 public:
42  m_board( nullptr )
43  {
44  }
45 
47  {
48  }
49 
50  virtual bool Run() override;
51 
52  virtual const wxString GetName() const override
53  {
54  return "hole_size";
55  };
56 
57  virtual const wxString GetDescription() const override
58  {
59  return "Tests sizes of drilled holes (via/pad drills)";
60  }
61 
62  virtual std::set<DRC_CONSTRAINT_T> GetConstraintTypes() const override;
63 
64  int GetNumPhases() const override;
65 
66 private:
67  void checkVia( VIA* via, bool aExceedMicro, bool aExceedStd );
68  void checkPad( PAD* aPad );
69 
71 };
72 
73 
75 {
77  {
78  if( !reportPhase( _( "Checking pad holes..." ) ) )
79  return false; // DRC cancelled
80 
82 
83  for( FOOTPRINT* footprint : m_board->Footprints() )
84  {
86  break;
87 
88  for( PAD* pad : footprint->Pads() )
89  {
91  break;
92 
93  checkPad( pad );
94  }
95  }
96  }
97 
100  {
102  {
103  if( !reportPhase( _( "Checking via holes..." ) ) )
104  return false; // DRC cancelled
105  }
106  else
107  {
108  if( !reportPhase( _( "Checking micro-via holes..." ) ) )
109  return false; // DRC cancelled
110  }
111 
112  std::vector<VIA*> vias;
113 
114  for( TRACK* track : m_board->Tracks() )
115  {
116  if( track->Type() == PCB_VIA_T )
117  vias.push_back( static_cast<VIA*>( track ) );
118  }
119 
120  for( VIA* via : vias )
121  {
124 
125  if( exceedMicro && exceedStd )
126  break;
127 
128  checkVia( via, exceedMicro, exceedStd );
129  }
130  }
131 
133 
134  return true;
135 }
136 
137 
139 {
140  int holeMinor = std::min( aPad->GetDrillSize().x, aPad->GetDrillSize().y );
141  int holeMajor = std::max( aPad->GetDrillSize().x, aPad->GetDrillSize().y );
142 
143  if( holeMinor == 0 )
144  return;
145 
146  auto constraint = m_drcEngine->EvalRules( HOLE_SIZE_CONSTRAINT, aPad, nullptr,
147  UNDEFINED_LAYER /* holes are not layer-specific */ );
148  bool fail_min = false;
149  bool fail_max = false;
150  int constraintValue;
151 
152  if( constraint.Value().HasMin() && holeMinor < constraint.Value().Min() )
153  {
154  fail_min = true;
155  constraintValue = constraint.Value().Min();
156  }
157 
158  if( constraint.Value().HasMax() && holeMajor > constraint.Value().Max() )
159  {
160  fail_max = true;
161  constraintValue = constraint.Value().Max();
162  }
163 
164  if( fail_min || fail_max )
165  {
166  std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_DRILL_OUT_OF_RANGE );
167 
168  if( fail_min )
169  {
170  m_msg.Printf( _( "(%s min width %s; actual %s)" ),
171  constraint.GetName(),
172  MessageTextFromValue( userUnits(), constraintValue ),
173  MessageTextFromValue( userUnits(), holeMinor ) );
174  }
175  else
176  {
177  m_msg.Printf( _( "(%s max width %s; actual %s)" ),
178  constraint.GetName(),
179  MessageTextFromValue( userUnits(), constraintValue ),
180  MessageTextFromValue( userUnits(), holeMajor ) );
181  }
182 
183  drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
184  drcItem->SetItems( aPad );
185  drcItem->SetViolatingRule( constraint.GetParentRule() );
186 
187  reportViolation( drcItem, aPad->GetPosition() );
188  }
189 }
190 
191 
192 void DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via, bool aExceedMicro, bool aExceedStd )
193 {
194  int errorCode;
195 
196  if( via->GetViaType() == VIATYPE::MICROVIA )
197  {
198  if( aExceedMicro )
199  return;
200 
202  }
203  else
204  {
205  if( aExceedStd )
206  return;
207 
208  errorCode = DRCE_DRILL_OUT_OF_RANGE;
209  }
210 
211  auto constraint = m_drcEngine->EvalRules( HOLE_SIZE_CONSTRAINT, via, nullptr,
212  UNDEFINED_LAYER /* holes are not layer-specific */ );
213  bool fail_min = false;
214  bool fail_max = false;
215  int constraintValue;
216 
217  if( constraint.Value().HasMin() && via->GetDrillValue() < constraint.Value().Min() )
218  {
219  fail_min = true;
220  constraintValue = constraint.Value().Min();
221  }
222 
223  if( constraint.Value().HasMax() && via->GetDrillValue() > constraint.Value().Max() )
224  {
225  fail_max = true;
226  constraintValue = constraint.Value().Max();
227  }
228 
229  if( fail_min || fail_max )
230  {
231  std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( errorCode );
232 
233  if( fail_min )
234  {
235  m_msg.Printf( _( "(%s min width %s; actual %s)" ),
236  constraint.GetName(),
237  MessageTextFromValue( userUnits(), constraintValue ),
238  MessageTextFromValue( userUnits(), via->GetDrillValue() ) );
239  }
240  else
241  {
242  m_msg.Printf( _( "(%s max width %s; actual %s)" ),
243  constraint.GetName(),
244  MessageTextFromValue( userUnits(), constraintValue ),
245  MessageTextFromValue( userUnits(), via->GetDrillValue() ) );
246  }
247 
248  drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
249  drcItem->SetItems( via );
250  drcItem->SetViolatingRule( constraint.GetParentRule() );
251 
252  reportViolation( drcItem, via->GetPosition() );
253  }
254 }
255 
256 
258 {
259  return 2;
260 }
261 
262 
263 std::set<DRC_CONSTRAINT_T> DRC_TEST_PROVIDER_HOLE_SIZE::GetConstraintTypes() const
264 {
265  return { HOLE_SIZE_CONSTRAINT };
266 }
267 
268 
269 namespace detail
270 {
272 }
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aAddUnitLabel, EDA_DATA_TYPE aType)
Convert a value to a string using double notation.
Definition: base_units.cpp:90
Definition: track.h:343
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
Definition: drc_item.cpp:245
MINOPTMAX< int > & Value()
Definition: drc_rule.h:122
static DRC_REGISTER_TEST_PROVIDER< DRC_TEST_PROVIDER_ANNULUS > dummy
bool IsErrorLimitExceeded(int error_code)
void checkVia(VIA *via, bool aExceedMicro, bool aExceedStd)
virtual bool Run() override
Runs this provider against the given PCB with configured options (if any).
T Min() const
Definition: minoptmax.h:33
virtual void reportRuleStatistics()
virtual std::set< DRC_CONSTRAINT_T > GetConstraintTypes() const override
const wxSize & GetDrillSize() const
Definition: pad.h:242
virtual const wxString GetName() const override
BOARD * GetBoard() const
Definition: drc_engine.h:87
virtual bool reportPhase(const wxString &aStageName)
FOOTPRINTS & Footprints()
Definition: board.h:305
EDA_UNITS userUnits() const
DRC_CONSTRAINT EvalRules(DRC_CONSTRAINT_T aConstraintId, const BOARD_ITEM *a, const BOARD_ITEM *b, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
Definition: drc_engine.cpp:761
virtual void reportViolation(std::shared_ptr< DRC_ITEM > &item, wxPoint aMarkerPos)
DRC_TEST_PROVIDER is a base class that represents a DRC "provider" which runs some DRC functions over...
wxPoint GetPosition() const override
Definition: pad.h:177
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
#define _(s)
Definition: 3d_actions.cpp:33
DRC_ENGINE * m_drcEngine
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
virtual const wxString GetDescription() const override
Definition: pad.h:60
TRACKS & Tracks()
Definition: board.h:302
Definition: track.h:83