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