Finish exorcising the old DRC system.

This moves the various BOARD_ITEM calls to the new system, and make
the DRC_ENGINE long-lived so that it can field those queries.
This commit is contained in:
Jeff Young 2020-09-15 20:13:45 +01:00
parent 67a7aa8ba4
commit e2e229da96
43 changed files with 138 additions and 581 deletions

View File

@ -509,9 +509,11 @@ set( PCB_COMMON_SRCS
${CMAKE_SOURCE_DIR}/pcbnew/connectivity/connectivity_items.cpp
${CMAKE_SOURCE_DIR}/pcbnew/connectivity/connectivity_data.cpp
${CMAKE_SOURCE_DIR}/pcbnew/convert_drawsegment_list_to_polygon.cpp
${CMAKE_SOURCE_DIR}/pcbnew/drc/drc_engine.cpp
${CMAKE_SOURCE_DIR}/pcbnew/drc/drc_item.cpp
${CMAKE_SOURCE_DIR}/pcbnew/drc/drc_rule.cpp
${CMAKE_SOURCE_DIR}/pcbnew/drc/drc_rule_condition.cpp
${CMAKE_SOURCE_DIR}/pcbnew/drc/drc_rule_parser.cpp
${CMAKE_SOURCE_DIR}/pcbnew/eagle_plugin.cpp
${CMAKE_SOURCE_DIR}/pcbnew/footprint_editor_settings.cpp
${CMAKE_SOURCE_DIR}/pcbnew/gpcb_plugin.cpp

View File

@ -29,7 +29,7 @@
#include <netclass.h>
#include <config_params.h>
#include <board_stackup_manager/class_board_stackup.h>
#include <drc/drc_rule.h>
#include <drc/drc_engine.h>
#include <settings/nested_settings.h>
#include <widgets/ui_common.h>
#include <zone_settings.h>
@ -240,9 +240,9 @@ public:
int m_CopperEdgeClearance;
int m_HoleToHoleMin; // Min width of peninsula between two drilled holes
std::vector<DRC_RULE*> m_DRCRules;
std::map< int, int > m_DRCSeverities; // Map from DRCErrorCode to SEVERITY
std::set<wxString> m_DrcExclusions;
std::shared_ptr<DRC_ENGINE> m_DRCEngine;
std::map<int, int> m_DRCSeverities; // Map from DRCErrorCode to SEVERITY
std::set<wxString> m_DrcExclusions;
// Option to handle filled polygons in zones:
// the "legacy" option is using thick outlines around filled polygons: give the best shape

View File

@ -232,9 +232,6 @@ set( PCBNEW_MICROWAVE_SRCS
)
set( PCBNEW_DRC_SRCS
drc/drc.cpp
drc/drc_engine.cpp
drc/drc_rule_parser.cpp
drc/drc_test_provider.cpp
drc/drc_test_provider_annulus.cpp
drc/drc_test_provider_clearance_base.cpp

View File

@ -27,6 +27,7 @@
#include <class_board.h>
#include <class_board_item.h>
#include <connectivity/connectivity_data.h>
#include <drc/drc_engine.h>
using namespace std::placeholders;
@ -81,82 +82,26 @@ NETCLASS* BOARD_CONNECTED_ITEM::GetEffectiveNetclass() const
* LEVEL 3: Accumulated local settings, netclass settings, & board design settings
*/
int BOARD_CONNECTED_ITEM::GetClearance( PCB_LAYER_ID aLayer, BOARD_ITEM* aItem,
wxString* aSource, REPORTER* aReporter ) const
wxString* aSource ) const
{
BOARD* board = GetBoard();
int clearance = 0;
wxString source;
wxString* localSource = aSource ? &source : nullptr;
BOARD_CONNECTED_ITEM* second = dynamic_cast<BOARD_CONNECTED_ITEM*>( aItem );
// No clearance if "this" is not (yet) linked to a board therefore no available netclass
if( !board )
return clearance;
if( !GetBoard() )
return 0;
// LEVEL 1: local overrides (pad, footprint, etc.)
//
if( GetLocalClearanceOverrides( nullptr ) > clearance )
clearance = GetLocalClearanceOverrides( localSource );
std::shared_ptr<DRC_ENGINE> drcEngine = GetBoard()->GetDesignSettings().m_DRCEngine;
if( second && second->GetLocalClearanceOverrides( nullptr ) > clearance )
clearance = second->GetLocalClearanceOverrides( localSource );
DRC_CONSTRAINT constraint = drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_CLEARANCE,
this, aItem, aLayer );
if( clearance )
if( constraint.Value().HasMin() )
{
if( aSource )
*aSource = *localSource;
*aSource = constraint.GetName();
return clearance;
return constraint.Value().Min();
}
// LEVEL 2: Rules
//
const DRC_CONSTRAINT* constraint = GetConstraint( this, aItem, DRC_CONSTRAINT_TYPE_CLEARANCE,
aLayer, aSource );
if( constraint )
{
if( aSource )
*aSource = wxString::Format( _( "'%s' rule" ), *aSource );
return constraint->m_Value.Min();
}
// LEVEL 3: Accumulated local settings, netclass settings, & board design settings
//
BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
NETCLASS* netclass = GetEffectiveNetclass();
NETCLASS* secondNetclass = second ? second->GetEffectiveNetclass() : nullptr;
if( bds.m_MinClearance > clearance )
{
if( aSource )
*aSource = _( "board minimum" );
clearance = bds.m_MinClearance;
}
if( netclass && netclass->GetClearance() > clearance )
clearance = netclass->GetClearance( aSource );
if( secondNetclass && secondNetclass->GetClearance() > clearance )
clearance = secondNetclass->GetClearance( aSource );
if( aItem && aItem->GetLayer() == Edge_Cuts && bds.m_CopperEdgeClearance > clearance )
{
if( aSource )
*aSource = _( "board edge" );
clearance = bds.m_CopperEdgeClearance;
}
if( GetLocalClearance( nullptr ) > clearance )
clearance = GetLocalClearance( aSource );
if( second && second->GetLocalClearance( nullptr ) > clearance )
clearance = second->GetLocalClearance( aSource );
return clearance;
return 0;
}

View File

@ -168,7 +168,7 @@ public:
* @return int - the clearance in internal units.
*/
virtual int GetClearance( PCB_LAYER_ID aLayer, BOARD_ITEM* aItem = nullptr,
wxString* aSource = nullptr, REPORTER* aReporter = nullptr ) const;
wxString* aSource = nullptr ) const;
/**
* Function GetLocalClearanceOverrides

View File

@ -27,11 +27,9 @@
#include <class_track.h>
#include <layers_id_colors_and_visibility.h>
#include <kiface_i.h>
//#include <pcbnew.h>
#include <board_design_settings.h>
#include <drc/drc.h>
//#include <widgets/ui_common.h>
#include <drc/drc_rule.h>
#include <drc/drc_item.h>
#include <drc/drc_engine.h>
#include <settings/parameters.h>
#include <project/project_file.h>
#include <advanced_config.h>
@ -626,7 +624,6 @@ void BOARD_DESIGN_SETTINGS::initFromOther( const BOARD_DESIGN_SETTINGS& aOther )
m_TrackWidthList = aOther.m_TrackWidthList;
m_ViasDimensionsList = aOther.m_ViasDimensionsList;
m_DiffPairDimensionsList = aOther.m_DiffPairDimensionsList;
m_DRCRules = aOther.m_DRCRules;
m_MicroViasAllowed = aOther.m_MicroViasAllowed;
m_BlindBuriedViaAllowed = aOther.m_BlindBuriedViaAllowed;
m_CurrentViaType = aOther.m_CurrentViaType;
@ -935,21 +932,12 @@ bool BOARD_DESIGN_SETTINGS::SetCurrentNetClass( const wxString& aNetClassName )
int BOARD_DESIGN_SETTINGS::GetBiggestClearanceValue()
{
int clearance = GetDefault()->GetClearance();
DRC_CONSTRAINT constraint;
for( const std::pair<const wxString, NETCLASSPTR>& netclass : GetNetClasses().NetClasses() )
clearance = std::max( clearance, netclass.second->GetClearance() );
m_DRCEngine->QueryWorstConstraint( DRC_CONSTRAINT_TYPE_CLEARANCE, constraint,
DRCCQ_LARGEST_MINIMUM );
for( const DRC_RULE* rule : m_DRCRules )
{
for( const DRC_CONSTRAINT& constraint : rule->m_Constraints )
{
if( constraint.m_Type == DRC_CONSTRAINT_TYPE_CLEARANCE )
clearance = std::max( clearance, constraint.m_Value.Min() );
}
}
return clearance;
return constraint.Value().HasMin() ? constraint.Value().Min() : 0;
}

View File

@ -38,6 +38,7 @@
#include <geometry/shape_segment.h>
#include <geometry/shape_circle.h>
#include <geometry/shape_arc.h>
#include <drc/drc_engine.h>
TRACK::TRACK( BOARD_ITEM* aParent, KICAD_T idtype ) :
BOARD_CONNECTED_ITEM( aParent, idtype )
@ -124,52 +125,41 @@ int TRACK::GetLocalClearance( wxString* aSource ) const
}
/*
* Width constraints exist in a hiearchy. If a given level is specified then the remaining
* levels are NOT consulted.
*
* LEVEL 1: (highest priority) local overrides (not currently implemented.)
* LEVEL 2: Rules
* LEVEL 3: Accumulated local settings, netclass settings, & board design settings
*/
void TRACK::GetWidthConstraints( int* aMin, int* aMax, wxString* aSource ) const
{
// LEVEL 1: local overrides
//
// Not currently implemented
// LEVEL 2: Rules
const DRC_CONSTRAINT* constraint = GetConstraint( this, nullptr,
DRC_CONSTRAINT_TYPE_TRACK_WIDTH,
m_Layer, aSource );
if( constraint )
// No constraints if "this" is not (yet) linked to a board
if( !GetBoard() )
{
*aMin = constraint->m_Value.Min();
*aMax = constraint->m_Value.Max();
if( aSource )
*aSource = wxString::Format( _( "'%s' rule" ), *aSource );
*aMin = 0;
*aMax = INT_MAX;
return;
}
// LEVEL 3: Netclasses & board design settings
//
// Note that local settings aren't currently implemented, and netclasses don't contain a
// minimum width (only a default width), so only the board design settings are relevant
// here.
//
*aMin = GetBoard()->GetDesignSettings().m_TrackMinWidth;
*aMax = INT_MAX / 2;
std::shared_ptr<DRC_ENGINE> drcEngine = GetBoard()->GetDesignSettings().m_DRCEngine;
if( aSource )
*aSource = _( "board minimum" );
DRC_CONSTRAINT constraint = drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_TRACK_WIDTH,
this, nullptr, GetLayer() );
if( constraint.Value().HasMin() || constraint.Value().HasMax() )
{
if( constraint.Value().HasMin() )
*aMin = constraint.Value().Min();
if( constraint.Value().HasMax() )
*aMax = constraint.Value().Max();
if( aSource )
*aSource = constraint.GetName();
}
}
int VIA::GetMinAnnulus( PCB_LAYER_ID aLayer, wxString* aSource ) const
{
// No constraints if "this" is not (yet) linked to a board
if( !GetBoard() )
return 0;
if( !IsPadOnLayer( aLayer ) )
{
if( aSource )
@ -178,24 +168,20 @@ int VIA::GetMinAnnulus( PCB_LAYER_ID aLayer, wxString* aSource ) const
return 0;
}
const DRC_CONSTRAINT* constraint = GetConstraint( this, nullptr,
DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH,
aLayer, aSource );
std::shared_ptr<DRC_ENGINE> drcEngine = GetBoard()->GetDesignSettings().m_DRCEngine;
if( constraint )
DRC_CONSTRAINT constraint = drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH,
this, nullptr, aLayer );
if( constraint.Value().HasMin() )
{
if( aSource )
*aSource = wxString::Format( _( "'%s' rule" ), *aSource );
*aSource = constraint.GetName();
return constraint->m_Value.Min();
return constraint.Value().Min();
}
else
{
if( aSource )
*aSource = _( "board minimum" );
return GetBoard()->GetDesignSettings().m_ViasMinAnnulus;
}
return 0;
}

View File

@ -353,83 +353,6 @@ int ZONE_CONTAINER::GetThermalReliefCopperBridge( D_PAD* aPad, wxString* aSource
}
int ZONE_CONTAINER::GetKeepouts( PCB_LAYER_ID aLayer, std::map<int, wxString>* aSources ) const
{
wxString source;
int keepouts = 0;
auto setFlag = [&]( int aFlag )
{
keepouts |= aFlag;
if( aSources )
(*aSources)[ aFlag ] = source;
};
if( m_isKeepout )
{
if( aSources )
source = _( "zone properties" );
if( m_doNotAllowTracks )
setFlag( DRC_DISALLOW_TRACKS );
if( m_doNotAllowVias )
setFlag( DRC_DISALLOW_VIAS );
if( m_doNotAllowPads )
setFlag( DRC_DISALLOW_PADS );
if( m_doNotAllowFootprints )
setFlag( DRC_DISALLOW_FOOTPRINTS );
if( m_doNotAllowCopperPour )
setFlag( DRC_DISALLOW_ZONES );
}
const DRC_CONSTRAINT* constraint = GetConstraint( this, nullptr, DRC_CONSTRAINT_TYPE_DISALLOW,
aLayer, &source );
if( constraint )
{
if( aSources )
source = wxString::Format( _( "'%s' rule" ), source );
if( ( constraint->m_DisallowFlags & DRC_DISALLOW_VIAS ) > 0 )
setFlag( DRC_DISALLOW_VIAS );
if( ( constraint->m_DisallowFlags & DRC_DISALLOW_MICRO_VIAS ) > 0 )
setFlag( DRC_DISALLOW_MICRO_VIAS );
if( ( constraint->m_DisallowFlags & DRC_DISALLOW_BB_VIAS ) > 0 )
setFlag( DRC_DISALLOW_BB_VIAS );
if( ( constraint->m_DisallowFlags & DRC_DISALLOW_TRACKS ) > 0 )
setFlag( DRC_DISALLOW_TRACKS );
if( ( constraint->m_DisallowFlags & DRC_DISALLOW_PADS ) > 0 )
setFlag( DRC_DISALLOW_PADS );
if( ( constraint->m_DisallowFlags & DRC_DISALLOW_ZONES ) > 0 )
setFlag( DRC_DISALLOW_ZONES );
if( ( constraint->m_DisallowFlags & DRC_DISALLOW_TEXTS ) > 0 )
setFlag( DRC_DISALLOW_TEXTS );
if( ( constraint->m_DisallowFlags & DRC_DISALLOW_GRAPHICS ) > 0 )
setFlag( DRC_DISALLOW_GRAPHICS );
if( ( constraint->m_DisallowFlags & DRC_DISALLOW_HOLES ) > 0 )
setFlag( DRC_DISALLOW_HOLES );
if( ( constraint->m_DisallowFlags & DRC_DISALLOW_FOOTPRINTS ) > 0 )
setFlag( DRC_DISALLOW_FOOTPRINTS );
}
return keepouts;
}
void ZONE_CONTAINER::SetCornerRadius( unsigned int aRadius )
{
if( m_cornerRadius != aRadius )

View File

@ -714,15 +714,6 @@ public:
bool GetDoNotAllowPads() const { return m_doNotAllowPads; }
bool GetDoNotAllowFootprints() const { return m_doNotAllowFootprints; }
/**
* Return a bitset of flags for keepouts. Includes both those set via the GUI
* and those set via DRC rules.
* @aSources indicates the source ("zone properties" or rule name) of each
* flag.
* @return a bitset of DISALLOW_* flags.
*/
int GetKeepouts( PCB_LAYER_ID aLayer, std::map<int, wxString>* aSources = nullptr ) const;
void SetIsKeepout( bool aEnable ) { m_isKeepout = aEnable; }
void SetDoNotAllowCopperPour( bool aEnable ) { m_doNotAllowCopperPour = aEnable; }
void SetDoNotAllowVias( bool aEnable ) { m_doNotAllowVias = aEnable; }

View File

@ -24,8 +24,7 @@
#ifndef CLEANUP_ITEM_H
#define CLEANUP_ITEM_H
#include <rc_item.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
class PCB_BASE_FRAME;

View File

@ -26,7 +26,6 @@
#include <../board_stackup_manager/panel_board_stackup.h>
#include <confirm.h>
#include <kiface_i.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <dialog_import_settings.h>
#include <io_mgr.h>

View File

@ -26,6 +26,7 @@
#include <tool/tool_manager.h>
#include <tools/pcb_actions.h>
#include <graphics_cleaner.h>
#include <pcb_base_frame.h>
DIALOG_CLEANUP_GRAPHICS::DIALOG_CLEANUP_GRAPHICS( PCB_BASE_FRAME* aParent, bool isModEdit ) :

View File

@ -30,7 +30,6 @@
#include <wx/htmllbox.h>
#include <fctsys.h>
#include <pcbnew.h>
#include <drc/drc.h>
#include <rc_item.h>
#include <class_marker_pcb.h>
#include <class_board.h>

View File

@ -25,15 +25,16 @@
#include <widgets/paged_dialog.h>
#include <pcb_edit_frame.h>
#include <pcb_expr_evaluator.h>
#include <class_board.h>
#include <board_design_settings.h>
#include <project.h>
#include <tool/tool_manager.h>
#include <drc/drc.h>
#include <panel_setup_rules.h>
#include <wx_html_report_box.h>
#include <html_messagebox.h>
#include <scintilla_tricks.h>
#include <drc/drc_rule_parser.h>
#include <tools/drc_tool.h>
PANEL_SETUP_RULES::PANEL_SETUP_RULES( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFrame ) :
PANEL_SETUP_RULES_BASE( aParent->GetTreebook() ),
@ -372,9 +373,11 @@ bool PANEL_SETUP_RULES::TransferDataFromWindow()
return false;
}
if( m_textEditor->SaveFile( m_frame->Prj().AbsolutePath( "drc-rules" ) ) )
wxString rulesFilepath = m_frame->Prj().AbsolutePath( "drc-rules" );
if( m_textEditor->SaveFile( rulesFilepath ) )
{
m_frame->GetToolManager()->GetTool<DRC>()->LoadRules();
m_frame->GetBoard()->GetDesignSettings().m_DRCEngine->LoadRules( rulesFilepath );
return true;
}

View File

@ -1,101 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2004-2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2014 Dick Hollenbeck, dick@softplc.com
* Copyright (C) 2017-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
*/
#include <fctsys.h>
#include <pcb_edit_frame.h>
#include <board_design_settings.h>
#include <class_drawsegment.h>
#include <tool/tool_manager.h>
#include <tools/pcb_tool_base.h>
#include <netlist_reader/pcb_netlist.h>
#include <drc/drc.h>
#include <drc/drc_rule_parser.h>
#include <dialogs/panel_setup_rules.h>
#include <project.h>
#include <reporter.h>
DRC::DRC() :
PCB_TOOL_BASE( "pcbnew.legacyDRCTool" ),
m_editFrame( nullptr )
{
}
DRC::~DRC()
{
}
void DRC::Reset( RESET_REASON aReason )
{
m_editFrame = getEditFrame<PCB_EDIT_FRAME>();
}
// JEY TODO: make DRC_TOOL's DRC_ENGINE be long-lived so it can be used for BOARD_CONNECTED_ITEM's
// GetClearance() and the retire this.
bool DRC::LoadRules()
{
wxString rulesFilepath = m_editFrame->Prj().AbsolutePath( "drc-rules" );
wxFileName rulesFile( rulesFilepath );
if( rulesFile.FileExists() )
{
m_rules.clear();
FILE* fp = wxFopen( rulesFilepath, wxT( "rt" ) );
if( fp )
{
try
{
DRC_RULES_PARSER parser( m_editFrame->GetBoard(), fp, rulesFilepath );
parser.Parse( m_rules, &NULL_REPORTER::GetInstance() );
}
catch( PARSE_ERROR& pe )
{
// Don't leave possibly malformed stuff around for us to trip over
m_rules.clear();
wxSafeYield( m_editFrame );
m_editFrame->ShowBoardSetupDialog( _( "Rules" ), pe.What(), ID_RULES_EDITOR,
pe.lineNumber, pe.byteIndex );
return false;
}
}
}
std::reverse( std::begin( m_rules ), std::end( m_rules ) );
BOARD_DESIGN_SETTINGS& bds = m_editFrame->GetBoard()->GetDesignSettings();
bds.m_DRCRules = m_rules;
return true;
}

View File

@ -1,71 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2007-2016 Dick Hollenbeck, dick@softplc.com
* Copyright (C) 2017-2019 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_H
#define DRC_H
#include <board_commit.h>
#include <class_board.h>
#include <class_track.h>
#include <class_marker_pcb.h>
#include <geometry/seg.h>
#include <geometry/shape_poly_set.h>
#include <memory>
#include <vector>
#include <tools/pcb_tool_base.h>
class PCB_EDIT_FRAME;
/**
* Design Rule Checker object that performs all the DRC tests. The output of
* the checking goes to the BOARD file in the form of two MARKER lists. Those
* two lists are displayable in the drc dialog box. And they can optionally
* be sent to a text file on disk.
* This class is given access to the windows and the BOARD
* that it needs via its constructor or public access functions.
*/
class DRC : public PCB_TOOL_BASE
{
public:
DRC();
~DRC();
/// @copydoc TOOL_INTERACTIVE::Reset()
void Reset( RESET_REASON aReason ) override;
private:
PCB_EDIT_FRAME* m_editFrame; // The pcb frame editor which owns the board
std::vector<DRC_RULE*> m_rules;
public:
/**
* Load the DRC rules. Must be called after the netclasses have been read.
*/
bool LoadRules();
};
#endif // DRC_H

View File

@ -31,7 +31,6 @@
#include <drc/drc_rule.h>
#include <drc/drc_rule_condition.h>
#include <drc/drc_test_provider.h>
#include <drc/drc.h>
void drcPrintDebugMessage( int level, const wxString& msg, const char *function, int line )
{
@ -162,40 +161,47 @@ void DRC_ENGINE::loadImplicitRules()
// 3) per-netclass rules
std::vector<NETCLASSPTR> netclasses;
int ruleCount = 0;
m_board->SynchronizeNetsAndNetClasses();
netclasses.push_back( bds.GetNetClasses().GetDefault() );
auto makeNetclassRule =
[&]( const NETCLASSPTR& nc, bool isDefault )
{
wxString className = nc->GetName();
wxString expr;
for( const std::pair<const wxString, NETCLASSPTR>& netclass : bds.GetNetClasses() )
netclasses.push_back( netclass.second );
if( !isDefault )
{
expr = wxString::Format( "A.NetClass == '%s' || B.NetClass == '%s'",
className,
className );
}
ReportAux( wxString::Format( "Building %d implicit netclass rules", (int) netclasses.size() ) );
for( const NETCLASSPTR& nc : netclasses )
{
wxString className = nc->GetName();
wxString expr = wxString::Format( "A.NetClass == '%s' || B.NetClass == '%s'",
className,
className );
DRC_RULE_CONDITION* inNetclassCondition = new DRC_RULE_CONDITION ( expr );
DRC_RULE* netclassRule = createImplicitRule( wxString::Format( _( "netclass '%s'" ),
DRC_RULE_CONDITION* inNetclassCondition = new DRC_RULE_CONDITION ( expr );
DRC_RULE* rule = createImplicitRule( wxString::Format( _( "netclass '%s'" ),
className ));
netclassRule->m_Condition = inNetclassCondition;
rule->m_Condition = inNetclassCondition;
// Only add netclass clearances if they're larger than board minimums. That way
// board minimums will still enforce a global minimum.
// Only add netclass clearances if they're larger than board minimums. That way
// board minimums will still enforce a global minimum.
if( nc->GetClearance() > bds.m_MinClearance )
{
DRC_CONSTRAINT ncClearanceConstraint( DRC_CONSTRAINT_TYPE_CLEARANCE );
ncClearanceConstraint.Value().SetMin( nc->GetClearance() );
netclassRule->AddConstraint( ncClearanceConstraint );
}
}
if( nc->GetClearance() > bds.m_MinClearance )
{
DRC_CONSTRAINT ncClearanceConstraint( DRC_CONSTRAINT_TYPE_CLEARANCE );
ncClearanceConstraint.Value().SetMin( nc->GetClearance() );
rule->AddConstraint( ncClearanceConstraint );
}
ruleCount++;
};
m_board->SynchronizeNetsAndNetClasses();
makeNetclassRule( bds.GetNetClasses().GetDefault(), true );
for( const std::pair<const wxString, NETCLASSPTR>& netclass : bds.GetNetClasses() )
makeNetclassRule( netclass.second, false );
ReportAux( wxString::Format( "Building %d implicit netclass rules", ruleCount ) );
}
static wxString formatConstraint( const DRC_CONSTRAINT& constraint )
@ -425,14 +431,14 @@ void DRC_ENGINE::RunTests( EDA_UNITS aUnits, bool aTestTracksAgainstZones,
DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintId,
BOARD_ITEM* a, BOARD_ITEM* b, PCB_LAYER_ID aLayer,
REPORTER* aReporter )
const BOARD_ITEM* a, const BOARD_ITEM* b,
PCB_LAYER_ID aLayer, REPORTER* aReporter )
{
#define REPORT( s ) { if( aReporter ) { aReporter->Report( s ); } }
#define UNITS aReporter ? aReporter->GetUnits() : EDA_UNITS::MILLIMETRES
auto* connectedA = a && a->IsConnected() ? static_cast<BOARD_CONNECTED_ITEM*>( a ) : nullptr;
auto* connectedB = b && b->IsConnected() ? static_cast<BOARD_CONNECTED_ITEM*>( b ) : nullptr;
const BOARD_CONNECTED_ITEM* connectedA = dynamic_cast<const BOARD_CONNECTED_ITEM*>( a );
const BOARD_CONNECTED_ITEM* connectedB = dynamic_cast<const BOARD_CONNECTED_ITEM*>( b );
// Local overrides take precedence
if( aConstraintId == DRC_CONSTRAINT_TYPE_CLEARANCE )

View File

@ -97,6 +97,11 @@ public:
m_violationHandler = std::move( aHandler );
}
void ClearViolationHandler()
{
m_violationHandler = DRC_VIOLATION_HANDLER();
}
/*
* Receives progress information to show the user.
*/
@ -123,8 +128,8 @@ public:
bool IsErrorLimitExceeded( int error_code );
DRC_CONSTRAINT EvalRulesForItems( DRC_CONSTRAINT_TYPE_T ruleID, BOARD_ITEM* a,
BOARD_ITEM* b = nullptr,
DRC_CONSTRAINT EvalRulesForItems( DRC_CONSTRAINT_TYPE_T ruleID, const BOARD_ITEM* a,
const BOARD_ITEM* b = nullptr,
PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
REPORTER* aReporter = nullptr );

View File

@ -27,7 +27,6 @@
#include <common.h>
#include "wx/html/m_templ.h"
#include "wx/html/styleparams.h"
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <class_board.h>
@ -277,46 +276,3 @@ wxString escapeHtml( wxString aString )
}
wxString DRC_ITEM::ShowHtml( PCB_BASE_FRAME* aFrame ) const
{
BOARD_ITEM* mainItem = nullptr;
BOARD_ITEM* auxItem = nullptr;
wxString msg = m_errorMessage.IsEmpty() ? GetErrorText() : m_errorMessage;
wxString mainText;
wxString auxText;
if( m_mainItemUuid != niluuid )
mainItem = aFrame->GetBoard()->GetItem( m_mainItemUuid );
if( m_auxItemUuid != niluuid )
auxItem = aFrame->GetBoard()->GetItem( m_auxItemUuid );
if( mainItem )
mainText = mainItem->GetSelectMenuText( aFrame->GetUserUnits() );
if( auxItem )
auxText = auxItem->GetSelectMenuText( aFrame->GetUserUnits() );
if( mainItem && auxItem )
{
// an html fragment for the entire message in the listbox. feel free
// to add color if you want:
return wxString::Format( wxT( "<b>%s</b><br>&nbsp;&nbsp; %s<br>&nbsp;&nbsp; %s" ),
escapeHtml( msg ),
escapeHtml( mainText ),
escapeHtml( auxText ) );
}
else if( mainItem )
{
return wxString::Format( wxT( "<b>%s</b><br>&nbsp;&nbsp; %s" ),
escapeHtml( msg ),
escapeHtml( mainText ) );
}
else
{
return wxString::Format( wxT( "<b>%s</b>" ),
escapeHtml( msg ) );
}
}

View File

@ -97,13 +97,6 @@ public:
return allItemTypes;
}
/**
* Translates this object into a fragment of HTML suitable for the wxHtmlListBox class.
* @return wxString - the html text.
*/
wxString ShowHtml( PCB_BASE_FRAME* aFrame ) const; // JEY TODO
wxString FormatHtml( ) const { return ""; } // fixme
void SetViolatingRule ( DRC_RULE *aRule ) { m_violatingRule = aRule; }
DRC_RULE* GetViolatingRule() const { return m_violatingRule; }

View File

@ -29,54 +29,6 @@
#include <drc/drc_rule_condition.h>
const DRC_CONSTRAINT* GetConstraint( const BOARD_ITEM* aItem, const BOARD_ITEM* bItem,
int aConstraint, PCB_LAYER_ID aLayer, wxString* aRuleName )
{
BOARD* board = aItem->GetBoard();
if( !board )
return nullptr;
for( DRC_RULE* rule : board->GetDesignSettings().m_DRCRules )
{
if( !rule->m_LayerCondition.test( aLayer ) )
continue;
const DRC_CONSTRAINT* constraint = nullptr;
for( const DRC_CONSTRAINT& candidate : rule->m_Constraints )
{
if( candidate.m_Type == aConstraint )
{
constraint = &candidate;
break;
}
}
if( constraint )
{
if( rule->m_Condition->EvaluateFor( aItem, bItem, aLayer ) )
{
if( aRuleName )
*aRuleName = rule->m_Name;
return constraint;
}
if( bItem && rule->m_Condition->EvaluateFor( bItem, aItem, aLayer ) )
{
if( aRuleName )
*aRuleName = rule->m_Name;
return constraint;
}
}
}
return nullptr;
}
DRC_RULE::DRC_RULE() :
m_Unary( false ),
m_Implicit( false ),

View File

@ -24,7 +24,6 @@
#include <common.h>
#include <class_track.h>
#include <drc/drc_engine.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc_test_provider.h>

View File

@ -28,7 +28,6 @@
#include <connectivity/connectivity_algo.h>
#include <drc/drc_engine.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc_test_provider.h>

View File

@ -25,15 +25,15 @@
#include <class_board.h>
#include <class_drawsegment.h>
#include <class_pad.h>
#include <class_track.h>
#include <geometry/polygon_test_point_inside.h>
//#include <geometry/polygon_test_point_inside.h>
#include <geometry/seg.h>
#include <geometry/shape_poly_set.h>
#include <geometry/shape_rect.h>
#include <geometry/shape_segment.h>
#include <drc/drc_engine.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc_test_provider_clearance_base.h>

View File

@ -23,7 +23,6 @@
#include <geometry/shape_poly_set.h>
#include <drc/drc_engine.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc_test_provider_clearance_base.h>

View File

@ -23,7 +23,6 @@
#include <common.h>
#include <drc/drc_engine.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc_test_provider.h>

View File

@ -28,7 +28,6 @@
#include <drc/drc_engine.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc.h>
#include <drc/drc_test_provider_clearance_base.h>
/*

View File

@ -24,11 +24,11 @@
#include <common.h>
#include <class_drawsegment.h>
#include <class_pad.h>
#include <class_track.h>
#include <geometry/shape_segment.h>
#include <drc/drc_engine.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc.h>
#include <drc/drc_test_provider_clearance_base.h>
/*

View File

@ -22,10 +22,10 @@
*/
#include <class_pad.h>
#include <class_track.h>
#include <drc/drc_engine.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc.h>
#include <drc/drc_test_provider_clearance_base.h>

View File

@ -23,7 +23,6 @@
#include <class_board.h>
#include <drc/drc_engine.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc_test_provider.h>

View File

@ -23,7 +23,6 @@
#include <class_pcb_text.h>
#include <drc/drc_engine.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc_test_provider.h>

View File

@ -24,7 +24,6 @@
//#include <common.h>
#include <class_track.h>
#include <drc/drc_engine.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc_test_provider.h>

View File

@ -23,7 +23,6 @@
#include <class_track.h>
#include <drc/drc_engine.h>
#include <drc/drc.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <drc/drc_test_provider.h>

View File

@ -27,7 +27,6 @@
#include <settings/settings_manager.h>
#include <wx/config.h>
#include <base_units.h>
#include <drc/drc.h>
#include <widgets/ui_common.h>
extern const char* traceSettings;

View File

@ -26,7 +26,6 @@
#include <advanced_config.h>
#include <drc/drc.h>
#include <filehistory.h>
#include <kiface_i.h>
#include <menus_helpers.h>

View File

@ -131,6 +131,10 @@ void PCB_BASE_EDIT_FRAME::SetBoard( BOARD* aBoard )
if( new_board )
{
BOARD_DESIGN_SETTINGS& bds = aBoard->GetDesignSettings();
bds.m_DRCEngine = std::make_shared<DRC_ENGINE>( aBoard, &bds );
bds.m_DRCEngine->InitEngine( Prj().AbsolutePath( "drc-rules" ) );
if( m_toolManager )
m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD );

View File

@ -30,7 +30,6 @@
#include <bitmaps.h>
#include <trace_helpers.h>
#include <pcbnew_id.h>
#include <drc/drc.h>
#include <pcbnew_settings.h>
#include <pcb_layer_box_selector.h>
#include <pcb_layer_widget.h>
@ -504,7 +503,6 @@ void PCB_EDIT_FRAME::setupTools()
m_toolManager->RegisterTool( new POSITION_RELATIVE_TOOL );
m_toolManager->RegisterTool( new ZONE_FILLER_TOOL );
m_toolManager->RegisterTool( new AUTOPLACE_TOOL );
m_toolManager->RegisterTool( new DRC );
m_toolManager->RegisterTool( new DRC_TOOL );
m_toolManager->RegisterTool( new PCB_VIEWER_TOOLS );
m_toolManager->RegisterTool( new CONVERT_TOOL );
@ -1046,8 +1044,6 @@ void PCB_EDIT_FRAME::onBoardLoaded()
SetMsgPanel( GetBoard() );
SetStatusText( wxEmptyString );
m_toolManager->GetTool<DRC>()->LoadRules();
KIPLATFORM::APP::SetShutdownBlockReason( this, _( "PCB file changes are unsaved" ) );
}

View File

@ -62,6 +62,7 @@ void DRC_TOOL::Reset( RESET_REASON aReason )
DestroyDRCDialog( wxID_OK );
m_pcb = m_editFrame->GetBoard();
m_drcEngine = m_pcb->GetDesignSettings().m_DRCEngine;
}
}
@ -131,10 +132,8 @@ void DRC_TOOL::RunTests( WX_PROGRESS_REPORTER* aProgressReporter, bool aTestTrac
bool aRefillZones, bool aReportAllTrackErrors, bool aTestFootprints )
{
ZONE_FILLER_TOOL* zoneFiller = m_toolMgr->GetTool<ZONE_FILLER_TOOL>();
BOARD_COMMIT commit( m_editFrame );
DRC_ENGINE drcEngine( m_pcb, &m_pcb->GetDesignSettings() );
NETLIST netlist;
BOARD_COMMIT commit( m_editFrame );
NETLIST netlist;
if( aRefillZones )
{
@ -149,9 +148,10 @@ void DRC_TOOL::RunTests( WX_PROGRESS_REPORTER* aProgressReporter, bool aTestTrac
zoneFiller->CheckAllZones( aProgressReporter->GetParent(), aProgressReporter );
}
drcEngine.InitEngine( m_editFrame->Prj().AbsolutePath( "drc-rules" ) );
drcEngine.SetWorksheet( m_editFrame->GetCanvas()->GetWorksheet() );
// Re-initialize the DRC_ENGINE to make doubly sure everything is up-to-date
//
m_drcEngine->InitEngine( m_editFrame->Prj().AbsolutePath( "drc-rules" ) );
m_drcEngine->SetWorksheet( m_editFrame->GetCanvas()->GetWorksheet() );
if( aTestFootprints && !Kiface().IsSingle() )
{
@ -160,12 +160,12 @@ void DRC_TOOL::RunTests( WX_PROGRESS_REPORTER* aProgressReporter, bool aTestTrac
if( m_drcDialog )
m_drcDialog->Raise();
drcEngine.SetSchematicNetlist( &netlist );
m_drcEngine->SetSchematicNetlist( &netlist );
}
drcEngine.SetProgressReporter( aProgressReporter );
m_drcEngine->SetProgressReporter( aProgressReporter );
drcEngine.SetViolationHandler(
m_drcEngine->SetViolationHandler(
[&]( const std::shared_ptr<DRC_ITEM>& aItem, wxPoint aPos )
{
if( aItem->GetErrorCode() == DRCE_MISSING_FOOTPRINT
@ -186,8 +186,11 @@ void DRC_TOOL::RunTests( WX_PROGRESS_REPORTER* aProgressReporter, bool aTestTrac
}
} );
drcEngine.RunTests( m_editFrame->GetUserUnits(), aTestTracksAgainstZones,
aReportAllTrackErrors, aTestFootprints );
m_drcEngine->RunTests( m_editFrame->GetUserUnits(), aTestTracksAgainstZones,
aReportAllTrackErrors, aTestFootprints );
m_drcEngine->SetProgressReporter( nullptr );
m_drcEngine->ClearViolationHandler();
commit.Push( _( "DRC" ), false );

View File

@ -39,12 +39,11 @@ class PCB_EDIT_FRAME;
class DIALOG_DRC;
class DRC_ITEM;
class WX_PROGRESS_REPORTER;
class DRC_ENGINE;
class DRC_TOOL : public PCB_TOOL_BASE
{
friend class DIALOG_DRC;
public:
DRC_TOOL();
~DRC_TOOL();
@ -57,6 +56,8 @@ private:
BOARD* m_pcb;
DIALOG_DRC* m_drcDialog;
std::shared_ptr<DRC_ENGINE> m_drcEngine;
std::vector<std::shared_ptr<DRC_ITEM>> m_unconnected; // list of unconnected pads
std::vector<std::shared_ptr<DRC_ITEM>> m_footprints; // list of footprint warnings

View File

@ -198,11 +198,6 @@ void PCB_INSPECTION_TOOL::reportCopperClearance( PCB_LAYER_ID aLayer, BOARD_CONN
r->Report( "" );
r->Report( wxString::Format( _( "Clearance: %s." ), clearance ) );
}
// JEY TODO: hook this up to new DRC engine to get "classic" sources as well; right now
// we're just reporting on rules....
// JEY TODO: retire this version
// aA->GetClearance( aLayer, aB, &source, r );
}

View File

@ -35,7 +35,6 @@
#include <pcbnew.h>
#include <zones.h>
#include <zones_functions_for_undo_redo.h>
#include <drc/drc.h>
#include <connectivity/connectivity_data.h>
#include <widgets/progress_reporter.h>
#include <zone_filler.h>

View File

@ -33,11 +33,10 @@
#include <geometry/shape_rect.h>
#include <geometry/shape_segment.h>
#include <pcbnew/drc/drc_engine.h>
#include <drc/drc.h>
#include <drc/drc_engine.h>
#include <drc/drc_item.h>
#include <drc/drc_rule.h>
#include <pcbnew/drc/drc_test_provider_clearance_base.h>
#include <drc/drc_test_provider_clearance_base.h>
/*
Silk to pads clearance test. Check all pads against silkscreen (mask opening in the pad vs silkscreen)

View File

@ -25,8 +25,6 @@
#include <class_edge_mod.h>
#include <class_module.h>
#include <drc/drc.h>
#include <geometry/seg.h>
#include <math/vector2d.h>