25#include <math_for_graphics.h>
74 virtual bool Run()
override;
76 virtual const wxString
GetName()
const override
78 return wxT(
"clearance" );
83 return wxT(
"Tests copper item clearance" );
135 reportAux( wxT(
"No Clearance constraints found. Tests not run." ) );
143 if( !
reportPhase(
_(
"Checking track & via clearances..." ) ) )
150 if( !
reportPhase(
_(
"Checking hole clearances..." ) ) )
174 if( !
reportPhase(
_(
"Checking copper graphic clearances..." ) ) )
182 if( !
reportPhase(
_(
"Checking copper zone clearances..." ) ) )
213 bool has_error =
false;
218 net = connectedItem->GetNet();
223 otherNet = connectedItem->GetNet();
226 SHAPE* otherShape = otherShapeStorage.get();
232 if(
pad->GetAttribute() == PAD_ATTRIB::NPTH && !
pad->FlashLayer( layer ) )
233 testClearance = testShorting =
false;
236 if( testClearance || testShorting )
248 std::swap( item, other );
249 std::swap( itemShape, otherShape );
250 std::swap( net, otherNet );
265 drcItem->SetItems( item, other );
281 else if( actual == 0 && otherNet && testShorting )
286 msg.Printf(
_(
"(nets %s and %s)" ),
288 otherNet ? otherNet->
GetNetname() :
_(
"<no net>" ) );
290 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
291 drce->SetItems( item, other );
299 else if( testClearance )
302 wxString msg =
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
307 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
308 drce->SetItems( item, other );
322 std::array<BOARD_ITEM*, 2> a{ item, other };
323 std::array<BOARD_ITEM*, 2> b{ other, item };
324 std::array<SHAPE*, 2> a_shape{ itemShape, otherShape };
326 for(
size_t ii = 0; ii < 2; ++ii )
328 std::shared_ptr<SHAPE_SEGMENT> holeShape;
332 if( !(
dynamic_cast<PCB_TRACK*
>( a[ii] ) ) || !b[ii]->HasHole() )
339 if( b[ii]->GetLayerSet().Contains( layer ) )
340 holeShape = b[ii]->GetEffectiveHoleShape();
344 holeShape = b[ii]->GetEffectiveHoleShape();
358 wxString msg =
formatMsg( clearance ?
_(
"(%s clearance %s; actual %s)" )
359 :
_(
"(%s clearance %s; actual < 0)" ),
364 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
365 drce->SetItems( a[ii], b[ii] );
392 BOX2I worstCaseBBox = itemBBox;
404 std::set<PAD*> allowedNetTiePads;
410 if(
pad->IsOnLayer( aLayer ) )
411 allowedNetTiePads.insert(
pad );
415 if( other->IsOnLayer( aLayer ) )
416 allowedNetTiePads.insert( other );
421 if( !allowedNetTiePads.empty() )
425 for(
PAD*
pad : allowedNetTiePads )
427 if(
pad->GetBoundingBox().Intersects( itemBBox )
428 &&
pad->GetEffectiveShape( aLayer )->Collide( itemShape.get() ) )
439 if( !testClearance && !testHoles )
455 bool flashedPad =
pad->FlashLayer( aLayer );
456 bool platedHole =
pad->HasHole() &&
pad->GetAttribute() == PAD_ATTRIB::PTH;
458 if( !flashedPad && !platedHole )
459 testClearance =
false;
470 std::shared_ptr<SHAPE> itemShape = aItem->
GetEffectiveShape( aLayer, FLASHING::DEFAULT );
473 std::max( 0, clearance -
m_drcEpsilon ), &actual, &pos ) )
476 wxString msg =
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
481 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
482 drce->SetItems( aItem, aZone );
488 if( testHoles && aItem->
HasHole() )
490 std::shared_ptr<SHAPE_SEGMENT> holeShape;
514 wxString msg =
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
519 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
520 drce->SetItems( aItem, aZone );
542 if( !testClearance && !testShorts )
551 BOX2I worstCaseBBox = itemBBox;
563 std::shared_ptr<SHAPE> itemShape = aText->
GetEffectiveShape( layer, FLASHING::DEFAULT );
565 if( *aInheritedNet ==
nullptr )
567 if( zoneTree->
QueryColliding( itemBBox, itemShape.get(), layer ) )
568 *aInheritedNet = aZone->
GetNet();
571 if( *aInheritedNet == aZone->
GetNet() )
582 std::max( 0, clearance -
m_drcEpsilon ), &actual, &pos ) )
584 std::shared_ptr<DRC_ITEM> drce;
587 if( testShorts && actual == 0 && *aInheritedNet )
590 msg.Printf(
_(
"(nets %s and %s)" ),
591 ( *aInheritedNet )->GetNetname(),
597 msg =
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
603 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
604 drce->SetItems( aText, aZone );
614 std::map<BOARD_ITEM*, int> freePadsUsageMap;
615 std::unordered_map<PTR_PTR_CACHE_KEY, layers_checked> checkedPairs;
616 std::mutex checkedPairsMutex;
617 std::mutex freePadsUsageMapMutex;
618 std::atomic<size_t> done( 0 );
621 reportAux( wxT(
"Testing %d tracks & vias..." ), count );
625 auto testTrack = [&](
const int start_idx,
const int end_idx )
627 for(
int trackIdx = start_idx; trackIdx < end_idx; ++trackIdx )
641 if( otherCItem && otherCItem->GetNetCode() == track->
GetNetCode() )
649 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
652 std::lock_guard<std::mutex> lock( checkedPairsMutex );
653 auto it = checkedPairs.find( { a, b } );
655 if( it != checkedPairs.end() && ( it->second.layers.test( layer )
662 checkedPairs[ { a, b } ].layers.set( layer );
676 std::lock_guard<std::mutex> lock( freePadsUsageMapMutex );
677 auto it = freePadsUsageMap.find( other );
679 if( it == freePadsUsageMap.end() )
681 freePadsUsageMap[ other ] = track->
GetNetCode();
696 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
702 std::lock_guard<std::mutex> lock( checkedPairsMutex );
703 auto it = checkedPairs.find( { a, b } );
705 if( it != checkedPairs.end() )
706 it->second.has_error =
true;
733 while( done < count )
743 std::this_thread::sleep_for( std::chrono::milliseconds( 250 ) );
761 int padGroupIdx = padToNetTieGroupMap[
pad->GetNumber() ];
765 PAD* otherPad =
static_cast<PAD*
>( other );
767 if( padGroupIdx >= 0 && padGroupIdx == padToNetTieGroupMap[ otherPad->
GetNumber() ] )
768 testClearance = testShorting =
false;
770 if(
pad->SameLogicalPadAs( otherPad ) )
775 testClearance = testShorting =
false;
778 PAD* otherPad =
nullptr;
782 otherPad =
static_cast<PAD*
>( other );
785 otherVia =
static_cast<PCB_VIA*
>( other );
788 testClearance = testShorting =
false;
791 if(
pad->GetAttribute() == PAD_ATTRIB::NPTH && !
pad->FlashLayer( aLayer ) )
792 testClearance = testShorting =
false;
795 testClearance = testShorting =
false;
799 testClearance = testShorting =
false;
801 int padNet =
pad->GetNetCode();
805 otherNet = connectedItem->GetNetCode();
808 if( otherNet && otherNet == padNet )
810 testClearance = testShorting =
false;
814 if( !(
pad->GetDrillSize().x > 0 )
816 && !( otherVia && otherVia->
GetDrill() > 0 ) )
821 if( !testClearance && !testShorting && !testHoles )
830 if( otherPad &&
pad->SameLogicalPadAs( otherPad ) )
840 if(
pad->GetShortNetname().StartsWith( wxS(
"unconnected-(" ) )
849 msg.Printf(
_(
"(nets %s and %s)" ),
853 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
854 drce->SetItems(
pad, otherPad );
862 if( testClearance || testShorting )
877 else if( actual == 0 && otherNet && testShorting )
882 msg.Printf(
_(
"(nets %s and %s)" ),
886 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
887 drce->SetItems(
pad, other );
892 else if( testClearance )
895 wxString msg =
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
900 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
901 drce->SetItems(
pad, other );
919 if( testHoles && otherPad &&
pad->FlashLayer( aLayer ) && otherPad->
HasHole() )
926 wxString msg =
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
931 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
932 drce->SetItems(
pad, other );
939 if( testHoles && otherPad && otherPad->
FlashLayer( aLayer ) &&
pad->HasHole() )
941 if( clearance > 0 && otherShape->Collide(
pad->GetEffectiveHoleShape().get(),
946 wxString msg =
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
951 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
952 drce->SetItems(
pad, other );
960 if( testHoles && otherVia && otherVia->
IsOnLayer( aLayer ) )
967 wxString msg =
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
972 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
973 drce->SetItems(
pad, otherVia );
985 std::atomic<size_t> done( 1 );
988 count += footprint->Pads().size();
990 reportAux( wxT(
"Testing %d pads..." ), count );
992 std::unordered_map<PTR_PTR_CACHE_KEY, int> checkedPairs;
996 std::future<void> retn =
tp.submit(
1001 for( PAD* pad : footprint->Pads() )
1003 for( PCB_LAYER_ID layer : LSET( pad->GetLayerSet() & boardCopperLayers ).Seq() )
1005 if( m_drcEngine->IsCancelled() )
1008 std::shared_ptr<SHAPE> padShape = pad->GetEffectiveShape( layer );
1010 m_board->m_CopperItemRTreeCache->QueryColliding( pad, layer, layer,
1012 [&]( BOARD_ITEM* other ) -> bool
1014 BOARD_ITEM* a = pad;
1015 BOARD_ITEM* b = other;
1019 if( static_cast<void*>( a ) > static_cast<void*>( b ) )
1022 if( checkedPairs.find( { a, b } ) != checkedPairs.end() )
1028 checkedPairs[ { a, b } ] = 1;
1033 [&]( BOARD_ITEM* other ) -> bool
1035 testPadAgainstItem( pad, padShape.get(), layer, other );
1037 return !m_drcEngine->IsCancelled();
1039 m_board->m_DRCMaxClearance );
1041 for( ZONE* zone : m_board->m_DRCCopperZones )
1043 testItemAgainstZone( pad, zone, layer );
1045 if( m_drcEngine->IsCancelled() )
1050 done.fetch_add( 1 );
1055 std::future_status status = retn.wait_for( std::chrono::milliseconds( 250 ) );
1057 while( status != std::future_status::ready )
1059 reportProgress( done, count );
1060 status = retn.wait_for( std::chrono::milliseconds( 250 ) );
1069 std::atomic<size_t> done( 1 );
1072 count += footprint->GraphicalItems().size();
1074 reportAux( wxT(
"Testing %d graphics..." ), count );
1076 auto isKnockoutText =
1082 auto testGraphicAgainstZone =
1098 if( isKnockoutText( item ) )
1108 std::unordered_map<PTR_PTR_CACHE_KEY, layers_checked> checkedPairs;
1110 auto testCopperGraphic =
1121 if( otherCItem && otherCItem->GetNetCode() == aShape->GetNetCode() )
1136 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
1139 auto it = checkedPairs.find( { a, b } );
1141 if( it != checkedPairs.end() && it->second.layers.test( layer ) )
1147 checkedPairs[ { a, b } ].layers.set( layer );
1159 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
1162 auto it = checkedPairs.find( { a, b } );
1165 aShape->GetEffectiveShape().get(),
1168 if( it != checkedPairs.end() )
1169 it->second.has_error =
true;
1177 std::future<void> retn =
tp.submit(
1182 testGraphicAgainstZone( item );
1184 if( item->Type() ==
PCB_SHAPE_T && item->IsOnCopperLayer() )
1185 testCopperGraphic(
static_cast<PCB_SHAPE*
>( item ) );
1187 done.fetch_add( 1 );
1195 for(
BOARD_ITEM* item : footprint->GraphicalItems() )
1197 testGraphicAgainstZone( item );
1199 done.fetch_add( 1 );
1207 std::future_status status = retn.wait_for( std::chrono::milliseconds( 250 ) );
1209 while( status != std::future_status::ready )
1212 status = retn.wait_for( std::chrono::milliseconds( 250 ) );
1223 std::vector<std::map<PCB_LAYER_ID, std::vector<SEG>>> poly_segments;
1228 using report_data = std::tuple<int, int, VECTOR2I, int, int, PCB_LAYER_ID>;
1230 std::vector<std::future<report_data>> futures;
1232 std::atomic<size_t> done( 1 );
1235 [
this, testClearance, testIntersects, &poly_segments, &done]
1236 (
int zoneA,
int zoneB,
int clearance,
PCB_LAYER_ID layer ) -> report_data
1239 std::map<VECTOR2I, int> conflictPoints;
1241 std::vector<SEG>& refSegments = poly_segments[zoneA][layer];
1242 std::vector<SEG>& testSegments = poly_segments[zoneB][layer];
1243 bool reported =
false;
1244 auto invalid_result = std::make_tuple( -1, -1,
VECTOR2I(), 0, 0,
F_Cu );
1246 for(
SEG& refSegment : refSegments )
1248 int ax1 = refSegment.A.x;
1249 int ay1 = refSegment.A.y;
1250 int ax2 = refSegment.B.x;
1251 int ay2 = refSegment.B.y;
1254 for(
SEG& testSegment : testSegments )
1259 int bx1 = testSegment.A.
x;
1260 int by1 = testSegment.A.y;
1261 int bx2 = testSegment.B.x;
1262 int by2 = testSegment.B.y;
1270 int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2, 0,
1271 ax1, ay1, ax2, ay2, 0,
1272 clearance, &pt.
x, &pt.
y );
1276 if( d == 0 && testIntersects )
1278 else if( testClearance )
1283 done.fetch_add( 1 );
1284 return std::make_tuple( zoneA, zoneB, pt, d, clearance, layer );
1289 return invalid_result;
1293 done.fetch_add( 1 );
1294 return invalid_result;
1300 int zone2zoneClearance;
1311 std::vector<SEG>& zone_layer_poly_segs = poly_segments[ii][layer];
1320 if( seg.
A.
x > seg.
B.
x )
1323 zone_layer_poly_segs.push_back( seg );
1326 std::sort( zone_layer_poly_segs.begin(), zone_layer_poly_segs.end() );
1330 std::vector<std::pair<int, int>> zonePairs;
1369 futures.push_back(
tp.submit( checkZones, ia, ia2, zone2zoneClearance, layer ) );
1374 size_t count = futures.size();
1376 for(
auto& task : futures )
1381 std::future_status result;
1385 result = task.wait_for( std::chrono::milliseconds( 250 ) );
1392 if( result == std::future_status::ready )
1394 report_data data = task.get();
1395 int zoneA_idx = std::get<0>( data );
1396 int zoneB_idx = std::get<1>( data );
1398 int actual = std::get<3>( data );
1399 int required = std::get<4>( data );
1402 if( zoneA_idx >= 0 )
1408 std::shared_ptr<DRC_ITEM> drce;
1410 if( actual <= 0 && testIntersects )
1414 else if( testClearance )
1417 wxString msg =
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
1420 std::max( actual, 0 ) );
1422 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
1427 drce->SetItems( zoneA, zoneB );
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
wxString GetNetname() const
NETINFO_ITEM * GetNet() const
Return #NET_INFO object for a given item.
const wxString & GetShortNetname() const
int GetDRCEpsilon() const
Return an epsilon which accounts for rounding errors, etc.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
virtual bool IsConnected() const
Returns information if the object is derived from BOARD_CONNECTED_ITEM.
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
FOOTPRINT * GetParentFootprint() const
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
BOARD_ITEM_CONTAINER * GetParent() const
virtual std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape() const
virtual bool HasHole() const
std::vector< ZONE * > m_DRCCopperZones
bool IsLayerEnabled(PCB_LAYER_ID aLayer) const
A proxy function that calls the correspondent function in m_BoardSettings tests whether a given layer...
int GetCopperLayerCount() const
const FOOTPRINTS & Footprints() const
const TRACKS & Tracks() const
std::shared_ptr< DRC_RTREE > m_CopperItemRTreeCache
std::unordered_map< ZONE *, std::unique_ptr< DRC_RTREE > > m_CopperZoneRTreeCache
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
const DRAWINGS & Drawings() const
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
constexpr bool Intersects(const BOX2< Vec > &aRect) const
SEVERITY GetSeverity() const
const MINOPTMAX< int > & GetValue() const
DRC_RULE * GetParentRule() const
bool GetReportAllTrackErrors() const
bool IsErrorLimitExceeded(int error_code)
DRC_CONSTRAINT EvalRules(DRC_CONSTRAINT_T aConstraintType, const BOARD_ITEM *a, const BOARD_ITEM *b, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
bool IsNetTieExclusion(int aTrackNetCode, PCB_LAYER_ID aTrackLayer, const VECTOR2I &aCollisionPos, BOARD_ITEM *aCollidingItem)
Check if the given collision between a track and another item occurs during the track's entry into a ...
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
Implement an R-tree for fast spatial and layer indexing of connectable items.
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.
void ReportAndShowPathCuToCu(std::shared_ptr< DRC_ITEM > &aDrce, const VECTOR2I &aMarkerPos, int aMarkerLayer, const BOARD_ITEM *aItem1, const BOARD_ITEM *aItem2, PCB_LAYER_ID layer, int aDistance)
void testPadAgainstItem(PAD *pad, SHAPE *padShape, PCB_LAYER_ID layer, BOARD_ITEM *other)
struct DRC_TEST_PROVIDER_COPPER_CLEARANCE::checked layers_checked
virtual bool Run() override
Run this provider against the given PCB with configured options (if any).
DRC_TEST_PROVIDER_COPPER_CLEARANCE()
bool testSingleLayerItemAgainstItem(BOARD_ITEM *item, SHAPE *itemShape, PCB_LAYER_ID layer, BOARD_ITEM *other)
Checks for track/via/hole <-> clearance.
void testItemAgainstZone(BOARD_ITEM *aItem, ZONE *aZone, PCB_LAYER_ID aLayer)
void testGraphicClearances()
void testTrackClearances()
virtual ~DRC_TEST_PROVIDER_COPPER_CLEARANCE()
virtual const wxString GetDescription() const override
virtual const wxString GetName() const override
void testKnockoutTextAgainstZone(BOARD_ITEM *aText, NETINFO_ITEM **aInheritedNet, ZONE *aZone)
wxString formatMsg(const wxString &aFormatString, const wxString &aSource, double aConstraint, double aActual)
virtual bool reportPhase(const wxString &aStageName)
virtual void reportViolation(std::shared_ptr< DRC_ITEM > &item, const VECTOR2I &aMarkerPos, int aMarkerLayer, DRC_CUSTOM_MARKER_HANDLER *aCustomHandler=nullptr)
void reportAux(const wxString &aMsg)
virtual void reportRuleStatistics()
virtual bool reportProgress(size_t aCount, size_t aSize, size_t aDelta=1)
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
KICAD_T Type() const
Returns the type of object.
LSET is a set of PCB_LAYER_IDs.
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
bool Contains(PCB_LAYER_ID aLayer) const
See if the layer set contains a PCB layer.
Handle the data for a net.
const wxString & GetNetname() const
bool FlashLayer(int aLayer, bool aOnlyCheckIfPermitted=false) const
Check to see whether the pad should be flashed on the specific layer.
const VECTOR2I & GetDrillSize() const
PAD_ATTRIB GetAttribute() const
const wxString & GetNumber() const
VECTOR2I GetPosition() const override
bool HasHole() const override
std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape() const override
Return a SHAPE_SEGMENT object representing the pad's hole.
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
const VECTOR2I & GetStart() const
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
const VECTOR2I & GetEnd() const
int GetDrill() const
Return the local drill setting for this PCB_VIA.
std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape() const override
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Compute intersection point of segment (this) with segment aSeg.
Represent a set of closed polygons.
int FullPointCount() const
Return the number of points in the shape poly set.
void BuildBBoxCaches() const
Construct BBoxCaches for Contains(), below.
SEGMENT_ITERATOR IterateSegmentsWithHoles()
Returns an iterator object, for all outlines in the set (with holes)
const BOX2I BBoxFromCaches() const
An abstract shape on 2D plane.
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,...
Handle a list of polygons defining a copper zone.
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
const BOX2I GetBoundingBox() const override
virtual PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
virtual bool IsOnLayer(PCB_LAYER_ID) const override
Test to see if this object is on the given layer.
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
@ HOLE_CLEARANCE_CONSTRAINT
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
static DRC_REGISTER_TEST_PROVIDER< DRC_TEST_PROVIDER_ANNULAR_WIDTH > dummy
std::optional< VECTOR2I > OPT_VECTOR2I
static bool Collide(const SHAPE_CIRCLE &aA, const SHAPE_CIRCLE &aB, int aClearance, int *aActual, VECTOR2I *aLocation, VECTOR2I *aMTV)
checked(PCB_LAYER_ID aLayer)
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::thread_pool thread_pool
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
@ PCB_REFERENCE_IMAGE_T
class PCB_REFERENCE_IMAGE, bitmap on a layer
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
VECTOR2< int32_t > VECTOR2I