KiCad PCB EDA Suite
DRC_TEST_PROVIDER_COPPER_CLEARANCE Class Reference
Inheritance diagram for DRC_TEST_PROVIDER_COPPER_CLEARANCE:
DRC_TEST_PROVIDER_CLEARANCE_BASE DRC_TEST_PROVIDER

Public Member Functions

 DRC_TEST_PROVIDER_COPPER_CLEARANCE ()
 
virtual ~DRC_TEST_PROVIDER_COPPER_CLEARANCE ()
 
virtual bool Run () override
 Run this provider against the given PCB with configured options (if any). More...
 
virtual const wxString GetName () const override
 
virtual const wxString GetDescription () const override
 
virtual std::set< DRC_CONSTRAINT_TGetConstraintTypes () const override
 
int GetNumPhases () const override
 
void SetDRCEngine (DRC_ENGINE *engine)
 
virtual bool IsRuleDriven () const
 
bool IsEnabled () const
 
void Enable (bool aEnable)
 

Protected Member Functions

int forEachGeometryItem (const std::vector< KICAD_T > &aTypes, LSET aLayers, const std::function< bool(BOARD_ITEM *)> &aFunc)
 
virtual void reportAux (wxString fmt,...)
 
virtual void reportViolation (std::shared_ptr< DRC_ITEM > &item, const wxPoint &aMarkerPos)
 
virtual bool reportProgress (int aCount, int aSize, int aDelta)
 
virtual bool reportPhase (const wxString &aStageName)
 
virtual void reportRuleStatistics ()
 
virtual void accountCheck (const DRC_RULE *ruleToTest)
 
virtual void accountCheck (const DRC_CONSTRAINT &constraintToTest)
 
bool isInvisibleText (const BOARD_ITEM *aItem) const
 
EDA_UNITS userUnits () const
 

Protected Attributes

BOARDm_board
 
int m_largestClearance
 
bool m_boardOutlineValid
 
DRC_ENGINEm_drcEngine
 
std::unordered_map< const DRC_RULE *, int > m_stats
 
bool m_isRuleDriven = true
 
bool m_enabled = true
 
wxString m_msg
 

Static Protected Attributes

static std::vector< KICAD_Ts_allBasicItems
 
static std::vector< KICAD_Ts_allBasicItemsButZones
 

Private Member Functions

bool testTrackAgainstItem (PCB_TRACK *track, SHAPE *trackShape, PCB_LAYER_ID layer, BOARD_ITEM *other)
 
void testTrackClearances ()
 
bool testPadAgainstItem (PAD *pad, SHAPE *padShape, PCB_LAYER_ID layer, BOARD_ITEM *other)
 
void testPadClearances ()
 
void testZonesToZones ()
 
void testItemAgainstZones (BOARD_ITEM *aItem, PCB_LAYER_ID aLayer)
 

Private Attributes

DRC_RTREE m_copperTree
 
int m_drcEpsilon
 
std::vector< ZONE * > m_zones
 

Detailed Description

Definition at line 56 of file drc_test_provider_copper_clearance.cpp.

Constructor & Destructor Documentation

◆ DRC_TEST_PROVIDER_COPPER_CLEARANCE()

DRC_TEST_PROVIDER_COPPER_CLEARANCE::DRC_TEST_PROVIDER_COPPER_CLEARANCE ( )
inline

◆ ~DRC_TEST_PROVIDER_COPPER_CLEARANCE()

virtual DRC_TEST_PROVIDER_COPPER_CLEARANCE::~DRC_TEST_PROVIDER_COPPER_CLEARANCE ( )
inlinevirtual

Definition at line 65 of file drc_test_provider_copper_clearance.cpp.

66  {
67  }

Member Function Documentation

◆ accountCheck() [1/2]

void DRC_TEST_PROVIDER::accountCheck ( const DRC_RULE ruleToTest)
protectedvirtualinherited

Definition at line 103 of file drc_test_provider.cpp.

104 {
105  auto it = m_stats.find( ruleToTest );
106 
107  if( it == m_stats.end() )
108  m_stats[ ruleToTest ] = 1;
109  else
110  m_stats[ ruleToTest ] += 1;
111 }
std::unordered_map< const DRC_RULE *, int > m_stats

References DRC_TEST_PROVIDER::m_stats.

Referenced by DRC_TEST_PROVIDER::accountCheck(), and DRC_TEST_PROVIDER::reportViolation().

◆ accountCheck() [2/2]

void DRC_TEST_PROVIDER::accountCheck ( const DRC_CONSTRAINT constraintToTest)
protectedvirtualinherited

Definition at line 114 of file drc_test_provider.cpp.

115 {
116  accountCheck( constraintToTest.GetParentRule() );
117 }
DRC_RULE * GetParentRule() const
Definition: drc_rule.h:126
virtual void accountCheck(const DRC_RULE *ruleToTest)

References DRC_TEST_PROVIDER::accountCheck(), and DRC_CONSTRAINT::GetParentRule().

◆ Enable()

void DRC_TEST_PROVIDER::Enable ( bool  aEnable)
inlineinherited

Definition at line 106 of file drc_test_provider.h.

107  {
108  m_enabled = aEnable;
109  }

References DRC_TEST_PROVIDER::m_enabled.

◆ forEachGeometryItem()

int DRC_TEST_PROVIDER::forEachGeometryItem ( const std::vector< KICAD_T > &  aTypes,
LSET  aLayers,
const std::function< bool(BOARD_ITEM *)> &  aFunc 
)
protectedinherited

Definition at line 139 of file drc_test_provider.cpp.

141 {
142  BOARD *brd = m_drcEngine->GetBoard();
143  std::bitset<MAX_STRUCT_TYPE_ID> typeMask;
144  int n = 0;
145 
146  if( s_allBasicItems.size() == 0 )
147  {
148  for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
149  {
150  if( i != PCB_FOOTPRINT_T && i != PCB_GROUP_T )
151  {
152  s_allBasicItems.push_back( (KICAD_T) i );
153 
154  if( i != PCB_ZONE_T && i != PCB_FP_ZONE_T )
155  s_allBasicItemsButZones.push_back( (KICAD_T) i );
156  }
157  }
158  }
159 
160  if( aTypes.size() == 0 )
161  {
162  for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
163  typeMask[ i ] = true;
164  }
165  else
166  {
167  for( KICAD_T aType : aTypes )
168  typeMask[ aType ] = true;
169  }
170 
171  for( PCB_TRACK* item : brd->Tracks() )
172  {
173  if( (item->GetLayerSet() & aLayers).any() )
174  {
175  if( typeMask[ PCB_TRACE_T ] && item->Type() == PCB_TRACE_T )
176  {
177  aFunc( item );
178  n++;
179  }
180  else if( typeMask[ PCB_VIA_T ] && item->Type() == PCB_VIA_T )
181  {
182  aFunc( item );
183  n++;
184  }
185  else if( typeMask[ PCB_ARC_T ] && item->Type() == PCB_ARC_T )
186  {
187  aFunc( item );
188  n++;
189  }
190  }
191  }
192 
193  for( BOARD_ITEM* item : brd->Drawings() )
194  {
195  if( (item->GetLayerSet() & aLayers).any() )
196  {
197  if( typeMask[PCB_DIMENSION_T] && BaseType( item->Type() ) == PCB_DIMENSION_T )
198  {
199  if( !aFunc( item ) )
200  return n;
201 
202  n++;
203  }
204  else if( typeMask[ PCB_SHAPE_T ] && item->Type() == PCB_SHAPE_T )
205  {
206  if( !aFunc( item ) )
207  return n;
208 
209  n++;
210  }
211  else if( typeMask[ PCB_TEXT_T ] && item->Type() == PCB_TEXT_T )
212  {
213  if( !aFunc( item ) )
214  return n;
215 
216  n++;
217  }
218  else if( typeMask[ PCB_TARGET_T ] && item->Type() == PCB_TARGET_T )
219  {
220  if( !aFunc( item ) )
221  return n;
222 
223  n++;
224  }
225  }
226  }
227 
228  if( typeMask[ PCB_ZONE_T ] )
229  {
230  for( ZONE* item : brd->Zones() )
231  {
232  if( ( item->GetLayerSet() & aLayers ).any() )
233  {
234  if( !aFunc( item ) )
235  return n;
236 
237  n++;
238  }
239  }
240  }
241 
242  for( FOOTPRINT* footprint : brd->Footprints() )
243  {
244  if( typeMask[ PCB_FP_TEXT_T ] )
245  {
246  if( ( footprint->Reference().GetLayerSet() & aLayers ).any() )
247  {
248  if( !aFunc( &footprint->Reference() ) )
249  return n;
250 
251  n++;
252  }
253 
254  if( ( footprint->Value().GetLayerSet() & aLayers ).any() )
255  {
256  if( !aFunc( &footprint->Value() ) )
257  return n;
258 
259  n++;
260  }
261  }
262 
263  if( typeMask[ PCB_PAD_T ] )
264  {
265  for( PAD* pad : footprint->Pads() )
266  {
267  // Careful: if a pad has a hole then it pierces all layers
268  if( ( pad->GetDrillSizeX() > 0 && pad->GetDrillSizeY() > 0 )
269  || ( pad->GetLayerSet() & aLayers ).any() )
270  {
271  if( !aFunc( pad ) )
272  return n;
273 
274  n++;
275  }
276  }
277  }
278 
279  for( BOARD_ITEM* dwg : footprint->GraphicalItems() )
280  {
281  if( (dwg->GetLayerSet() & aLayers).any() )
282  {
283  if( typeMask[ PCB_FP_TEXT_T ] && dwg->Type() == PCB_FP_TEXT_T )
284  {
285  if( !aFunc( dwg ) )
286  return n;
287 
288  n++;
289  }
290  else if( typeMask[ PCB_FP_SHAPE_T ] && dwg->Type() == PCB_FP_SHAPE_T )
291  {
292  if( !aFunc( dwg ) )
293  return n;
294 
295  n++;
296  }
297  }
298  }
299 
300  if( typeMask[ PCB_FP_ZONE_T ] )
301  {
302  for( ZONE* zone : footprint->Zones() )
303  {
304  if( (zone->GetLayerSet() & aLayers).any() )
305  {
306  if( !aFunc( zone ) )
307  return n;
308 
309  n++;
310  }
311  }
312  }
313 
314  if( typeMask[ PCB_FOOTPRINT_T ] )
315  {
316  if( !aFunc( footprint ) )
317  return n;
318 
319  n++;
320  }
321  }
322 
323  return n;
324 }
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
ZONES & Zones()
Definition: board.h:240
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:49
class PCB_GROUP, a set of BOARD_ITEMs
Definition: typeinfo.h:108
constexpr KICAD_T BaseType(const KICAD_T aType)
Return the underlying type of the given type.
Definition: typeinfo.h:231
class PCB_TEXT, text on a layer
Definition: typeinfo.h:91
class PCB_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
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:77
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
BOARD * GetBoard() const
Definition: drc_engine.h:88
FOOTPRINTS & Footprints()
Definition: board.h:234
Handle a list of polygons defining a copper zone.
Definition: zone.h:56
class ZONE, a copper pour area
Definition: typeinfo.h:105
class PCB_DIMENSION_BASE: abstract dimension meta-type
Definition: typeinfo.h:99
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:104
class FOOTPRINT, a footprint
Definition: typeinfo.h:88
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:191
static std::vector< KICAD_T > s_allBasicItems
static std::vector< KICAD_T > s_allBasicItemsButZones
DRC_ENGINE * m_drcEngine
class ZONE, managed by a footprint
Definition: typeinfo.h:94
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
Definition: pad.h:57
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:90
DRAWINGS & Drawings()
Definition: board.h:237
TRACKS & Tracks()
Definition: board.h:231

References BaseType(), BOARD::Drawings(), BOARD::Footprints(), DRC_ENGINE::GetBoard(), DRC_TEST_PROVIDER::m_drcEngine, MAX_STRUCT_TYPE_ID, pad, PCB_ARC_T, PCB_DIMENSION_T, PCB_FOOTPRINT_T, PCB_FP_SHAPE_T, PCB_FP_TEXT_T, PCB_FP_ZONE_T, PCB_GROUP_T, PCB_PAD_T, PCB_SHAPE_T, PCB_TARGET_T, PCB_TEXT_T, PCB_TRACE_T, PCB_VIA_T, PCB_ZONE_T, DRC_TEST_PROVIDER::s_allBasicItems, DRC_TEST_PROVIDER::s_allBasicItemsButZones, BOARD::Tracks(), and BOARD::Zones().

Referenced by DRC_TEST_PROVIDER_DISALLOW::Run(), DRC_TEST_PROVIDER_SILK_TO_MASK::Run(), DRC_TEST_PROVIDER_SILK_CLEARANCE::Run(), DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run(), DRC_TEST_PROVIDER_HOLE_TO_HOLE::Run(), test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run(), Run(), DRC_TEST_PROVIDER_MATCHED_LENGTH::runInternal(), DRC_TEST_PROVIDER_MISC::testDisabledLayers(), and DRC_TEST_PROVIDER_MISC::testTextVars().

◆ GetConstraintTypes()

std::set< DRC_CONSTRAINT_T > DRC_TEST_PROVIDER_COPPER_CLEARANCE::GetConstraintTypes ( ) const
overridevirtual

◆ GetDescription()

virtual const wxString DRC_TEST_PROVIDER_COPPER_CLEARANCE::GetDescription ( ) const
inlineoverridevirtual

Reimplemented from DRC_TEST_PROVIDER.

Definition at line 76 of file drc_test_provider_copper_clearance.cpp.

77  {
78  return "Tests copper item clearance";
79  }

◆ GetName()

virtual const wxString DRC_TEST_PROVIDER_COPPER_CLEARANCE::GetName ( void  ) const
inlineoverridevirtual

Reimplemented from DRC_TEST_PROVIDER.

Definition at line 71 of file drc_test_provider_copper_clearance.cpp.

72  {
73  return "clearance";
74  };

◆ GetNumPhases()

int DRC_TEST_PROVIDER_COPPER_CLEARANCE::GetNumPhases ( ) const
overridevirtual

Implements DRC_TEST_PROVIDER.

Definition at line 1009 of file drc_test_provider_copper_clearance.cpp.

1010 {
1011  return 4;
1012 }

◆ IsEnabled()

bool DRC_TEST_PROVIDER::IsEnabled ( ) const
inlineinherited

Definition at line 101 of file drc_test_provider.h.

102  {
103  return m_enabled;
104  }

References DRC_TEST_PROVIDER::m_enabled.

◆ isInvisibleText()

bool DRC_TEST_PROVIDER::isInvisibleText ( const BOARD_ITEM aItem) const
protectedinherited

Definition at line 327 of file drc_test_provider.cpp.

328 {
329 
330  if( const FP_TEXT* text = dyn_cast<const FP_TEXT*>( aItem ) )
331  {
332  if( !text->IsVisible() )
333  return true;
334  }
335 
336  if( const PCB_TEXT* text = dyn_cast<const PCB_TEXT*>( aItem ) )
337  {
338  if( !text->IsVisible() )
339  return true;
340  }
341 
342  return false;
343 }

References text.

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

◆ IsRuleDriven()

virtual bool DRC_TEST_PROVIDER::IsRuleDriven ( ) const
inlinevirtualinherited

Definition at line 96 of file drc_test_provider.h.

97  {
98  return m_isRuleDriven;
99  }

References DRC_TEST_PROVIDER::m_isRuleDriven.

◆ reportAux()

◆ reportPhase()

◆ reportProgress()

◆ reportRuleStatistics()

void DRC_TEST_PROVIDER::reportRuleStatistics ( )
protectedvirtualinherited

Definition at line 120 of file drc_test_provider.cpp.

121 {
122  if( !m_isRuleDriven )
123  return;
124 
125  m_drcEngine->ReportAux( "Rule hit statistics: " );
126 
127  for( const std::pair<const DRC_RULE* const, int>& stat : m_stats )
128  {
129  if( stat.first )
130  {
131  m_drcEngine->ReportAux( wxString::Format( " - rule '%s': %d hits ",
132  stat.first->m_Name,
133  stat.second ) );
134  }
135  }
136 }
std::unordered_map< const DRC_RULE *, int > m_stats
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
void ReportAux(const wxString &aStr)
DRC_ENGINE * m_drcEngine

References Format(), DRC_TEST_PROVIDER::m_drcEngine, DRC_TEST_PROVIDER::m_isRuleDriven, DRC_TEST_PROVIDER::m_stats, and DRC_ENGINE::ReportAux().

Referenced by DRC_TEST_PROVIDER_VIA_DIAMETER::Run(), DRC_TEST_PROVIDER_TRACK_WIDTH::Run(), DRC_TEST_PROVIDER_DISALLOW::Run(), DRC_TEST_PROVIDER_HOLE_SIZE::Run(), DRC_TEST_PROVIDER_ANNULAR_WIDTH::Run(), DRC_TEST_PROVIDER_CONNECTIVITY::Run(), DRC_TEST_PROVIDER_SILK_TO_MASK::Run(), DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run(), DRC_TEST_PROVIDER_HOLE_TO_HOLE::Run(), DRC_TEST_PROVIDER_SILK_CLEARANCE::Run(), DRC_TEST_PROVIDER_LVS::Run(), test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run(), Run(), and DRC_TEST_PROVIDER_MATCHED_LENGTH::runInternal().

◆ reportViolation()

void DRC_TEST_PROVIDER::reportViolation ( std::shared_ptr< DRC_ITEM > &  item,
const wxPoint &  aMarkerPos 
)
protectedvirtualinherited

Definition at line 56 of file drc_test_provider.cpp.

58 {
59  if( item->GetViolatingRule() )
60  accountCheck( item->GetViolatingRule() );
61 
62  item->SetViolatingTest( this );
63  m_drcEngine->ReportViolation( item, aMarkerPos );
64 }
virtual void accountCheck(const DRC_RULE *ruleToTest)
DRC_ENGINE * m_drcEngine
void ReportViolation(const std::shared_ptr< DRC_ITEM > &aItem, const wxPoint &aPos)

References DRC_TEST_PROVIDER::accountCheck(), DRC_TEST_PROVIDER::m_drcEngine, and DRC_ENGINE::ReportViolation().

Referenced by DRC_TEST_PROVIDER_MATCHED_LENGTH::checkLengths(), DRC_TEST_PROVIDER_HOLE_SIZE::checkPad(), DRC_TEST_PROVIDER_MATCHED_LENGTH::checkSkews(), DRC_TEST_PROVIDER_HOLE_SIZE::checkVia(), DRC_TEST_PROVIDER_MATCHED_LENGTH::checkViaCounts(), DRC_TEST_PROVIDER_VIA_DIAMETER::Run(), DRC_TEST_PROVIDER_TRACK_WIDTH::Run(), DRC_TEST_PROVIDER_DISALLOW::Run(), DRC_TEST_PROVIDER_ANNULAR_WIDTH::Run(), DRC_TEST_PROVIDER_CONNECTIVITY::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_EDGE_CLEARANCE::testAgainstEdge(), DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances(), DRC_TEST_PROVIDER_MISC::testDisabledLayers(), DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testFootprintCourtyardDefinitions(), DRC_TEST_PROVIDER_LVS::testFootprints(), DRC_TEST_PROVIDER_HOLE_TO_HOLE::testHoleAgainstHole(), testItemAgainstZones(), DRC_TEST_PROVIDER_MISC::testOutline(), testPadAgainstItem(), DRC_TEST_PROVIDER_MISC::testTextVars(), testTrackAgainstItem(), and testZonesToZones().

◆ Run()

bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::Run ( )
overridevirtual

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

Implements DRC_TEST_PROVIDER.

Definition at line 107 of file drc_test_provider_copper_clearance.cpp.

108 {
110  DRC_CONSTRAINT worstConstraint;
111 
112  if( m_drcEngine->QueryWorstConstraint( CLEARANCE_CONSTRAINT, worstConstraint ) )
113  m_largestClearance = worstConstraint.GetValue().Min();
114 
116  m_largestClearance = std::max( m_largestClearance, worstConstraint.GetValue().Min() );
117 
118  if( m_largestClearance <= 0 )
119  {
120  reportAux( "No Clearance constraints found. Tests not run." );
121  return true; // continue with other tests
122  }
123 
125 
126  m_zones.clear();
127 
128  for( ZONE* zone : m_board->Zones() )
129  {
130  if( !zone->GetIsRuleArea() )
131  {
132  m_zones.push_back( zone );
133  m_largestClearance = std::max( m_largestClearance, zone->GetLocalClearance() );
134  }
135  }
136 
137  for( FOOTPRINT* footprint : m_board->Footprints() )
138  {
139  for( PAD* pad : footprint->Pads() )
140  m_largestClearance = std::max( m_largestClearance, pad->GetLocalClearance() );
141 
142  for( ZONE* zone : footprint->Zones() )
143  {
144  if( !zone->GetIsRuleArea() )
145  {
146  m_zones.push_back( zone );
147  m_largestClearance = std::max( m_largestClearance, zone->GetLocalClearance() );
148  }
149  }
150  }
151 
152  reportAux( "Worst clearance : %d nm", m_largestClearance );
153 
154  // This is the number of tests between 2 calls to the progress bar
155  size_t delta = 50;
156  size_t count = 0;
157  size_t ii = 0;
158 
160 
161  auto countItems =
162  [&]( BOARD_ITEM* item ) -> bool
163  {
164  ++count;
165  return true;
166  };
167 
168  auto addToCopperTree =
169  [&]( BOARD_ITEM* item ) -> bool
170  {
171  if( !reportProgress( ii++, count, delta ) )
172  return false;
173 
174  LSET layers = item->GetLayerSet();
175 
176  // Special-case pad holes which pierce all the copper layers
177  if( item->Type() == PCB_PAD_T )
178  {
179  PAD* pad = static_cast<PAD*>( item );
180 
181  if( pad->GetDrillSizeX() > 0 && pad->GetDrillSizeY() > 0 )
182  layers |= LSET::AllCuMask();
183  }
184 
185  for( PCB_LAYER_ID layer : layers.Seq() )
186  {
187  if( IsCopperLayer( layer ) )
188  m_copperTree.Insert( item, layer, m_largestClearance );
189  }
190 
191  return true;
192  };
193 
194  if( !reportPhase( _( "Gathering copper items..." ) ) )
195  return false; // DRC cancelled
196 
197  static const std::vector<KICAD_T> itemTypes = {
201  };
202 
203  forEachGeometryItem( itemTypes, LSET::AllCuMask(), countItems );
204  forEachGeometryItem( itemTypes, LSET::AllCuMask(), addToCopperTree );
205 
206  reportAux( "Testing %d copper items and %d zones...", count, m_zones.size() );
207 
209  {
210  if( !reportPhase( _( "Checking track & via clearances..." ) ) )
211  return false; // DRC cancelled
212 
214  }
216  {
217  if( !reportPhase( _( "Checking hole clearances..." ) ) )
218  return false; // DRC cancelled
219 
221  }
222 
224  {
225  if( !reportPhase( _( "Checking pad clearances..." ) ) )
226  return false; // DRC cancelled
227 
229  }
232  {
233  if( !reportPhase( _( "Checking pads..." ) ) )
234  return false; // DRC cancelled
235 
237  }
238 
240  {
241  if( !reportPhase( _( "Checking copper zone clearances..." ) ) )
242  return false; // DRC cancelled
243 
245  }
247  {
248  if( !reportPhase( _( "Checking zones..." ) ) )
249  return false; // DRC cancelled
250 
252  }
253 
255 
256  return true;
257 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:759
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
Definition: typeinfo.h:100
class PCB_DIM_LEADER, a leader dimension (graphic item)
Definition: typeinfo.h:101
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
ZONES & Zones()
Definition: board.h:240
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:49
class PCB_DIM_CENTER, a center point marking (graphic item)
Definition: typeinfo.h:102
bool IsErrorLimitExceeded(int error_code)
class PCB_TEXT, text on a layer
Definition: typeinfo.h:91
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:97
virtual bool reportProgress(int aCount, int aSize, int aDelta)
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:93
class PAD, a pad in a footprint
Definition: typeinfo.h:89
T Min() const
Definition: minoptmax.h:33
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 & GetDesignSettings() const
Definition: board.cpp:590
virtual void reportRuleStatistics()
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:505
bool QueryWorstConstraint(DRC_CONSTRAINT_T aRuleId, DRC_CONSTRAINT &aConstraint)
BOARD * GetBoard() const
Definition: drc_engine.h:88
virtual bool reportPhase(const wxString &aStageName)
FOOTPRINTS & Footprints()
Definition: board.h:234
void clear()
Remove all items from the RTree.
Definition: drc_rtree.h:133
#define _(s)
Handle a list of polygons defining a copper zone.
Definition: zone.h:56
class PCB_DIMENSION_BASE: abstract dimension meta-type
Definition: typeinfo.h:99
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:797
int forEachGeometryItem(const std::vector< KICAD_T > &aTypes, LSET aLayers, const std::function< bool(BOARD_ITEM *)> &aFunc)
const MINOPTMAX< int > & GetValue() const
Definition: drc_rule.h:122
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
DRC_ENGINE * m_drcEngine
void Insert(BOARD_ITEM *aItem, PCB_LAYER_ID aLayer, int aWorstClearance=0)
Insert an item into the tree on a particular layer with an optional worst clearance.
Definition: drc_rtree.h:88
constexpr int delta
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
Definition: typeinfo.h:103
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
Definition: pad.h:57
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:90
virtual void reportAux(wxString fmt,...)

References _, LSET::AllCuMask(), DRC_RTREE::clear(), CLEARANCE_CONSTRAINT, delta, DRCE_CLEARANCE, DRCE_HOLE_CLEARANCE, DRCE_SHORTING_ITEMS, DRCE_ZONES_INTERSECT, BOARD::Footprints(), DRC_TEST_PROVIDER::forEachGeometryItem(), DRC_ENGINE::GetBoard(), BOARD::GetDesignSettings(), BOARD_DESIGN_SETTINGS::GetDRCEpsilon(), DRC_CONSTRAINT::GetValue(), HOLE_CLEARANCE_CONSTRAINT, DRC_RTREE::Insert(), IsCopperLayer(), DRC_ENGINE::IsErrorLimitExceeded(), DRC_TEST_PROVIDER_CLEARANCE_BASE::m_board, m_copperTree, DRC_TEST_PROVIDER::m_drcEngine, m_drcEpsilon, DRC_TEST_PROVIDER_CLEARANCE_BASE::m_largestClearance, m_zones, MINOPTMAX< T >::Min(), pad, PCB_ARC_T, PCB_DIM_ALIGNED_T, PCB_DIM_CENTER_T, PCB_DIM_LEADER_T, PCB_DIM_ORTHOGONAL_T, PCB_DIMENSION_T, PCB_FP_SHAPE_T, PCB_FP_TEXT_T, PCB_PAD_T, PCB_SHAPE_T, PCB_TEXT_T, PCB_TRACE_T, PCB_VIA_T, DRC_ENGINE::QueryWorstConstraint(), DRC_TEST_PROVIDER::reportAux(), DRC_TEST_PROVIDER::reportPhase(), DRC_TEST_PROVIDER::reportProgress(), DRC_TEST_PROVIDER::reportRuleStatistics(), LSET::Seq(), testPadClearances(), testTrackClearances(), testZonesToZones(), and BOARD::Zones().

◆ SetDRCEngine()

void DRC_TEST_PROVIDER::SetDRCEngine ( DRC_ENGINE engine)
inlineinherited

Definition at line 78 of file drc_test_provider.h.

79  {
80  m_drcEngine = engine;
81  m_stats.clear();
82  }
std::unordered_map< const DRC_RULE *, int > m_stats
DRC_ENGINE * m_drcEngine

References DRC_TEST_PROVIDER::m_drcEngine, and DRC_TEST_PROVIDER::m_stats.

◆ testItemAgainstZones()

void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testItemAgainstZones ( BOARD_ITEM aItem,
PCB_LAYER_ID  aLayer 
)
private

Definition at line 379 of file drc_test_provider_copper_clearance.cpp.

381 {
382  for( ZONE* zone : m_zones )
383  {
384  if( !zone->GetLayerSet().test( aLayer ) )
385  continue;
386 
387  if( zone->GetNetCode() && aItem->IsConnected() )
388  {
389  if( zone->GetNetCode() == static_cast<BOARD_CONNECTED_ITEM*>( aItem )->GetNetCode() )
390  continue;
391  }
392 
393  if( aItem->GetBoundingBox().Intersects( zone->GetCachedBoundingBox() ) )
394  {
395  bool testClearance = !m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE );
397 
398  if( !testClearance && !testHoles )
399  return;
400 
401  DRC_RTREE* zoneTree = m_board->m_CopperZoneRTrees[ zone ].get();
402  EDA_RECT itemBBox = aItem->GetBoundingBox();
403  DRC_CONSTRAINT constraint;
404  int clearance = -1;
405  int actual;
406  VECTOR2I pos;
407 
408  if( zoneTree && testClearance )
409  {
410  constraint = m_drcEngine->EvalRules( CLEARANCE_CONSTRAINT, aItem, zone, aLayer );
411  clearance = constraint.GetValue().Min();
412  }
413 
414  if( clearance >= 0 )
415  {
416  std::shared_ptr<SHAPE> itemShape = aItem->GetEffectiveShape( aLayer );
417 
418  if( aItem->Type() == PCB_PAD_T )
419  {
420  PAD* pad = static_cast<PAD*>( aItem );
421 
422  if( !pad->FlashLayer( aLayer ) )
423  {
424  if( pad->GetDrillSize().x == 0 && pad->GetDrillSize().y == 0 )
425  continue;
426 
427  const SHAPE_SEGMENT* hole = pad->GetEffectiveHoleShape();
428  int size = hole->GetWidth();
429 
430  // Note: drill size represents finish size, which means the actual hole
431  // size is the plating thickness larger.
432  if( pad->GetAttribute() == PAD_ATTRIB::PTH )
434 
435  itemShape = std::make_shared<SHAPE_SEGMENT>( hole->GetSeg(), size );
436  }
437  }
438 
439  if( zoneTree && zoneTree->QueryColliding( itemBBox, itemShape.get(), aLayer,
440  std::max( 0, clearance - m_drcEpsilon ),
441  &actual, &pos ) )
442  {
443  std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
444 
445  m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
446  constraint.GetName(),
447  MessageTextFromValue( userUnits(), clearance ),
448  MessageTextFromValue( userUnits(), actual ) );
449 
450  drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
451  drce->SetItems( aItem, zone );
452  drce->SetViolatingRule( constraint.GetParentRule() );
453 
454  reportViolation( drce, (wxPoint) pos );
455  }
456  }
457 
458  if( testHoles && ( aItem->Type() == PCB_VIA_T || aItem->Type() == PCB_PAD_T ) )
459  {
460  std::unique_ptr<SHAPE_SEGMENT> holeShape;
461 
462  if( aItem->Type() == PCB_VIA_T )
463  {
464  PCB_VIA* via = static_cast<PCB_VIA*>( aItem );
465  pos = via->GetPosition();
466 
467  if( via->GetLayerSet().Contains( aLayer ) )
468  holeShape.reset( new SHAPE_SEGMENT( pos, pos, via->GetDrill() ) );
469  }
470  else if( aItem->Type() == PCB_PAD_T )
471  {
472  PAD* pad = static_cast<PAD*>( aItem );
473 
474  if( pad->GetDrillSize().x )
475  holeShape.reset( new SHAPE_SEGMENT( *pad->GetEffectiveHoleShape() ) );
476  }
477 
478  if( holeShape )
479  {
480  constraint = m_drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, aItem, zone,
481  aLayer );
482  clearance = constraint.GetValue().Min();
483 
484  if( zoneTree && zoneTree->QueryColliding( itemBBox, holeShape.get(), aLayer,
485  std::max( 0, clearance - m_drcEpsilon ),
486  &actual, &pos ) )
487  {
488  std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
489 
490  m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
491  constraint.GetName(),
492  MessageTextFromValue( userUnits(), clearance ),
493  MessageTextFromValue( userUnits(), actual ) );
494 
495  drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
496  drce->SetItems( aItem, zone );
497  drce->SetViolatingRule( constraint.GetParentRule() );
498 
499  reportViolation( drce, (wxPoint) pos );
500  }
501  }
502  }
503  }
504  }
505 }
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:104
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
Definition: drc_item.cpp:266
virtual void reportViolation(std::shared_ptr< DRC_ITEM > &item, const wxPoint &aMarkerPos)
int GetHolePlatingThickness() const
Pad & via drills are finish size.
bool IsErrorLimitExceeded(int error_code)
class PAD, a pad in a footprint
Definition: typeinfo.h:89
T Min() const
Definition: minoptmax.h:33
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:590
wxString GetName() const
Definition: drc_rule.h:130
const SEG & GetSeg() const
Plated through hole pad.
DRC_RULE * GetParentRule() const
Definition: drc_rule.h:126
#define _(s)
Handle a list of polygons defining a copper zone.
Definition: zone.h:56
EDA_UNITS userUnits() const
DRC_CONSTRAINT EvalRules(DRC_CONSTRAINT_T aConstraintType, const BOARD_ITEM *a, const BOARD_ITEM *b, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
Definition: drc_engine.cpp:760
const MINOPTMAX< int > & GetValue() const
Definition: drc_rule.h:122
DRC_ENGINE * m_drcEngine
Handle the component boundary box.
Definition: eda_rect.h:42
bool Intersects(const EDA_RECT &aRect) const
Test for a common area between rectangles.
Definition: eda_rect.cpp:150
std::map< ZONE *, std::unique_ptr< DRC_RTREE > > m_CopperZoneRTrees
Definition: board.h:1097
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:169
virtual bool IsConnected() const
Returns information if the object is derived from BOARD_CONNECTED_ITEM.
Definition: board_item.h:103
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
virtual const EDA_RECT GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition: eda_item.cpp:75
Definition: pad.h:57
Implement an R-tree for fast spatial and layer indexing of connectable items.
Definition: drc_rtree.h:46
int GetWidth() const
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:112
int QueryColliding(BOARD_ITEM *aRefItem, PCB_LAYER_ID aRefLayer, PCB_LAYER_ID aTargetLayer, std::function< bool(BOARD_ITEM *)> aFilter=nullptr, std::function< bool(BOARD_ITEM *)> aVisitor=nullptr, int aClearance=0) const
This is a fast test which essentially does bounding-box overlap given a worst-case clearance.
Definition: drc_rtree.h:178

References _, CLEARANCE_CONSTRAINT, DRC_ITEM::Create(), DRCE_CLEARANCE, DRCE_HOLE_CLEARANCE, DRC_ENGINE::EvalRules(), EDA_ITEM::GetBoundingBox(), BOARD::GetDesignSettings(), BOARD_ITEM::GetEffectiveShape(), BOARD_DESIGN_SETTINGS::GetHolePlatingThickness(), DRC_CONSTRAINT::GetName(), DRC_CONSTRAINT::GetParentRule(), SHAPE_SEGMENT::GetSeg(), DRC_CONSTRAINT::GetValue(), SHAPE_SEGMENT::GetWidth(), HOLE_CLEARANCE_CONSTRAINT, EDA_RECT::Intersects(), BOARD_ITEM::IsConnected(), DRC_ENGINE::IsErrorLimitExceeded(), DRC_TEST_PROVIDER_CLEARANCE_BASE::m_board, BOARD::m_CopperZoneRTrees, DRC_TEST_PROVIDER::m_drcEngine, m_drcEpsilon, DRC_TEST_PROVIDER::m_msg, m_zones, MessageTextFromValue(), MINOPTMAX< T >::Min(), pad, PCB_PAD_T, PCB_VIA_T, PTH, DRC_RTREE::QueryColliding(), DRC_TEST_PROVIDER::reportViolation(), EDA_ITEM::Type(), DRC_TEST_PROVIDER::userUnits(), and via.

Referenced by testPadClearances(), and testTrackClearances().

◆ testPadAgainstItem()

bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem ( PAD pad,
SHAPE padShape,
PCB_LAYER_ID  layer,
BOARD_ITEM other 
)
private

Definition at line 572 of file drc_test_provider_copper_clearance.cpp.

575 {
576  bool testClearance = !m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE );
577  bool testShorting = !m_drcEngine->IsErrorLimitExceeded( DRCE_SHORTING_ITEMS );
579 
580  // Disable some tests *within* a single footprint
581  if( other->GetParent() == pad->GetParent() )
582  {
583  FOOTPRINT* fp = static_cast<FOOTPRINT*>( pad->GetParent() );
584 
585  // Graphic items are allowed to act as net-ties within their own footprint
586  if( fp->IsNetTie() && ( other->Type() == PCB_FP_SHAPE_T || other->Type() == PCB_PAD_T ) )
587  testClearance = false;
588 
589  // No hole testing within a footprint
590  testHoles = false;
591  }
592 
593  PAD* otherPad = nullptr;
594  PCB_VIA* otherVia = nullptr;
595 
596  if( other->Type() == PCB_PAD_T )
597  otherPad = static_cast<PAD*>( other );
598 
599  if( other->Type() == PCB_VIA_T )
600  otherVia = static_cast<PCB_VIA*>( other );
601 
602  if( !IsCopperLayer( layer ) )
603  testClearance = false;
604 
605  // A NPTH has no cylinder, but it may still have pads on some layers
606  if( pad->GetAttribute() == PAD_ATTRIB::NPTH && !pad->FlashLayer( layer ) )
607  testClearance = false;
608 
609  if( otherPad && otherPad->GetAttribute() == PAD_ATTRIB::NPTH && !otherPad->FlashLayer( layer ) )
610  testClearance = false;
611 
612  // Track clearances are tested in testTrackClearances()
613  if( dynamic_cast<PCB_TRACK*>( other) )
614  testClearance = false;
615 
616  int padNet = pad->GetNetCode();
617  int otherPadNet = otherPad ? otherPad->GetNetCode() : 0;
618  int otherViaNet = otherVia ? otherVia->GetNetCode() : 0;
619 
620  // Pads and vias of the same (defined) net get a waiver on clearance and hole tests
621  if( ( otherPadNet && otherPadNet == padNet ) || ( otherViaNet && otherViaNet == padNet ) )
622  {
623  testClearance = false;
624  testHoles = false;
625  }
626 
627  if( !( pad->GetDrillSize().x > 0 )
628  && !( otherPad && otherPad->GetDrillSize().x > 0 )
629  && !( otherVia && otherVia->GetDrill() > 0 ) )
630  {
631  testHoles = false;
632  }
633 
634  if( !testClearance && !testShorting && !testHoles )
635  return false;
636 
637  std::shared_ptr<SHAPE> otherShape = DRC_ENGINE::GetShape( other, layer );
638  DRC_CONSTRAINT constraint;
639  int clearance;
640  int actual;
641  VECTOR2I pos;
642 
643  if( otherPad && pad->SameLogicalPadAs( otherPad ) )
644  {
645  // If pads are equivalent (ie: from the same footprint with the same pad number)...
646  // ... and have nets...
647  // then they must be the same net
648  if( pad->GetNetCode() && otherPad->GetNetCode()
649  && pad->GetNetCode() != otherPad->GetNetCode()
650  && testShorting )
651  {
652  std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_SHORTING_ITEMS );
653 
654  m_msg.Printf( _( "(nets %s and %s)" ),
655  pad->GetNetname(),
656  otherPad->GetNetname() );
657 
658  drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
659  drce->SetItems( pad, otherPad );
660 
661  reportViolation( drce, otherPad->GetPosition() );
662  }
663 
664  return true;
665  }
666 
667  if( testClearance )
668  {
669  constraint = m_drcEngine->EvalRules( CLEARANCE_CONSTRAINT, pad, other, layer );
670  clearance = constraint.GetValue().Min();
671 
672  if( clearance > 0 && padShape->Collide( otherShape.get(),
673  std::max( 0, clearance - m_drcEpsilon ),
674  &actual, &pos ) )
675  {
676  std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
677 
678  m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
679  constraint.GetName(),
680  MessageTextFromValue( userUnits(), clearance ),
681  MessageTextFromValue( userUnits(), actual ) );
682 
683  drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
684  drce->SetItems( pad, other );
685  drce->SetViolatingRule( constraint.GetParentRule() );
686 
687  reportViolation( drce, (wxPoint) pos );
688  testHoles = false; // No need for multiple violations
689  }
690  }
691 
692  if( testHoles )
693  {
694  constraint = m_drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, pad, other, layer );
695  clearance = constraint.GetValue().Min();
696  }
697 
698  if( testHoles && otherPad && pad->FlashLayer( layer ) && otherPad->GetDrillSize().x )
699  {
700  if( clearance > 0 && padShape->Collide( otherPad->GetEffectiveHoleShape(),
701  std::max( 0, clearance - m_drcEpsilon ),
702  &actual, &pos ) )
703  {
704  std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
705 
706  m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
707  constraint.GetName(),
708  MessageTextFromValue( userUnits(), clearance ),
709  MessageTextFromValue( userUnits(), actual ) );
710 
711  drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
712  drce->SetItems( pad, other );
713  drce->SetViolatingRule( constraint.GetParentRule() );
714 
715  reportViolation( drce, (wxPoint) pos );
716  testHoles = false; // No need for multiple violations
717  }
718  }
719 
720  if( testHoles && otherPad && otherPad->FlashLayer( layer ) && pad->GetDrillSize().x )
721  {
722  if( clearance >= 0 && otherShape->Collide( pad->GetEffectiveHoleShape(),
723  std::max( 0, clearance - m_drcEpsilon ),
724  &actual, &pos ) )
725  {
726  std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
727 
728  m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
729  constraint.GetName(),
730  MessageTextFromValue( userUnits(), clearance ),
731  MessageTextFromValue( userUnits(), actual ) );
732 
733  drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
734  drce->SetItems( pad, other );
735  drce->SetViolatingRule( constraint.GetParentRule() );
736 
737  reportViolation( drce, (wxPoint) pos );
738  testHoles = false; // No need for multiple violations
739  }
740  }
741 
742  if( testHoles && otherVia && otherVia->IsOnLayer( layer ) )
743  {
744  pos = otherVia->GetPosition();
745  otherShape.reset( new SHAPE_SEGMENT( pos, pos, otherVia->GetDrill() ) );
746 
747  if( clearance > 0 && padShape->Collide( otherShape.get(),
748  std::max( 0, clearance - m_drcEpsilon ),
749  &actual, &pos ) )
750  {
751  std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
752 
753  m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
754  constraint.GetName(),
755  MessageTextFromValue( userUnits(), clearance ),
756  MessageTextFromValue( userUnits(), actual ) );
757 
758  drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
759  drce->SetItems( pad, otherVia );
760  drce->SetViolatingRule( constraint.GetParentRule() );
761 
762  reportViolation( drce, (wxPoint) pos );
763  }
764  }
765 
766  return true;
767 }
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
Definition: pcb_track.cpp:360
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:104
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
Definition: drc_item.cpp:266
wxPoint GetPosition() const override
Definition: pcb_track.h:390
static std::shared_ptr< SHAPE > GetShape(BOARD_ITEM *aItem, PCB_LAYER_ID aLayer)
virtual void reportViolation(std::shared_ptr< DRC_ITEM > &item, const wxPoint &aMarkerPos)
bool IsErrorLimitExceeded(int error_code)
const SHAPE_SEGMENT * GetEffectiveHoleShape() const
Return a SHAPE object representing the pad's hole.
Definition: pad.cpp:319
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:93
class PAD, a pad in a footprint
Definition: typeinfo.h:89
T Min() const
Definition: minoptmax.h:33
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const
Check if the boundary of shape (this) lies closer to the point aP than aClearance,...
Definition: shape.h:165
wxString GetName() const
Definition: drc_rule.h:130
DRC_RULE * GetParentRule() const
Definition: drc_rule.h:126
const wxSize & GetDrillSize() const
Definition: pad.h:243
like PAD_PTH, but not plated
bool FlashLayer(int aLayer) const
Check to see whether the pad should be flashed on the specific layer.
Definition: pad.cpp:213
int GetDrill() const
Function GetDrill returns the local drill setting for this PCB_VIA.
Definition: pcb_track.h:460
bool IsNetTie() const
Definition: footprint.h:244
#define _(s)
EDA_UNITS userUnits() const
DRC_CONSTRAINT EvalRules(DRC_CONSTRAINT_T aConstraintType, const BOARD_ITEM *a, const BOARD_ITEM *b, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
Definition: drc_engine.cpp:760
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:797
const MINOPTMAX< int > & GetValue() const
Definition: drc_rule.h:122
wxPoint GetPosition() const override
Definition: pad.h:178
PAD_ATTRIB GetAttribute() const
Definition: pad.h:371
DRC_ENGINE * m_drcEngine
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
Definition: pad.h:57
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:135
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:112

References _, CLEARANCE_CONSTRAINT, SHAPE::Collide(), DRC_ITEM::Create(), DRCE_CLEARANCE, DRCE_HOLE_CLEARANCE, DRCE_SHORTING_ITEMS, DRC_ENGINE::EvalRules(), PAD::FlashLayer(), PAD::GetAttribute(), PCB_VIA::GetDrill(), PAD::GetDrillSize(), PAD::GetEffectiveHoleShape(), DRC_CONSTRAINT::GetName(), BOARD_CONNECTED_ITEM::GetNetCode(), BOARD_CONNECTED_ITEM::GetNetname(), BOARD_ITEM::GetParent(), DRC_CONSTRAINT::GetParentRule(), PAD::GetPosition(), PCB_VIA::GetPosition(), DRC_ENGINE::GetShape(), DRC_CONSTRAINT::GetValue(), HOLE_CLEARANCE_CONSTRAINT, IsCopperLayer(), DRC_ENGINE::IsErrorLimitExceeded(), FOOTPRINT::IsNetTie(), PCB_VIA::IsOnLayer(), DRC_TEST_PROVIDER::m_drcEngine, m_drcEpsilon, DRC_TEST_PROVIDER::m_msg, MessageTextFromValue(), MINOPTMAX< T >::Min(), NPTH, pad, PCB_FP_SHAPE_T, PCB_PAD_T, PCB_VIA_T, DRC_TEST_PROVIDER::reportViolation(), EDA_ITEM::Type(), and DRC_TEST_PROVIDER::userUnits().

Referenced by testPadClearances().

◆ testPadClearances()

void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadClearances ( )
private

Definition at line 770 of file drc_test_provider_copper_clearance.cpp.

771 {
772  const int delta = 50; // This is the number of tests between 2 calls to the progress bar
773 
774  size_t count = 0;
775 
776  for( FOOTPRINT* footprint : m_board->Footprints() )
777  count += footprint->Pads().size();
778 
779  reportAux( "Testing %d pads...", count );
780 
781  int ii = 0;
782  std::map< std::pair<BOARD_ITEM*, BOARD_ITEM*>, int> checkedPairs;
783 
784  for( FOOTPRINT* footprint : m_board->Footprints() )
785  {
786  for( PAD* pad : footprint->Pads() )
787  {
788  if( !reportProgress( ii++, count, delta ) )
789  break;
790 
791  for( PCB_LAYER_ID layer : pad->GetLayerSet().Seq() )
792  {
793  std::shared_ptr<SHAPE> padShape = DRC_ENGINE::GetShape( pad, layer );
794 
795  m_copperTree.QueryColliding( pad, layer, layer,
796  // Filter:
797  [&]( BOARD_ITEM* other ) -> bool
798  {
799  BOARD_ITEM* a = pad;
800  BOARD_ITEM* b = other;
801 
802  // store canonical order so we don't collide in both directions
803  // (a:b and b:a)
804  if( static_cast<void*>( a ) > static_cast<void*>( b ) )
805  std::swap( a, b );
806 
807  if( checkedPairs.count( { a, b } ) )
808  {
809  return false;
810  }
811  else
812  {
813  checkedPairs[ { a, b } ] = 1;
814  return true;
815  }
816  },
817  // Visitor
818  [&]( BOARD_ITEM* other ) -> bool
819  {
820  return testPadAgainstItem( pad, padShape.get(), layer, other );
821  },
823 
824  testItemAgainstZones( pad, layer );
825  }
826  }
827  }
828 }
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:49
static std::shared_ptr< SHAPE > GetShape(BOARD_ITEM *aItem, PCB_LAYER_ID aLayer)
void testItemAgainstZones(BOARD_ITEM *aItem, PCB_LAYER_ID aLayer)
virtual bool reportProgress(int aCount, int aSize, int aDelta)
FOOTPRINTS & Footprints()
Definition: board.h:234
bool testPadAgainstItem(PAD *pad, SHAPE *padShape, PCB_LAYER_ID layer, BOARD_ITEM *other)
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
constexpr int delta
Definition: pad.h:57
virtual void reportAux(wxString fmt,...)
int QueryColliding(BOARD_ITEM *aRefItem, PCB_LAYER_ID aRefLayer, PCB_LAYER_ID aTargetLayer, std::function< bool(BOARD_ITEM *)> aFilter=nullptr, std::function< bool(BOARD_ITEM *)> aVisitor=nullptr, int aClearance=0) const
This is a fast test which essentially does bounding-box overlap given a worst-case clearance.
Definition: drc_rtree.h:178

References delta, BOARD::Footprints(), DRC_ENGINE::GetShape(), DRC_TEST_PROVIDER_CLEARANCE_BASE::m_board, m_copperTree, DRC_TEST_PROVIDER_CLEARANCE_BASE::m_largestClearance, pad, DRC_RTREE::QueryColliding(), DRC_TEST_PROVIDER::reportAux(), DRC_TEST_PROVIDER::reportProgress(), testItemAgainstZones(), and testPadAgainstItem().

Referenced by Run().

◆ testTrackAgainstItem()

bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem ( PCB_TRACK track,
SHAPE trackShape,
PCB_LAYER_ID  layer,
BOARD_ITEM other 
)
private

Definition at line 260 of file drc_test_provider_copper_clearance.cpp.

263 {
264  bool testClearance = !m_drcEngine->IsErrorLimitExceeded( DRCE_CLEARANCE );
266  DRC_CONSTRAINT constraint;
267  int clearance = -1;
268  int actual;
269  VECTOR2I pos;
270 
271  if( other->Type() == PCB_PAD_T )
272  {
273  PAD* pad = static_cast<PAD*>( other );
274 
275  if( pad->GetAttribute() == PAD_ATTRIB::NPTH && !pad->FlashLayer( layer ) )
276  testClearance = false;
277  }
278 
279  if( testClearance )
280  {
281  constraint = m_drcEngine->EvalRules( CLEARANCE_CONSTRAINT, track, other, layer );
282  clearance = constraint.GetValue().Min();
283  }
284 
285  if( clearance >= 0 )
286  {
287  // Special processing for track:track intersections
288  if( track->Type() == PCB_TRACE_T && other->Type() == PCB_TRACE_T )
289  {
290  SEG trackSeg( track->GetStart(), track->GetEnd() );
291  SEG otherSeg( track->GetStart(), track->GetEnd() );
292 
293  if( OPT_VECTOR2I intersection = trackSeg.Intersect( otherSeg ) )
294  {
295  std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_TRACKS_CROSSING );
296  drcItem->SetItems( track, other );
297  drcItem->SetViolatingRule( constraint.GetParentRule() );
298 
299  reportViolation( drcItem, (wxPoint) intersection.get() );
300 
302  }
303  }
304 
305  std::shared_ptr<SHAPE> otherShape = DRC_ENGINE::GetShape( other, layer );
306 
307  if( trackShape->Collide( otherShape.get(), clearance - m_drcEpsilon, &actual, &pos ) )
308  {
309  std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
310 
311  m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
312  constraint.GetName(),
313  MessageTextFromValue( userUnits(), clearance ),
314  MessageTextFromValue( userUnits(), actual ) );
315 
316  drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
317  drce->SetItems( track, other );
318  drce->SetViolatingRule( constraint.GetParentRule() );
319 
320  reportViolation( drce, (wxPoint) pos );
321 
323  return false;
324  }
325  }
326 
327  if( testHoles && ( other->Type() == PCB_VIA_T || other->Type() == PCB_PAD_T ) )
328  {
329  std::unique_ptr<SHAPE_SEGMENT> holeShape;
330 
331  if( other->Type() == PCB_VIA_T )
332  {
333  PCB_VIA* via = static_cast<PCB_VIA*>( other );
334  pos = via->GetPosition();
335 
336  if( via->GetLayerSet().Contains( layer ) )
337  holeShape.reset( new SHAPE_SEGMENT( pos, pos, via->GetDrill() ) );
338  }
339  else if( other->Type() == PCB_PAD_T )
340  {
341  PAD* pad = static_cast<PAD*>( other );
342 
343  if( pad->GetDrillSize().x )
344  holeShape.reset( new SHAPE_SEGMENT( *pad->GetEffectiveHoleShape() ) );
345  }
346 
347  if( holeShape )
348  {
349  constraint = m_drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, other, track, layer );
350  clearance = constraint.GetValue().Min();
351 
352  if( clearance > 0 && trackShape->Collide( holeShape.get(),
353  std::max( 0, clearance - m_drcEpsilon ),
354  &actual, &pos ) )
355  {
356  std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
357 
358  m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
359  constraint.GetName(),
360  MessageTextFromValue( userUnits(), clearance ),
361  MessageTextFromValue( userUnits(), actual ) );
362 
363  drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
364  drce->SetItems( track, other );
365  drce->SetViolatingRule( constraint.GetParentRule() );
366 
367  reportViolation( drce, (wxPoint) pos );
368 
370  return false;
371  }
372  }
373  }
374 
375  return true;
376 }
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:104
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
Definition: drc_item.cpp:266
const wxPoint & GetEnd() const
Definition: pcb_track.h:105
static std::shared_ptr< SHAPE > GetShape(BOARD_ITEM *aItem, PCB_LAYER_ID aLayer)
virtual void reportViolation(std::shared_ptr< DRC_ITEM > &item, const wxPoint &aMarkerPos)
bool IsErrorLimitExceeded(int error_code)
class PAD, a pad in a footprint
Definition: typeinfo.h:89
T Min() const
Definition: minoptmax.h:33
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const
Check if the boundary of shape (this) lies closer to the point aP than aClearance,...
Definition: shape.h:165
wxString GetName() const
Definition: drc_rule.h:130
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
DRC_RULE * GetParentRule() const
Definition: drc_rule.h:126
like PAD_PTH, but not plated
OPT< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:38
bool GetReportAllTrackErrors() const
Definition: drc_engine.h:156
#define _(s)
EDA_UNITS userUnits() const
DRC_CONSTRAINT EvalRules(DRC_CONSTRAINT_T aConstraintType, const BOARD_ITEM *a, const BOARD_ITEM *b, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
Definition: drc_engine.cpp:760
Definition: seg.h:40
const MINOPTMAX< int > & GetValue() const
Definition: drc_rule.h:122
DRC_ENGINE * m_drcEngine
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
Definition: pad.h:57
const wxPoint & GetStart() const
Definition: pcb_track.h:108
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:112

References _, CLEARANCE_CONSTRAINT, SHAPE::Collide(), DRC_ITEM::Create(), DRCE_CLEARANCE, DRCE_HOLE_CLEARANCE, DRCE_TRACKS_CROSSING, DRC_ENGINE::EvalRules(), PCB_TRACK::GetEnd(), DRC_CONSTRAINT::GetName(), DRC_CONSTRAINT::GetParentRule(), DRC_ENGINE::GetReportAllTrackErrors(), DRC_ENGINE::GetShape(), PCB_TRACK::GetStart(), DRC_CONSTRAINT::GetValue(), HOLE_CLEARANCE_CONSTRAINT, DRC_ENGINE::IsErrorLimitExceeded(), DRC_TEST_PROVIDER::m_drcEngine, m_drcEpsilon, DRC_TEST_PROVIDER::m_msg, MessageTextFromValue(), MINOPTMAX< T >::Min(), NPTH, pad, PCB_PAD_T, PCB_TRACE_T, PCB_VIA_T, DRC_TEST_PROVIDER::reportViolation(), EDA_ITEM::Type(), DRC_TEST_PROVIDER::userUnits(), and via.

Referenced by testTrackClearances().

◆ testTrackClearances()

void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances ( )
private

Definition at line 508 of file drc_test_provider_copper_clearance.cpp.

509 {
510  // This is the number of tests between 2 calls to the progress bar
511  const int delta = 100;
512  int ii = 0;
513 
514  reportAux( "Testing %d tracks & vias...", m_board->Tracks().size() );
515 
516  std::map< std::pair<BOARD_ITEM*, BOARD_ITEM*>, int> checkedPairs;
517 
518  for( PCB_TRACK* track : m_board->Tracks() )
519  {
520  if( !reportProgress( ii++, m_board->Tracks().size(), delta ) )
521  break;
522 
523  for( PCB_LAYER_ID layer : track->GetLayerSet().Seq() )
524  {
525  std::shared_ptr<SHAPE> trackShape = track->GetEffectiveShape( layer );
526 
527  m_copperTree.QueryColliding( track, layer, layer,
528  // Filter:
529  [&]( BOARD_ITEM* other ) -> bool
530  {
531  // It would really be better to know what particular nets a nettie
532  // should allow, but for now it is what it is.
533  if( DRC_ENGINE::IsNetTie( other ) )
534  return false;
535 
536  auto otherCItem = dynamic_cast<BOARD_CONNECTED_ITEM*>( other );
537 
538  if( otherCItem && otherCItem->GetNetCode() == track->GetNetCode() )
539  return false;
540 
541  BOARD_ITEM* a = track;
542  BOARD_ITEM* b = other;
543 
544  // store canonical order so we don't collide in both directions
545  // (a:b and b:a)
546  if( static_cast<void*>( a ) > static_cast<void*>( b ) )
547  std::swap( a, b );
548 
549  if( checkedPairs.count( { a, b } ) )
550  {
551  return false;
552  }
553  else
554  {
555  checkedPairs[ { a, b } ] = 1;
556  return true;
557  }
558  },
559  // Visitor:
560  [&]( BOARD_ITEM* other ) -> bool
561  {
562  return testTrackAgainstItem( track, trackShape.get(), layer, other );
563  },
565 
566  testItemAgainstZones( track, layer );
567  }
568  }
569 }
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:49
void testItemAgainstZones(BOARD_ITEM *aItem, PCB_LAYER_ID aLayer)
virtual bool reportProgress(int aCount, int aSize, int aDelta)
static bool IsNetTie(BOARD_ITEM *aItem)
bool testTrackAgainstItem(PCB_TRACK *track, SHAPE *trackShape, PCB_LAYER_ID layer, BOARD_ITEM *other)
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
constexpr int delta
TRACKS & Tracks()
Definition: board.h:231
virtual void reportAux(wxString fmt,...)
int QueryColliding(BOARD_ITEM *aRefItem, PCB_LAYER_ID aRefLayer, PCB_LAYER_ID aTargetLayer, std::function< bool(BOARD_ITEM *)> aFilter=nullptr, std::function< bool(BOARD_ITEM *)> aVisitor=nullptr, int aClearance=0) const
This is a fast test which essentially does bounding-box overlap given a worst-case clearance.
Definition: drc_rtree.h:178

References delta, DRC_ENGINE::IsNetTie(), DRC_TEST_PROVIDER_CLEARANCE_BASE::m_board, m_copperTree, DRC_TEST_PROVIDER_CLEARANCE_BASE::m_largestClearance, DRC_RTREE::QueryColliding(), DRC_TEST_PROVIDER::reportAux(), DRC_TEST_PROVIDER::reportProgress(), testItemAgainstZones(), testTrackAgainstItem(), and BOARD::Tracks().

Referenced by Run().

◆ testZonesToZones()

void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones ( )
private

Definition at line 831 of file drc_test_provider_copper_clearance.cpp.

832 {
833  const int delta = 50; // This is the number of tests between 2 calls to the progress bar
834 
835  SHAPE_POLY_SET buffer;
836  SHAPE_POLY_SET* boardOutline = nullptr;
837 
838  if( m_board->GetBoardPolygonOutlines( buffer ) )
839  boardOutline = &buffer;
840 
841  for( int layer_id = F_Cu; layer_id <= B_Cu; ++layer_id )
842  {
843  PCB_LAYER_ID layer = static_cast<PCB_LAYER_ID>( layer_id );
844  std::vector<SHAPE_POLY_SET> smoothed_polys;
845  smoothed_polys.resize( m_zones.size() );
846 
847  // Skip over layers not used on the current board
848  if( !m_board->IsLayerEnabled( layer ) )
849  continue;
850 
851  for( size_t ii = 0; ii < m_zones.size(); ii++ )
852  {
853  if( m_zones[ii]->IsOnLayer( layer ) )
854  m_zones[ii]->BuildSmoothedPoly( smoothed_polys[ii], layer, boardOutline );
855  }
856 
857  // iterate through all areas
858  for( size_t ia = 0; ia < m_zones.size(); ia++ )
859  {
860  if( !reportProgress( layer_id * m_zones.size() + ia, B_Cu * m_zones.size(), delta ) )
861  break;
862 
863  ZONE* zoneRef = m_zones[ia];
864 
865  if( !zoneRef->IsOnLayer( layer ) )
866  continue;
867 
868  // If we are testing a single zone, then iterate through all other zones
869  // Otherwise, we have already tested the zone combination
870  for( size_t ia2 = ia + 1; ia2 < m_zones.size(); ia2++ )
871  {
872  ZONE* zoneToTest = m_zones[ia2];
873 
874  if( zoneRef == zoneToTest )
875  continue;
876 
877  // test for same layer
878  if( !zoneToTest->IsOnLayer( layer ) )
879  continue;
880 
881  // Test for same net
882  if( zoneRef->GetNetCode() == zoneToTest->GetNetCode()
883  && zoneRef->GetNetCode() >= 0 )
884  continue;
885 
886  // test for different priorities
887  if( zoneRef->GetPriority() != zoneToTest->GetPriority() )
888  continue;
889 
890  // rule areas may overlap at will
891  if( zoneRef->GetIsRuleArea() || zoneToTest->GetIsRuleArea() )
892  continue;
893 
894  // Examine a candidate zone: compare zoneToTest to zoneRef
895 
896  // Get clearance used in zone to zone test.
897  auto constraint = m_drcEngine->EvalRules( CLEARANCE_CONSTRAINT, zoneRef, zoneToTest,
898  layer );
899  int zone2zoneClearance = constraint.GetValue().Min();
900 
901  // test for some corners of zoneRef inside zoneToTest
902  for( auto iterator = smoothed_polys[ia].IterateWithHoles(); iterator; iterator++ )
903  {
904  VECTOR2I currentVertex = *iterator;
905  wxPoint pt( currentVertex.x, currentVertex.y );
906 
907  if( smoothed_polys[ia2].Contains( currentVertex ) )
908  {
909  std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_ZONES_INTERSECT );
910  drce->SetItems( zoneRef, zoneToTest );
911  drce->SetViolatingRule( constraint.GetParentRule() );
912 
913  reportViolation( drce, pt );
914  }
915  }
916 
917  // test for some corners of zoneToTest inside zoneRef
918  for( auto iterator = smoothed_polys[ia2].IterateWithHoles(); iterator; iterator++ )
919  {
920  VECTOR2I currentVertex = *iterator;
921  wxPoint pt( currentVertex.x, currentVertex.y );
922 
923  if( smoothed_polys[ia].Contains( currentVertex ) )
924  {
925  std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_ZONES_INTERSECT );
926  drce->SetItems( zoneToTest, zoneRef );
927  drce->SetViolatingRule( constraint.GetParentRule() );
928 
929  reportViolation( drce, pt );
930  }
931  }
932 
933  // Iterate through all the segments of refSmoothedPoly
934  std::map<wxPoint, int> conflictPoints;
935 
936  for( auto refIt = smoothed_polys[ia].IterateSegmentsWithHoles(); refIt; refIt++ )
937  {
938  // Build ref segment
939  SEG refSegment = *refIt;
940 
941  // Iterate through all the segments in smoothed_polys[ia2]
942  for( auto testIt = smoothed_polys[ia2].IterateSegmentsWithHoles(); testIt; testIt++ )
943  {
944  // Build test segment
945  SEG testSegment = *testIt;
946  wxPoint pt;
947 
948  int ax1, ay1, ax2, ay2;
949  ax1 = refSegment.A.x;
950  ay1 = refSegment.A.y;
951  ax2 = refSegment.B.x;
952  ay2 = refSegment.B.y;
953 
954  int bx1, by1, bx2, by2;
955  bx1 = testSegment.A.x;
956  by1 = testSegment.A.y;
957  bx2 = testSegment.B.x;
958  by2 = testSegment.B.y;
959 
960  int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2,
961  0,
962  ax1, ay1, ax2, ay2,
963  0,
964  zone2zoneClearance,
965  &pt.x, &pt.y );
966 
967  if( d < zone2zoneClearance )
968  {
969  if( conflictPoints.count( pt ) )
970  conflictPoints[ pt ] = std::min( conflictPoints[ pt ], d );
971  else
972  conflictPoints[ pt ] = d;
973  }
974  }
975  }
976 
977  for( const std::pair<const wxPoint, int>& conflict : conflictPoints )
978  {
979  int actual = conflict.second;
980  std::shared_ptr<DRC_ITEM> drce;
981 
982  if( actual <= 0 )
983  {
985  }
986  else
987  {
989 
990  m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
991  constraint.GetName(),
992  MessageTextFromValue( userUnits(), zone2zoneClearance ),
993  MessageTextFromValue( userUnits(), conflict.second ) );
994 
995  drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
996  }
997 
998  drce->SetItems( zoneRef, zoneToTest );
999  drce->SetViolatingRule( constraint.GetParentRule() );
1000 
1001  reportViolation( drce, conflict.first );
1002  }
1003  }
1004  }
1005  }
1006 }
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:104
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
Definition: drc_item.cpp:266
bool GetBoardPolygonOutlines(SHAPE_POLY_SET &aOutlines, OUTLINE_ERROR_HANDLER *aErrorHandler=nullptr)
Extract the board outlines and build a closed polygon from lines, arcs and circle items on edge cut l...
Definition: board.cpp:1880
unsigned GetPriority() const
Definition: zone.h:122
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
Definition: zone.h:733
virtual void reportViolation(std::shared_ptr< DRC_ITEM > &item, const wxPoint &aMarkerPos)
virtual bool reportProgress(int aCount, int aSize, int aDelta)
virtual bool IsOnLayer(PCB_LAYER_ID) const override
Test to see if this object is on the given layer.
Definition: zone.cpp:320
T Min() const
Definition: minoptmax.h:33
bool IsLayerEnabled(PCB_LAYER_ID aLayer) const
A proxy function that calls the correspondent function in m_BoardSettings tests whether a given layer...
Definition: board.cpp:493
Represent a set of closed polygons.
#define _(s)
Handle a list of polygons defining a copper zone.
Definition: zone.h:56
EDA_UNITS userUnits() const
DRC_CONSTRAINT EvalRules(DRC_CONSTRAINT_T aConstraintType, const BOARD_ITEM *a, const BOARD_ITEM *b, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
Definition: drc_engine.cpp:760
Definition: seg.h:40
const MINOPTMAX< int > & GetValue() const
Definition: drc_rule.h:122
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
DRC_ENGINE * m_drcEngine
Definition: layer_ids.h:71
VECTOR2I A
Definition: seg.h:48
constexpr int delta
VECTOR2I B
Definition: seg.h:49

References _, SEG::A, SEG::B, B_Cu, CLEARANCE_CONSTRAINT, DRC_ITEM::Create(), delta, DRCE_CLEARANCE, DRCE_ZONES_INTERSECT, DRC_ENGINE::EvalRules(), F_Cu, BOARD::GetBoardPolygonOutlines(), ZONE::GetIsRuleArea(), BOARD_CONNECTED_ITEM::GetNetCode(), ZONE::GetPriority(), DRC_CONSTRAINT::GetValue(), BOARD::IsLayerEnabled(), ZONE::IsOnLayer(), DRC_TEST_PROVIDER_CLEARANCE_BASE::m_board, DRC_TEST_PROVIDER::m_drcEngine, DRC_TEST_PROVIDER::m_msg, m_zones, MessageTextFromValue(), MINOPTMAX< T >::Min(), DRC_TEST_PROVIDER::reportProgress(), DRC_TEST_PROVIDER::reportViolation(), DRC_TEST_PROVIDER::userUnits(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by Run().

◆ userUnits()

Member Data Documentation

◆ m_board

◆ m_boardOutlineValid

bool DRC_TEST_PROVIDER_CLEARANCE_BASE::m_boardOutlineValid
protectedinherited

Definition at line 53 of file drc_test_provider_clearance_base.h.

◆ m_copperTree

DRC_RTREE DRC_TEST_PROVIDER_COPPER_CLEARANCE::m_copperTree
private

◆ m_drcEngine

DRC_ENGINE* DRC_TEST_PROVIDER::m_drcEngine
protectedinherited

Definition at line 131 of file drc_test_provider.h.

Referenced by DRC_TEST_PROVIDER_HOLE_SIZE::checkPad(), DRC_TEST_PROVIDER_HOLE_SIZE::checkVia(), DRC_TEST_PROVIDER::forEachGeometryItem(), DRC_TEST_PROVIDER_LVS::GetNumPhases(), DRC_TEST_PROVIDER::reportAux(), DRC_TEST_PROVIDER::reportPhase(), DRC_TEST_PROVIDER::reportProgress(), DRC_TEST_PROVIDER::reportRuleStatistics(), DRC_TEST_PROVIDER::reportViolation(), DRC_TEST_PROVIDER_VIA_DIAMETER::Run(), DRC_TEST_PROVIDER_TRACK_WIDTH::Run(), DRC_TEST_PROVIDER_DISALLOW::Run(), DRC_TEST_PROVIDER_HOLE_SIZE::Run(), DRC_TEST_PROVIDER_ANNULAR_WIDTH::Run(), DRC_TEST_PROVIDER_CONNECTIVITY::Run(), DRC_TEST_PROVIDER_SILK_TO_MASK::Run(), DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::Run(), DRC_TEST_PROVIDER_MISC::Run(), DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run(), DRC_TEST_PROVIDER_SILK_CLEARANCE::Run(), DRC_TEST_PROVIDER_HOLE_TO_HOLE::Run(), DRC_TEST_PROVIDER_LVS::Run(), test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run(), Run(), DRC_TEST_PROVIDER_MATCHED_LENGTH::runInternal(), DRC_TEST_PROVIDER::SetDRCEngine(), DRC_TEST_PROVIDER_EDGE_CLEARANCE::testAgainstEdge(), DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances(), DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testFootprintCourtyardDefinitions(), DRC_TEST_PROVIDER_LVS::testFootprints(), DRC_TEST_PROVIDER_HOLE_TO_HOLE::testHoleAgainstHole(), testItemAgainstZones(), testPadAgainstItem(), DRC_TEST_PROVIDER_MISC::testTextVars(), testTrackAgainstItem(), testZonesToZones(), and DRC_TEST_PROVIDER::userUnits().

◆ m_drcEpsilon

int DRC_TEST_PROVIDER_COPPER_CLEARANCE::m_drcEpsilon
private

◆ m_enabled

bool DRC_TEST_PROVIDER::m_enabled = true
protectedinherited

Definition at line 134 of file drc_test_provider.h.

Referenced by DRC_TEST_PROVIDER::Enable(), and DRC_TEST_PROVIDER::IsEnabled().

◆ m_isRuleDriven

◆ m_largestClearance

◆ m_msg

◆ m_stats

std::unordered_map<const DRC_RULE*, int> DRC_TEST_PROVIDER::m_stats
protectedinherited

◆ m_zones

std::vector<ZONE*> DRC_TEST_PROVIDER_COPPER_CLEARANCE::m_zones
private

◆ s_allBasicItems

std::vector< KICAD_T > DRC_TEST_PROVIDER::s_allBasicItems
staticprotectedinherited

◆ s_allBasicItemsButZones

std::vector< KICAD_T > DRC_TEST_PROVIDER::s_allBasicItemsButZones
staticprotectedinherited

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