Move hole testing to DRC client and improve performance.

This commit is contained in:
Jeff Young 2020-05-17 15:40:06 +01:00
parent 0658d297e5
commit 75b139c7b4
11 changed files with 411 additions and 237 deletions

View File

@ -233,6 +233,7 @@ set( PCBNEW_MICROWAVE_SRCS
set( PCBNEW_DRC_SRCS
drc/drc_courtyard_tester.cpp
drc/drc_drilled_hole_tester.cpp
drc/drc.cpp
drc/drc_clearance_test_functions.cpp
drc/drc_rule_parser.cpp

View File

@ -24,7 +24,13 @@
/**
* @file class_track.h
* @brief Definitions for tracks, vias and zones.
* @brief A single base class (TRACK) represents both tracks and vias, with subclasses
* for curved tracks (ARC) and vias (VIA). All told there are three KICAD_Ts:
* PCB_TRACK_T, PCB_ARC_T, and PCB_VIA_T.
*
* For vias there is a further VIATYPE which indicates THROUGH, BLIND_BURIED, or
* MICROVIA, which are supported by the synthetic KICAD_Ts PCB_LOCATE_STDVIA_T,
* PCB_LOCATE_BBVIA_T, and PCB_LOCATE_UVIA_T.
*/
#ifndef CLASS_TRACK_H
@ -367,6 +373,9 @@ public:
return false;
}
VIATYPE GetViaType() const { return m_ViaType; }
void SetViaType( VIATYPE aViaType ) { m_ViaType = aViaType; }
bool IsOnLayer( PCB_LAYER_ID aLayer ) const override;
virtual LSET GetLayerSet() const override;
@ -429,16 +438,6 @@ public:
void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
#endif
VIATYPE GetViaType() const
{
return m_ViaType;
}
void SetViaType( VIATYPE aViaType )
{
m_ViaType = aViaType;
}
/**
* Function SetDrill
* sets the drill value for vias.

View File

@ -41,6 +41,7 @@
#include <tool/tool_manager.h>
#include <tools/pcb_actions.h>
#include <tools/pcb_tool_base.h>
#include <tools/zone_filler_tool.h>
#include <kiface_i.h>
#include <pcbnew.h>
#include <drc/drc.h>
@ -53,7 +54,7 @@
#include <geometry/shape_arc.h>
#include <drc/drc_item.h>
#include <drc/drc_courtyard_tester.h>
#include <tools/zone_filler_tool.h>
#include <drc/drc_drilled_hole_tester.h>
#include <confirm.h>
#include "drc_rule_parser.h"
@ -776,192 +777,9 @@ void DRC::testPad2Pad()
void DRC::testDrilledHoles()
{
BOARD_DESIGN_SETTINGS& bds = m_pcb->GetDesignSettings();
DRC_DRILLED_HOLE_TESTER tester( [&]( MARKER_PCB* aMarker ) { addMarkerToPcb( aMarker ); } );
// Test drilled holes to minimize drill bit breakage.
//
// Check pad & std. via circular holes for hole-to-hole-min (non-circular holes are milled)
// Check pad & std. via holes for via-min-drill (minimum hole classification)
// Check uvia holes for uvia-min-drill (laser drill classification)
struct DRILLED_HOLE
{
wxPoint m_location;
int m_drillRadius = 0;
BOARD_ITEM* m_owner = nullptr;
};
std::vector<DRILLED_HOLE> holes;
DRILLED_HOLE hole;
wxString msg;
for( MODULE* mod : m_pcb->Modules() )
{
for( D_PAD* pad : mod->Pads( ) )
{
int holeSize = std::min( pad->GetDrillSize().x, pad->GetDrillSize().y );
if( holeSize == 0 )
continue;
NETCLASS* netclass = pad->GetNet()->GetNet() == 0 ? bds.GetDefault().get()
: pad->GetNetClass().get();
int minHole = bds.m_MinThroughDrill;
wxString minHoleSource = _( "board" );
std::vector<DRC_SELECTOR*> matched;
MatchSelectors( bds.m_DRCRuleSelectors, pad, netclass, nullptr, nullptr, &matched );
for( DRC_SELECTOR* selector : matched )
{
if( selector->m_Rule->m_Hole > minHole )
{
minHole = selector->m_Rule->m_Hole;
minHoleSource = wxString::Format( _( "'%s' rule" ), selector->m_Rule->m_Name );
}
}
if( !bds.Ignore( DRCE_TOO_SMALL_PAD_DRILL ) && holeSize < minHole )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_PAD_DRILL );
msg.Printf( drcItem->GetErrorText() + _( " (%s min hole %s; actual %s)" ),
minHoleSource,
MessageTextFromValue( userUnits(), minHole, true ),
MessageTextFromValue( userUnits(), holeSize, true ) );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( pad );
MARKER_PCB* marker = new MARKER_PCB( drcItem, pad->GetPosition() );
addMarkerToPcb( marker );
}
if( pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
{
hole.m_location = pad->GetPosition();
hole.m_drillRadius = pad->GetDrillSize().x / 2;
hole.m_owner = pad;
holes.push_back( hole );
}
}
}
for( TRACK* track : m_pcb->Tracks() )
{
VIA* via = dynamic_cast<VIA*>( track );
if( !via )
continue;
NETCLASS* netclass = via->GetNet()->GetNet() == 0 ? bds.GetDefault().get()
: via->GetNetClass().get();
int minHole = 0;
wxString minHoleSource;
std::vector<DRC_SELECTOR*> matched;
MatchSelectors( bds.m_DRCRuleSelectors, via, netclass, nullptr, nullptr, &matched );
for( DRC_SELECTOR* selector : matched )
{
if( selector->m_Rule->m_Hole > minHole )
{
minHole = selector->m_Rule->m_Hole;
minHoleSource = wxString::Format( _( "'%s' rule" ), selector->m_Rule->m_Name );
}
}
if( via->GetViaType() == VIATYPE::MICROVIA )
{
if( bds.m_MicroViasMinDrill > minHole )
{
minHole = bds.m_MicroViasMinDrill;
minHoleSource = _( "board" );
}
if( !bds.Ignore( DRCE_TOO_SMALL_MICROVIA_DRILL ) && via->GetDrillValue() < minHole )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_MICROVIA_DRILL );
msg.Printf( drcItem->GetErrorText() + _( " (%s minimum %s; actual %s)" ),
minHoleSource,
MessageTextFromValue( userUnits(), minHole, true ),
MessageTextFromValue( userUnits(), via->GetDrillValue(), true ) );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( via );
MARKER_PCB* marker = new MARKER_PCB( drcItem, via->GetPosition() );
addMarkerToPcb( marker );
}
}
else
{
if( bds.m_MinThroughDrill > minHole )
{
minHole = bds.m_MinThroughDrill;
minHoleSource = _( "board" );
}
if( !bds.Ignore( DRCE_TOO_SMALL_VIA_DRILL ) && via->GetDrillValue() < minHole )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_VIA_DRILL );
msg.Printf( drcItem->GetErrorText() + _( " (%s min hole %s; actual %s)" ),
minHoleSource,
MessageTextFromValue( userUnits(), minHole, true ),
MessageTextFromValue( userUnits(), via->GetDrillValue(), true ) );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( via );
MARKER_PCB* marker = new MARKER_PCB( drcItem, via->GetPosition() );
addMarkerToPcb( marker );
}
hole.m_location = via->GetPosition();
hole.m_drillRadius = via->GetDrillValue() / 2;
hole.m_owner = via;
holes.push_back( hole );
}
}
if( bds.m_HoleToHoleMin == 0 || bds.Ignore( DRCE_DRILLED_HOLES_TOO_CLOSE ) )
return;
for( size_t ii = 0; ii < holes.size(); ++ii )
{
const DRILLED_HOLE& refHole = holes[ ii ];
for( size_t jj = ii + 1; jj < holes.size(); ++jj )
{
const DRILLED_HOLE& checkHole = holes[ jj ];
// Holes with identical locations are allowable
if( checkHole.m_location == refHole.m_location )
continue;
int actual = KiROUND( GetLineLength( checkHole.m_location, refHole.m_location ) );
actual = std::max( 0, actual - checkHole.m_drillRadius - refHole.m_drillRadius );
if( actual < bds.m_HoleToHoleMin )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_DRILLED_HOLES_TOO_CLOSE );
msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; actual %s)" ),
MessageTextFromValue( userUnits(), bds.m_HoleToHoleMin, true ),
MessageTextFromValue( userUnits(), actual, true ) );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( refHole.m_owner, checkHole.m_owner );
MARKER_PCB* marker = new MARKER_PCB( drcItem, refHole.m_location );
addMarkerToPcb( marker );
}
}
}
tester.RunDRC( userUnits(), *m_pcb );
}
@ -1890,9 +1708,9 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_li
void DRC::doCourtyardsDrc()
{
DRC_COURTYARD_TESTER drc_overlap( [&]( MARKER_PCB* aMarker ) { addMarkerToPcb( aMarker ); } );
DRC_COURTYARD_TESTER tester( [&]( MARKER_PCB* aMarker ) { addMarkerToPcb( aMarker ); } );
drc_overlap.RunDRC( *m_pcb );
tester.RunDRC( userUnits(), *m_pcb );
}

View File

@ -33,26 +33,15 @@
#include <memory>
/**
* Flag to enable courtyard DRC debug tracing.
*
* Use "KICAD_DRC_COURTYARD" to enable.
*
* @ingroup trace_env_vars
*/
static const wxChar* DRC_COURTYARD_TRACE = wxT( "KICAD_DRC_COURTYARD" );
DRC_COURTYARD_TESTER::DRC_COURTYARD_TESTER( MARKER_HANDLER aMarkerHandler ) :
DRC_TEST_PROVIDER( aMarkerHandler )
DRC_TEST_PROVIDER( std::move( aMarkerHandler ) )
{
}
bool DRC_COURTYARD_TESTER::RunDRC( BOARD& aBoard ) const
bool DRC_COURTYARD_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard )
{
wxLogTrace( DRC_COURTYARD_TRACE, "Running DRC: Courtyard" );
// Detects missing (or malformed) footprint courtyards and courtyard incursions (for those
// with a courtyard).
wxString msg;
@ -96,8 +85,6 @@ bool DRC_COURTYARD_TESTER::RunDRC( BOARD& aBoard ) const
if( !aBoard.GetDesignSettings().Ignore( DRCE_OVERLAPPING_FOOTPRINTS ) )
{
wxLogTrace( DRC_COURTYARD_TRACE, "Checking for courtyard overlap" );
for( auto it1 = aBoard.Modules().begin(); it1 != aBoard.Modules().end(); it1++ )
{
MODULE* footprint = *it1;
@ -162,8 +149,6 @@ bool DRC_COURTYARD_TESTER::RunDRC( BOARD& aBoard ) const
if( !aBoard.GetDesignSettings().Ignore( DRCE_PTH_IN_COURTYARD )
|| !aBoard.GetDesignSettings().Ignore( DRCE_NPTH_IN_COURTYARD ) )
{
wxLogTrace( DRC_COURTYARD_TRACE, "Checking for through-holes in courtyards" );
for( MODULE* footprint : aBoard.Modules() )
{
SHAPE_POLY_SET& footprintFront = footprint->GetPolyCourtyardFront();

View File

@ -25,13 +25,11 @@
#ifndef DRC_COURTYARD_OVERLAP__H
#define DRC_COURTYARD_OVERLAP__H
#include <class_board.h>
#include <drc/drc_provider.h>
/**
* A class that provides the courtyard-based DRC checks.
*/
class BOARD;
class DRC_COURTYARD_TESTER : public DRC_TEST_PROVIDER
{
public:
@ -39,7 +37,7 @@ public:
virtual ~DRC_COURTYARD_TESTER() {};
bool RunDRC( BOARD& aBoard ) const override;
bool RunDRC( EDA_UNITS aUnits, BOARD& aBoard ) override;
};
#endif // DRC_COURTYARD_OVERLAP__H

View File

@ -0,0 +1,308 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <drc/drc_drilled_hole_tester.h>
#include <class_module.h>
#include <drc/drc.h>
#include <widgets/ui_common.h>
DRC_DRILLED_HOLE_TESTER::DRC_DRILLED_HOLE_TESTER( MARKER_HANDLER aMarkerHandler ) :
DRC_TEST_PROVIDER( std::move( aMarkerHandler ) ),
m_units( EDA_UNITS::MILLIMETRES ),
m_board( nullptr ),
m_largestRadius( 0 )
{
}
bool DRC_DRILLED_HOLE_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard )
{
bool success = true;
// Test drilled holes to minimize drill bit breakage.
//
// Check pad & std. via circular holes for hole-to-hole-min (non-circular holes are milled)
// Check pad & std. via holes for via-min-drill (minimum hole classification)
// Check uvia holes for uvia-min-drill (laser drill classification)
m_units = aUnits;
m_board = &aBoard;
m_holes.clear();
m_largestRadius = 0;
for( MODULE* mod : aBoard.Modules() )
{
for( D_PAD* pad : mod->Pads( ) )
success |= checkPad( pad );
}
for( TRACK* track : aBoard.Tracks() )
{
VIA* via = dynamic_cast<VIA*>( track );
if( via )
{
if( via->GetViaType() == VIATYPE::MICROVIA )
success |= checkMicroVia( via );
else
success |= checkVia( via );
}
}
success |= checkHoles();
return success;
}
bool DRC_DRILLED_HOLE_TESTER::checkPad( D_PAD* aPad )
{
wxString msg;
bool success = true;
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
int holeSize = std::min( aPad->GetDrillSize().x, aPad->GetDrillSize().y );
if( holeSize == 0 )
return true;
if( !bds.Ignore( DRCE_TOO_SMALL_PAD_DRILL ) )
{
NETCLASS* netclass = aPad->GetNet()->GetNet() == 0 ? bds.GetDefault().get()
: aPad->GetNetClass().get();
int minHole = bds.m_MinThroughDrill;
wxString minHoleSource = _( "board" );
std::vector<DRC_SELECTOR*> matched;
MatchSelectors( bds.m_DRCRuleSelectors, aPad, netclass, nullptr, nullptr, &matched );
for( DRC_SELECTOR* selector : matched )
{
if( selector->m_Rule->m_Hole > minHole )
{
minHole = selector->m_Rule->m_Hole;
minHoleSource = wxString::Format( _( "'%s' rule" ), selector->m_Rule->m_Name );
}
}
if( holeSize < minHole )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_PAD_DRILL );
msg.Printf( drcItem->GetErrorText() + _( " (%s min hole %s; actual %s)" ),
minHoleSource,
MessageTextFromValue( m_units, minHole, true ),
MessageTextFromValue( m_units, holeSize, true ) );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( aPad );
HandleMarker( new MARKER_PCB( drcItem, aPad->GetPosition() ) );
success = false;
}
}
if( !bds.Ignore( DRCE_DRILLED_HOLES_TOO_CLOSE ) && bds.m_HoleToHoleMin != 0 )
{
if( aPad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
addHole( aPad->GetPosition(), aPad->GetDrillSize().x / 2, aPad );
}
return success;
}
bool DRC_DRILLED_HOLE_TESTER::checkVia( VIA* via )
{
wxString msg;
bool success = true;
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
if( !bds.Ignore( DRCE_TOO_SMALL_VIA_DRILL ) )
{
NETCLASS* netclass = via->GetNet()->GetNet() == 0 ? bds.GetDefault().get()
: via->GetNetClass().get();
int minHole = bds.m_MinThroughDrill;
wxString minHoleSource = _( "board" );
std::vector<DRC_SELECTOR*> matched;
MatchSelectors( bds.m_DRCRuleSelectors, via, netclass, nullptr, nullptr, &matched );
for( DRC_SELECTOR* selector : matched )
{
if( selector->m_Rule->m_Hole > minHole )
{
minHole = selector->m_Rule->m_Hole;
minHoleSource = wxString::Format( _( "'%s' rule" ), selector->m_Rule->m_Name );
}
}
if( via->GetDrillValue() < minHole )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_VIA_DRILL );
msg.Printf( drcItem->GetErrorText() + _( " (%s min hole %s; actual %s)" ),
minHoleSource,
MessageTextFromValue( m_units, minHole, true ),
MessageTextFromValue( m_units, via->GetDrillValue(), true ) );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( via );
HandleMarker( new MARKER_PCB( drcItem, via->GetPosition() ) );
success = false;
}
}
if( !bds.Ignore( DRCE_DRILLED_HOLES_TOO_CLOSE ) && bds.m_HoleToHoleMin != 0 )
{
addHole( via->GetPosition(), via->GetDrillValue() / 2, via );
}
return success;
}
bool DRC_DRILLED_HOLE_TESTER::checkMicroVia( VIA* via )
{
wxString msg;
bool success = true;
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
if( !bds.Ignore( DRCE_TOO_SMALL_MICROVIA_DRILL ) )
{
NETCLASS* netclass = via->GetNet()->GetNet() == 0 ? bds.GetDefault().get()
: via->GetNetClass().get();
int minHole = bds.m_MicroViasMinDrill;
wxString minHoleSource = _( "board" );
std::vector<DRC_SELECTOR*> matched;
MatchSelectors( bds.m_DRCRuleSelectors, via, netclass, nullptr, nullptr, &matched );
for( DRC_SELECTOR* selector : matched )
{
if( selector->m_Rule->m_Hole > minHole )
{
minHole = selector->m_Rule->m_Hole;
minHoleSource = wxString::Format( _( "'%s' rule" ), selector->m_Rule->m_Name );
}
}
if( via->GetDrillValue() < minHole )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_MICROVIA_DRILL );
msg.Printf( drcItem->GetErrorText() + _( " (%s minimum %s; actual %s)" ),
minHoleSource,
MessageTextFromValue( m_units, minHole, true ),
MessageTextFromValue( m_units, via->GetDrillValue(), true ) );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( via );
HandleMarker( new MARKER_PCB( drcItem, via->GetPosition() ) );
success = false;
}
}
return success;
}
void DRC_DRILLED_HOLE_TESTER::addHole( const wxPoint& aLocation, int aRadius, BOARD_ITEM* aOwner )
{
DRILLED_HOLE hole;
hole.m_location = aLocation;
hole.m_drillRadius = aRadius;
hole.m_owner = aOwner;
m_largestRadius = std::max( m_largestRadius, aRadius );
m_holes.push_back( hole );
}
bool DRC_DRILLED_HOLE_TESTER::checkHoles()
{
wxString msg;
bool success = true;
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
// No need to check if we're ignoring DRCE_DRILLED_HOLES_TOO_CLOSE; if we are then we
// won't have collected any holes to test.
// Sort holes by X for performance. In the nested iteration we then need to look at
// following holes only while they are within the refHole's neighborhood as defined by
// the refHole radius + the minimum hole-to-hole clearance + the largest radius any of
// the following holes can have.
std::sort( m_holes.begin(), m_holes.end(),
[]( const DRILLED_HOLE& a, const DRILLED_HOLE& b )
{
if( a.m_location.x == b.m_location.x )
return a.m_location.y < b.m_location.y;
else
return a.m_location.x < b.m_location.x;
} );
for( size_t ii = 0; ii < m_holes.size(); ++ii )
{
const DRILLED_HOLE& refHole = m_holes[ ii ];
int neighborhood = refHole.m_drillRadius + bds.m_HoleToHoleMin + m_largestRadius;
for( size_t jj = ii + 1; jj < m_holes.size(); ++jj )
{
const DRILLED_HOLE& checkHole = m_holes[ jj ];
if( refHole.m_location.x + neighborhood < checkHole.m_location.x )
break;
// Holes with identical locations are allowable
if( checkHole.m_location == refHole.m_location )
continue;
int actual = KiROUND( GetLineLength( checkHole.m_location, refHole.m_location ) );
actual = std::max( 0, actual - checkHole.m_drillRadius - refHole.m_drillRadius );
if( actual < bds.m_HoleToHoleMin )
{
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_DRILLED_HOLES_TOO_CLOSE );
msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; actual %s)" ),
MessageTextFromValue( m_units, bds.m_HoleToHoleMin, true ),
MessageTextFromValue( m_units, actual, true ) );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( refHole.m_owner, checkHole.m_owner );
HandleMarker( new MARKER_PCB( drcItem, refHole.m_location ) );
success = false;
}
}
}
return success;
}

View File

@ -0,0 +1,66 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef DRC_DRILLED_HOLE_TESTER__H
#define DRC_DRILLED_HOLE_TESTER__H
#include <drc/drc_provider.h>
class BOARD;
class BOARD_ITEM;
class DRC_DRILLED_HOLE_TESTER : public DRC_TEST_PROVIDER
{
public:
DRC_DRILLED_HOLE_TESTER( MARKER_HANDLER aMarkerHandler );
virtual ~DRC_DRILLED_HOLE_TESTER() {};
bool RunDRC( EDA_UNITS aUnits, BOARD& aBoard ) override;
private:
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:
struct DRILLED_HOLE
{
wxPoint m_location;
int m_drillRadius = 0;
BOARD_ITEM* m_owner = nullptr;
};
EDA_UNITS m_units;
BOARD* m_board;
std::vector<DRILLED_HOLE> m_holes;
int m_largestRadius;
};
#endif // DRC_DRILLED_HOLE_TESTER__H

View File

@ -50,7 +50,7 @@ public:
* Note: Board is non-const, as some DRC functions modify the board (e.g. zone fill
* or polygon coalescing)
*/
virtual bool RunDRC( BOARD& aBoard ) const = 0;
virtual bool RunDRC( EDA_UNITS aUnits, BOARD& aBoard ) = 0;
virtual ~DRC_TEST_PROVIDER() {}

View File

@ -33,7 +33,6 @@
#include <widgets/ui_common.h>
#include "../board_test_utils.h"
#include "drc_test_utils.h"
struct COURTYARD_TEST_FIXTURE
@ -294,8 +293,8 @@ static void CheckInvalidsMatchExpected( BOARD& aBoard,
}
void DoCourtyardInvalidTest(
const COURTYARD_INVALID_CASE& aCase, const KI_TEST::BOARD_DUMPER& aDumper )
void DoCourtyardInvalidTest( const COURTYARD_INVALID_CASE& aCase,
const KI_TEST::BOARD_DUMPER& aDumper )
{
auto board = MakeBoard( aCase.m_mods );
@ -313,7 +312,7 @@ void DoCourtyardInvalidTest(
markers.push_back( std::unique_ptr<MARKER_PCB>( aMarker ) );
} );
drc_overlap.RunDRC( *board );
drc_overlap.RunDRC( EDA_UNITS::MILLIMETRES, *board );
CheckInvalidsMatchExpected( *board, markers, aCase.m_exp_errors );
}

View File

@ -460,8 +460,8 @@ static BOARD_DESIGN_SETTINGS GetOverlapCheckDesignSettings()
* Run a single courtyard overlap testcase
* @param aCase The testcase to run.
*/
static void DoCourtyardOverlapTest(
const COURTYARD_OVERLAP_TEST_CASE& aCase, const KI_TEST::BOARD_DUMPER& aDumper )
static void DoCourtyardOverlapTest( const COURTYARD_OVERLAP_TEST_CASE& aCase,
const KI_TEST::BOARD_DUMPER& aDumper )
{
auto board = MakeBoard( aCase.m_mods );
@ -479,7 +479,7 @@ static void DoCourtyardOverlapTest(
markers.push_back( std::unique_ptr<MARKER_PCB>( aMarker ) );
} );
drc_overlap.RunDRC( *board );
drc_overlap.RunDRC( EDA_UNITS::MILLIMETRES, *board );
CheckCollisionsMatchExpected( *board, markers, aCase.m_collisions );
}

View File

@ -83,7 +83,7 @@ public:
DRC_DURATION duration;
{
SCOPED_PROF_COUNTER<DRC_DURATION> timer( duration );
drc_prov->RunDRC( aBoard );
drc_prov->RunDRC( EDA_UNITS::MILLIMETRES, aBoard );
}
// report results