69 virtual bool Run()
override;
71 virtual const wxString
GetName()
const override {
return wxT(
"clearance" ); };
122 if(
m_board->m_DRCMaxClearance <= 0 )
124 REPORT_AUX( wxT(
"No Clearance constraints found. Tests not run." ) );
130 struct ZONE_INDEX_GUARD
132 ~ZONE_INDEX_GUARD() {
index.Clear(); }
140 if( !
reportPhase(
_(
"Checking track & via clearances..." ) ) )
147 if( !
reportPhase(
_(
"Checking hole clearances..." ) ) )
171 if( !
reportPhase(
_(
"Checking copper graphic clearances..." ) ) )
178 if( !
reportPhase(
_(
"Checking copper graphic hole clearances..." ) ) )
186 if( !
reportPhase(
_(
"Checking copper zone clearances..." ) ) )
191 if( !
reportPhase(
_(
"Checking teardrop clearances..." ) ) )
202 std::vector<ZONE*>& aZones )
219 SHAPE* aPreparedOther )
228 bool has_error =
false;
238 if( itemNet == otherNet )
239 testClearance = testShorting =
false;
241 std::shared_ptr<SHAPE> otherShape_shared_ptr;
247 if( !
pad->FlashLayer( layer ) )
250 testClearance = testShorting =
false;
259 if( !
via->FlashLayer( layer ) )
264 SHAPE* otherShape = otherShape_shared_ptr ? otherShape_shared_ptr.get() : aPreparedOther;
270 std::swap( item, other );
271 std::swap( itemShape, otherShape );
272 std::swap( itemNet, otherNet );
275 if( testClearance || testShorting )
295 drcItem->SetItems( item, other );
310 else if(
actual == 0 && otherNet && testShorting )
312 int itemNetCode = itemNet ? itemNet->
GetNetCode() : 0;
313 int otherNetCode = otherNet ? otherNet->
GetNetCode() : 0;
316 drcItem->SetErrorDetail( wxString::Format(
_(
"(nets %s and %s)" ),
317 itemNetCode ? itemNet->
GetNetname() :
_(
"<no net>" ),
318 otherNetCode ? otherNet->
GetNetname() :
_(
"<no net>" ) ) );
319 drcItem->SetItems( item, other );
326 else if( testClearance )
329 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
333 drcItem->SetItems( item, other );
346 std::array<BOARD_ITEM*, 2> a{ item, other };
347 std::array<BOARD_ITEM*, 2> b{ other, item };
348 std::array<NETINFO_ITEM*, 2> b_net{ otherNet, itemNet };
349 std::array<SHAPE*, 2> a_shape{ itemShape, otherShape };
351 for(
size_t ii = 0; ii < 2; ++ii )
353 std::shared_ptr<SHAPE_SEGMENT> holeShape;
357 if( b[ii]->GetLayerSet().Contains( layer ) )
364 if( b[ii]->HasHole() )
370 int netcode = b_net[ii] ? b_net[ii]->GetNetCode() : 0;
372 if( netcode &&
m_drcEngine->IsNetTieExclusion( netcode, layer, holeShape->Centre(), a[ii] ) )
386 :
_(
"(%s clearance %s; actual < 0)" ),
390 drcItem->SetItems( a[ii], b[ii] );
416 BOX2I worstCaseBBox = itemBBox;
428 std::set<PAD*> allowedNetTiePads;
434 if(
pad->IsOnLayer( aLayer ) )
435 allowedNetTiePads.insert(
pad );
439 if( other->IsOnLayer( aLayer ) )
440 allowedNetTiePads.insert( other );
445 if( !allowedNetTiePads.empty() )
449 for(
PAD*
pad : allowedNetTiePads )
451 if(
pad->GetBoundingBox( aLayer ).Intersects( itemBBox )
452 &&
pad->GetEffectiveShape( aLayer )->Collide( itemShape.get() ) )
463 if( !testClearance && !testHoles )
479 bool flashedPad =
pad->FlashLayer( aLayer );
482 if( !flashedPad && !platedHole )
483 testClearance =
false;
499 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
503 drcItem->SetItems( aItem, aZone );
509 if( testHoles && aItem->
HasHole() )
511 std::shared_ptr<SHAPE_SEGMENT> holeShape;
533 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
537 drcItem->SetItems( aItem, aZone );
561 if( !testClearance && !testShorts )
570 BOX2I worstCaseBBox = itemBBox;
584 if( *aInheritedNet ==
nullptr )
586 if( zoneTree->
QueryColliding( itemBBox, itemShape.get(), layer ) )
587 *aInheritedNet = aZone->
GetNet();
590 if( *aInheritedNet == aZone->
GetNet() )
602 std::shared_ptr<DRC_ITEM> drcItem;
604 if( testShorts &&
actual == 0 && *aInheritedNet )
606 int inheritedNetCode = ( *aInheritedNet )->GetNetCode();
607 const wxString& inheritedNetname = ( *aInheritedNet )->GetNetname();
611 drcItem->SetErrorDetail( wxString::Format(
_(
"(nets %s and %s)" ),
612 inheritedNetCode ? inheritedNetname :
_(
"<no net>" ),
613 zoneNetCode ? aZone->
GetNetname() :
_(
"<no net>" ) ) );
618 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
624 drcItem->SetItems( aText, aZone );
634 std::map<BOARD_ITEM*, int> freePadsUsageMap;
635 std::mutex freePadsUsageMapMutex;
636 std::atomic<size_t> done( 0 );
637 size_t count =
m_board->Tracks().size();
639 REPORT_AUX( wxString::Format( wxT(
"Testing %d tracks & vias..." ), count ) );
644 [&](
const int trackIdx )
647 std::vector<ZONE*> zones;
653 m_board->m_CopperItemRTreeCache->QueryCollidingPreparedCopper( track, trackShape, layer,
677 [&](
BOARD_ITEM* other,
const std::shared_ptr<SHAPE>& aPreparedOther ) ->
bool
684 if( aPreparedOther->Collide( trackShape.get() ) )
686 std::lock_guard<std::mutex> lock( freePadsUsageMapMutex );
687 auto it = freePadsUsageMap.find( other );
689 if( it == freePadsUsageMap.end() )
691 freePadsUsageMap[ other ] = track->
GetNetCode();
702 aPreparedOther.get() ) )
710 m_board->m_DRCMaxClearance, true );
714 for(
ZONE* zone : zones )
728 auto track_futures =
tp.submit_loop( 0,
m_board->Tracks().size(), testTrack,
m_board->Tracks().size() );
730 while( done < count )
737 track_futures.wait();
741 track_futures.wait_for( std::chrono::milliseconds( 250 ) );
748 SHAPE* aPreparedOther )
759 int padGroupIdx = padToNetTieGroupMap[
pad->GetNumber() ];
763 PAD* otherPad =
static_cast<PAD*
>( other );
765 if( padGroupIdx >= 0 && padGroupIdx == padToNetTieGroupMap[ otherPad->
GetNumber() ] )
766 testClearance = testShorting =
false;
768 if(
pad->SameLogicalPadAs( otherPad ) )
773 testClearance = testShorting =
false;
778 PAD* otherPad =
nullptr;
782 otherPad =
static_cast<PAD*
>( other );
785 otherVia =
static_cast<PCB_VIA*
>( other );
788 testClearance = testShorting =
false;
792 testClearance = testShorting =
false;
795 testClearance = testShorting =
false;
799 testClearance = testShorting =
false;
803 testClearance = testShorting =
false;
805 int padNet =
pad->GetNetCode();
806 int otherNet = otherCItem ? otherCItem->
GetNetCode() : 0;
809 if( otherNet && otherNet == padNet )
811 testClearance = testShorting =
false;
815 if( !(
pad->GetDrillSize().x > 0 )
817 && !( otherVia && otherVia->
GetDrill() > 0 ) )
822 if( !testClearance && !testShorting && !testHoles )
825 SHAPE* otherShape = aPreparedOther;
830 bool has_error =
false;
832 if( otherPad &&
pad->SameLogicalPadAs( otherPad ) )
842 if(
pad->GetShortNetname().StartsWith( wxS(
"unconnected-(" ) )
849 drcItem->SetErrorDetail( wxString::Format(
_(
"(nets %s and %s)" ),
850 padNet ?
pad->GetNetname() :
_(
"<no net>" ),
851 otherNet ? otherPad->
GetNetname() :
_(
"<no net>" ) ) );
853 drcItem->SetItems(
pad, otherPad );
861 if( testClearance || testShorting )
870 if(
m_drcEngine->IsNetTieExclusion(
pad->GetNetCode(), aLayer, pos, other ) )
875 else if(
actual == 0 && padNet && otherNet && testShorting )
878 drcItem->SetErrorDetail( wxString::Format(
_(
"(nets %s and %s)" ),
879 padNet ?
pad->GetNetname() :
_(
"<no net>" ),
880 otherNet ? otherPad->
GetNetname() :
_(
"<no net>" ) ) );
881 drcItem->SetItems(
pad, other );
886 else if( testClearance )
889 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
893 drcItem->SetItems(
pad, other );
905 const std::shared_ptr<SHAPE_SEGMENT>& aOtherShape,
int aClearance )
907 if( shape->Collide( aOtherShape.get(),
sub_e( aClearance ), &
actual, &pos ) )
910 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
913 drcItem->SetItems( item, otherItem );
929 if( testHoles && otherPad && otherPad->
HasHole() &&
pad->FlashLayer( aLayer ) )
935 doTestHole(
pad, padShape.get(), otherPad,
942 if( testHoles &&
pad->HasHole() && otherPad && otherPad->
FlashLayer( aLayer ) )
953 if( testHoles && otherVia && otherVia->
HasHole() )
962 doTestHole(
pad, padShape.get(), otherVia,
974 std::atomic<size_t> done( 1 );
978 const auto fp_check =
982 std::vector<ZONE*> zones;
994 std::shared_ptr<SHAPE> padShape =
pad->GetEffectiveShape( layer );
996 m_board->m_CopperItemRTreeCache->QueryCollidingPreparedCopper(
997 pad, padShape, layer,
1011 [&](
BOARD_ITEM* other,
const std::shared_ptr<SHAPE>& aPreparedOther ) ->
bool
1016 m_board->m_DRCMaxClearance, true );
1020 for(
ZONE* zone : zones )
1030 done.fetch_add( 1 );
1033 size_t numFootprints =
m_board->Footprints().size();
1034 auto returns =
tp.submit_loop( 0, numFootprints, fp_check, numFootprints );
1037 for(
const std::future<void>& ret : returns )
1039 while( ret.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() + footprint->GetFields().size();
1054 REPORT_AUX( wxString::Format( wxT(
"Testing %d graphics..." ), count ) );
1056 auto isKnockoutText =
1062 auto testGraphicAgainstZone =
1077 std::vector<ZONE*> zones;
1081 for(
ZONE* zone : zones )
1083 if( isKnockoutText( item ) )
1093 auto testCopperGraphic =
1097 std::shared_ptr<SHAPE> queryShape = graphic->GetEffectiveShape( layer );
1098 std::shared_ptr<SHAPE> semanticShape;
1100 m_board->m_CopperItemRTreeCache->QueryCollidingPreparedCopper( graphic, queryShape, layer,
1108 && graphic->GetParentFootprint()
1122 int graphicNet = graphic->IsConnected()
1129 if( graphicNet && graphicNet == otherNet )
1137 && graphic->m_Uuid > other->
m_Uuid )
1145 [&](
BOARD_ITEM* other,
const std::shared_ptr<SHAPE>& aPreparedOther ) ->
bool
1147 if( !semanticShape )
1148 semanticShape = graphic->GetEffectiveShape();
1151 aPreparedOther.get() );
1157 m_board->m_DRCMaxClearance, false );
1160 BS::multi_future<void> graphic_futures;
1164 graphic_futures.push_back(
tp.submit_task(
1165 [
this, item, &done, testGraphicAgainstZone, testCopperGraphic]()
1167 if( !m_drcEngine->IsCancelled() )
1169 testGraphicAgainstZone( item );
1171 if( ( item->Type() == PCB_SHAPE_T || item->Type() == PCB_BARCODE_T )
1172 && item->IsOnCopperLayer() )
1174 testCopperGraphic( item );
1177 done.fetch_add( 1 );
1182 for(
FOOTPRINT* footprint : m_board->Footprints() )
1184 graphic_futures.push_back(
tp.submit_task(
1185 [
this, footprint, &done, testGraphicAgainstZone, testCopperGraphic]()
1187 for( BOARD_ITEM* item : footprint->GraphicalItems() )
1189 if( !m_drcEngine->IsCancelled() )
1191 testGraphicAgainstZone( item );
1193 if( ( item->Type() == PCB_SHAPE_T || item->Type() == PCB_BARCODE_T )
1194 && item->IsOnCopperLayer() )
1196 testCopperGraphic( item );
1199 done.fetch_add( 1 );
1205 for(
PCB_FIELD* field : footprint->GetFields() )
1207 if( !m_drcEngine->IsCancelled() )
1209 testGraphicAgainstZone( field );
1210 done.fetch_add( 1 );
1218 for( std::future<void>& future : graphic_futures )
1222 reportProgress( done, count );
1223 }
while( future.wait_for( std::chrono::milliseconds( 250 ) ) != std::future_status::ready );
1231 std::vector<ZONE*> zones;
1245 for(
ZONE* zone : zones )
1247 if( zone == teardrop )
1252 if( zone->IsTeardropArea() && zone < teardrop )
1269 std::vector<std::map<PCB_LAYER_ID, std::vector<SEG>>> poly_segments(
m_board->m_DRCCopperZones.size() );
1270 std::vector<std::map<PCB_LAYER_ID, SEG_RTREE>> seg_rtrees(
m_board->m_DRCCopperZones.size() );
1273 std::atomic<size_t> done( 0 );
1275 BS::multi_future<void> zone_futures;
1277 auto reportZoneZoneViolation =
1282 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
1283 constraint.GetName(),
1284 constraint.GetValue().Min(),
1285 std::max(
actual, 0 ) ) );
1286 drcItem->SetItems( zoneA, zoneB );
1287 drcItem->SetViolatingRule( constraint.GetParentRule() );
1292 [
this, reportZoneZoneViolation, &poly_segments, &seg_rtrees, &done]
1293 (
size_t zoneA_idx,
size_t zoneB_idx,
PCB_LAYER_ID layer ) ->
void
1297 done.fetch_add( 1 );
1301 ZONE* zoneA =
m_board->m_DRCCopperZones[zoneA_idx];
1302 ZONE* zoneB =
m_board->m_DRCCopperZones[zoneB_idx];
1310 const auto refIt = poly_segments[zoneA_idx].find( layer );
1311 const auto targetIt = poly_segments[zoneB_idx].find( layer );
1312 const auto testIt = seg_rtrees[zoneB_idx].find( layer );
1314 if( refIt == poly_segments[zoneA_idx].
end()
1315 || targetIt == poly_segments[zoneB_idx].
end()
1316 || testIt == seg_rtrees[zoneB_idx].
end() )
1318 done.fetch_add( 1 );
1322 const std::vector<SEG>& refSegments = refIt->second;
1323 const std::vector<SEG>& testSegments = targetIt->second;
1325 if( !testIt->second.empty() )
1327 const SEG_RTREE& testTree = testIt->second;
1329 for(
const SEG& refSegment : refSegments )
1334 done.fetch_add( 1 );
1338 int minX = std::min( refSegment.A.x, refSegment.B.x ) -
clearance;
1339 int minY = std::min( refSegment.A.y, refSegment.B.y ) -
clearance;
1340 int maxX = std::max( refSegment.A.x, refSegment.B.x ) +
clearance;
1341 int maxY = std::max( refSegment.A.y, refSegment.B.y ) +
clearance;
1342 int qmin[2] = { minX, minY };
1343 int qmax[2] = { maxX, maxY };
1347 [&](
size_t segIdx ) ->
bool
1349 const SEG& testSegment = testSegments[segIdx];
1350 int64_t dist_sq = 0;
1353 refSegment.NearestPoints( testSegment, pt, other_pt, dist_sq );
1354 actual = std::floor( std::sqrt( dist_sq ) + 0.5 );
1365 testTree.Search( qmin, qmax, visitor );
1369 done.fetch_add( 1 );
1370 reportZoneZoneViolation( zoneA, zoneB, pt,
actual, constraint, layer );
1377 done.fetch_add( 1 );
1381 std::map<PCB_LAYER_ID, std::vector<size_t>> zone_idx_by_layer;
1383 for (
size_t ii = 0; ii <
m_board->m_DRCCopperZones.size(); ii++ )
1396 zone_idx_by_layer[layer].push_back( ii );
1408 std::set<std::pair<size_t, PCB_LAYER_ID>> participating;
1412 if( !
m_board->IsLayerEnabled( layer ) )
1416 [&](
size_t aIndex ) -> std::optional<BOX2I>
1419 return poly->BBoxFromCaches();
1421 return std::nullopt;
1447 participating.emplace( ia, layer );
1448 participating.emplace( ia2, layer );
1452 for(
const auto& [zoneIndex, layer] : participating )
1459 std::vector<SEG>& segments = poly_segments[zoneIndex][layer];
1466 if( seg.
A.
x > seg.
B.
x )
1469 segments.push_back( seg );
1472 SEG_RTREE::Builder builder;
1473 builder.Reserve( segments.size() );
1475 for(
size_t si = 0; si < segments.size(); ++si )
1477 const SEG& seg = segments[si];
1478 int min[2] = { std::min( seg.
A.
x, seg.
B.
x ), std::min( seg.
A.
y, seg.
B.
y ) };
1479 int max[2] = { std::max( seg.
A.
x, seg.
B.
x ), std::max( seg.
A.
y, seg.
B.
y ) };
1480 builder.Add( min, max, si );
1483 seg_rtrees[zoneIndex].emplace( layer, builder.Build() );
1490 zone_futures.push_back(
tp.submit_task(
1491 [checkZones, pair]()
1493 checkZones( pair.first, pair.second, pair.layer );
1499 for( std::future<void>& future : zone_futures )
1504 }
while( future.wait_for( std::chrono::milliseconds( 250 ) ) != std::future_status::ready );
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 NETINFO_ITEM 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 bool IsConnected() const
Returns information if the object is derived from BOARD_CONNECTED_ITEM.
virtual std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, DRC_CONSTRAINT_T aUsage=NULL_CONSTRAINT) const
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
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 > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT, DRC_CONSTRAINT_T aUsage=NULL_CONSTRAINT) const
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
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.
bool testSingleLayerItemAgainstItem(BOARD_ITEM *item, SHAPE *itemShape, PCB_LAYER_ID layer, BOARD_ITEM *other, SHAPE *aPreparedOther)
Checks for track/via/hole <-> clearance.
virtual bool Run() override
Run this provider against the given PCB with configured options (if any).
DRC_TEST_PROVIDER_COPPER_CLEARANCE()
bool testPadAgainstItem(PAD *pad, const std::shared_ptr< SHAPE > &padShape, PCB_LAYER_ID layer, BOARD_ITEM *other, SHAPE *aPreparedOther)
int sub_e(int aClearance)
void collectZonesNear(BOARD_ITEM *aItem, PCB_LAYER_ID aLayer, std::vector< ZONE * > &aZones)
Copper zones on aLayer reachable from aItem at the worst clearance; aZones is reused.
DRC_ZONE_INDEX m_zoneIndex
void testItemAgainstZone(BOARD_ITEM *aItem, ZONE *aZone, PCB_LAYER_ID aLayer)
void testTeardropClearances()
void testGraphicClearances()
void testTrackClearances()
virtual ~DRC_TEST_PROVIDER_COPPER_CLEARANCE()=default
virtual const wxString GetName() const override
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)
bool isInvisibleText(const BOARD_ITEM *aItem) const
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.
Static (immutable) packed R-tree built via Hilbert-curve bulk loading.
LSET is a set of PCB_LAYER_IDs.
static const 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.
std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, DRC_CONSTRAINT_T aUsage=NULL_CONSTRAINT) const override
Return a SHAPE_SEGMENT object representing the pad's hole.
PAD_ATTRIB GetAttribute() const
const wxString & GetNumber() const
VECTOR2I GetPosition() const override
VECTOR2I GetDrillSize() const
bool HasHole() const override
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
const VECTOR2I & GetStart() const
const VECTOR2I & GetEnd() const
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT, DRC_CONSTRAINT_T aUsage=NULL_CONSTRAINT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
int GetDrill() const
Return the local drill setting for this PCB_VIA.
std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, DRC_CONSTRAINT_T aUsage=NULL_CONSTRAINT) 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.
int FullPointCount() const
Return the number of points in the shape poly set.
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
SHAPE_POLY_SET * GetFill(PCB_LAYER_ID aLayer)
bool IsTeardropArea() const
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT, DRC_CONSTRAINT_T aUsage=NULL_CONSTRAINT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
@ HOLE_CLEARANCE_CONSTRAINT
std::vector< std::pair< size_t, size_t > > CollectOverlappingPairs(const std::vector< size_t > &aOrderedIndices, BOX_FN aBox)
Enumerate the pairs of aOrderedIndices whose boxes overlap, in the order a nested loop over the vecto...
@ 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)
static std::vector< int > candidates(const SEGMENT_INDEX &aIndex, const SEG &aQuery, int aPadding)
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::priority_thread_pool thread_pool
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
@ 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_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
@ PCB_REFERENCE_IMAGE_T
class PCB_REFERENCE_IMAGE, bitmap on a layer
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
@ PCB_BARCODE_T
class PCB_BARCODE, a barcode (graphic item)
@ 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