Move track-to-zone testing to RTrees.
Also implemente pad-to-zone testing and removes the control in the GUI (now that it's fast).
This commit is contained in:
parent
f1e9ecad41
commit
115fd1d7f3
|
@ -98,7 +98,6 @@ DIALOG_DRC::~DIALOG_DRC()
|
|||
|
||||
PCBNEW_SETTINGS* settings = m_brdEditor->GetPcbNewSettings();
|
||||
settings->m_DrcDialog.refill_zones = m_cbRefillZones->GetValue();
|
||||
settings->m_DrcDialog.test_track_to_zone = m_cbReportTracksToZonesErrors->GetValue();
|
||||
settings->m_DrcDialog.test_all_track_errors = m_cbReportAllTrackErrors->GetValue();
|
||||
|
||||
if( !Kiface().IsSingle() )
|
||||
|
@ -134,7 +133,6 @@ void DIALOG_DRC::initValues()
|
|||
auto cfg = m_brdEditor->GetPcbNewSettings();
|
||||
|
||||
m_cbRefillZones->SetValue( cfg->m_DrcDialog.refill_zones );
|
||||
m_cbReportTracksToZonesErrors->SetValue( cfg->m_DrcDialog.test_track_to_zone );
|
||||
m_cbReportAllTrackErrors->SetValue( cfg->m_DrcDialog.test_all_track_errors );
|
||||
|
||||
if( Kiface().IsSingle() )
|
||||
|
@ -196,7 +194,6 @@ void DIALOG_DRC::OnErrorLinkClicked( wxHtmlLinkEvent& event )
|
|||
void DIALOG_DRC::OnRunDRCClick( wxCommandEvent& aEvent )
|
||||
{
|
||||
DRC_TOOL* drcTool = m_brdEditor->GetToolManager()->GetTool<DRC_TOOL>();
|
||||
bool testTracksAgainstZones = m_cbReportTracksToZonesErrors->GetValue();
|
||||
bool refillZones = m_cbRefillZones->GetValue();
|
||||
bool reportAllTrackErrors = m_cbReportAllTrackErrors->GetValue();
|
||||
bool testFootprints = m_cbTestFootprints->GetValue();
|
||||
|
@ -247,8 +244,7 @@ void DIALOG_DRC::OnRunDRCClick( wxCommandEvent& aEvent )
|
|||
m_DeleteAllMarkersButton->Enable( false );
|
||||
m_saveReport->Enable( false );
|
||||
|
||||
drcTool->RunTests( this, testTracksAgainstZones, refillZones, reportAllTrackErrors,
|
||||
testFootprints );
|
||||
drcTool->RunTests( this, refillZones, reportAllTrackErrors, testFootprints );
|
||||
|
||||
if( m_cancelled )
|
||||
m_messages->Report( _( "-------- DRC cancelled by user.<br><br>" ) );
|
||||
|
|
|
@ -24,15 +24,13 @@ DIALOG_DRC_BASE::DIALOG_DRC_BASE( wxWindow* parent, wxWindowID id, const wxStrin
|
|||
wxBoxSizer* bSizer12;
|
||||
bSizer12 = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_cbRefillZones = new wxCheckBox( this, wxID_ANY, _("Refill all zones before performing DRC"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bSizer12->Add( m_cbRefillZones, 0, wxALL, 5 );
|
||||
|
||||
m_cbReportAllTrackErrors = new wxCheckBox( this, wxID_ANY, _("Report all errors for each track"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_cbReportAllTrackErrors->SetToolTip( _("If selected, all DRC violations for tracks will be reported. This can be slow for complicated designs.\n\nIf unselected, only the first DRC violation will be reported for each track connection.") );
|
||||
|
||||
bSizer12->Add( m_cbReportAllTrackErrors, 0, wxALL, 5 );
|
||||
|
||||
m_cbReportTracksToZonesErrors = new wxCheckBox( this, wxID_ANY, _("Test tracks against zone fills (slow)"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_cbReportTracksToZonesErrors->SetToolTip( _("If selected, tracks will be tested against copper zones. \nIf copper zones are up to date, this test should be not needed.\n\nThis test can be *very slow* for complicated designs.") );
|
||||
|
||||
bSizer12->Add( m_cbReportTracksToZonesErrors, 0, wxBOTTOM|wxLEFT, 5 );
|
||||
bSizer12->Add( m_cbReportAllTrackErrors, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
|
||||
bSizerOptions->Add( bSizer12, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
|
@ -40,11 +38,8 @@ DIALOG_DRC_BASE::DIALOG_DRC_BASE( wxWindow* parent, wxWindowID id, const wxStrin
|
|||
wxBoxSizer* bSizerOptSettings;
|
||||
bSizerOptSettings = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_cbRefillZones = new wxCheckBox( this, wxID_ANY, _("Refill all zones before performing DRC"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bSizerOptSettings->Add( m_cbRefillZones, 0, wxALL, 5 );
|
||||
|
||||
m_cbTestFootprints = new wxCheckBox( this, wxID_ANY, _("Test for parity between PCB and schematic"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bSizerOptSettings->Add( m_cbTestFootprints, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||
bSizerOptSettings->Add( m_cbTestFootprints, 0, wxALL, 5 );
|
||||
|
||||
|
||||
bSizerOptions->Add( bSizerOptSettings, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
|
|
|
@ -78,145 +78,6 @@
|
|||
<property name="name">bSizer12</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxCheckBox" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="checked">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Report all errors for each track</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_cbReportAllTrackErrors</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip">If selected, all DRC violations for tracks will be reported. This can be slow for complicated designs.

If unselected, only the first DRC violation will be reported for each track connection.</property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxBOTTOM|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxCheckBox" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="checked">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Test tracks against zone fills (slow)</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_cbReportTracksToZonesErrors</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip">If selected, tracks will be tested against copper zones. 
If copper zones are up to date, this test should be not needed.

This test can be *very slow* for complicated designs.</property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizerOptSettings</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL</property>
|
||||
|
@ -285,6 +146,81 @@
|
|||
<property name="border">5</property>
|
||||
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxCheckBox" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="checked">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Report all errors for each track</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_cbReportAllTrackErrors</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip">If selected, all DRC violations for tracks will be reported. This can be slow for complicated designs.

If unselected, only the first DRC violation will be reported for each track connection.</property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizerOptSettings</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxCheckBox" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
|
|
|
@ -48,9 +48,8 @@ class DIALOG_DRC_BASE : public DIALOG_SHIM
|
|||
wxPanel* m_panelUnconnectedItems;
|
||||
|
||||
protected:
|
||||
wxCheckBox* m_cbReportAllTrackErrors;
|
||||
wxCheckBox* m_cbReportTracksToZonesErrors;
|
||||
wxCheckBox* m_cbRefillZones;
|
||||
wxCheckBox* m_cbReportAllTrackErrors;
|
||||
wxCheckBox* m_cbTestFootprints;
|
||||
wxSimplebook* m_runningResultsBook;
|
||||
wxPanel* running;
|
||||
|
|
|
@ -55,7 +55,6 @@ DRC_ENGINE::DRC_ENGINE( BOARD* aBoard, BOARD_DESIGN_SETTINGS *aSettings ) :
|
|||
m_schematicNetlist( nullptr ),
|
||||
m_rulesValid( false ),
|
||||
m_userUnits( EDA_UNITS::MILLIMETRES ),
|
||||
m_testTracksAgainstZones( false ),
|
||||
m_reportAllTrackErrors( false ),
|
||||
m_testFootprints( false ),
|
||||
m_reporter( nullptr ),
|
||||
|
@ -629,13 +628,11 @@ void DRC_ENGINE::InitEngine( const wxFileName& aRulePath )
|
|||
}
|
||||
|
||||
|
||||
void DRC_ENGINE::RunTests( EDA_UNITS aUnits, bool aTestTracksAgainstZones,
|
||||
bool aReportAllTrackErrors, bool aTestFootprints )
|
||||
void DRC_ENGINE::RunTests( EDA_UNITS aUnits, bool aReportAllTrackErrors, bool aTestFootprints )
|
||||
{
|
||||
m_userUnits = aUnits;
|
||||
|
||||
// Note: set these first. The phase counts may be dependent on some of them.
|
||||
m_testTracksAgainstZones = aTestTracksAgainstZones;
|
||||
m_reportAllTrackErrors = aReportAllTrackErrors;
|
||||
m_testFootprints = aTestFootprints;
|
||||
|
||||
|
|
|
@ -140,13 +140,8 @@ public:
|
|||
|
||||
/**
|
||||
* Runs the DRC tests.
|
||||
* @param aUnits
|
||||
* @param aTestTracksAgainstZones
|
||||
* @param aReportAllTrackErrors
|
||||
* @param aTestFootprints
|
||||
*/
|
||||
void RunTests( EDA_UNITS aUnits = EDA_UNITS::MILLIMETRES, bool aTestTracksAgainstZones = true,
|
||||
bool aReportAllTrackErrors = true, bool aTestFootprints = true );
|
||||
void RunTests( EDA_UNITS aUnits, bool aReportAllTrackErrors, bool aTestFootprints );
|
||||
|
||||
|
||||
bool IsErrorLimitExceeded( int error_code );
|
||||
|
@ -161,7 +156,6 @@ public:
|
|||
bool HasRulesForConstraintType( DRC_CONSTRAINT_TYPE_T constraintID );
|
||||
|
||||
EDA_UNITS UserUnits() const { return m_userUnits; }
|
||||
bool GetTestTracksAgainstZones() const { return m_testTracksAgainstZones; }
|
||||
bool GetReportAllTrackErrors() const { return m_reportAllTrackErrors; }
|
||||
bool GetTestFootprints() const { return m_testFootprints; }
|
||||
|
||||
|
@ -220,7 +214,6 @@ protected:
|
|||
|
||||
EDA_UNITS m_userUnits;
|
||||
std::vector<int> m_errorLimits;
|
||||
bool m_testTracksAgainstZones;
|
||||
bool m_reportAllTrackErrors;
|
||||
bool m_testFootprints;
|
||||
|
||||
|
|
|
@ -168,6 +168,11 @@ public:
|
|||
return count > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a fast test which essentially does bounding-box overlap given a worst-case
|
||||
* clearance. It's used when looking up the specific item-to-item clearance might be
|
||||
* expensive and should be deferred till we know we have a possible hit.
|
||||
*/
|
||||
int QueryColliding( BOARD_ITEM* aRefItem,
|
||||
PCB_LAYER_ID aRefLayer,
|
||||
PCB_LAYER_ID aTargetLayer,
|
||||
|
@ -218,6 +223,60 @@ public:
|
|||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* This one is for tessellated items. (All shapes in the tree will be from a single
|
||||
* BOARD_ITEM.)
|
||||
* It checks all items in the bbox overlap to find the minimal actual distance and
|
||||
* position.
|
||||
*/
|
||||
bool QueryColliding( BOARD_ITEM* aRefItem, PCB_LAYER_ID aLayer,
|
||||
int aClearance, int* aActual, VECTOR2I* aPos ) const
|
||||
{
|
||||
EDA_RECT box = aRefItem->GetBoundingBox();
|
||||
box.Inflate( aClearance );
|
||||
|
||||
int min[2] = { box.GetX(), box.GetY() };
|
||||
int max[2] = { box.GetRight(), box.GetBottom() };
|
||||
|
||||
std::shared_ptr<SHAPE> refShape = aRefItem->GetEffectiveShape( aLayer );
|
||||
|
||||
bool collision = false;
|
||||
int actual = INT_MAX;
|
||||
VECTOR2I pos;
|
||||
|
||||
auto visit =
|
||||
[&]( ITEM_WITH_SHAPE* aItem ) -> bool
|
||||
{
|
||||
int curActual;
|
||||
VECTOR2I curPos;
|
||||
|
||||
if( refShape->Collide( aItem->shape, aClearance, &curActual, &curPos ) )
|
||||
{
|
||||
collision = true;
|
||||
|
||||
if( curActual < actual )
|
||||
{
|
||||
actual = curActual;
|
||||
pos = curPos;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
this->m_tree[aLayer]->Search( min, max, visit );
|
||||
|
||||
if( collision )
|
||||
{
|
||||
*aActual = std::max( 0, actual );
|
||||
*aPos = pos;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef std::pair<PCB_LAYER_ID, PCB_LAYER_ID> LAYER_PAIR;
|
||||
|
||||
struct PAIR_INFO
|
||||
|
|
|
@ -48,8 +48,6 @@
|
|||
- DRCE_TRACKS_CROSSING
|
||||
- DRCE_ZONES_INTERSECT
|
||||
- DRCE_SHORTING_ITEMS
|
||||
|
||||
TODO: improve zone clearance check (super slow)
|
||||
*/
|
||||
|
||||
class DRC_TEST_PROVIDER_COPPER_CLEARANCE : public DRC_TEST_PROVIDER_CLEARANCE_BASE
|
||||
|
@ -92,11 +90,15 @@ private:
|
|||
|
||||
void testZones();
|
||||
|
||||
void testTrackAgainstZones( TRACK* aTrack, PCB_LAYER_ID aLayer );
|
||||
void testItemAgainstZones( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer );
|
||||
|
||||
private:
|
||||
DRC_RTREE m_copperTree;
|
||||
int m_drcEpsilon;
|
||||
|
||||
std::vector<ZONE_CONTAINER*> m_zones;
|
||||
std::map<ZONE_CONTAINER*, std::unique_ptr<DRC_RTREE>> m_zoneTrees;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -118,12 +120,29 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::Run()
|
|||
|
||||
m_drcEpsilon = m_board->GetDesignSettings().GetDRCEpsilon();
|
||||
|
||||
m_zones.clear();
|
||||
|
||||
for( ZONE_CONTAINER* zone : m_board->Zones() )
|
||||
{
|
||||
if( !zone->GetIsRuleArea() )
|
||||
m_zones.push_back( zone );
|
||||
}
|
||||
|
||||
for( MODULE* footprint : m_board->Modules() )
|
||||
{
|
||||
for( ZONE_CONTAINER* zone : footprint->Zones() )
|
||||
{
|
||||
if( !zone->GetIsRuleArea() )
|
||||
m_zones.push_back( zone );
|
||||
}
|
||||
}
|
||||
|
||||
reportAux( "Worst clearance : %d nm", m_largestClearance );
|
||||
|
||||
// This is the number of tests between 2 calls to the progress bar
|
||||
const size_t delta = 50;
|
||||
size_t count = 0;
|
||||
size_t ii = 0;
|
||||
size_t delta = 50;
|
||||
size_t count = 0;
|
||||
size_t ii = 0;
|
||||
|
||||
auto countItems =
|
||||
[&]( BOARD_ITEM* item ) -> bool
|
||||
|
@ -159,7 +178,24 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::Run()
|
|||
forEachGeometryItem( itemTypes, LSET::AllCuMask(), countItems );
|
||||
forEachGeometryItem( itemTypes, LSET::AllCuMask(), addToCopperTree );
|
||||
|
||||
reportAux( "Testing %d copper items...", count );
|
||||
if( !reportPhase( _( "Tessellating copper zones..." ) ) )
|
||||
return false;
|
||||
|
||||
delta = 5;
|
||||
ii = 0;
|
||||
m_zoneTrees.clear();
|
||||
|
||||
for( ZONE_CONTAINER* zone : m_zones )
|
||||
{
|
||||
if( !reportProgress( ii++, m_zones.size(), delta ) )
|
||||
break;
|
||||
|
||||
zone->CacheBoundingBox();
|
||||
m_zoneTrees[ zone ] = std::make_unique<DRC_RTREE>();
|
||||
m_zoneTrees[ zone ]->insert( zone );
|
||||
}
|
||||
|
||||
reportAux( "Testing %d copper items and %d zones...", count, m_zones.size() );
|
||||
|
||||
if( !reportPhase( _( "Checking track & via clearances..." ) ) )
|
||||
return false;
|
||||
|
@ -262,112 +298,46 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( TRACK* track, SHA
|
|||
}
|
||||
|
||||
|
||||
void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstZones( TRACK* aTrack, PCB_LAYER_ID aLayer )
|
||||
void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testItemAgainstZones( BOARD_ITEM* aItem,
|
||||
PCB_LAYER_ID aLayer )
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
|
||||
SHAPE_SEGMENT refSeg( aTrack->GetStart(), aTrack->GetEnd(), aTrack->GetWidth() );
|
||||
EDA_RECT refSegInflatedBB = aTrack->GetBoundingBox();
|
||||
int refSegWidth = aTrack->GetWidth();
|
||||
|
||||
refSegInflatedBB.Inflate( m_largestClearance );
|
||||
|
||||
// Can be *very* time consuming.
|
||||
|
||||
if( ( aTrack->Type() != PCB_VIA_T
|
||||
|| static_cast<VIA*>( aTrack )->FlashLayer( aLayer )
|
||||
|| static_cast<VIA*>( aTrack )->GetDrill() > 0 ) )
|
||||
for( ZONE_CONTAINER* zone : m_zones )
|
||||
{
|
||||
for( ZONE_CONTAINER* zone : m_board->Zones() )
|
||||
if( m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE ) )
|
||||
break;
|
||||
|
||||
if( !zone->GetLayerSet().test( aLayer ) )
|
||||
continue;
|
||||
|
||||
if( zone->GetNetCode() && aItem->IsConnected() )
|
||||
{
|
||||
if( m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE ) )
|
||||
break;
|
||||
|
||||
if( !zone->GetLayerSet().test( aLayer ) || zone->GetIsRuleArea() )
|
||||
if( zone->GetNetCode() == static_cast<BOARD_CONNECTED_ITEM*>( aItem )->GetNetCode() )
|
||||
continue;
|
||||
}
|
||||
|
||||
if( zone->GetNetCode() && zone->GetNetCode() == aTrack->GetNetCode() )
|
||||
continue;
|
||||
|
||||
if( zone->GetFilledPolysList( aLayer ).IsEmpty() )
|
||||
continue;
|
||||
|
||||
if( !refSegInflatedBB.Intersects( zone->GetCachedBoundingBox() ) )
|
||||
continue;
|
||||
|
||||
int halfWidth = refSegWidth / 2;
|
||||
|
||||
if( aTrack->Type() == PCB_VIA_T )
|
||||
{
|
||||
VIA* refVia = static_cast<VIA*>( aTrack );
|
||||
|
||||
if( !refVia->FlashLayer( aLayer ) )
|
||||
halfWidth = refVia->GetDrill() / 2 + bds.GetHolePlatingThickness();
|
||||
}
|
||||
else if ( aTrack->Type() == PCB_ARC_T )
|
||||
{
|
||||
// We're going to do a collision with the arc "spine" using an increased
|
||||
// clearance to proxy for both the clearance and the arc track width. We
|
||||
// therefore need to subtract the polygonization error from the track width
|
||||
// so that it is all "inside" the track.
|
||||
halfWidth -= bds.m_MaxError / 2;
|
||||
}
|
||||
|
||||
if( aItem->GetBoundingBox().Intersects( zone->GetCachedBoundingBox() ) )
|
||||
{
|
||||
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_CLEARANCE,
|
||||
aTrack, zone, aLayer );
|
||||
int minClearance = constraint.GetValue().Min();
|
||||
int allowedDist = minClearance + halfWidth - bds.GetDRCEpsilon();
|
||||
aItem, zone, aLayer );
|
||||
int clearance = constraint.GetValue().Min();
|
||||
int actual;
|
||||
VECTOR2I pos;
|
||||
DRC_RTREE* zoneTree = m_zoneTrees[ zone ].get();
|
||||
|
||||
const SHAPE_POLY_SET& zonePoly = zone->GetFilledPolysList( aLayer );
|
||||
int actual = INT_MAX;
|
||||
VECTOR2I location;
|
||||
|
||||
accountCheck( constraint );
|
||||
|
||||
if( aTrack->Type() == PCB_ARC_T )
|
||||
if( zoneTree->QueryColliding( aItem, aLayer, clearance - m_drcEpsilon, &actual, &pos ) )
|
||||
{
|
||||
std::shared_ptr<SHAPE> refShape = aTrack->GetEffectiveShape();
|
||||
SHAPE_ARC* refArc = dynamic_cast<SHAPE_ARC*>( refShape.get() );
|
||||
SHAPE_LINE_CHAIN refArcSegs = refArc->ConvertToPolyline( bds.m_MaxError );
|
||||
|
||||
for( int i = 0; i < refArcSegs.SegmentCount(); ++i )
|
||||
{
|
||||
SEG refArcSeg = refArcSegs.Segment( i );
|
||||
int segActual;
|
||||
VECTOR2I segLocation;
|
||||
|
||||
if( zonePoly.Collide( refArcSeg, allowedDist, &segActual, &segLocation ) )
|
||||
{
|
||||
if( segActual < actual )
|
||||
{
|
||||
actual = segActual;
|
||||
location = segLocation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG testSeg( aTrack->GetStart(), aTrack->GetEnd() );
|
||||
|
||||
zonePoly.Collide( testSeg, allowedDist, &actual, &location );
|
||||
}
|
||||
|
||||
if( actual != INT_MAX )
|
||||
{
|
||||
actual = std::max( 0, actual - halfWidth );
|
||||
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
|
||||
|
||||
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), minClearance ),
|
||||
MessageTextFromValue( userUnits(), clearance ),
|
||||
MessageTextFromValue( userUnits(), actual ) );
|
||||
|
||||
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
|
||||
drce->SetItems( aTrack, zone );
|
||||
drce->SetItems( aItem, zone );
|
||||
drce->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
reportViolation( drce, (wxPoint) location );
|
||||
reportViolation( drce, (wxPoint) pos );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -410,8 +380,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances()
|
|||
},
|
||||
m_largestClearance );
|
||||
|
||||
if( m_drcEngine->GetTestTracksAgainstZones() )
|
||||
testTrackAgainstZones( track, layer );
|
||||
testItemAgainstZones( track, layer );
|
||||
}
|
||||
|
||||
track->SetFlags( SKIP_STRUCT );
|
||||
|
@ -567,6 +536,8 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadClearances( )
|
|||
return testPadAgainstItem( pad, padShape.get(), layer, other );
|
||||
},
|
||||
m_largestClearance );
|
||||
|
||||
testItemAgainstZones( pad, layer );
|
||||
}
|
||||
|
||||
pad->SetFlags( SKIP_STRUCT );
|
||||
|
@ -585,49 +556,38 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZones()
|
|||
if( m_board->GetBoardPolygonOutlines( buffer ) )
|
||||
boardOutline = &buffer;
|
||||
|
||||
std::vector<ZONE_CONTAINER*> zones;
|
||||
|
||||
for( ZONE_CONTAINER* zone : m_board->Zones() )
|
||||
zones.push_back( zone );
|
||||
|
||||
for( MODULE* footprint : m_board->Modules() )
|
||||
{
|
||||
for( ZONE_CONTAINER* zone : footprint->Zones() )
|
||||
zones.push_back( zone );
|
||||
}
|
||||
|
||||
for( int layer_id = F_Cu; layer_id <= B_Cu; ++layer_id )
|
||||
{
|
||||
PCB_LAYER_ID layer = static_cast<PCB_LAYER_ID>( layer_id );
|
||||
std::vector<SHAPE_POLY_SET> smoothed_polys;
|
||||
smoothed_polys.resize( zones.size() );
|
||||
smoothed_polys.resize( m_zones.size() );
|
||||
|
||||
// Skip over layers not used on the current board
|
||||
if( !m_board->IsLayerEnabled( layer ) )
|
||||
continue;
|
||||
|
||||
for( size_t ii = 0; ii < zones.size(); ii++ )
|
||||
for( size_t ii = 0; ii < m_zones.size(); ii++ )
|
||||
{
|
||||
if( zones[ii]->IsOnLayer( layer ) )
|
||||
zones[ii]->BuildSmoothedPoly( smoothed_polys[ii], layer, boardOutline );
|
||||
if( m_zones[ii]->IsOnLayer( layer ) )
|
||||
m_zones[ii]->BuildSmoothedPoly( smoothed_polys[ii], layer, boardOutline );
|
||||
}
|
||||
|
||||
// iterate through all areas
|
||||
for( size_t ia = 0; ia < zones.size(); ia++ )
|
||||
for( size_t ia = 0; ia < m_zones.size(); ia++ )
|
||||
{
|
||||
if( !reportProgress( layer_id * zones.size() + ia, B_Cu * zones.size(), delta ) )
|
||||
if( !reportProgress( layer_id * m_zones.size() + ia, B_Cu * m_zones.size(), delta ) )
|
||||
break;
|
||||
|
||||
ZONE_CONTAINER* zoneRef = zones[ia];
|
||||
ZONE_CONTAINER* zoneRef = m_zones[ia];
|
||||
|
||||
if( !zoneRef->IsOnLayer( layer ) )
|
||||
continue;
|
||||
|
||||
// If we are testing a single zone, then iterate through all other zones
|
||||
// Otherwise, we have already tested the zone combination
|
||||
for( size_t ia2 = ia + 1; ia2 < zones.size(); ia2++ )
|
||||
for( size_t ia2 = ia + 1; ia2 < m_zones.size(); ia2++ )
|
||||
{
|
||||
ZONE_CONTAINER* zoneToTest = zones[ia2];
|
||||
ZONE_CONTAINER* zoneToTest = m_zones[ia2];
|
||||
|
||||
if( zoneRef == zoneToTest )
|
||||
continue;
|
||||
|
@ -772,7 +732,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZones()
|
|||
|
||||
int DRC_TEST_PROVIDER_COPPER_CLEARANCE::GetNumPhases() const
|
||||
{
|
||||
return 4;
|
||||
return 5;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -206,9 +206,6 @@ PCBNEW_SETTINGS::PCBNEW_SETTINGS()
|
|||
m_params.emplace_back( new PARAM<bool>( "drc_dialog.refill_zones",
|
||||
&m_DrcDialog.refill_zones, false ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "drc_dialog.test_track_to_zone",
|
||||
&m_DrcDialog.test_track_to_zone, false ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "drc_dialog.test_all_track_errors",
|
||||
&m_DrcDialog.test_all_track_errors, false ) );
|
||||
|
||||
|
@ -541,7 +538,6 @@ bool PCBNEW_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
|
|||
aCfg->SetPath( "../.." );
|
||||
|
||||
ret &= fromLegacy<bool>( aCfg, "RefillZonesBeforeDrc", "drc_dialog.refill_zones" );
|
||||
ret &= fromLegacy<bool>( aCfg, "DrcTrackToZoneTest", "drc_dialog.test_track_to_zone" );
|
||||
ret &= fromLegacy<bool>( aCfg, "DrcTestFootprints", "drc_dialog.test_footprints" );
|
||||
|
||||
ret &= fromLegacy<bool>( aCfg, "DrillMergePTHNPTH", "gen_drill.merge_pth_npth" );
|
||||
|
|
|
@ -85,7 +85,6 @@ public:
|
|||
struct DIALOG_DRC
|
||||
{
|
||||
bool refill_zones;
|
||||
bool test_track_to_zone;
|
||||
bool test_all_track_errors;
|
||||
bool test_footprints;
|
||||
int severities;
|
||||
|
|
|
@ -405,7 +405,7 @@ bool WriteDRCReport( BOARD* aBoard, const wxString& aFileName, EDA_UNITS aUnits,
|
|||
}
|
||||
} );
|
||||
|
||||
engine->RunTests( aUnits, aTestTracksAgainstZones, aReportAllTrackErrors, false );
|
||||
engine->RunTests( aUnits, aReportAllTrackErrors, false );
|
||||
engine->ClearViolationHandler();
|
||||
|
||||
// TODO: Unify this with DIALOG_DRC::writeReport
|
||||
|
|
|
@ -139,8 +139,8 @@ void DRC_TOOL::DestroyDRCDialog()
|
|||
}
|
||||
|
||||
|
||||
void DRC_TOOL::RunTests( PROGRESS_REPORTER* aProgressReporter, bool aTestTracksAgainstZones,
|
||||
bool aRefillZones, bool aReportAllTrackErrors, bool aTestFootprints )
|
||||
void DRC_TOOL::RunTests( PROGRESS_REPORTER* aProgressReporter, bool aRefillZones,
|
||||
bool aReportAllTrackErrors, bool aTestFootprints )
|
||||
{
|
||||
// One at a time, please.
|
||||
// Note that the main GUI entry points to get here are blocked, so this is really an
|
||||
|
@ -205,8 +205,7 @@ void DRC_TOOL::RunTests( PROGRESS_REPORTER* aProgressReporter, bool aTestTracksA
|
|||
}
|
||||
} );
|
||||
|
||||
m_drcEngine->RunTests( m_editFrame->GetUserUnits(), aTestTracksAgainstZones,
|
||||
aReportAllTrackErrors, aTestFootprints );
|
||||
m_drcEngine->RunTests( m_editFrame->GetUserUnits(), aReportAllTrackErrors, aTestFootprints );
|
||||
|
||||
m_drcEngine->SetProgressReporter( nullptr );
|
||||
m_drcEngine->ClearViolationHandler();
|
||||
|
|
|
@ -115,8 +115,8 @@ public:
|
|||
/**
|
||||
* Run the DRC tests.
|
||||
*/
|
||||
void RunTests( PROGRESS_REPORTER* aProgressReporter, bool aTestTracksAgainstZones,
|
||||
bool aRefillZones, bool aReportAllTrackErrors, bool aTestFootprints );
|
||||
void RunTests( PROGRESS_REPORTER* aProgressReporter, bool aRefillZones,
|
||||
bool aReportAllTrackErrors, bool aTestFootprints );
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -132,6 +132,6 @@ int runDRCProto( PROJECT_CONTEXT project, std::shared_ptr<KIGFX::VIEW_OVERLAY> a
|
|||
// provider->Enable(false);
|
||||
}
|
||||
|
||||
drcEngine->RunTests();
|
||||
drcEngine->RunTests( EDA_UNITS::MILLIMETRES, true, false );
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -309,7 +309,7 @@ void DoCourtyardInvalidTest( const COURTYARD_INVALID_CASE& aCase,
|
|||
}
|
||||
} );
|
||||
|
||||
drcEngine.RunTests();
|
||||
drcEngine.RunTests( EDA_UNITS::MILLIMETRES, true, false );
|
||||
|
||||
CheckInvalidsMatchExpected( *board, markers, aCase.m_exp_errors );
|
||||
}
|
||||
|
|
|
@ -478,7 +478,7 @@ static void DoCourtyardOverlapTest( const COURTYARD_OVERLAP_TEST_CASE& aCase,
|
|||
}
|
||||
} );
|
||||
|
||||
drcEngine.RunTests();
|
||||
drcEngine.RunTests( EDA_UNITS::MILLIMETRES, true, false );
|
||||
|
||||
CheckCollisionsMatchExpected( *board, markers, aCase.m_collisions );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue