KiCad PCB EDA Suite
DRC_DRILLED_HOLE_TESTER Class Reference

#include <drc_drilled_hole_tester.h>

Inheritance diagram for DRC_DRILLED_HOLE_TESTER:
DRC_TEST_PROVIDER

Classes

struct  DRILLED_HOLE
 

Public Types

using MARKER_HANDLER = std::function< void(MARKER_PCB *)>
 A callable that can handle a single generated PCB_MARKER. More...
 

Public Member Functions

 DRC_DRILLED_HOLE_TESTER (MARKER_HANDLER aMarkerHandler)
 
virtual ~DRC_DRILLED_HOLE_TESTER ()
 
bool RunDRC (EDA_UNITS aUnits, BOARD &aBoard) override
 Runs this provider against the given PCB with configured options (if any). More...
 

Protected Member Functions

void HandleMarker (MARKER_PCB *aMarker) const
 Pass a given marker to the marker handler. More...
 

Private Member Functions

bool checkPad (D_PAD *aPad)
 
bool checkVia (VIA *aVia)
 
bool checkMicroVia (VIA *aVia)
 
void addHole (const wxPoint &aLocation, int aRadius, BOARD_ITEM *aOwner)
 
bool checkHoles ()
 

Private Attributes

EDA_UNITS m_units
 
BOARDm_board
 
std::vector< DRILLED_HOLEm_holes
 
int m_largestRadius
 
wxString m_msg
 

Detailed Description

Definition at line 35 of file drc_drilled_hole_tester.h.

Member Typedef Documentation

◆ MARKER_HANDLER

using DRC_TEST_PROVIDER::MARKER_HANDLER = std::function<void( MARKER_PCB* )>
inherited

A callable that can handle a single generated PCB_MARKER.

Definition at line 47 of file drc_provider.h.

Constructor & Destructor Documentation

◆ DRC_DRILLED_HOLE_TESTER()

DRC_DRILLED_HOLE_TESTER::DRC_DRILLED_HOLE_TESTER ( MARKER_HANDLER  aMarkerHandler)

Definition at line 33 of file drc_drilled_hole_tester.cpp.

33  :
34  DRC_TEST_PROVIDER( std::move( aMarkerHandler ) ),
36  m_board( nullptr ),
37  m_largestRadius( 0 )
38 {
39 }
DRC_TEST_PROVIDER(MARKER_HANDLER aMarkerHandler)
Definition: drc_provider.h:60

◆ ~DRC_DRILLED_HOLE_TESTER()

virtual DRC_DRILLED_HOLE_TESTER::~DRC_DRILLED_HOLE_TESTER ( )
inlinevirtual

Definition at line 40 of file drc_drilled_hole_tester.h.

40 {};

Member Function Documentation

◆ addHole()

void DRC_DRILLED_HOLE_TESTER::addHole ( const wxPoint aLocation,
int  aRadius,
BOARD_ITEM aOwner 
)
private

Definition at line 211 of file drc_drilled_hole_tester.cpp.

212 {
213  DRILLED_HOLE hole;
214 
215  hole.m_location = aLocation;
216  hole.m_drillRadius = aRadius;
217  hole.m_owner = aOwner;
218 
219  m_largestRadius = std::max( m_largestRadius, aRadius );
220 
221  m_holes.push_back( hole );
222 }
std::vector< DRILLED_HOLE > m_holes

References DRC_DRILLED_HOLE_TESTER::DRILLED_HOLE::m_drillRadius, m_holes, m_largestRadius, DRC_DRILLED_HOLE_TESTER::DRILLED_HOLE::m_location, and DRC_DRILLED_HOLE_TESTER::DRILLED_HOLE::m_owner.

Referenced by checkPad(), and checkVia().

◆ checkHoles()

bool DRC_DRILLED_HOLE_TESTER::checkHoles ( )
private

Definition at line 225 of file drc_drilled_hole_tester.cpp.

226 {
227  bool success = true;
229 
230  // No need to check if we're ignoring DRCE_DRILLED_HOLES_TOO_CLOSE; if we are then we
231  // won't have collected any holes to test.
232 
233  // Sort holes by X for performance. In the nested iteration we then need to look at
234  // following holes only while they are within the refHole's neighborhood as defined by
235  // the refHole radius + the minimum hole-to-hole clearance + the largest radius any of
236  // the following holes can have.
237  std::sort( m_holes.begin(), m_holes.end(),
238  []( const DRILLED_HOLE& a, const DRILLED_HOLE& b )
239  {
240  if( a.m_location.x == b.m_location.x )
241  return a.m_location.y < b.m_location.y;
242  else
243  return a.m_location.x < b.m_location.x;
244  } );
245 
246  for( size_t ii = 0; ii < m_holes.size(); ++ii )
247  {
248  const DRILLED_HOLE& refHole = m_holes[ ii ];
249  int neighborhood = refHole.m_drillRadius + bds.m_HoleToHoleMin + m_largestRadius;
250 
251  for( size_t jj = ii + 1; jj < m_holes.size(); ++jj )
252  {
253  const DRILLED_HOLE& checkHole = m_holes[ jj ];
254 
255  if( refHole.m_location.x + neighborhood < checkHole.m_location.x )
256  break;
257 
258  // Holes with identical locations are allowable
259  if( checkHole.m_location == refHole.m_location )
260  continue;
261 
262  int actual = KiROUND( GetLineLength( checkHole.m_location, refHole.m_location ) );
263  actual = std::max( 0, actual - checkHole.m_drillRadius - refHole.m_drillRadius );
264 
265  if( actual < bds.m_HoleToHoleMin )
266  {
268 
269  m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; actual %s)" ),
271  MessageTextFromValue( m_units, actual, true ) );
272 
273  drcItem->SetErrorMessage( m_msg );
274  drcItem->SetItems( refHole.m_owner, checkHole.m_owner );
275 
276  HandleMarker( new MARKER_PCB( drcItem, refHole.m_location ) );
277  success = false;
278  }
279  }
280  }
281 
282  return success;
283 }
double GetLineLength(const wxPoint &aPointA, const wxPoint &aPointB)
Return the length of a line segment defined by aPointA and aPointB.
Definition: trigo.h:206
overlapping drilled holes break drill bits
Definition: drc.h:51
void SetItems(EDA_ITEM *aItem, EDA_ITEM *bItem=nullptr, EDA_ITEM *cItem=nullptr, EDA_ITEM *dItem=nullptr)
Definition: rc_item.h:119
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:551
wxString GetErrorText() const
Definition: rc_item.h:169
std::vector< DRILLED_HOLE > m_holes
void HandleMarker(MARKER_PCB *aMarker) const
Pass a given marker to the marker handler.
Definition: drc_provider.h:68
static DRC_ITEM * Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
Definition: drc_item.cpp:197
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aUseMils, EDA_DATA_TYPE aType)
Definition: base_units.cpp:124
#define _(s)
Definition: 3d_actions.cpp:33
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:68
void SetErrorMessage(const wxString &aMessage)
Definition: rc_item.h:117
BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.

References _, DRC_ITEM::Create(), DRCE_DRILLED_HOLES_TOO_CLOSE, BOARD::GetDesignSettings(), RC_ITEM::GetErrorText(), GetLineLength(), DRC_TEST_PROVIDER::HandleMarker(), KiROUND(), m_board, DRC_DRILLED_HOLE_TESTER::DRILLED_HOLE::m_drillRadius, m_holes, BOARD_DESIGN_SETTINGS::m_HoleToHoleMin, m_largestRadius, DRC_DRILLED_HOLE_TESTER::DRILLED_HOLE::m_location, m_msg, DRC_DRILLED_HOLE_TESTER::DRILLED_HOLE::m_owner, m_units, MessageTextFromValue(), RC_ITEM::SetErrorMessage(), RC_ITEM::SetItems(), wxPoint::x, and wxPoint::y.

Referenced by RunDRC().

◆ checkMicroVia()

bool DRC_DRILLED_HOLE_TESTER::checkMicroVia ( VIA aVia)
private

Definition at line 173 of file drc_drilled_hole_tester.cpp.

174 {
175  bool success = true;
177 
179  {
180  int minHole = bds.m_MicroViasMinDrill;
181  wxString minHoleSource = _( "board minimum" );
182  DRC_RULE* rule = GetRule( via, nullptr, HOLE_CONSTRAINT );
183 
184  if( rule )
185  {
186  minHole = rule->m_MinHole;
187  minHoleSource = wxString::Format( _( "'%s' rule" ), rule->m_Name );
188  }
189 
190  if( via->GetDrillValue() < minHole )
191  {
193 
194  m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
195  minHoleSource,
196  MessageTextFromValue( m_units, minHole, true ),
197  MessageTextFromValue( m_units, via->GetDrillValue(), true ) );
198 
199  drcItem->SetErrorMessage( m_msg );
200  drcItem->SetItems( via );
201 
202  HandleMarker( new MARKER_PCB( drcItem, via->GetPosition() ) );
203  success = false;
204  }
205  }
206 
207  return success;
208 }
wxString m_Name
Definition: drc_rule.h:73
void SetItems(EDA_ITEM *aItem, EDA_ITEM *bItem=nullptr, EDA_ITEM *cItem=nullptr, EDA_ITEM *dItem=nullptr)
Definition: rc_item.h:119
bool Ignore(int aDRCErrorCode)
returns true if the DRC error code's severity is SEVERITY_IGNORE
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:551
int m_MinHole
Definition: drc_rule.h:82
wxString GetErrorText() const
Definition: rc_item.h:169
DRC_RULE * GetRule(const BOARD_ITEM *aItem, const BOARD_ITEM *bItem, int aConstraint)
Definition: drc_rule.cpp:67
void HandleMarker(MARKER_PCB *aMarker) const
Pass a given marker to the marker handler.
Definition: drc_provider.h:68
static DRC_ITEM * Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
Definition: drc_item.cpp:197
Too small micro via drill.
Definition: drc.h:59
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aUseMils, EDA_DATA_TYPE aType)
Definition: base_units.cpp:124
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
#define _(s)
Definition: 3d_actions.cpp:33
#define HOLE_CONSTRAINT
Definition: drc_rule.h:38
void SetErrorMessage(const wxString &aMessage)
Definition: rc_item.h:117
BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.

References _, DRC_ITEM::Create(), DRCE_TOO_SMALL_MICROVIA_DRILL, Format(), BOARD::GetDesignSettings(), VIA::GetDrillValue(), RC_ITEM::GetErrorText(), VIA::GetPosition(), GetRule(), DRC_TEST_PROVIDER::HandleMarker(), HOLE_CONSTRAINT, BOARD_DESIGN_SETTINGS::Ignore(), m_board, BOARD_DESIGN_SETTINGS::m_MicroViasMinDrill, DRC_RULE::m_MinHole, m_msg, DRC_RULE::m_Name, m_units, MessageTextFromValue(), RC_ITEM::SetErrorMessage(), and RC_ITEM::SetItems().

Referenced by RunDRC().

◆ checkPad()

bool DRC_DRILLED_HOLE_TESTER::checkPad ( D_PAD aPad)
private

Definition at line 82 of file drc_drilled_hole_tester.cpp.

83 {
84  bool success = true;
86 
87  int holeSize = std::min( aPad->GetDrillSize().x, aPad->GetDrillSize().y );
88 
89  if( holeSize == 0 )
90  return true;
91 
92  if( !bds.Ignore( DRCE_TOO_SMALL_DRILL ) )
93  {
94  int minHole = bds.m_MinThroughDrill;
95  wxString minHoleSource = _( "board minimum" );
96  DRC_RULE* rule = GetRule( aPad, nullptr, HOLE_CONSTRAINT );
97 
98  if( rule )
99  {
100  minHole = rule->m_MinHole;
101  minHoleSource = wxString::Format( _( "'%s' rule" ), rule->m_Name );
102  }
103 
104  if( holeSize < minHole )
105  {
107 
108  m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
109  minHoleSource,
110  MessageTextFromValue( m_units, minHole, true ),
111  MessageTextFromValue( m_units, holeSize, true ) );
112 
113  drcItem->SetErrorMessage( m_msg );
114  drcItem->SetItems( aPad );
115 
116  HandleMarker( new MARKER_PCB( drcItem, aPad->GetPosition() ) );
117  success = false;
118  }
119  }
120 
121  if( !bds.Ignore( DRCE_DRILLED_HOLES_TOO_CLOSE ) && bds.m_HoleToHoleMin != 0 )
122  {
123  if( aPad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
124  addHole( aPad->GetPosition(), aPad->GetDrillSize().x / 2, aPad );
125  }
126 
127  return success;
128 }
overlapping drilled holes break drill bits
Definition: drc.h:51
void addHole(const wxPoint &aLocation, int aRadius, BOARD_ITEM *aOwner)
wxString m_Name
Definition: drc_rule.h:73
void SetItems(EDA_ITEM *aItem, EDA_ITEM *bItem=nullptr, EDA_ITEM *cItem=nullptr, EDA_ITEM *dItem=nullptr)
Definition: rc_item.h:119
bool Ignore(int aDRCErrorCode)
returns true if the DRC error code's severity is SEVERITY_IGNORE
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:551
int m_MinHole
Definition: drc_rule.h:82
wxString GetErrorText() const
Definition: rc_item.h:169
DRC_RULE * GetRule(const BOARD_ITEM *aItem, const BOARD_ITEM *bItem, int aConstraint)
Definition: drc_rule.cpp:67
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: class_pad.h:318
void HandleMarker(MARKER_PCB *aMarker) const
Pass a given marker to the marker handler.
Definition: drc_provider.h:68
static DRC_ITEM * Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
Definition: drc_item.cpp:197
Too small via or pad drill.
Definition: drc.h:55
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aUseMils, EDA_DATA_TYPE aType)
Definition: base_units.cpp:124
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
#define _(s)
Definition: 3d_actions.cpp:33
const wxSize & GetDrillSize() const
Definition: class_pad.h:226
#define HOLE_CONSTRAINT
Definition: drc_rule.h:38
void SetErrorMessage(const wxString &aMessage)
Definition: rc_item.h:117
const wxPoint GetPosition() const override
Definition: class_pad.h:161
BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.

References _, addHole(), DRC_ITEM::Create(), DRCE_DRILLED_HOLES_TOO_CLOSE, DRCE_TOO_SMALL_DRILL, Format(), BOARD::GetDesignSettings(), D_PAD::GetDrillShape(), D_PAD::GetDrillSize(), RC_ITEM::GetErrorText(), D_PAD::GetPosition(), GetRule(), DRC_TEST_PROVIDER::HandleMarker(), HOLE_CONSTRAINT, BOARD_DESIGN_SETTINGS::Ignore(), m_board, BOARD_DESIGN_SETTINGS::m_HoleToHoleMin, DRC_RULE::m_MinHole, BOARD_DESIGN_SETTINGS::m_MinThroughDrill, m_msg, DRC_RULE::m_Name, m_units, MessageTextFromValue(), PAD_DRILL_SHAPE_CIRCLE, RC_ITEM::SetErrorMessage(), and RC_ITEM::SetItems().

Referenced by RunDRC().

◆ checkVia()

bool DRC_DRILLED_HOLE_TESTER::checkVia ( VIA aVia)
private

Definition at line 130 of file drc_drilled_hole_tester.cpp.

131 {
132  bool success = true;
134 
135  if( !bds.Ignore( DRCE_TOO_SMALL_DRILL ) )
136  {
137  int minHole = bds.m_MinThroughDrill;
138  wxString minHoleSource = _( "board minimum" );
139  DRC_RULE* rule = GetRule( via, nullptr, HOLE_CONSTRAINT );
140 
141  if( rule )
142  {
143  minHole = rule->m_MinHole;
144  minHoleSource = wxString::Format( _( "'%s' rule" ), rule->m_Name );
145  }
146 
147  if( via->GetDrillValue() < minHole )
148  {
150 
151  m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
152  minHoleSource,
153  MessageTextFromValue( m_units, minHole, true ),
154  MessageTextFromValue( m_units, via->GetDrillValue(), true ) );
155 
156  drcItem->SetErrorMessage( m_msg );
157  drcItem->SetItems( via );
158 
159  HandleMarker( new MARKER_PCB( drcItem, via->GetPosition() ) );
160  success = false;
161  }
162  }
163 
164  if( !bds.Ignore( DRCE_DRILLED_HOLES_TOO_CLOSE ) && bds.m_HoleToHoleMin != 0 )
165  {
166  addHole( via->GetPosition(), via->GetDrillValue() / 2, via );
167  }
168 
169  return success;
170 }
overlapping drilled holes break drill bits
Definition: drc.h:51
void addHole(const wxPoint &aLocation, int aRadius, BOARD_ITEM *aOwner)
wxString m_Name
Definition: drc_rule.h:73
void SetItems(EDA_ITEM *aItem, EDA_ITEM *bItem=nullptr, EDA_ITEM *cItem=nullptr, EDA_ITEM *dItem=nullptr)
Definition: rc_item.h:119
bool Ignore(int aDRCErrorCode)
returns true if the DRC error code's severity is SEVERITY_IGNORE
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:551
int m_MinHole
Definition: drc_rule.h:82
wxString GetErrorText() const
Definition: rc_item.h:169
DRC_RULE * GetRule(const BOARD_ITEM *aItem, const BOARD_ITEM *bItem, int aConstraint)
Definition: drc_rule.cpp:67
void HandleMarker(MARKER_PCB *aMarker) const
Pass a given marker to the marker handler.
Definition: drc_provider.h:68
static DRC_ITEM * Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
Definition: drc_item.cpp:197
Too small via or pad drill.
Definition: drc.h:55
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aUseMils, EDA_DATA_TYPE aType)
Definition: base_units.cpp:124
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
#define _(s)
Definition: 3d_actions.cpp:33
#define HOLE_CONSTRAINT
Definition: drc_rule.h:38
void SetErrorMessage(const wxString &aMessage)
Definition: rc_item.h:117
BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.

References _, addHole(), DRC_ITEM::Create(), DRCE_DRILLED_HOLES_TOO_CLOSE, DRCE_TOO_SMALL_DRILL, Format(), BOARD::GetDesignSettings(), VIA::GetDrillValue(), RC_ITEM::GetErrorText(), VIA::GetPosition(), GetRule(), DRC_TEST_PROVIDER::HandleMarker(), HOLE_CONSTRAINT, BOARD_DESIGN_SETTINGS::Ignore(), m_board, BOARD_DESIGN_SETTINGS::m_HoleToHoleMin, DRC_RULE::m_MinHole, BOARD_DESIGN_SETTINGS::m_MinThroughDrill, m_msg, DRC_RULE::m_Name, m_units, MessageTextFromValue(), RC_ITEM::SetErrorMessage(), and RC_ITEM::SetItems().

Referenced by RunDRC().

◆ HandleMarker()

void DRC_TEST_PROVIDER::HandleMarker ( MARKER_PCB aMarker) const
inlineprotectedinherited

◆ RunDRC()

bool DRC_DRILLED_HOLE_TESTER::RunDRC ( EDA_UNITS  aUnits,
BOARD aBoard 
)
overridevirtual

Runs this provider against the given PCB with configured options (if any).

Note: Board is non-const, as some DRC functions modify the board (e.g. zone fill or polygon coalescing)

Implements DRC_TEST_PROVIDER.

Definition at line 42 of file drc_drilled_hole_tester.cpp.

43 {
44  bool success = true;
45 
46  // Test drilled holes to minimize drill bit breakage.
47  //
48  // Check pad & std. via circular holes for hole-to-hole-min (non-circular holes are milled)
49  // Check pad & std. via holes for via-min-drill (minimum hole classification)
50  // Check uvia holes for uvia-min-drill (laser drill classification)
51 
52  m_units = aUnits;
53  m_board = &aBoard;
54  m_holes.clear();
55  m_largestRadius = 0;
56 
57  for( MODULE* mod : aBoard.Modules() )
58  {
59  for( D_PAD* pad : mod->Pads( ) )
60  success &= checkPad( pad );
61  }
62 
63  for( TRACK* track : aBoard.Tracks() )
64  {
65  VIA* via = dynamic_cast<VIA*>( track );
66 
67  if( via )
68  {
69  if( via->GetViaType() == VIATYPE::MICROVIA )
70  success &= checkMicroVia( via );
71  else
72  success &= checkVia( via );
73  }
74  }
75 
76  success &= checkHoles();
77 
78  return success;
79 }
std::vector< DRILLED_HOLE > m_holes
MODULES & Modules()
Definition: class_board.h:266
VIATYPE GetViaType() const
Definition: class_track.h:368
TRACKS & Tracks()
Definition: class_board.h:257

References checkHoles(), checkMicroVia(), checkPad(), checkVia(), VIA::GetViaType(), m_board, m_holes, m_largestRadius, m_units, MICROVIA, BOARD::Modules(), and BOARD::Tracks().

Referenced by DRC::RunTests().

Member Data Documentation

◆ m_board

BOARD* DRC_DRILLED_HOLE_TESTER::m_board
private

Definition at line 61 of file drc_drilled_hole_tester.h.

Referenced by checkHoles(), checkMicroVia(), checkPad(), checkVia(), and RunDRC().

◆ m_holes

std::vector<DRILLED_HOLE> DRC_DRILLED_HOLE_TESTER::m_holes
private

Definition at line 62 of file drc_drilled_hole_tester.h.

Referenced by addHole(), checkHoles(), and RunDRC().

◆ m_largestRadius

int DRC_DRILLED_HOLE_TESTER::m_largestRadius
private

Definition at line 63 of file drc_drilled_hole_tester.h.

Referenced by addHole(), checkHoles(), and RunDRC().

◆ m_msg

wxString DRC_DRILLED_HOLE_TESTER::m_msg
private

Definition at line 65 of file drc_drilled_hole_tester.h.

Referenced by checkHoles(), checkMicroVia(), checkPad(), and checkVia().

◆ m_units

EDA_UNITS DRC_DRILLED_HOLE_TESTER::m_units
private

Definition at line 60 of file drc_drilled_hole_tester.h.

Referenced by checkHoles(), checkMicroVia(), checkPad(), checkVia(), and RunDRC().


The documentation for this class was generated from the following files: