KiCad PCB EDA Suite
DRC_ENGINE Class Reference

Design Rule Checker object that performs all the DRC tests. More...

#include <drc_engine.h>

Classes

struct  DRC_ENGINE_CONSTRAINT
 

Public Member Functions

 DRC_ENGINE (BOARD *aBoard=nullptr, BOARD_DESIGN_SETTINGS *aSettings=nullptr)
 
 ~DRC_ENGINE ()
 
void SetBoard (BOARD *aBoard)
 
BOARDGetBoard () const
 
void SetDesignSettings (BOARD_DESIGN_SETTINGS *aSettings)
 
BOARD_DESIGN_SETTINGSGetDesignSettings () const
 
void SetSchematicNetlist (NETLIST *aNetlist)
 
NETLISTGetSchematicNetlist () const
 
void SetDrawingSheet (DS_PROXY_VIEW_ITEM *aDrawingSheet)
 
DS_PROXY_VIEW_ITEMGetDrawingSheet () const
 
void SetDebugOverlay (std::shared_ptr< KIGFX::VIEW_OVERLAY > aOverlay)
 
std::shared_ptr< KIGFX::VIEW_OVERLAYGetDebugOverlay () const
 
void SetViolationHandler (DRC_VIOLATION_HANDLER aHandler)
 Set an optional DRC violation handler (receives DRC_ITEMs and positions). More...
 
void ClearViolationHandler ()
 
void SetProgressReporter (PROGRESS_REPORTER *aProgRep)
 Set an optional reporter for user-level progress info. More...
 
PROGRESS_REPORTERGetProgressReporter () const
 
void SetLogReporter (REPORTER *aReporter)
 
void InitEngine (const wxFileName &aRulePath)
 Initializes the DRC engine. More...
 
void RunTests (EDA_UNITS aUnits, bool aReportAllTrackErrors, bool aTestFootprints)
 Runs the DRC tests. More...
 
bool IsErrorLimitExceeded (int error_code)
 
DRC_CONSTRAINT EvalRules (DRC_CONSTRAINT_T aConstraintId, const BOARD_ITEM *a, const BOARD_ITEM *b, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
 
bool HasRulesForConstraintType (DRC_CONSTRAINT_T constraintID)
 
EDA_UNITS UserUnits () const
 
bool GetReportAllTrackErrors () const
 
bool GetTestFootprints () const
 
bool RulesValid ()
 
void ReportViolation (const std::shared_ptr< DRC_ITEM > &aItem, wxPoint aPos)
 
bool ReportProgress (double aProgress)
 
bool ReportPhase (const wxString &aMessage)
 
void ReportAux (const wxString &aStr)
 
bool QueryWorstConstraint (DRC_CONSTRAINT_T aRuleId, DRC_CONSTRAINT &aConstraint)
 
std::vector< DRC_TEST_PROVIDER * > GetTestProviders () const
 
DRC_TEST_PROVIDERGetTestProvider (const wxString &name) const
 

Static Public Member Functions

static bool IsNetADiffPair (BOARD *aBoard, NETINFO_ITEM *aNet, int &aNetP, int &aNetN)
 
static int MatchDpSuffix (const wxString &aNetName, wxString &aComplementNet, wxString &aBaseDpName)
 Checks if the given net is a diff pair, returning its polarity and complement if so. More...
 
static bool IsNetTie (BOARD_ITEM *aItem)
 
static std::shared_ptr< SHAPEGetShape (BOARD_ITEM *aItem, PCB_LAYER_ID aLayer)
 

Protected Attributes

BOARD_DESIGN_SETTINGSm_designSettings
 
BOARDm_board
 
DS_PROXY_VIEW_ITEMm_drawingSheet
 
NETLISTm_schematicNetlist
 
std::vector< DRC_RULE * > m_rules
 
bool m_rulesValid
 
std::vector< DRC_TEST_PROVIDER * > m_testProviders
 
EDA_UNITS m_userUnits
 
std::vector< int > m_errorLimits
 
bool m_reportAllTrackErrors
 
bool m_testFootprints
 
std::unordered_map< DRC_CONSTRAINT_T, std::vector< DRC_ENGINE_CONSTRAINT * > * > m_constraintMap
 
DRC_VIOLATION_HANDLER m_violationHandler
 
REPORTERm_reporter
 
PROGRESS_REPORTERm_progressReporter
 
wxString m_msg
 
std::shared_ptr< KIGFX::VIEW_OVERLAYm_debugOverlay
 

Private Member Functions

void addRule (DRC_RULE *rule)
 
void loadRules (const wxFileName &aPath)
 Loads and parses a rule set from an sexpr text file. More...
 
void compileRules ()
 
void loadImplicitRules ()
 
DRC_RULEcreateImplicitRule (const wxString &name)
 

Detailed Description

Design Rule Checker object that performs all the DRC tests.

Optionally reports violations via a DRC_VIOLATION_HANDLER, user-level progress via a PROGRESS_REPORTER and rule parse errors via a REPORTER, all set through various setter calls.

Note that EvalRules() has yet another optional REPORTER for reporting resolution info to the user.

Definition at line 80 of file drc_engine.h.

Constructor & Destructor Documentation

◆ DRC_ENGINE()

DRC_ENGINE::DRC_ENGINE ( BOARD aBoard = nullptr,
BOARD_DESIGN_SETTINGS aSettings = nullptr 
)

Definition at line 56 of file drc_engine.cpp.

56  :
57  m_designSettings ( aSettings ),
58  m_board( aBoard ),
59  m_drawingSheet( nullptr ),
60  m_schematicNetlist( nullptr ),
61  m_rulesValid( false ),
63  m_reportAllTrackErrors( false ),
64  m_testFootprints( false ),
65  m_reporter( nullptr ),
66  m_progressReporter( nullptr )
67 {
68  m_errorLimits.resize( DRCE_LAST + 1 );
69 
70  for( int ii = DRCE_FIRST; ii <= DRCE_LAST; ++ii )
71  m_errorLimits[ ii ] = INT_MAX;
72 }
EDA_UNITS m_userUnits
Definition: drc_engine.h:220
std::vector< int > m_errorLimits
Definition: drc_engine.h:221
NETLIST * m_schematicNetlist
Definition: drc_engine.h:214
bool m_testFootprints
Definition: drc_engine.h:223
bool m_rulesValid
Definition: drc_engine.h:217
BOARD_DESIGN_SETTINGS * m_designSettings
Definition: drc_engine.h:211
PROGRESS_REPORTER * m_progressReporter
Definition: drc_engine.h:230
REPORTER * m_reporter
Definition: drc_engine.h:229
BOARD * m_board
Definition: drc_engine.h:212
bool m_reportAllTrackErrors
Definition: drc_engine.h:222
DS_PROXY_VIEW_ITEM * m_drawingSheet
Definition: drc_engine.h:213

References DRCE_FIRST, DRCE_LAST, and m_errorLimits.

◆ ~DRC_ENGINE()

DRC_ENGINE::~DRC_ENGINE ( )

Definition at line 75 of file drc_engine.cpp.

76 {
77  for( DRC_RULE* rule : m_rules )
78  delete rule;
79 
80  for( std::pair<DRC_CONSTRAINT_T, std::vector<DRC_ENGINE_CONSTRAINT*>*> pair : m_constraintMap )
81  {
82  for( DRC_ENGINE_CONSTRAINT* constraint : *pair.second )
83  delete constraint;
84 
85  delete pair.second;
86  }
87 }
DRC_CONSTRAINT_T
Definition: drc_rule.h:41
std::vector< DRC_RULE * > m_rules
Definition: drc_engine.h:216
std::unordered_map< DRC_CONSTRAINT_T, std::vector< DRC_ENGINE_CONSTRAINT * > * > m_constraintMap
Definition: drc_engine.h:226

References m_constraintMap, and m_rules.

Member Function Documentation

◆ addRule()

void DRC_ENGINE::addRule ( DRC_RULE rule)
inlineprivate

Definition at line 185 of file drc_engine.h.

186  {
187  m_rules.push_back(rule);
188  }
std::vector< DRC_RULE * > m_rules
Definition: drc_engine.h:216

References m_rules.

Referenced by createImplicitRule(), and loadImplicitRules().

◆ ClearViolationHandler()

void DRC_ENGINE::ClearViolationHandler ( )
inline

Definition at line 110 of file drc_engine.h.

111  {
113  }
std::function< void(const std::shared_ptr< DRC_ITEM > &aItem, wxPoint aPos)> DRC_VIOLATION_HANDLER
Definition: drc_engine.h:63
DRC_VIOLATION_HANDLER m_violationHandler
Definition: drc_engine.h:228

References m_violationHandler.

◆ compileRules()

void DRC_ENGINE::compileRules ( )
private

Definition at line 542 of file drc_engine.cpp.

543 {
544  ReportAux( wxString::Format( "Compiling Rules (%d rules): ",
545  (int) m_rules.size() ) );
546 
547  for( DRC_TEST_PROVIDER* provider : m_testProviders )
548  {
549  ReportAux( wxString::Format( "- Provider: '%s': ", provider->GetName() ) );
550  drc_dbg( 7, "do prov %s", provider->GetName() );
551 
552  for( DRC_CONSTRAINT_T id : provider->GetConstraintTypes() )
553  {
554  drc_dbg( 7, "do id %d", id );
555 
556  if( m_constraintMap.find( id ) == m_constraintMap.end() )
557  m_constraintMap[ id ] = new std::vector<DRC_ENGINE_CONSTRAINT*>();
558 
559  for( DRC_RULE* rule : m_rules )
560  {
561  DRC_RULE_CONDITION* condition = nullptr;
562  bool compileOk = false;
563  std::vector<DRC_CONSTRAINT> matchingConstraints;
564  drc_dbg( 7, "Scan provider %s, rule %s", provider->GetName(), rule->m_Name );
565 
566  if( rule->m_Condition && !rule->m_Condition->GetExpression().IsEmpty() )
567  {
568  condition = rule->m_Condition;
569  compileOk = condition->Compile( nullptr, 0, 0 ); // fixme
570  }
571 
572  for( const DRC_CONSTRAINT& constraint : rule->m_Constraints )
573  {
574  drc_dbg(7, "scan constraint id %d\n", constraint.m_Type );
575 
576  if( constraint.m_Type != id )
577  continue;
578 
579  DRC_ENGINE_CONSTRAINT* rcons = new DRC_ENGINE_CONSTRAINT;
580 
581  rcons->layerTest = rule->m_LayerCondition;
582  rcons->condition = condition;
583 
584  matchingConstraints.push_back( constraint );
585 
586  rcons->constraint = constraint;
587  rcons->parentRule = rule;
588  m_constraintMap[ id ]->push_back( rcons );
589  }
590 
591  if( !matchingConstraints.empty() )
592  {
593  ReportAux( wxString::Format( " |- Rule: '%s' ",
594  rule->m_Name ) );
595 
596  if( condition )
597  {
598  ReportAux( wxString::Format( " |- condition: '%s' compile: %s",
599  condition->GetExpression(),
600  compileOk ? "OK" : "ERROR" ) );
601  }
602 
603  for (const DRC_CONSTRAINT& constraint : matchingConstraints )
604  {
605  ReportAux( wxString::Format( " |- constraint: %s",
606  formatConstraint( constraint ) ) );
607  }
608  }
609  }
610  }
611  }
612 }
std::vector< DRC_TEST_PROVIDER * > m_testProviders
Definition: drc_engine.h:218
DRC_CONSTRAINT_T
Definition: drc_rule.h:41
wxString GetExpression() const
std::vector< DRC_RULE * > m_rules
Definition: drc_engine.h:216
std::unordered_map< DRC_CONSTRAINT_T, std::vector< DRC_ENGINE_CONSTRAINT * > * > m_constraintMap
Definition: drc_engine.h:226
static wxString formatConstraint(const DRC_CONSTRAINT &constraint)
Definition: drc_engine.cpp:454
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
DRC_TEST_PROVIDER is a base class that represents a DRC "provider" which runs some DRC functions over...
void ReportAux(const wxString &aStr)
bool Compile(REPORTER *aReporter, int aSourceLine=0, int aSourceOffset=0)
DRC_CONSTRAINT_T m_Type
Definition: drc_rule.h:141
#define drc_dbg(level, fmt,...)
Definition: drc_engine.h:57

References DRC_RULE_CONDITION::Compile(), DRC_ENGINE::DRC_ENGINE_CONSTRAINT::condition, DRC_ENGINE::DRC_ENGINE_CONSTRAINT::constraint, drc_dbg, Format(), formatConstraint(), DRC_RULE_CONDITION::GetExpression(), DRC_ENGINE::DRC_ENGINE_CONSTRAINT::layerTest, m_constraintMap, m_rules, m_testProviders, DRC_CONSTRAINT::m_Type, DRC_ENGINE::DRC_ENGINE_CONSTRAINT::parentRule, and ReportAux().

Referenced by InitEngine().

◆ createImplicitRule()

DRC_RULE * DRC_ENGINE::createImplicitRule ( const wxString &  name)
private

Definition at line 119 of file drc_engine.cpp.

120 {
121  DRC_RULE *rule = new DRC_RULE;
122 
123  rule->m_Name = name;
124  rule->m_Implicit = true;
125 
126  addRule( rule );
127 
128  return rule;
129 }
bool m_Implicit
Definition: drc_rule.h:95
wxString m_Name
Definition: drc_rule.h:96
void addRule(DRC_RULE *rule)
Definition: drc_engine.h:185
const char * name
Definition: DXF_plotter.cpp:59

References addRule(), DRC_RULE::m_Implicit, DRC_RULE::m_Name, and name.

Referenced by loadImplicitRules().

◆ EvalRules()

DRC_CONSTRAINT DRC_ENGINE::EvalRules ( DRC_CONSTRAINT_T  aConstraintId,
const BOARD_ITEM a,
const BOARD_ITEM b,
PCB_LAYER_ID  aLayer,
REPORTER aReporter = nullptr 
)

Definition at line 758 of file drc_engine.cpp.

761 {
762 #define REPORT( s ) { if( aReporter ) { aReporter->Report( s ); } }
763 #define UNITS aReporter ? aReporter->GetUnits() : EDA_UNITS::MILLIMETRES
764  /*
765  * NOTE: all string manipulation MUST BE KEPT INSIDE the REPORT macro. It absolutely
766  * kills performance when running bulk DRC tests (where aReporter is nullptr).
767  */
768 
769  const BOARD_CONNECTED_ITEM* ac = a && a->IsConnected() ?
770  static_cast<const BOARD_CONNECTED_ITEM*>( a ) : nullptr;
771  const BOARD_CONNECTED_ITEM* bc = b && b->IsConnected() ?
772  static_cast<const BOARD_CONNECTED_ITEM*>( b ) : nullptr;
773 
774  bool a_is_non_copper = a && ( !a->IsOnCopperLayer() || isKeepoutZone( a, false ) );
775  bool b_is_non_copper = b && ( !b->IsOnCopperLayer() || isKeepoutZone( b, false ) );
776 
777  const DRC_CONSTRAINT* constraintRef = nullptr;
778  bool implicit = false;
779 
780  // Local overrides take precedence
781  if( aConstraintId == CLEARANCE_CONSTRAINT || aConstraintId == HOLE_CLEARANCE_CONSTRAINT )
782  {
783  int overrideA = 0;
784  int overrideB = 0;
785 
786  if( ac && !b_is_non_copper && ac->GetLocalClearanceOverrides( nullptr ) > 0 )
787  {
788  overrideA = ac->GetLocalClearanceOverrides( &m_msg );
789 
790  REPORT( "" )
791  REPORT( wxString::Format( _( "Local override on %s; clearance: %s." ),
792  EscapeHTML( a->GetSelectMenuText( UNITS ) ),
793  EscapeHTML( MessageTextFromValue( UNITS, overrideA ) ) ) )
794  }
795 
796  if( bc && !a_is_non_copper && bc->GetLocalClearanceOverrides( nullptr ) > 0 )
797  {
798  overrideB = bc->GetLocalClearanceOverrides( &m_msg );
799 
800  REPORT( "" )
801  REPORT( wxString::Format( _( "Local override on %s; clearance: %s." ),
802  EscapeHTML( b->GetSelectMenuText( UNITS ) ),
803  EscapeHTML( MessageTextFromValue( UNITS, overrideB ) ) ) )
804  }
805 
806  if( overrideA || overrideB )
807  {
808  DRC_CONSTRAINT constraint( aConstraintId, m_msg );
809  constraint.m_Value.SetMin( std::max( overrideA, overrideB ) );
810  return constraint;
811  }
812  }
813 
814  auto processConstraint =
815  [&]( const DRC_ENGINE_CONSTRAINT* c ) -> bool
816  {
817  implicit = c->parentRule && c->parentRule->m_Implicit;
818 
819  REPORT( "" )
820 
821  if( aConstraintId == CLEARANCE_CONSTRAINT )
822  {
823  int val = c->constraint.m_Value.Min();
824  REPORT( wxString::Format( _( "Checking %s; clearance: %s." ),
825  EscapeHTML( c->constraint.GetName() ),
826  EscapeHTML( MessageTextFromValue( UNITS, val ) ) ) )
827  }
828  else if( aConstraintId == COURTYARD_CLEARANCE_CONSTRAINT )
829  {
830  int val = c->constraint.m_Value.Min();
831  REPORT( wxString::Format( _( "Checking %s; courtyard clearance: %s." ),
832  EscapeHTML( c->constraint.GetName() ),
833  EscapeHTML( MessageTextFromValue( UNITS, val ) ) ) )
834  }
835  else if( aConstraintId == SILK_CLEARANCE_CONSTRAINT )
836  {
837  int val = c->constraint.m_Value.Min();
838  REPORT( wxString::Format( _( "Checking %s; silk clearance: %s." ),
839  EscapeHTML( c->constraint.GetName() ),
840  EscapeHTML( MessageTextFromValue( UNITS, val ) ) ) )
841  }
842  else if( aConstraintId == HOLE_CLEARANCE_CONSTRAINT )
843  {
844  int val = c->constraint.m_Value.Min();
845  REPORT( wxString::Format( _( "Checking %s; hole clearance: %s." ),
846  EscapeHTML( c->constraint.GetName() ),
847  EscapeHTML( MessageTextFromValue( UNITS, val ) ) ) )
848  }
849  else if( aConstraintId == EDGE_CLEARANCE_CONSTRAINT )
850  {
851  int val = c->constraint.m_Value.Min();
852  REPORT( wxString::Format( _( "Checking %s; edge clearance: %s." ),
853  EscapeHTML( c->constraint.GetName() ),
854  EscapeHTML( MessageTextFromValue( UNITS, val ) ) ) )
855  }
856  else
857  {
858  REPORT( wxString::Format( _( "Checking %s." ), c->constraint.GetName() ) )
859  }
860 
861  if( aConstraintId == CLEARANCE_CONSTRAINT )
862  {
863  if( implicit && ( a_is_non_copper || b_is_non_copper ) )
864  {
865  REPORT( _( "Board and netclass clearances apply only between copper "
866  "items." ) );
867  return true;
868  }
869  }
870  else if( aConstraintId == DISALLOW_CONSTRAINT )
871  {
872  int mask;
873 
874  if( a->GetFlags() & HOLE_PROXY )
875  {
876  mask = DRC_DISALLOW_HOLES;
877  }
878  else if( a->Type() == PCB_VIA_T )
879  {
880  if( static_cast<const VIA*>( a )->GetViaType() == VIATYPE::BLIND_BURIED )
882  else if( static_cast<const VIA*>( a )->GetViaType() == VIATYPE::MICROVIA )
884  else
885  mask = DRC_DISALLOW_VIAS;
886  }
887  else
888  {
889  switch( a->Type() )
890  {
891  case PCB_TRACE_T: mask = DRC_DISALLOW_TRACKS; break;
892  case PCB_ARC_T: mask = DRC_DISALLOW_TRACKS; break;
893  case PCB_PAD_T: mask = DRC_DISALLOW_PADS; break;
894  case PCB_FOOTPRINT_T: mask = DRC_DISALLOW_FOOTPRINTS; break;
895  case PCB_SHAPE_T: mask = DRC_DISALLOW_GRAPHICS; break;
896  case PCB_FP_SHAPE_T: mask = DRC_DISALLOW_GRAPHICS; break;
897  case PCB_TEXT_T: mask = DRC_DISALLOW_TEXTS; break;
898  case PCB_FP_TEXT_T: mask = DRC_DISALLOW_TEXTS; break;
899  case PCB_ZONE_T: mask = DRC_DISALLOW_ZONES; break;
900  case PCB_FP_ZONE_T: mask = DRC_DISALLOW_ZONES; break;
901  case PCB_LOCATE_HOLE_T: mask = DRC_DISALLOW_HOLES; break;
902  default: mask = 0; break;
903  }
904  }
905 
906  if( ( c->constraint.m_DisallowFlags & mask ) == 0 )
907  {
908  if( implicit )
909  REPORT( _( "Keepout constraint not met." ) )
910  else
911  REPORT( _( "Disallow constraint not met." ) )
912 
913  return false;
914  }
915 
916  LSET itemLayers = a->GetLayerSet();
917 
918  if( a->Type() == PCB_FOOTPRINT_T )
919  {
920  const FOOTPRINT* footprint = static_cast<const FOOTPRINT*>( a );
921 
922  if( !footprint->GetPolyCourtyardFront().IsEmpty() )
923  itemLayers |= LSET::FrontMask();
924 
925  if( !footprint->GetPolyCourtyardBack().IsEmpty() )
926  itemLayers |= LSET::BackMask();
927  }
928 
929  if( !( c->layerTest & itemLayers ).any() )
930  {
931  if( implicit )
932  {
933  REPORT( _( "Keepout layer(s) not matched." ) )
934  }
935  else if( c->parentRule )
936  {
937  REPORT( wxString::Format( _( "Rule layer '%s' not matched; rule "
938  "ignored." ),
939  EscapeHTML( c->parentRule->m_LayerSource ) ) )
940  }
941  else
942  {
943  REPORT( _( "Rule layer not matched; rule ignored." ) )
944  }
945 
946  return false;
947  }
948  }
949 
950  if( aLayer != UNDEFINED_LAYER && !c->layerTest.test( aLayer ) )
951  {
952  if( implicit )
953  {
954  REPORT( "Constraint layer not matched." )
955  }
956  else if( c->parentRule )
957  {
958  REPORT( wxString::Format( _( "Rule layer '%s' not matched; rule ignored." ),
959  EscapeHTML( c->parentRule->m_LayerSource ) ) )
960  }
961  else
962  {
963  REPORT( _( "Rule layer not matched; rule ignored." ) )
964  }
965 
966  return false;
967  }
968 
969  if( !c->condition || c->condition->GetExpression().IsEmpty() )
970  {
971  REPORT( implicit ? _( "Unconditional constraint applied." )
972  : _( "Unconditional rule applied." ) );
973 
974  constraintRef = &c->constraint;
975  return true;
976  }
977  else
978  {
979  if( implicit )
980  {
981  // Don't report on implicit rule conditions; they're synthetic.
982  }
983  else
984  {
985  REPORT( wxString::Format( _( "Checking rule condition \"%s\"." ),
986  EscapeHTML( c->condition->GetExpression() ) ) )
987  }
988 
989  if( c->condition->EvaluateFor( a, b, aLayer, aReporter ) )
990  {
991  REPORT( implicit ? _( "Constraint applied." )
992  : _( "Rule applied; overrides previous constraints." ) )
993 
994  constraintRef = &c->constraint;
995  return true;
996  }
997  else
998  {
999  REPORT( implicit ? _( "Membership not satisfied; constraint ignored." )
1000  : _( "Condition not satisfied; rule ignored." ) )
1001 
1002  return false;
1003  }
1004  }
1005  };
1006 
1007  if( m_constraintMap.count( aConstraintId ) )
1008  {
1009  std::vector<DRC_ENGINE_CONSTRAINT*>* ruleset = m_constraintMap[ aConstraintId ];
1010 
1011  if( aReporter )
1012  {
1013  // We want to see all results so process in "natural" order
1014  for( int ii = 0; ii < (int) ruleset->size(); ++ii )
1015  {
1016  processConstraint( ruleset->at( ii ) );
1017  }
1018  }
1019  else
1020  {
1021  // Last matching rule wins, so process in reverse order and quit when match found
1022  for( int ii = (int) ruleset->size() - 1; ii >= 0; --ii )
1023  {
1024  if( processConstraint( ruleset->at( ii ) ) )
1025  break;
1026  }
1027  }
1028  }
1029 
1030  bool explicitConstraintFound = constraintRef && !implicit;
1031 
1032  // Unfortunately implicit rules don't work for local clearances (such as zones) because
1033  // they have to be max'ed with netclass values (which are already implicit rules), and our
1034  // rule selection paradigm is "winner takes all".
1035  if( aConstraintId == CLEARANCE_CONSTRAINT && !explicitConstraintFound )
1036  {
1037  int global = constraintRef ? constraintRef->m_Value.Min() : 0;
1038  int localA = ac ? ac->GetLocalClearance( nullptr ) : 0;
1039  int localB = bc ? bc->GetLocalClearance( nullptr ) : 0;
1040  int clearance = global;
1041 
1042  if( localA > 0 )
1043  {
1044  REPORT( "" )
1045  REPORT( wxString::Format( _( "Local clearance on %s; clearance: %s." ),
1046  EscapeHTML( a->GetSelectMenuText( UNITS ) ),
1047  EscapeHTML( MessageTextFromValue( UNITS, localA ) ) ) )
1048 
1049  if( localA > clearance )
1050  clearance = ac->GetLocalClearance( &m_msg );
1051  }
1052 
1053  if( localB > 0 )
1054  {
1055  REPORT( "" )
1056  REPORT( wxString::Format( _( "Local clearance on %s; clearance: %s." ),
1057  EscapeHTML( b->GetSelectMenuText( UNITS ) ),
1058  EscapeHTML( MessageTextFromValue( UNITS, localB ) ) ) )
1059 
1060  if( localB > clearance )
1061  clearance = bc->GetLocalClearance( &m_msg );
1062  }
1063 
1064  if( localA > global || localB > global )
1065  {
1066  DRC_CONSTRAINT constraint( CLEARANCE_CONSTRAINT, m_msg );
1067  constraint.m_Value.SetMin( clearance );
1068  return constraint;
1069  }
1070  }
1071 
1072  static DRC_CONSTRAINT nullConstraint( NULL_CONSTRAINT );
1073  nullConstraint.m_DisallowFlags = 0;
1074 
1075  return constraintRef ? *constraintRef : nullConstraint;
1076 
1077 #undef REPORT
1078 #undef UNITS
1079 }
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aAddUnitLabel, EDA_DATA_TYPE aType)
Convert a value to a string using double notation.
Definition: base_units.cpp:125
#define UNITS
const SHAPE_POLY_SET & GetPolyCourtyardFront() const
Used in DRC to test the courtyard area (a complex polygon).
Definition: footprint.h:657
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
bool IsEmpty() const
class PCB_TEXT, text on a layer
Definition: typeinfo.h:91
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:97
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:93
class PAD, a pad in a footprint
Definition: typeinfo.h:89
virtual int GetLocalClearanceOverrides(wxString *aSource) const
Return any local clearance overrides set in the "classic" (ie: pre-rule) system.
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
static LSET FrontMask()
Return a mask holding all technical layers and the external CU layer on front side.
Definition: lset.cpp:874
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
LSET is a set of PCB_LAYER_IDs.
std::unordered_map< DRC_CONSTRAINT_T, std::vector< DRC_ENGINE_CONSTRAINT * > * > m_constraintMap
Definition: drc_engine.h:226
const SHAPE_POLY_SET & GetPolyCourtyardBack() const
Definition: footprint.h:658
class ZONE, a copper pour area
Definition: typeinfo.h:105
static bool isKeepoutZone(const BOARD_ITEM *aItem, bool aCheckFlags)
Definition: drc_engine.cpp:90
class FOOTPRINT, a footprint
Definition: typeinfo.h:88
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
#define HOLE_PROXY
Indicates the BOARD_ITEM is a proxy for its hole.
Definition: eda_item.h:129
#define _(s)
Definition: 3d_actions.cpp:33
class ZONE, managed by a footprint
Definition: typeinfo.h:94
wxString m_msg
Definition: drc_engine.h:232
static LSET BackMask()
Return a mask holding all technical layers and the external CU layer on back side.
Definition: lset.cpp:881
virtual bool IsConnected() const
Returns information if the object is derived from BOARD_CONNECTED_ITEM.
Definition: board_item.h:136
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
wxString EscapeHTML(const wxString &aString)
Return a new wxString escaped for embedding in HTML.
Definition: string.cpp:365
STATUS_FLAGS GetFlags() const
Definition: eda_item.h:205
virtual int GetLocalClearance(wxString *aSource) const
Return any local clearances set in the "classic" (ie: pre-rule) system.
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:90
virtual bool IsOnCopperLayer() const
Definition: board_item.h:144
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163

References _, LSET::BackMask(), BLIND_BURIED, CLEARANCE_CONSTRAINT, COURTYARD_CLEARANCE_CONSTRAINT, DISALLOW_CONSTRAINT, DRC_DISALLOW_BB_VIAS, DRC_DISALLOW_FOOTPRINTS, DRC_DISALLOW_GRAPHICS, DRC_DISALLOW_HOLES, DRC_DISALLOW_MICRO_VIAS, DRC_DISALLOW_PADS, DRC_DISALLOW_TEXTS, DRC_DISALLOW_TRACKS, DRC_DISALLOW_VIAS, DRC_DISALLOW_ZONES, EDGE_CLEARANCE_CONSTRAINT, EscapeHTML(), Format(), LSET::FrontMask(), EDA_ITEM::GetFlags(), BOARD_ITEM::GetLayerSet(), BOARD_CONNECTED_ITEM::GetLocalClearance(), BOARD_CONNECTED_ITEM::GetLocalClearanceOverrides(), FOOTPRINT::GetPolyCourtyardBack(), FOOTPRINT::GetPolyCourtyardFront(), EDA_ITEM::GetSelectMenuText(), HOLE_CLEARANCE_CONSTRAINT, HOLE_PROXY, BOARD_ITEM::IsConnected(), SHAPE_POLY_SET::IsEmpty(), isKeepoutZone(), BOARD_ITEM::IsOnCopperLayer(), m_constraintMap, DRC_CONSTRAINT::m_DisallowFlags, m_msg, DRC_CONSTRAINT::m_Value, MessageTextFromValue(), MICROVIA, NULL_CONSTRAINT, PCB_ARC_T, PCB_FOOTPRINT_T, PCB_FP_SHAPE_T, PCB_FP_TEXT_T, PCB_FP_ZONE_T, PCB_LOCATE_HOLE_T, PCB_PAD_T, PCB_SHAPE_T, PCB_TEXT_T, PCB_TRACE_T, PCB_VIA_T, PCB_ZONE_T, REPORT, MINOPTMAX< T >::SetMin(), SILK_CLEARANCE_CONSTRAINT, EDA_ITEM::Type(), UNDEFINED_LAYER, and UNITS.

Referenced by DRC_TEST_PROVIDER_HOLE_SIZE::checkPad(), DRC_TEST_PROVIDER_HOLE_SIZE::checkVia(), DRC_TEST_PROVIDER_DISALLOW::Run(), DRC_TEST_PROVIDER_VIA_DIAMETER::Run(), DRC_TEST_PROVIDER_TRACK_WIDTH::Run(), DRC_TEST_PROVIDER_ANNULUS::Run(), DRC_TEST_PROVIDER_SILK_TO_MASK::Run(), DRC_TEST_PROVIDER_SILK_CLEARANCE::Run(), test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run(), DRC_TEST_PROVIDER_MATCHED_LENGTH::runInternal(), DRC_TEST_PROVIDER_EDGE_CLEARANCE::testAgainstEdge(), DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances(), DRC_TEST_PROVIDER_HOLE_CLEARANCE::testHoleAgainstHole(), DRC_TEST_PROVIDER_COPPER_CLEARANCE::testItemAgainstZones(), DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem(), DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem(), and DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZones().

◆ GetBoard()

◆ GetDebugOverlay()

std::shared_ptr<KIGFX::VIEW_OVERLAY> DRC_ENGINE::GetDebugOverlay ( ) const
inline

Definition at line 99 of file drc_engine.h.

99 { return m_debugOverlay; }
std::shared_ptr< KIGFX::VIEW_OVERLAY > m_debugOverlay
Definition: drc_engine.h:233

References m_debugOverlay.

Referenced by test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run().

◆ GetDesignSettings()

BOARD_DESIGN_SETTINGS* DRC_ENGINE::GetDesignSettings ( ) const
inline

Definition at line 90 of file drc_engine.h.

90 { return m_designSettings; }
BOARD_DESIGN_SETTINGS * m_designSettings
Definition: drc_engine.h:211

References m_designSettings.

◆ GetDrawingSheet()

DS_PROXY_VIEW_ITEM* DRC_ENGINE::GetDrawingSheet ( ) const
inline

Definition at line 96 of file drc_engine.h.

96 { return m_drawingSheet; }
DS_PROXY_VIEW_ITEM * m_drawingSheet
Definition: drc_engine.h:213

References m_drawingSheet.

Referenced by DRC_TEST_PROVIDER_MISC::testTextVars().

◆ GetProgressReporter()

PROGRESS_REPORTER* DRC_ENGINE::GetProgressReporter ( ) const
inline

Definition at line 119 of file drc_engine.h.

119 { return m_progressReporter; }
PROGRESS_REPORTER * m_progressReporter
Definition: drc_engine.h:230

References m_progressReporter.

Referenced by DRC_TEST_PROVIDER_CONNECTIVITY::Run().

◆ GetReportAllTrackErrors()

bool DRC_ENGINE::GetReportAllTrackErrors ( ) const
inline

Definition at line 152 of file drc_engine.h.

152 { return m_reportAllTrackErrors; }
bool m_reportAllTrackErrors
Definition: drc_engine.h:222

References m_reportAllTrackErrors.

Referenced by DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem().

◆ GetSchematicNetlist()

NETLIST* DRC_ENGINE::GetSchematicNetlist ( ) const
inline

Definition at line 93 of file drc_engine.h.

93 { return m_schematicNetlist; }
NETLIST * m_schematicNetlist
Definition: drc_engine.h:214

References m_schematicNetlist.

Referenced by DRC_TEST_PROVIDER_LVS::Run().

◆ GetShape()

std::shared_ptr< SHAPE > DRC_ENGINE::GetShape ( BOARD_ITEM aItem,
PCB_LAYER_ID  aLayer 
)
static

Definition at line 1269 of file drc_engine.cpp.

1270 {
1271  if( aItem->Type() == PCB_PAD_T && !static_cast<PAD*>( aItem )->FlashLayer( aLayer ) )
1272  {
1273  PAD* aPad = static_cast<PAD*>( aItem );
1274 
1275  if( aPad->GetAttribute() == PAD_ATTRIB_PTH )
1276  {
1278 
1279  // Note: drill size represents finish size, which means the actual holes size is the
1280  // plating thickness larger.
1281  auto hole = static_cast<SHAPE_SEGMENT*>( aPad->GetEffectiveHoleShape()->Clone() );
1282  hole->SetWidth( hole->GetWidth() + bds.GetHolePlatingThickness() );
1283  return std::make_shared<SHAPE_SEGMENT>( *hole );
1284  }
1285 
1286  return std::make_shared<SHAPE_NULL>();
1287  }
1288 
1289  return aItem->GetEffectiveShape( aLayer );
1290 }
int GetHolePlatingThickness() const
Pad & via drills are finish size.
const SHAPE_SEGMENT * GetEffectiveHoleShape() const
Return a SHAPE object representing the pad's hole.
Definition: pad.cpp:286
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:593
class PAD, a pad in a footprint
Definition: typeinfo.h:89
PAD_ATTR_T GetAttribute() const
Definition: pad.h:363
virtual BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:46
SHAPE * Clone() const override
Return a dynamically allocated copy of the shape.
Definition: shape_segment.h:57
Plated through hole pad.
Definition: pad_shapes.h:80
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER) const
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
Definition: board_item.cpp:153
Definition: pad.h:60
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163
Container for design settings for a BOARD object.

References SHAPE_SEGMENT::Clone(), PAD::GetAttribute(), BOARD_ITEM::GetBoard(), BOARD::GetDesignSettings(), PAD::GetEffectiveHoleShape(), BOARD_ITEM::GetEffectiveShape(), BOARD_DESIGN_SETTINGS::GetHolePlatingThickness(), PAD_ATTRIB_PTH, PCB_PAD_T, and EDA_ITEM::Type().

Referenced by DRAWING_TOOL::DrawVia(), DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem(), DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadClearances(), and DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem().

◆ GetTestFootprints()

bool DRC_ENGINE::GetTestFootprints ( ) const
inline

Definition at line 153 of file drc_engine.h.

153 { return m_testFootprints; }
bool m_testFootprints
Definition: drc_engine.h:223

References m_testFootprints.

Referenced by DRC_TEST_PROVIDER_LVS::GetNumPhases(), and DRC_TEST_PROVIDER_LVS::Run().

◆ GetTestProvider()

DRC_TEST_PROVIDER * DRC_ENGINE::GetTestProvider ( const wxString &  name) const

Definition at line 1302 of file drc_engine.cpp.

1303 {
1304  for( auto prov : m_testProviders )
1305  if( name == prov->GetName() )
1306  return prov;
1307 
1308  return nullptr;
1309 }
std::vector< DRC_TEST_PROVIDER * > m_testProviders
Definition: drc_engine.h:218
const char * name
Definition: DXF_plotter.cpp:59

References m_testProviders, and name.

◆ GetTestProviders()

std::vector<DRC_TEST_PROVIDER* > DRC_ENGINE::GetTestProviders ( ) const
inline

Definition at line 164 of file drc_engine.h.

164 { return m_testProviders; };
std::vector< DRC_TEST_PROVIDER * > m_testProviders
Definition: drc_engine.h:218

References m_testProviders.

◆ HasRulesForConstraintType()

bool DRC_ENGINE::HasRulesForConstraintType ( DRC_CONSTRAINT_T  constraintID)

Definition at line 1147 of file drc_engine.cpp.

1148 {
1149  //drc_dbg(10,"hascorrect id %d size %d\n", ruleID, m_ruleMap[ruleID]->sortedRules.size( ) );
1150  if( m_constraintMap.count( constraintID ) )
1151  return m_constraintMap[ constraintID ]->size() > 0;
1152 
1153  return false;
1154 }
std::unordered_map< DRC_CONSTRAINT_T, std::vector< DRC_ENGINE_CONSTRAINT * > * > m_constraintMap
Definition: drc_engine.h:226

References m_constraintMap.

Referenced by DRC_TEST_PROVIDER_DISALLOW::Run(), DRC_TEST_PROVIDER_VIA_DIAMETER::Run(), DRC_TEST_PROVIDER_TRACK_WIDTH::Run(), and DRC_TEST_PROVIDER_ANNULUS::Run().

◆ InitEngine()

void DRC_ENGINE::InitEngine ( const wxFileName &  aRulePath)

Initializes the DRC engine.

Exceptions
PARSE_ERRORif the rules file contains errors
PARSE_ERROR

Definition at line 618 of file drc_engine.cpp.

619 {
621 
622  for( DRC_TEST_PROVIDER* provider : m_testProviders )
623  {
624  ReportAux( wxString::Format( "Create DRC provider: '%s'", provider->GetName() ) );
625  provider->SetDRCEngine( this );
626  }
627 
628  for( DRC_RULE* rule : m_rules )
629  delete rule;
630 
631  m_rules.clear();
632  m_rulesValid = false;
633 
634  for( std::pair<DRC_CONSTRAINT_T, std::vector<DRC_ENGINE_CONSTRAINT*>*> pair : m_constraintMap )
635  {
636  for( DRC_ENGINE_CONSTRAINT* constraint : *pair.second )
637  delete constraint;
638 
639  delete pair.second;
640  }
641 
642  m_constraintMap.clear();
643 
644  m_board->IncrementTimeStamp(); // Clear board-level caches
645 
646  try // attempt to load full set of rules (implicit + user rules)
647  {
649  loadRules( aRulePath );
650  compileRules();
651  }
652  catch( PARSE_ERROR& original_parse_error )
653  {
654  try // try again with just our implicit rules
655  {
657  compileRules();
658  }
659  catch( PARSE_ERROR& )
660  {
661  wxFAIL_MSG( "Compiling implict rules failed." );
662  }
663 
664  throw original_parse_error;
665  }
666 
667  for( int ii = DRCE_FIRST; ii < DRCE_LAST; ++ii )
668  m_errorLimits[ ii ] = INT_MAX;
669 
670  m_rulesValid = true;
671 }
void loadRules(const wxFileName &aPath)
Loads and parses a rule set from an sexpr text file.
Definition: drc_engine.cpp:519
std::vector< int > m_errorLimits
Definition: drc_engine.h:221
std::vector< DRC_TEST_PROVIDER * > m_testProviders
Definition: drc_engine.h:218
std::vector< DRC_TEST_PROVIDER * > GetTestProviders() const
static DRC_TEST_PROVIDER_REGISTRY & Instance()
void compileRules()
Definition: drc_engine.cpp:542
bool m_rulesValid
Definition: drc_engine.h:217
DRC_CONSTRAINT_T
Definition: drc_rule.h:41
std::vector< DRC_RULE * > m_rules
Definition: drc_engine.h:216
std::unordered_map< DRC_CONSTRAINT_T, std::vector< DRC_ENGINE_CONSTRAINT * > * > m_constraintMap
Definition: drc_engine.h:226
void IncrementTimeStamp()
Definition: board.h:271
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
DRC_TEST_PROVIDER is a base class that represents a DRC "provider" which runs some DRC functions over...
A filename or source description, a problem input line, a line number, a byte offset,...
Definition: ki_exception.h:118
void ReportAux(const wxString &aStr)
BOARD * m_board
Definition: drc_engine.h:212
void loadImplicitRules()
Definition: drc_engine.cpp:132

References compileRules(), DRCE_FIRST, DRCE_LAST, Format(), DRC_TEST_PROVIDER_REGISTRY::GetTestProviders(), BOARD::IncrementTimeStamp(), DRC_TEST_PROVIDER_REGISTRY::Instance(), loadImplicitRules(), loadRules(), m_board, m_constraintMap, m_errorLimits, m_rules, m_rulesValid, m_testProviders, and ReportAux().

Referenced by DoCourtyardInvalidTest(), DoCourtyardOverlapTest(), BOARD_INSPECTION_TOOL::InspectConstraints(), and BOARD_INSPECTION_TOOL::reportClearance().

◆ IsErrorLimitExceeded()

◆ IsNetADiffPair()

bool DRC_ENGINE::IsNetADiffPair ( BOARD aBoard,
NETINFO_ITEM aNet,
int &  aNetP,
int &  aNetN 
)
static

Definition at line 1239 of file drc_engine.cpp.

1240 {
1241  wxString refName = aNet->GetNetname();
1242  wxString dummy, coupledNetName;
1243 
1244  if( int polarity = MatchDpSuffix( refName, coupledNetName, dummy ) )
1245  {
1246  NETINFO_ITEM* net = aBoard->FindNet( coupledNetName );
1247 
1248  if( !net )
1249  return false;
1250 
1251  if( polarity > 0 )
1252  {
1253  aNetP = aNet->GetNetCode();
1254  aNetN = net->GetNetCode();
1255  }
1256  else
1257  {
1258  aNetP = net->GetNetCode();
1259  aNetN = aNet->GetNetCode();
1260  }
1261 
1262  return true;
1263  }
1264 
1265  return false;
1266 }
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition: board.cpp:1268
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
Definition: sch_symbol.cpp:69
static int MatchDpSuffix(const wxString &aNetName, wxString &aComplementNet, wxString &aBaseDpName)
Checks if the given net is a diff pair, returning its polarity and complement if so.
const wxString & GetNetname() const
Definition: netinfo.h:119
Handle the data for a net.
Definition: netinfo.h:64
int GetNetCode() const
Definition: netinfo.h:113

References dummy(), BOARD::FindNet(), NETINFO_ITEM::GetNetCode(), NETINFO_ITEM::GetNetname(), and MatchDpSuffix().

Referenced by test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run().

◆ IsNetTie()

bool DRC_ENGINE::IsNetTie ( BOARD_ITEM aItem)
static

Definition at line 1293 of file drc_engine.cpp.

1294 {
1295  if( aItem->GetParent() && aItem->GetParent()->Type() == PCB_FOOTPRINT_T )
1296  return static_cast<FOOTPRINT*>( aItem->GetParent() )->IsNetTie();
1297 
1298  return false;
1299 }
static bool IsNetTie(BOARD_ITEM *aItem)
class FOOTPRINT, a footprint
Definition: typeinfo.h:88
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:168
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163

References BOARD_ITEM::GetParent(), PCB_FOOTPRINT_T, and EDA_ITEM::Type().

Referenced by DRAWING_TOOL::DrawVia(), and DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances().

◆ loadImplicitRules()

void DRC_ENGINE::loadImplicitRules ( )
private

Definition at line 132 of file drc_engine.cpp.

133 {
134  ReportAux( wxString::Format( "Building implicit rules (per-item/class overrides, etc...)" ) );
135 
137 
138  // 1) global defaults
139 
140  DRC_RULE* rule = createImplicitRule( _( "board setup constraints" ) );
141 
142  DRC_CONSTRAINT clearanceConstraint( CLEARANCE_CONSTRAINT );
143  clearanceConstraint.Value().SetMin( bds.m_MinClearance );
144  rule->AddConstraint( clearanceConstraint );
145 
146  DRC_CONSTRAINT widthConstraint( TRACK_WIDTH_CONSTRAINT );
147  widthConstraint.Value().SetMin( bds.m_TrackMinWidth );
148  rule->AddConstraint( widthConstraint );
149 
150  DRC_CONSTRAINT drillConstraint( HOLE_SIZE_CONSTRAINT );
151  drillConstraint.Value().SetMin( bds.m_MinThroughDrill );
152  rule->AddConstraint( drillConstraint );
153 
154  DRC_CONSTRAINT annulusConstraint( ANNULAR_WIDTH_CONSTRAINT );
155  annulusConstraint.Value().SetMin( bds.m_ViasMinAnnulus );
156  rule->AddConstraint( annulusConstraint );
157 
158  DRC_CONSTRAINT diameterConstraint( VIA_DIAMETER_CONSTRAINT );
159  diameterConstraint.Value().SetMin( bds.m_ViasMinSize );
160  rule->AddConstraint( diameterConstraint );
161 
162  DRC_CONSTRAINT edgeClearanceConstraint( EDGE_CLEARANCE_CONSTRAINT );
163  edgeClearanceConstraint.Value().SetMin( bds.m_CopperEdgeClearance );
164  rule->AddConstraint( edgeClearanceConstraint );
165 
166  DRC_CONSTRAINT holeClearanceConstraint( HOLE_CLEARANCE_CONSTRAINT );
167  holeClearanceConstraint.Value().SetMin( bds.m_HoleClearance );
168  rule->AddConstraint( holeClearanceConstraint );
169 
170  DRC_CONSTRAINT holeToHoleConstraint( HOLE_TO_HOLE_CONSTRAINT );
171  holeToHoleConstraint.Value().SetMin( bds.m_HoleToHoleMin );
172  rule->AddConstraint( holeToHoleConstraint );
173 
174  DRC_CONSTRAINT courtyardClearanceConstraint( COURTYARD_CLEARANCE_CONSTRAINT );
175  holeToHoleConstraint.Value().SetMin( 0 );
176  rule->AddConstraint( courtyardClearanceConstraint );
177 
178  DRC_CONSTRAINT diffPairGapConstraint( DIFF_PAIR_GAP_CONSTRAINT );
179  diffPairGapConstraint.Value().SetMin( bds.GetDefault()->GetClearance() );
180  rule->AddConstraint( diffPairGapConstraint );
181 
182  rule = createImplicitRule( _( "board setup constraints" ) );
183  rule->m_LayerCondition = LSET( 2, F_SilkS, B_SilkS );
184  DRC_CONSTRAINT silkClearanceConstraint( SILK_CLEARANCE_CONSTRAINT );
185  silkClearanceConstraint.Value().SetMin( bds.m_SilkClearance );
186  rule->AddConstraint( silkClearanceConstraint );
187 
188 
189  // 2) micro-via specific defaults (new DRC doesn't treat microvias in any special way)
190 
191  DRC_RULE* uViaRule = createImplicitRule( _( "board setup micro-via constraints" ) );
192 
193  uViaRule->m_Condition = new DRC_RULE_CONDITION( "A.Via_Type == 'Micro'" );
194 
195  DRC_CONSTRAINT uViaDrillConstraint( HOLE_SIZE_CONSTRAINT );
196  uViaDrillConstraint.Value().SetMin( bds.m_MicroViasMinDrill );
197  uViaRule->AddConstraint( uViaDrillConstraint );
198 
199  DRC_CONSTRAINT uViaDiameterConstraint( VIA_DIAMETER_CONSTRAINT );
200  uViaDiameterConstraint.Value().SetMin( bds.m_MicroViasMinSize );
201  uViaRule->AddConstraint( uViaDiameterConstraint );
202 
203  if( !bds.m_MicroViasAllowed )
204  {
205  DRC_CONSTRAINT disallowConstraint( DISALLOW_CONSTRAINT );
206  disallowConstraint.m_DisallowFlags = DRC_DISALLOW_MICRO_VIAS;
207  uViaRule->AddConstraint( disallowConstraint );
208  }
209 
210  if( !bds.m_BlindBuriedViaAllowed )
211  {
212  DRC_RULE* bbViaRule = createImplicitRule( _( "board setup constraints" ) );
213 
214  bbViaRule->m_Condition = new DRC_RULE_CONDITION( "A.Via_Type == 'Blind/buried'" );
215 
216  DRC_CONSTRAINT disallowConstraint( DISALLOW_CONSTRAINT );
217  disallowConstraint.m_DisallowFlags = DRC_DISALLOW_BB_VIAS;
218  bbViaRule->AddConstraint( disallowConstraint );
219  }
220 
221  // 3) per-netclass rules
222 
223  std::vector<DRC_RULE*> netclassClearanceRules;
224  std::vector<DRC_RULE*> netclassItemSpecificRules;
225 
226  auto makeNetclassRules =
227  [&]( const NETCLASSPTR& nc, bool isDefault )
228  {
229  wxString ncName = nc->GetName();
230 
231  DRC_RULE* netclassRule;
232  wxString expr;
233 
234  if( nc->GetClearance() || nc->GetTrackWidth() )
235  {
236  netclassRule = new DRC_RULE;
237  netclassRule->m_Name = wxString::Format( _( "netclass '%s'" ), ncName );
238  netclassRule->m_Implicit = true;
239 
240  expr = wxString::Format( "A.NetClass == '%s'",
241  ncName );
242  netclassRule->m_Condition = new DRC_RULE_CONDITION( expr );
243  netclassClearanceRules.push_back( netclassRule );
244 
245  if( nc->GetClearance() )
246  {
247  DRC_CONSTRAINT constraint( CLEARANCE_CONSTRAINT );
248  constraint.Value().SetMin( std::max( bds.m_MinClearance,
249  nc->GetClearance() ) );
250  netclassRule->AddConstraint( constraint );
251  }
252 
253  if( nc->GetTrackWidth() )
254  {
256  constraint.Value().SetMin( bds.m_TrackMinWidth );
257  constraint.Value().SetOpt( nc->GetTrackWidth() );
258  netclassRule->AddConstraint( constraint );
259  }
260  }
261 
262  if( nc->GetDiffPairWidth() || nc->GetDiffPairGap() )
263  {
264  netclassRule = new DRC_RULE;
265  netclassRule->m_Name = wxString::Format( _( "netclass '%s' (diff pair)" ),
266  ncName );
267  netclassRule->m_Implicit = true;
268 
269  expr = wxString::Format( "A.NetClass == '%s' && A.inDiffPair('*')",
270  ncName );
271  netclassRule->m_Condition = new DRC_RULE_CONDITION( expr );
272  netclassItemSpecificRules.push_back( netclassRule );
273 
274  if( nc->GetDiffPairWidth() )
275  {
277  constraint.Value().SetMin( bds.m_TrackMinWidth );
278  constraint.Value().SetOpt( nc->GetDiffPairWidth() );
279  netclassRule->AddConstraint( constraint );
280  }
281 
282  if( nc->GetDiffPairGap() )
283  {
285  constraint.Value().SetMin( bds.m_MinClearance );
286  constraint.Value().SetOpt( nc->GetDiffPairGap() );
287  netclassRule->AddConstraint( constraint );
288  }
289  }
290 
291  if( nc->GetDiffPairGap() )
292  {
293  netclassRule = new DRC_RULE;
294  netclassRule->m_Name = wxString::Format( _( "netclass '%s' (diff pair)" ),
295  ncName );
296  netclassRule->m_Implicit = true;
297 
298  expr = wxString::Format( "A.NetClass == '%s' && AB.isCoupledDiffPair()",
299  ncName );
300  netclassRule->m_Condition = new DRC_RULE_CONDITION( expr );
301  netclassItemSpecificRules.push_back( netclassRule );
302 
303  DRC_CONSTRAINT constraint( CLEARANCE_CONSTRAINT );
304  constraint.Value().SetMin( std::max( bds.m_MinClearance,
305  nc->GetDiffPairGap() ) );
306  netclassRule->AddConstraint( constraint );
307  }
308 
309  if( nc->GetViaDiameter() || nc->GetViaDrill() )
310  {
311  netclassRule = new DRC_RULE;
312  netclassRule->m_Name = wxString::Format( _( "netclass '%s'" ), ncName );
313  netclassRule->m_Implicit = true;
314 
315  expr = wxString::Format( "A.NetClass == '%s' && A.Via_Type != 'Micro'",
316  ncName );
317  netclassRule->m_Condition = new DRC_RULE_CONDITION( expr );
318  netclassItemSpecificRules.push_back( netclassRule );
319 
320  if( nc->GetViaDiameter() )
321  {
323  constraint.Value().SetMin( bds.m_ViasMinSize );
324  constraint.Value().SetOpt( nc->GetViaDiameter() );
325  netclassRule->AddConstraint( constraint );
326  }
327 
328  if( nc->GetViaDrill() )
329  {
330  DRC_CONSTRAINT constraint( HOLE_SIZE_CONSTRAINT );
331  constraint.Value().SetMin( bds.m_MinThroughDrill );
332  constraint.Value().SetOpt( nc->GetViaDrill() );
333  netclassRule->AddConstraint( constraint );
334  }
335  }
336 
337  if( nc->GetuViaDiameter() || nc->GetuViaDrill() )
338  {
339  netclassRule = new DRC_RULE;
340  netclassRule->m_Name = wxString::Format( _( "netclass '%s'" ), ncName );
341  netclassRule->m_Implicit = true;
342 
343  expr = wxString::Format( "A.NetClass == '%s' && A.Via_Type == 'Micro'",
344  ncName );
345  netclassRule->m_Condition = new DRC_RULE_CONDITION( expr );
346  netclassItemSpecificRules.push_back( netclassRule );
347 
348  if( nc->GetuViaDiameter() )
349  {
351  constraint.Value().SetMin( bds.m_MicroViasMinSize );
352  constraint.Value().SetMin( nc->GetuViaDiameter() );
353  netclassRule->AddConstraint( constraint );
354  }
355 
356  if( nc->GetuViaDrill() )
357  {
358  DRC_CONSTRAINT constraint( HOLE_SIZE_CONSTRAINT );
359  constraint.Value().SetMin( bds.m_MicroViasMinDrill );
360  constraint.Value().SetOpt( nc->GetuViaDrill() );
361  netclassRule->AddConstraint( constraint );
362  }
363  }
364  };
365 
367  makeNetclassRules( bds.GetNetClasses().GetDefault(), true );
368 
369  for( const std::pair<const wxString, NETCLASSPTR>& netclass : bds.GetNetClasses() )
370  makeNetclassRules( netclass.second, false );
371 
372  // The netclass clearance rules have to be sorted by min clearance so the right one fires
373  // if 'A' and 'B' belong to two different netclasses.
374  //
375  // The item-specific netclass rules are all unary, so there's no 'A' vs 'B' issue.
376 
377  std::sort( netclassClearanceRules.begin(), netclassClearanceRules.end(),
378  []( DRC_RULE* lhs, DRC_RULE* rhs )
379  {
380  return lhs->m_Constraints[0].m_Value.Min()
381  < rhs->m_Constraints[0].m_Value.Min();
382  } );
383 
384  for( DRC_RULE* ncRule : netclassClearanceRules )
385  addRule( ncRule );
386 
387  for( DRC_RULE* ncRule : netclassItemSpecificRules )
388  addRule( ncRule );
389 
390  // 3) keepout area rules
391 
392  std::vector<ZONE*> keepoutZones;
393 
394  for( ZONE* zone : m_board->Zones() )
395  {
396  if( isKeepoutZone( zone, true ) )
397  keepoutZones.push_back( zone );
398  }
399 
400  for( FOOTPRINT* footprint : m_board->Footprints() )
401  {
402  for( ZONE* zone : footprint->Zones() )
403  {
404  if( isKeepoutZone( zone, true ) )
405  keepoutZones.push_back( zone );
406  }
407  }
408 
409  for( ZONE* zone : keepoutZones )
410  {
411  wxString name = zone->GetZoneName();
412 
413  if( name.IsEmpty() )
414  {
415  rule = createImplicitRule( _( "keepout area" ) );
416  name = zone->m_Uuid.AsString();
417  }
418  else
419  {
420  rule = createImplicitRule( wxString::Format( _( "keepout area '%s'" ), name ) );
421  }
422 
423  rule->m_Condition = new DRC_RULE_CONDITION( wxString::Format( "A.insideArea('%s')",
424  name ) );
425 
426  rule->m_LayerCondition = zone->GetLayerSet();
427 
428  int disallowFlags = 0;
429 
430  if( zone->GetDoNotAllowTracks() )
431  disallowFlags |= DRC_DISALLOW_TRACKS;
432 
433  if( zone->GetDoNotAllowVias() )
434  disallowFlags |= DRC_DISALLOW_VIAS;
435 
436  if( zone->GetDoNotAllowPads() )
437  disallowFlags |= DRC_DISALLOW_PADS;
438 
439  if( zone->GetDoNotAllowCopperPour() )
440  disallowFlags |= DRC_DISALLOW_ZONES;
441 
442  if( zone->GetDoNotAllowFootprints() )
443  disallowFlags |= DRC_DISALLOW_FOOTPRINTS;
444 
445  DRC_CONSTRAINT disallowConstraint( DISALLOW_CONSTRAINT );
446  disallowConstraint.m_DisallowFlags = disallowFlags;
447  rule->AddConstraint( disallowConstraint );
448  }
449 
450  ReportAux( wxString::Format( "Building %d implicit netclass rules",
451  (int) netclassClearanceRules.size() ) );
452 }
ZONES & Zones()
Definition: board.h:311
DRC_RULE_CONDITION * m_Condition
Definition: drc_rule.h:99
bool m_Implicit
Definition: drc_rule.h:95
wxString m_Name
Definition: drc_rule.h:96
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:593
void SynchronizeNetsAndNetClasses()
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
Definition: board.cpp:1413
LSET is a set of PCB_LAYER_IDs.
void addRule(DRC_RULE *rule)
Definition: drc_engine.h:185
std::vector< DRC_CONSTRAINT > m_Constraints
Definition: drc_rule.h:100
FOOTPRINTS & Footprints()
Definition: board.h:305
NETCLASSES & GetNetClasses() const
bool m_BlindBuriedViaAllowed
true to allow blind/buried vias
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
static bool isKeepoutZone(const BOARD_ITEM *aItem, bool aCheckFlags)
Definition: drc_engine.cpp:90
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
DRC_RULE * createImplicitRule(const wxString &name)
Definition: drc_engine.cpp:119
const char * name
Definition: DXF_plotter.cpp:59
LSET m_LayerCondition
Definition: drc_rule.h:98
#define _(s)
Definition: 3d_actions.cpp:33
void ReportAux(const wxString &aStr)
int GetClearance() const
Definition: netclass.h:124
void AddConstraint(DRC_CONSTRAINT &aConstraint)
Definition: drc_rule.cpp:46
NETCLASS * GetDefault() const
BOARD * m_board
Definition: drc_engine.h:212
NETCLASSPTR GetDefault() const
Definition: netclass.h:253
bool m_MicroViasAllowed
true to allow micro vias
Container for design settings for a BOARD object.

References _, DRC_RULE::AddConstraint(), addRule(), ANNULAR_WIDTH_CONSTRAINT, B_SilkS, CLEARANCE_CONSTRAINT, COURTYARD_CLEARANCE_CONSTRAINT, createImplicitRule(), DIFF_PAIR_GAP_CONSTRAINT, DISALLOW_CONSTRAINT, DRC_DISALLOW_BB_VIAS, DRC_DISALLOW_FOOTPRINTS, DRC_DISALLOW_MICRO_VIAS, DRC_DISALLOW_PADS, DRC_DISALLOW_TRACKS, DRC_DISALLOW_VIAS, DRC_DISALLOW_ZONES, EDGE_CLEARANCE_CONSTRAINT, F_SilkS, BOARD::Footprints(), Format(), NETCLASS::GetClearance(), NETCLASSES::GetDefault(), BOARD_DESIGN_SETTINGS::GetDefault(), BOARD::GetDesignSettings(), BOARD_DESIGN_SETTINGS::GetNetClasses(), HOLE_CLEARANCE_CONSTRAINT, HOLE_SIZE_CONSTRAINT, HOLE_TO_HOLE_CONSTRAINT, isKeepoutZone(), BOARD_DESIGN_SETTINGS::m_BlindBuriedViaAllowed, m_board, DRC_RULE::m_Condition, DRC_RULE::m_Constraints, BOARD_DESIGN_SETTINGS::m_CopperEdgeClearance, DRC_CONSTRAINT::m_DisallowFlags, BOARD_DESIGN_SETTINGS::m_HoleClearance, BOARD_DESIGN_SETTINGS::m_HoleToHoleMin, DRC_RULE::m_Implicit, DRC_RULE::m_LayerCondition, BOARD_DESIGN_SETTINGS::m_MicroViasAllowed, BOARD_DESIGN_SETTINGS::m_MicroViasMinDrill, BOARD_DESIGN_SETTINGS::m_MicroViasMinSize, BOARD_DESIGN_SETTINGS::m_MinClearance, BOARD_DESIGN_SETTINGS::m_MinThroughDrill, DRC_RULE::m_Name, BOARD_DESIGN_SETTINGS::m_SilkClearance, BOARD_DESIGN_SETTINGS::m_TrackMinWidth, BOARD_DESIGN_SETTINGS::m_ViasMinAnnulus, BOARD_DESIGN_SETTINGS::m_ViasMinSize, name, ReportAux(), MINOPTMAX< T >::SetMin(), MINOPTMAX< T >::SetOpt(), SILK_CLEARANCE_CONSTRAINT, BOARD::SynchronizeNetsAndNetClasses(), TRACK_WIDTH_CONSTRAINT, DRC_CONSTRAINT::Value(), VIA_DIAMETER_CONSTRAINT, and BOARD::Zones().

Referenced by InitEngine().

◆ loadRules()

void DRC_ENGINE::loadRules ( const wxFileName &  aPath)
private

Loads and parses a rule set from an sexpr text file.

Exceptions
PARSE_ERROR

Definition at line 519 of file drc_engine.cpp.

520 {
521  if( aPath.FileExists() )
522  {
523  std::vector<DRC_RULE*> rules;
524 
525  FILE* fp = wxFopen( aPath.GetFullPath(), wxT( "rt" ) );
526 
527  if( fp )
528  {
529  DRC_RULES_PARSER parser( fp, aPath.GetFullPath() );
530  parser.Parse( rules, m_reporter );
531  }
532 
533  // Copy the rules into the member variable afterwards so that if Parse() throws then
534  // the possibly malformed rules won't contaminate the current ruleset.
535 
536  for( DRC_RULE* rule : rules )
537  m_rules.push_back( rule );
538  }
539 }
std::vector< DRC_RULE * > m_rules
Definition: drc_engine.h:216
void Parse(std::vector< DRC_RULE * > &aRules, REPORTER *aReporter)
REPORTER * m_reporter
Definition: drc_engine.h:229

References m_reporter, m_rules, and DRC_RULES_PARSER::Parse().

Referenced by InitEngine().

◆ MatchDpSuffix()

int DRC_ENGINE::MatchDpSuffix ( const wxString &  aNetName,
wxString &  aComplementNet,
wxString &  aBaseDpName 
)
static

Checks if the given net is a diff pair, returning its polarity and complement if so.

Parameters
aNetNameis the input net name, like DIFF_P
aComplementNetwill be filled with the complement, like DIFF_N
aBaseDpNamewill be filled with the base name, like DIFF
Returns
1 if aNetName is the positive half of a pair, -1 if negative, 0 if not a diff pair

Definition at line 1180 of file drc_engine.cpp.

1182 {
1183  int rv = 0;
1184 
1185  if( aNetName.EndsWith( "+" ) )
1186  {
1187  aComplementNet = "-";
1188  rv = 1;
1189  }
1190  else if( aNetName.EndsWith( "P" ) )
1191  {
1192  aComplementNet = "N";
1193  rv = 1;
1194  }
1195  else if( aNetName.EndsWith( "-" ) )
1196  {
1197  aComplementNet = "+";
1198  rv = -1;
1199  }
1200  else if( aNetName.EndsWith( "N" ) )
1201  {
1202  aComplementNet = "P";
1203  rv = -1;
1204  }
1205  // Match P followed by 2 digits
1206  else if( aNetName.Right( 2 ).IsNumber() && aNetName.Right( 3 ).Left( 1 ) == "P" )
1207  {
1208  aComplementNet = "N" + aNetName.Right( 2 );
1209  rv = 1;
1210  }
1211  // Match P followed by 1 digit
1212  else if( aNetName.Right( 1 ).IsNumber() && aNetName.Right( 2 ).Left( 1 ) == "P" )
1213  {
1214  aComplementNet = "N" + aNetName.Right( 1 );
1215  rv = 1;
1216  }
1217  // Match N followed by 2 digits
1218  else if( aNetName.Right( 2 ).IsNumber() && aNetName.Right( 3 ).Left( 1 ) == "N" )
1219  {
1220  aComplementNet = "P" + aNetName.Right( 2 );
1221  rv = -1;
1222  }
1223  // Match N followed by 1 digit
1224  else if( aNetName.Right( 1 ).IsNumber() && aNetName.Right( 2 ).Left( 1 ) == "N" )
1225  {
1226  aComplementNet = "P" + aNetName.Right( 1 );
1227  rv = -1;
1228  }
1229  if( rv != 0 )
1230  {
1231  aBaseDpName = aNetName.Left( aNetName.Length() - aComplementNet.Length() );
1232  aComplementNet = aBaseDpName + aComplementNet;
1233  }
1234 
1235  return rv;
1236 }

Referenced by inDiffPair(), isCoupledDiffPair(), and IsNetADiffPair().

◆ QueryWorstConstraint()

bool DRC_ENGINE::QueryWorstConstraint ( DRC_CONSTRAINT_T  aRuleId,
DRC_CONSTRAINT aConstraint 
)

Definition at line 1157 of file drc_engine.cpp.

1158 {
1159  int worst = 0;
1160 
1161  if( m_constraintMap.count( aConstraintId ) )
1162  {
1163  for( DRC_ENGINE_CONSTRAINT* c : *m_constraintMap[aConstraintId] )
1164  {
1165  int current = c->constraint.GetValue().Min();
1166 
1167  if( current > worst )
1168  {
1169  worst = current;
1170  aConstraint = c->constraint;
1171  }
1172  }
1173  }
1174 
1175  return worst > 0;
1176 }
std::unordered_map< DRC_CONSTRAINT_T, std::vector< DRC_ENGINE_CONSTRAINT * > * > m_constraintMap
Definition: drc_engine.h:226

References m_constraintMap.

Referenced by DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::Run(), DRC_TEST_PROVIDER_HOLE_CLEARANCE::Run(), DRC_TEST_PROVIDER_SILK_TO_MASK::Run(), DRC_TEST_PROVIDER_SILK_CLEARANCE::Run(), DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run(), and DRC_TEST_PROVIDER_COPPER_CLEARANCE::Run().

◆ ReportAux()

void DRC_ENGINE::ReportAux ( const wxString &  aStr)

Definition at line 1118 of file drc_engine.cpp.

1119 {
1120  if( !m_reporter )
1121  return;
1122 
1124 }
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
REPORTER * m_reporter
Definition: drc_engine.h:229

References m_reporter, REPORTER::Report(), and RPT_SEVERITY_INFO.

Referenced by compileRules(), InitEngine(), loadImplicitRules(), DRC_TEST_PROVIDER::reportAux(), DRC_TEST_PROVIDER::reportRuleStatistics(), and RunTests().

◆ ReportPhase()

bool DRC_ENGINE::ReportPhase ( const wxString &  aMessage)

Definition at line 1137 of file drc_engine.cpp.

1138 {
1139  if( !m_progressReporter )
1140  return true;
1141 
1142  m_progressReporter->AdvancePhase( aMessage );
1143  return m_progressReporter->KeepRefreshing( false );
1144 }
virtual void AdvancePhase()
Uses the next vailable virtual zone of the dialog progress bar.
PROGRESS_REPORTER * m_progressReporter
Definition: drc_engine.h:230
bool KeepRefreshing(bool aWait=false)
Update the UI dialog.

References PROGRESS_REPORTER::AdvancePhase(), PROGRESS_REPORTER::KeepRefreshing(), and m_progressReporter.

Referenced by DRC_TEST_PROVIDER::reportPhase(), and RunTests().

◆ ReportProgress()

bool DRC_ENGINE::ReportProgress ( double  aProgress)

Definition at line 1127 of file drc_engine.cpp.

1128 {
1129  if( !m_progressReporter )
1130  return true;
1131 
1132  m_progressReporter->SetCurrentProgress( aProgress );
1133  return m_progressReporter->KeepRefreshing( false );
1134 }
virtual void SetCurrentProgress(double aProgress)
Set the progress value to aProgress (0..1)
PROGRESS_REPORTER * m_progressReporter
Definition: drc_engine.h:230
bool KeepRefreshing(bool aWait=false)
Update the UI dialog.

References PROGRESS_REPORTER::KeepRefreshing(), m_progressReporter, and PROGRESS_REPORTER::SetCurrentProgress().

Referenced by DRC_TEST_PROVIDER::reportProgress(), and RunTests().

◆ ReportViolation()

void DRC_ENGINE::ReportViolation ( const std::shared_ptr< DRC_ITEM > &  aItem,
wxPoint  aPos 
)

Definition at line 1089 of file drc_engine.cpp.

1090 {
1091  m_errorLimits[ aItem->GetErrorCode() ] -= 1;
1092 
1093  if( m_violationHandler )
1094  m_violationHandler( aItem, aPos );
1095 
1096  if( m_reporter )
1097  {
1098  wxString msg = wxString::Format( "Test '%s': %s (code %d)",
1099  aItem->GetViolatingTest()->GetName(),
1100  aItem->GetErrorMessage(),
1101  aItem->GetErrorCode() );
1102 
1103  DRC_RULE* rule = aItem->GetViolatingRule();
1104 
1105  if( rule )
1106  msg += wxString::Format( ", violating rule: '%s'", rule->m_Name );
1107 
1108  m_reporter->Report( msg );
1109 
1110  wxString violatingItemsStr = "Violating items: ";
1111 
1112  m_reporter->Report( wxString::Format( " |- violating position (%d, %d)",
1113  aPos.x,
1114  aPos.y ) );
1115  }
1116 }
std::vector< int > m_errorLimits
Definition: drc_engine.h:221
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
REPORTER * m_reporter
Definition: drc_engine.h:229
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
DRC_VIOLATION_HANDLER m_violationHandler
Definition: drc_engine.h:228

References Format(), m_errorLimits, m_reporter, m_violationHandler, and REPORTER::Report().

Referenced by DRC_TEST_PROVIDER::reportViolation().

◆ RulesValid()

bool DRC_ENGINE::RulesValid ( )
inline

Definition at line 155 of file drc_engine.h.

155 { return m_rulesValid; }
bool m_rulesValid
Definition: drc_engine.h:217

References m_rulesValid.

◆ RunTests()

void DRC_ENGINE::RunTests ( EDA_UNITS  aUnits,
bool  aReportAllTrackErrors,
bool  aTestFootprints 
)

Runs the DRC tests.

Definition at line 674 of file drc_engine.cpp.

675 {
676  m_userUnits = aUnits;
677 
678  // Note: set these first. The phase counts may be dependent on some of them.
679  m_reportAllTrackErrors = aReportAllTrackErrors;
680  m_testFootprints = aTestFootprints;
681 
682  for( int ii = DRCE_FIRST; ii < DRCE_LAST; ++ii )
683  {
684  if( m_designSettings->Ignore( ii ) )
685  m_errorLimits[ ii ] = 0;
686  else
687  m_errorLimits[ ii ] = INT_MAX;
688  }
689 
690  m_board->IncrementTimeStamp(); // Invalidate all caches
691 
692  if( !ReportPhase( _( "Tessellating copper zones..." ) ) )
693  return;
694 
695  // Number of zones between progress bar updates
696  int delta = 5;
697  std::vector<ZONE*> copperZones;
698 
699  for( ZONE* zone : m_board->Zones() )
700  {
701  zone->CacheBoundingBox();
702  zone->CacheTriangulation();
703 
704  if( !zone->GetIsRuleArea() )
705  copperZones.push_back( zone );
706  }
707 
708  for( FOOTPRINT* footprint : m_board->Footprints() )
709  {
710  for( ZONE* zone : footprint->Zones() )
711  {
712  zone->CacheBoundingBox();
713  zone->CacheTriangulation();
714 
715  if( !zone->GetIsRuleArea() )
716  copperZones.push_back( zone );
717  }
718 
719  footprint->BuildPolyCourtyards();
720  }
721 
722  int zoneCount = copperZones.size();
723 
724  for( int ii = 0; ii < zoneCount; ++ii )
725  {
726  ZONE* zone = copperZones[ ii ];
727 
728  if( ( ii % delta ) == 0 || ii == zoneCount - 1 )
729  {
730  if( !ReportProgress( (double) ii / (double) zoneCount ) )
731  return;
732  }
733 
734  m_board->m_CopperZoneRTrees[ zone ] = std::make_unique<DRC_RTREE>();
735 
736  for( int layer : zone->GetLayerSet().Seq() )
737  {
738  if( IsCopperLayer( layer ) )
739  m_board->m_CopperZoneRTrees[ zone ]->Insert( zone, layer );
740  }
741  }
742 
743  for( DRC_TEST_PROVIDER* provider : m_testProviders )
744  {
745  if( !provider->IsEnabled() )
746  continue;
747 
748  drc_dbg( 0, "Running test provider: '%s'\n", provider->GetName() );
749 
750  ReportAux( wxString::Format( "Run DRC provider: '%s'", provider->GetName() ) );
751 
752  if( !provider->Run() )
753  break;
754  }
755 }
EDA_UNITS m_userUnits
Definition: drc_engine.h:220
std::vector< int > m_errorLimits
Definition: drc_engine.h:221
ZONES & Zones()
Definition: board.h:311
bool ReportPhase(const wxString &aMessage)
std::vector< DRC_TEST_PROVIDER * > m_testProviders
Definition: drc_engine.h:218
bool Ignore(int aDRCErrorCode)
Return true if the DRC error code's severity is SEVERITY_IGNORE.
bool m_testFootprints
Definition: drc_engine.h:223
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: zone.cpp:289
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:411
BOARD_DESIGN_SETTINGS * m_designSettings
Definition: drc_engine.h:211
FOOTPRINTS & Footprints()
Definition: board.h:305
bool ReportProgress(double aProgress)
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
void IncrementTimeStamp()
Definition: board.h:271
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
DRC_TEST_PROVIDER is a base class that represents a DRC "provider" which runs some DRC functions over...
#define _(s)
Definition: 3d_actions.cpp:33
void ReportAux(const wxString &aStr)
std::map< ZONE *, std::unique_ptr< DRC_RTREE > > m_CopperZoneRTrees
Definition: board.h:1158
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
BOARD * m_board
Definition: drc_engine.h:212
#define drc_dbg(level, fmt,...)
Definition: drc_engine.h:57
bool m_reportAllTrackErrors
Definition: drc_engine.h:222

References _, drc_dbg, DRCE_FIRST, DRCE_LAST, BOARD::Footprints(), Format(), ZONE::GetLayerSet(), BOARD_DESIGN_SETTINGS::Ignore(), BOARD::IncrementTimeStamp(), IsCopperLayer(), m_board, BOARD::m_CopperZoneRTrees, m_designSettings, m_errorLimits, m_reportAllTrackErrors, m_testFootprints, m_testProviders, m_userUnits, ReportAux(), ReportPhase(), ReportProgress(), LSET::Seq(), and BOARD::Zones().

◆ SetBoard()

void DRC_ENGINE::SetBoard ( BOARD aBoard)
inline

Definition at line 86 of file drc_engine.h.

86 { m_board = aBoard; }
BOARD * m_board
Definition: drc_engine.h:212

References m_board.

◆ SetDebugOverlay()

void DRC_ENGINE::SetDebugOverlay ( std::shared_ptr< KIGFX::VIEW_OVERLAY aOverlay)
inline

Definition at line 98 of file drc_engine.h.

98 { m_debugOverlay = aOverlay; }
std::shared_ptr< KIGFX::VIEW_OVERLAY > m_debugOverlay
Definition: drc_engine.h:233

References m_debugOverlay.

◆ SetDesignSettings()

void DRC_ENGINE::SetDesignSettings ( BOARD_DESIGN_SETTINGS aSettings)
inline

Definition at line 89 of file drc_engine.h.

89 { m_designSettings = aSettings; }
BOARD_DESIGN_SETTINGS * m_designSettings
Definition: drc_engine.h:211

References m_designSettings.

◆ SetDrawingSheet()

void DRC_ENGINE::SetDrawingSheet ( DS_PROXY_VIEW_ITEM aDrawingSheet)
inline

Definition at line 95 of file drc_engine.h.

95 { m_drawingSheet = aDrawingSheet; }
DS_PROXY_VIEW_ITEM * m_drawingSheet
Definition: drc_engine.h:213

References m_drawingSheet.

◆ SetLogReporter()

void DRC_ENGINE::SetLogReporter ( REPORTER aReporter)
inline

Definition at line 128 of file drc_engine.h.

128 { m_reporter = aReporter; }
REPORTER * m_reporter
Definition: drc_engine.h:229

References m_reporter.

◆ SetProgressReporter()

void DRC_ENGINE::SetProgressReporter ( PROGRESS_REPORTER aProgRep)
inline

Set an optional reporter for user-level progress info.

Definition at line 118 of file drc_engine.h.

118 { m_progressReporter = aProgRep; }
PROGRESS_REPORTER * m_progressReporter
Definition: drc_engine.h:230

References m_progressReporter.

◆ SetSchematicNetlist()

void DRC_ENGINE::SetSchematicNetlist ( NETLIST aNetlist)
inline

Definition at line 92 of file drc_engine.h.

92 { m_schematicNetlist = aNetlist; }
NETLIST * m_schematicNetlist
Definition: drc_engine.h:214

References m_schematicNetlist.

◆ SetViolationHandler()

void DRC_ENGINE::SetViolationHandler ( DRC_VIOLATION_HANDLER  aHandler)
inline

Set an optional DRC violation handler (receives DRC_ITEMs and positions).

Definition at line 105 of file drc_engine.h.

106  {
107  m_violationHandler = std::move( aHandler );
108  }
DRC_VIOLATION_HANDLER m_violationHandler
Definition: drc_engine.h:228

References m_violationHandler.

◆ UserUnits()

EDA_UNITS DRC_ENGINE::UserUnits ( ) const
inline

Definition at line 151 of file drc_engine.h.

151 { return m_userUnits; }
EDA_UNITS m_userUnits
Definition: drc_engine.h:220

References m_userUnits.

Referenced by DRC_TEST_PROVIDER::userUnits().

Member Data Documentation

◆ m_board

BOARD* DRC_ENGINE::m_board
protected

Definition at line 212 of file drc_engine.h.

Referenced by GetBoard(), InitEngine(), loadImplicitRules(), RunTests(), and SetBoard().

◆ m_constraintMap

std::unordered_map<DRC_CONSTRAINT_T, std::vector<DRC_ENGINE_CONSTRAINT*>*> DRC_ENGINE::m_constraintMap
protected

◆ m_debugOverlay

std::shared_ptr<KIGFX::VIEW_OVERLAY> DRC_ENGINE::m_debugOverlay
protected

Definition at line 233 of file drc_engine.h.

Referenced by GetDebugOverlay(), and SetDebugOverlay().

◆ m_designSettings

BOARD_DESIGN_SETTINGS* DRC_ENGINE::m_designSettings
protected

Definition at line 211 of file drc_engine.h.

Referenced by GetDesignSettings(), RunTests(), and SetDesignSettings().

◆ m_drawingSheet

DS_PROXY_VIEW_ITEM* DRC_ENGINE::m_drawingSheet
protected

Definition at line 213 of file drc_engine.h.

Referenced by GetDrawingSheet(), and SetDrawingSheet().

◆ m_errorLimits

std::vector<int> DRC_ENGINE::m_errorLimits
protected

Definition at line 221 of file drc_engine.h.

Referenced by DRC_ENGINE(), InitEngine(), IsErrorLimitExceeded(), ReportViolation(), and RunTests().

◆ m_msg

wxString DRC_ENGINE::m_msg
protected

Definition at line 232 of file drc_engine.h.

Referenced by EvalRules().

◆ m_progressReporter

PROGRESS_REPORTER* DRC_ENGINE::m_progressReporter
protected

◆ m_reportAllTrackErrors

bool DRC_ENGINE::m_reportAllTrackErrors
protected

Definition at line 222 of file drc_engine.h.

Referenced by GetReportAllTrackErrors(), and RunTests().

◆ m_reporter

REPORTER* DRC_ENGINE::m_reporter
protected

Definition at line 229 of file drc_engine.h.

Referenced by loadRules(), ReportAux(), ReportViolation(), and SetLogReporter().

◆ m_rules

std::vector<DRC_RULE*> DRC_ENGINE::m_rules
protected

Definition at line 216 of file drc_engine.h.

Referenced by addRule(), compileRules(), InitEngine(), loadRules(), and ~DRC_ENGINE().

◆ m_rulesValid

bool DRC_ENGINE::m_rulesValid
protected

Definition at line 217 of file drc_engine.h.

Referenced by InitEngine(), and RulesValid().

◆ m_schematicNetlist

NETLIST* DRC_ENGINE::m_schematicNetlist
protected

Definition at line 214 of file drc_engine.h.

Referenced by GetSchematicNetlist(), and SetSchematicNetlist().

◆ m_testFootprints

bool DRC_ENGINE::m_testFootprints
protected

Definition at line 223 of file drc_engine.h.

Referenced by GetTestFootprints(), and RunTests().

◆ m_testProviders

std::vector<DRC_TEST_PROVIDER*> DRC_ENGINE::m_testProviders
protected

Definition at line 218 of file drc_engine.h.

Referenced by compileRules(), GetTestProvider(), GetTestProviders(), InitEngine(), and RunTests().

◆ m_userUnits

EDA_UNITS DRC_ENGINE::m_userUnits
protected

Definition at line 220 of file drc_engine.h.

Referenced by RunTests(), and UserUnits().

◆ m_violationHandler

DRC_VIOLATION_HANDLER DRC_ENGINE::m_violationHandler
protected

Definition at line 228 of file drc_engine.h.

Referenced by ClearViolationHandler(), ReportViolation(), and SetViolationHandler().


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