KiCad PCB EDA Suite
DRC_COURTYARD_TESTER Class Reference

#include <drc_courtyard_tester.h>

Inheritance diagram for DRC_COURTYARD_TESTER:
DRC_TEST_PROVIDER

Public Types

using MARKER_HANDLER = std::function< void(MARKER_PCB *)>
 A callable that can handle a single generated PCB_MARKER. More...
 

Public Member Functions

 DRC_COURTYARD_TESTER (MARKER_HANDLER aMarkerHandler)
 
virtual ~DRC_COURTYARD_TESTER ()
 
bool RunDRC (EDA_UNITS aUnits, BOARD &aBoard) override
 Runs this provider against the given PCB with configured options (if any). More...
 

Protected Member Functions

void HandleMarker (MARKER_PCB *aMarker) const
 Pass a given marker to the marker handler. More...
 

Detailed Description

Definition at line 33 of file drc_courtyard_tester.h.

Member Typedef Documentation

◆ MARKER_HANDLER

using DRC_TEST_PROVIDER::MARKER_HANDLER = std::function<void( MARKER_PCB* )>
inherited

A callable that can handle a single generated PCB_MARKER.

Definition at line 47 of file drc_provider.h.

Constructor & Destructor Documentation

◆ DRC_COURTYARD_TESTER()

DRC_COURTYARD_TESTER::DRC_COURTYARD_TESTER ( MARKER_HANDLER  aMarkerHandler)

Definition at line 37 of file drc_courtyard_tester.cpp.

37  :
38  DRC_TEST_PROVIDER( std::move( aMarkerHandler ) )
39 {
40 }
DRC_TEST_PROVIDER(MARKER_HANDLER aMarkerHandler)
Definition: drc_provider.h:60

◆ ~DRC_COURTYARD_TESTER()

virtual DRC_COURTYARD_TESTER::~DRC_COURTYARD_TESTER ( )
inlinevirtual

Definition at line 38 of file drc_courtyard_tester.h.

38 {};

Member Function Documentation

◆ HandleMarker()

void DRC_TEST_PROVIDER::HandleMarker ( MARKER_PCB aMarker) const
inlineprotectedinherited

◆ RunDRC()

bool DRC_COURTYARD_TESTER::RunDRC ( EDA_UNITS  aUnits,
BOARD aBoard 
)
overridevirtual

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

Note: Board is non-const, as some DRC functions modify the board (e.g. zone fill or polygon coalescing)

Implements DRC_TEST_PROVIDER.

Definition at line 43 of file drc_courtyard_tester.cpp.

44 {
45  // Detects missing (or malformed) footprint courtyards and courtyard incursions (for those
46  // with a courtyard).
47  wxString msg;
48  bool success = true;
49 
50  // Update courtyard polygons, and test for missing courtyard definition:
51  for( MODULE* footprint : aBoard.Modules() )
52  {
53  if( footprint->BuildPolyCourtyard() )
54  {
56  && footprint->GetPolyCourtyardFront().OutlineCount() == 0
57  && footprint->GetPolyCourtyardBack().OutlineCount() == 0 )
58  {
60  drcItem->SetItems( footprint );
61  HandleMarker( new MARKER_PCB( drcItem, footprint->GetPosition() ) );
62  success = false;
63  }
64  else
65  {
66  footprint->GetPolyCourtyardFront().BuildBBoxCaches();
67  footprint->GetPolyCourtyardBack().BuildBBoxCaches();
68  }
69  }
70  else
71  {
73  {
75 
76  msg.Printf( drcItem->GetErrorText() + _( " (not a closed shape)" ) );
77 
78  drcItem->SetErrorMessage( msg );
79  drcItem->SetItems( footprint );
80  HandleMarker( new MARKER_PCB( drcItem, footprint->GetPosition() ) );
81  success = false;
82  }
83  }
84  }
85 
87  {
88  for( auto it1 = aBoard.Modules().begin(); it1 != aBoard.Modules().end(); it1++ )
89  {
90  MODULE* footprint = *it1;
91  SHAPE_POLY_SET& footprintFront = footprint->GetPolyCourtyardFront();
92  SHAPE_POLY_SET& footprintBack = footprint->GetPolyCourtyardBack();
93 
94  if( footprintFront.OutlineCount() == 0 && footprintBack.OutlineCount() == 0 )
95  continue; // No courtyards defined
96 
97  for( auto it2 = it1 + 1; it2 != aBoard.Modules().end(); it2++ )
98  {
99  MODULE* test = *it2;
100  SHAPE_POLY_SET& testFront = test->GetPolyCourtyardFront();
101  SHAPE_POLY_SET& testBack = test->GetPolyCourtyardBack();
102  SHAPE_POLY_SET intersection;
103  bool overlap = false;
104  wxPoint pos;
105 
106  if( footprintFront.OutlineCount() > 0 && testFront.OutlineCount() > 0
107  && footprintFront.BBoxFromCaches().Intersects( testFront.BBoxFromCaches() ) )
108  {
109  intersection.RemoveAllContours();
110  intersection.Append( footprintFront );
111 
112  // Build the common area between footprint and the test:
113  intersection.BooleanIntersection( testFront, SHAPE_POLY_SET::PM_FAST );
114 
115  // If the intersection exists then they overlap
116  if( intersection.OutlineCount() > 0 )
117  {
118  overlap = true;
119  pos = (wxPoint) intersection.CVertex( 0, 0, -1 );
120  }
121  }
122 
123  if( footprintBack.OutlineCount() > 0 && testBack.OutlineCount() > 0
124  && footprintBack.BBoxFromCaches().Intersects( testBack.BBoxFromCaches() ) )
125  {
126  intersection.RemoveAllContours();
127  intersection.Append( footprintBack );
128 
129  intersection.BooleanIntersection( testBack, SHAPE_POLY_SET::PM_FAST );
130 
131  if( intersection.OutlineCount() > 0 )
132  {
133  overlap = true;
134  pos = (wxPoint) intersection.CVertex( 0, 0, -1 );
135  }
136  }
137 
138  if( overlap )
139  {
141  drcItem->SetItems( footprint, test );
142  HandleMarker( new MARKER_PCB( drcItem, pos ) );
143  success = false;
144  }
145  }
146  }
147  }
148 
151  {
152  for( MODULE* footprint : aBoard.Modules() )
153  {
154  SHAPE_POLY_SET& footprintFront = footprint->GetPolyCourtyardFront();
155  SHAPE_POLY_SET& footprintBack = footprint->GetPolyCourtyardBack();
156 
157  if( footprintFront.OutlineCount() == 0 && footprintBack.OutlineCount() == 0 )
158  continue; // No courtyards defined
159 
160  for( MODULE* candidate : aBoard.Modules() )
161  {
162  if( footprint == candidate )
163  continue;
164 
165  for( D_PAD* pad : candidate->Pads() )
166  {
167  if( pad->GetDrillSize().x == 0 || pad->GetDrillSize().y == 0 )
168  continue;
169 
170  wxPoint pos = pad->GetPosition();
171 
172  if( footprintFront.Contains( pos, -1, 0, true /* use bbox caches */ )
173  || footprintBack.Contains( pos, -1, 0, true /* use bbox caches */ ) )
174  {
175  int code = pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED ?
178  DRC_ITEM* drcItem = DRC_ITEM::Create( code );
179  drcItem->SetItems( footprint, pad );
180  HandleMarker( new MARKER_PCB( drcItem, pos ) );
181  success = false;
182  }
183  }
184  }
185  }
186  }
187 
188  return success;
189 }
SHAPE_POLY_SET & GetPolyCourtyardFront()
Used in DRC to test the courtyard area (a complex polygon)
Definition: class_module.h:660
int OutlineCount() const
Returns the number of outlines in the set
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:85
const BOX2I BBoxFromCaches() const
void SetItems(EDA_ITEM *aItem, EDA_ITEM *bItem=nullptr, EDA_ITEM *cItem=nullptr, EDA_ITEM *dItem=nullptr)
Definition: rc_item.h:119
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Returns the index-th vertex in a given hole outline within a given outline
bool Ignore(int aDRCErrorCode)
returns true if the DRC error code's severity is SEVERITY_IGNORE
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:551
footprint has a courtyard but malformed (not convertible to a closed polygon with holes)
Definition: drc.h:63
bool Contains(const VECTOR2I &aP, int aSubpolyIndex=-1, int aAccuracy=0, bool aUseBBoxCaches=false) const
Returns true if a given subpolygon contains the point aP.
wxString GetErrorText() const
Definition: rc_item.h:169
bool Intersects(const BOX2< Vec > &aRect) const
Function Intersects.
Definition: box2.h:235
MODULES & Modules()
Definition: class_board.h:266
SHAPE_POLY_SET.
void HandleMarker(MARKER_PCB *aMarker) const
Pass a given marker to the marker handler.
Definition: drc_provider.h:68
static DRC_ITEM * Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
Definition: drc_item.cpp:197
void BooleanIntersection(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Performs boolean polyset intersection For aFastMode meaning, see function booleanOp
#define _(s)
Definition: 3d_actions.cpp:33
footprint has no courtyard defined
Definition: drc.h:62
void RemoveAllContours()
Removes all outlines & holes (clears) the polygon set.
footprint courtyards overlap
Definition: drc.h:61
void SetErrorMessage(const wxString &aMessage)
Definition: rc_item.h:117
SHAPE_POLY_SET & GetPolyCourtyardBack()
Definition: class_module.h:661
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)

References _, SHAPE_POLY_SET::Append(), SHAPE_POLY_SET::BBoxFromCaches(), SHAPE_POLY_SET::BooleanIntersection(), SHAPE_POLY_SET::Contains(), DRC_ITEM::Create(), SHAPE_POLY_SET::CVertex(), DRCE_MALFORMED_COURTYARD, DRCE_MISSING_COURTYARD, DRCE_NPTH_IN_COURTYARD, DRCE_OVERLAPPING_FOOTPRINTS, DRCE_PTH_IN_COURTYARD, BOARD::GetDesignSettings(), RC_ITEM::GetErrorText(), MODULE::GetPolyCourtyardBack(), MODULE::GetPolyCourtyardFront(), DRC_TEST_PROVIDER::HandleMarker(), BOARD_DESIGN_SETTINGS::Ignore(), BOX2< Vec >::Intersects(), BOARD::Modules(), SHAPE_POLY_SET::OutlineCount(), PAD_ATTRIB_HOLE_NOT_PLATED, SHAPE_POLY_SET::PM_FAST, SHAPE_POLY_SET::RemoveAllContours(), RC_ITEM::SetErrorMessage(), and RC_ITEM::SetItems().

Referenced by DoCourtyardInvalidTest(), DoCourtyardOverlapTest(), and DRC::RunTests().


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