70 virtual bool Run()
override;
72 virtual const wxString
GetName()
const override {
return wxT(
"clearance" ); };
109 if(
m_board->m_DRCMaxClearance <= 0 )
111 REPORT_AUX( wxT(
"No Clearance constraints found. Tests not run." ) );
119 if( !
reportPhase(
_(
"Checking track & via clearances..." ) ) )
126 if( !
reportPhase(
_(
"Checking hole clearances..." ) ) )
150 if( !
reportPhase(
_(
"Checking copper graphic clearances..." ) ) )
157 if( !
reportPhase(
_(
"Checking copper graphic hole clearances..." ) ) )
165 if( !
reportPhase(
_(
"Checking copper zone clearances..." ) ) )
194 bool has_error =
false;
199 itemNet = connectedItem->GetNet();
202 otherNet = connectedItem->GetNet();
204 if( itemNet == otherNet )
205 testClearance = testShorting =
false;
207 std::shared_ptr<SHAPE> otherShape_shared_ptr;
213 if( !
pad->FlashLayer( layer ) )
216 testClearance = testShorting =
false;
218 otherShape_shared_ptr =
pad->GetEffectiveHoleShape();
225 if( !
via->FlashLayer( layer ) )
226 otherShape_shared_ptr =
via->GetEffectiveHoleShape();
229 if( !otherShape_shared_ptr )
232 SHAPE* otherShape = otherShape_shared_ptr.get();
238 std::swap( item, other );
239 std::swap( itemShape, otherShape );
240 std::swap( itemNet, otherNet );
243 if( testClearance || testShorting )
263 drcItem->SetItems( item, other );
277 else if(
actual == 0 && otherNet && testShorting )
280 drcItem->SetErrorDetail( wxString::Format(
_(
"(nets %s and %s)" ),
282 otherNet ? otherNet->
GetNetname() :
_(
"<no net>" ) ) );
283 drcItem->SetItems( item, other );
290 else if( testClearance )
293 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
297 drcItem->SetItems( item, other );
310 std::array<BOARD_ITEM*, 2> a{ item, other };
311 std::array<BOARD_ITEM*, 2> b{ other, item };
312 std::array<NETINFO_ITEM*, 2> b_net{ otherNet, itemNet };
313 std::array<SHAPE*, 2> a_shape{ itemShape, otherShape };
315 for(
size_t ii = 0; ii < 2; ++ii )
317 std::shared_ptr<SHAPE_SEGMENT> holeShape;
321 if( b[ii]->GetLayerSet().Contains( layer ) )
322 holeShape = b[ii]->GetEffectiveHoleShape();
328 if( b[ii]->HasHole() )
329 holeShape = b[ii]->GetEffectiveHoleShape();
334 int netcode = b_net[ii] ? b_net[ii]->GetNetCode() : 0;
336 if( netcode &&
m_drcEngine->IsNetTieExclusion( netcode, layer, holeShape->Centre(), a[ii] ) )
351 :
_(
"(%s clearance %s; actual < 0)" ),
355 drcItem->SetItems( a[ii], b[ii] );
381 BOX2I worstCaseBBox = itemBBox;
393 std::set<PAD*> allowedNetTiePads;
399 if(
pad->IsOnLayer( aLayer ) )
400 allowedNetTiePads.insert(
pad );
404 if( other->IsOnLayer( aLayer ) )
405 allowedNetTiePads.insert( other );
410 if( !allowedNetTiePads.empty() )
414 for(
PAD*
pad : allowedNetTiePads )
416 if(
pad->GetBoundingBox().Intersects( itemBBox )
417 &&
pad->GetEffectiveShape( aLayer )->Collide( itemShape.get() ) )
428 if( !testClearance && !testHoles )
444 bool flashedPad =
pad->FlashLayer( aLayer );
447 if( !flashedPad && !platedHole )
448 testClearance =
false;
465 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
469 drcItem->SetItems( aItem, aZone );
475 if( testHoles && aItem->
HasHole() )
477 std::shared_ptr<SHAPE_SEGMENT> holeShape;
501 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
505 drcItem->SetItems( aItem, aZone );
529 if( !testClearance && !testShorts )
538 BOX2I worstCaseBBox = itemBBox;
552 if( *aInheritedNet ==
nullptr )
554 if( zoneTree->
QueryColliding( itemBBox, itemShape.get(), layer ) )
555 *aInheritedNet = aZone->
GetNet();
558 if( *aInheritedNet == aZone->
GetNet() )
571 std::shared_ptr<DRC_ITEM> drcItem;
573 if( testShorts &&
actual == 0 && *aInheritedNet )
576 drcItem->SetErrorDetail( wxString::Format(
_(
"(nets %s and %s)" ),
577 ( *aInheritedNet )->GetNetname(),
583 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
589 drcItem->SetItems( aText, aZone );
599 std::map<BOARD_ITEM*, int> freePadsUsageMap;
600 std::unordered_map<PTR_PTR_CACHE_KEY, LAYERS_CHECKED> checkedPairs;
601 std::mutex checkedPairsMutex;
602 std::mutex freePadsUsageMapMutex;
603 std::atomic<size_t> done( 0 );
604 size_t count =
m_board->Tracks().size();
606 REPORT_AUX( wxString::Format( wxT(
"Testing %d tracks & vias..." ), count ) );
611 [&](
const int trackIdx )
619 m_board->m_CopperItemRTreeCache->QueryColliding( track, layer, layer,
633 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
636 std::lock_guard<std::mutex> lock( checkedPairsMutex );
637 auto it = checkedPairs.find( { a, b } );
639 if( it != checkedPairs.end()
640 && ( it->second.layers.test( layer ) || ( it->second.has_error ) ) )
646 checkedPairs[ { a, b } ].layers.set( layer );
660 std::lock_guard<std::mutex> lock( freePadsUsageMapMutex );
661 auto it = freePadsUsageMap.find( other );
663 if( it == freePadsUsageMap.end() )
665 freePadsUsageMap[ other ] = track->
GetNetCode();
685 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
688 std::lock_guard<std::mutex> lock( checkedPairsMutex );
689 auto it = checkedPairs.find( { a, b } );
691 if( it != checkedPairs.end() )
692 it->second.has_error =
true;
716 auto track_futures =
tp.submit_loop( 0,
m_board->Tracks().size(), testTrack );
718 while( done < count )
725 track_futures.wait();
729 std::this_thread::sleep_for( std::chrono::milliseconds( 250 ) );
747 int padGroupIdx = padToNetTieGroupMap[
pad->GetNumber() ];
751 PAD* otherPad =
static_cast<PAD*
>( other );
753 if( padGroupIdx >= 0 && padGroupIdx == padToNetTieGroupMap[ otherPad->
GetNumber() ] )
754 testClearance = testShorting =
false;
756 if(
pad->SameLogicalPadAs( otherPad ) )
761 testClearance = testShorting =
false;
765 PAD* otherPad =
nullptr;
769 otherPad =
static_cast<PAD*
>( other );
772 otherVia =
static_cast<PCB_VIA*
>( other );
775 testClearance = testShorting =
false;
779 testClearance = testShorting =
false;
782 testClearance = testShorting =
false;
786 testClearance = testShorting =
false;
790 testClearance = testShorting =
false;
792 int padNet =
pad->GetNetCode();
793 int otherNet = otherCItem ? otherCItem->
GetNetCode() : 0;
796 if( otherNet && otherNet == padNet )
798 testClearance = testShorting =
false;
802 if( !(
pad->GetDrillSize().x > 0 )
804 && !( otherVia && otherVia->
GetDrill() > 0 ) )
809 if( !testClearance && !testShorting && !testHoles )
817 bool has_error =
false;
819 auto sub_e = [
this](
int aclearance )
824 if( otherPad &&
pad->SameLogicalPadAs( otherPad ) )
834 if(
pad->GetShortNetname().StartsWith( wxS(
"unconnected-(" ) )
841 drcItem->SetErrorDetail( wxString::Format(
_(
"(nets %s and %s)" ),
844 drcItem->SetItems(
pad, otherPad );
852 if( testClearance || testShorting )
861 if(
m_drcEngine->IsNetTieExclusion(
pad->GetNetCode(), aLayer, pos, other ) )
866 else if(
actual == 0 && padNet && otherNet && testShorting )
869 drcItem->SetErrorDetail( wxString::Format(
_(
"(nets %s and %s)" ),
872 drcItem->SetItems(
pad, other );
877 else if( testClearance )
880 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
884 drcItem->SetItems(
pad, other );
897 if( shape->Collide( aOtherShape, sub_e( aClearance ), &
actual, &pos ) )
900 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
904 drcItem->SetItems( item, otherItem );
920 if( testHoles && otherPad && otherPad->
HasHole() )
924 if( !
pad->FlashLayer( aLayer ) )
931 if( testHoles && otherVia && otherVia->
HasHole() )
949 std::atomic<size_t> done( 1 );
951 std::unordered_map<PTR_PTR_CACHE_KEY, LAYERS_CHECKED> checkedPairs;
952 std::mutex checkedPairsMutex;
956 const auto fp_check =
968 std::shared_ptr<SHAPE> padShape =
pad->GetEffectiveShape( layer );
970 m_board->m_CopperItemRTreeCache->QueryColliding(
pad, layer, layer,
979 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
982 std::lock_guard<std::mutex> lock( checkedPairsMutex );
983 auto it = checkedPairs.find( { a, b } );
985 if( it != checkedPairs.end()
986 && ( it->second.layers.test( layer ) || it->second.has_error ) )
992 checkedPairs[ { a, b } ].layers.set( layer );
1006 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
1009 std::lock_guard<std::mutex> lock( checkedPairsMutex );
1010 auto it = checkedPairs.find( { a, b } );
1012 if( it != checkedPairs.end() )
1013 it->second.has_error =
true;
1030 done.fetch_add( 1 );
1033 size_t numFootprints =
m_board->Footprints().size();
1034 auto returns =
tp.submit_loop( 0, numFootprints, fp_check );
1037 for(
size_t ii = 0; ii < returns.size(); ++ii )
1039 while( returns[ii].wait_for( std::chrono::milliseconds( 250 ) ) != std::future_status::ready )
1048 size_t count =
m_board->Drawings().size();
1049 std::atomic<size_t> done( 1 );
1052 count += footprint->GraphicalItems().size();
1054 REPORT_AUX( wxString::Format( wxT(
"Testing %d graphics..." ), count ) );
1056 auto isKnockoutText =
1062 auto testGraphicAgainstZone =
1078 if( isKnockoutText( item ) )
1088 std::unordered_map<PTR_PTR_CACHE_KEY, LAYERS_CHECKED> checkedPairs;
1089 std::mutex checkedPairsMutex;
1091 auto testCopperGraphic =
1092 [
this, &checkedPairs, &checkedPairsMutex](
BOARD_ITEM* graphic )
1096 m_board->m_CopperItemRTreeCache->QueryColliding( graphic, layer, layer,
1103 && graphic->GetParentFootprint()
1115 int graphicNet = graphic_bci ? graphic_bci->
GetNetCode() : 0;
1116 int otherNet = other_bci ? other_bci->
GetNetCode() : 0;
1118 if( graphicNet && graphicNet == otherNet )
1126 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
1129 std::lock_guard<std::mutex> lock( checkedPairsMutex );
1130 auto it = checkedPairs.find( { a, b } );
1132 if( it != checkedPairs.end() && it->second.layers.test( layer ) )
1138 checkedPairs[ { a, b } ].layers.set( layer );
1155 (void)
tp.submit_task(
1156 [
this, item, &done, testGraphicAgainstZone, testCopperGraphic]()
1158 if( !m_drcEngine->IsCancelled() )
1160 testGraphicAgainstZone( item );
1162 if( ( item->Type() == PCB_SHAPE_T || item->Type() == PCB_BARCODE_T )
1163 && item->IsOnCopperLayer() )
1165 testCopperGraphic( static_cast<PCB_SHAPE*>( item ) );
1168 done.fetch_add( 1 );
1173 for(
FOOTPRINT* footprint : m_board->Footprints() )
1175 (void)
tp.submit_task(
1176 [
this, footprint, &done, testGraphicAgainstZone, testCopperGraphic]()
1178 for( BOARD_ITEM* item : footprint->GraphicalItems() )
1180 if( !m_drcEngine->IsCancelled() )
1182 testGraphicAgainstZone( item );
1184 if( ( item->Type() == PCB_SHAPE_T || item->Type() == PCB_BARCODE_T )
1185 && item->IsOnCopperLayer() )
1187 testCopperGraphic( static_cast<PCB_SHAPE*>( item ) );
1190 done.fetch_add( 1 );
1198 reportProgress( done, count );
1200 if( m_drcEngine->IsCancelled() )
1203 if(
tp.wait_for( std::chrono::milliseconds( 250 ) ) )
1214 std::vector<std::map<PCB_LAYER_ID, std::vector<SEG>>> poly_segments;
1215 poly_segments.resize(
m_board->m_DRCCopperZones.size() );
1218 std::atomic<size_t> done( 0 );
1221 auto reportZoneZoneViolation =
1225 std::shared_ptr<DRC_ITEM> drcItem;
1227 if( constraint.IsNull() )
1230 drcItem->SetErrorDetail(
_(
"(intersecting zones must have distinct priorities)" ) );
1231 drcItem->SetItems( zoneA, zoneB );
1237 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
1238 constraint.GetName(),
1239 constraint.GetValue().Min(),
1240 std::max(
actual, 0 ) ) );
1241 drcItem->SetItems( zoneA, zoneB );
1242 drcItem->SetViolatingRule( constraint.GetParentRule() );
1248 [
this, testClearance, testIntersects, reportZoneZoneViolation, &poly_segments, &done]
1249 (
int zoneA_idx,
int zoneB_idx,
bool sameNet,
PCB_LAYER_ID layer ) ->
void
1251 ZONE* zoneA =
m_board->m_DRCCopperZones[zoneA_idx];
1252 ZONE* zoneB =
m_board->m_DRCCopperZones[zoneB_idx];
1256 if( sameNet && testIntersects )
1260 done.fetch_add( 1 );
1265 else if( !sameNet && testClearance )
1272 std::map<VECTOR2I, int> conflictPoints;
1274 std::vector<SEG>& refSegments = poly_segments[zoneA_idx][layer];
1275 std::vector<SEG>& testSegments = poly_segments[zoneB_idx][layer];
1278 for(
SEG& refSegment : refSegments )
1281 for(
SEG& testSegment : testSegments )
1285 if( refSegment.B.x < testSegment.A.x )
1288 int64_t dist_sq = 0;
1290 refSegment.NearestPoints( testSegment, pt, other_pt, dist_sq );
1291 actual = std::floor( std::sqrt( dist_sq ) + 0.5 );
1295 done.fetch_add( 1 );
1296 reportZoneZoneViolation( zoneA, zoneB, pt,
actual, constraint, layer );
1304 done.fetch_add( 1 );
1308 std::map<PCB_LAYER_ID, std::vector<size_t>> zone_idx_by_layer;
1310 for (
size_t ii = 0; ii <
m_board->m_DRCCopperZones.size(); ii++ )
1319 zone_idx_by_layer[layer].push_back( ii );
1326 if( !
m_board->IsLayerEnabled( layer ) )
1329 for(
size_t ii : zone_idx_by_layer[layer] )
1333 std::vector<SEG>& zone_layer_poly_segs = poly_segments[ii][layer];
1334 zone_layer_poly_segs.reserve( poly->FullPointCount() );
1336 for(
auto it = poly->IterateSegmentsWithHoles(); it; it++ )
1340 if( seg.
A.
x > seg.
B.
x )
1343 zone_layer_poly_segs.push_back( seg );
1350 std::sort( zone_layer_poly_segs.begin(), zone_layer_poly_segs.end(),
1351 [](
const SEG& a,
const SEG& b ) ->
bool
1353 if( a.A.x != b.A.x )
1354 return a.A.x < b.A.x;
1356 if( a.A.y != b.A.y )
1357 return a.A.y < b.A.y;
1359 if( a.B.x != b.B.x )
1360 return a.B.x < b.B.x;
1362 return a.B.y < b.B.y;
1367 for(
auto it_a = zone_idx_by_layer[layer].begin(); it_a != zone_idx_by_layer[layer].end(); ++it_a )
1372 for(
auto it_a2 = std::next( it_a ); it_a2 != zone_idx_by_layer[layer].end(); ++it_a2 )
1374 size_t ia2 = *it_a2;
1397 polyA = zoneA->
GetFill( layer );
1398 polyB = zoneB->
GetFill( layer );
1401 if( !polyA || !polyB
1406 (void)
tp.submit_task(
1407 [checkZones, ia, ia2, sameNet, layer]()
1409 checkZones( ia, ia2, sameNet, layer );
1422 if(
tp.wait_for( std::chrono::milliseconds( 250 ) ) )
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
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
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
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.
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()=default
virtual const wxString GetName() const override
bool testPadAgainstItem(PAD *pad, SHAPE *padShape, PCB_LAYER_ID layer, BOARD_ITEM *other)
void testKnockoutTextAgainstZone(BOARD_ITEM *aText, NETINFO_ITEM **aInheritedNet, ZONE *aZone)
virtual bool reportPhase(const wxString &aStageName)
void reportTwoShapeGeometry(std::shared_ptr< DRC_ITEM > &aDrcItem, const VECTOR2I &aMarkerPos, const SHAPE *aShape1, const SHAPE *aShape2, PCB_LAYER_ID aLayer, int aDistance)
void reportTwoItemGeometry(std::shared_ptr< DRC_ITEM > &aDrcItem, const VECTOR2I &aMarkerPos, const BOARD_ITEM *aItem1, const BOARD_ITEM *aItem2, PCB_LAYER_ID aLayer, int aDistance)
void reportViolation(std::shared_ptr< DRC_ITEM > &item, const VECTOR2I &aMarkerPos, int aMarkerLayer, const std::function< void(PCB_MARKER *)> &aPathGenerator=[](PCB_MARKER *){})
void reportTwoPointGeometry(std::shared_ptr< DRC_ITEM > &aDrcItem, const VECTOR2I &aMarkerPos, const VECTOR2I &ptA, const VECTOR2I &ptB, PCB_LAYER_ID aLayer)
wxString formatMsg(const wxString &aFormatString, const wxString &aSource, double aConstraint, double aActual, EDA_DATA_TYPE aDataType=EDA_DATA_TYPE::DISTANCE)
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()
return AllCuMask( MAX_CU_LAYERS );
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 HasHole() 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.
bool Collide(const SHAPE *aShape, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if the boundary of shape (this) lies closer to the shape aShape than aClearance,...
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.
SHAPE_POLY_SET * Outline()
SHAPE_POLY_SET * GetFill(PCB_LAYER_ID aLayer)
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
unsigned GetAssignedPriority() const
virtual 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.
@ HOLE_CLEARANCE_CONSTRAINT
@ DEFAULT
Flashing follows connectivity.
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
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
@ PTH
Plated through hole pad.
std::optional< VECTOR2I > OPT_VECTOR2I
static bool Collide(const SHAPE_CIRCLE &aA, const SHAPE_CIRCLE &aB, int aClearance, int *aActual, VECTOR2I *aLocation, VECTOR2I *aMTV)
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::priority_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_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
VECTOR2< int32_t > VECTOR2I