67 virtual bool Run()
override;
69 virtual const wxString
GetName()
const override {
return wxT(
"clearance" ); };
113 if(
m_board->m_DRCMaxClearance <= 0 )
115 REPORT_AUX( wxT(
"No Clearance constraints found. Tests not run." ) );
123 if( !
reportPhase(
_(
"Checking track & via clearances..." ) ) )
130 if( !
reportPhase(
_(
"Checking hole clearances..." ) ) )
154 if( !
reportPhase(
_(
"Checking copper graphic clearances..." ) ) )
161 if( !
reportPhase(
_(
"Checking copper graphic hole clearances..." ) ) )
169 if( !
reportPhase(
_(
"Checking copper zone clearances..." ) ) )
174 if( !
reportPhase(
_(
"Checking teardrop clearances..." ) ) )
203 bool has_error =
false;
213 if( itemNet == otherNet )
214 testClearance = testShorting =
false;
216 std::shared_ptr<SHAPE> otherShape_shared_ptr;
222 if( !
pad->FlashLayer( layer ) )
225 testClearance = testShorting =
false;
227 otherShape_shared_ptr =
pad->GetEffectiveHoleShape();
234 if( !
via->FlashLayer( layer ) )
235 otherShape_shared_ptr =
via->GetEffectiveHoleShape();
238 if( !otherShape_shared_ptr )
241 SHAPE* otherShape = otherShape_shared_ptr.get();
247 std::swap( item, other );
248 std::swap( itemShape, otherShape );
249 std::swap( itemNet, otherNet );
252 if( testClearance || testShorting )
272 drcItem->SetItems( item, other );
286 else if(
actual == 0 && otherNet && testShorting )
289 drcItem->SetErrorDetail( wxString::Format(
_(
"(nets %s and %s)" ),
291 otherNet ? otherNet->
GetNetname() :
_(
"<no net>" ) ) );
292 drcItem->SetItems( item, other );
299 else if( testClearance )
302 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
306 drcItem->SetItems( item, other );
319 std::array<BOARD_ITEM*, 2> a{ item, other };
320 std::array<BOARD_ITEM*, 2> b{ other, item };
321 std::array<NETINFO_ITEM*, 2> b_net{ otherNet, itemNet };
322 std::array<SHAPE*, 2> a_shape{ itemShape, otherShape };
324 for(
size_t ii = 0; ii < 2; ++ii )
326 std::shared_ptr<SHAPE_SEGMENT> holeShape;
330 if( b[ii]->GetLayerSet().Contains( layer ) )
331 holeShape = b[ii]->GetEffectiveHoleShape();
337 if( b[ii]->HasHole() )
338 holeShape = b[ii]->GetEffectiveHoleShape();
343 int netcode = b_net[ii] ? b_net[ii]->GetNetCode() : 0;
345 if( netcode &&
m_drcEngine->IsNetTieExclusion( netcode, layer, holeShape->Centre(), a[ii] ) )
359 :
_(
"(%s clearance %s; actual < 0)" ),
363 drcItem->SetItems( a[ii], b[ii] );
389 BOX2I worstCaseBBox = itemBBox;
401 std::set<PAD*> allowedNetTiePads;
407 if(
pad->IsOnLayer( aLayer ) )
408 allowedNetTiePads.insert(
pad );
412 if( other->IsOnLayer( aLayer ) )
413 allowedNetTiePads.insert( other );
418 if( !allowedNetTiePads.empty() )
422 for(
PAD*
pad : allowedNetTiePads )
424 if(
pad->GetBoundingBox().Intersects( itemBBox )
425 &&
pad->GetEffectiveShape( aLayer )->Collide( itemShape.get() ) )
436 if( !testClearance && !testHoles )
452 bool flashedPad =
pad->FlashLayer( aLayer );
455 if( !flashedPad && !platedHole )
456 testClearance =
false;
472 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
476 drcItem->SetItems( aItem, aZone );
482 if( testHoles && aItem->
HasHole() )
484 std::shared_ptr<SHAPE_SEGMENT> holeShape;
506 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
510 drcItem->SetItems( aItem, aZone );
534 if( !testClearance && !testShorts )
543 BOX2I worstCaseBBox = itemBBox;
557 if( *aInheritedNet ==
nullptr )
559 if( zoneTree->
QueryColliding( itemBBox, itemShape.get(), layer ) )
560 *aInheritedNet = aZone->
GetNet();
563 if( *aInheritedNet == aZone->
GetNet() )
575 std::shared_ptr<DRC_ITEM> drcItem;
577 if( testShorts &&
actual == 0 && *aInheritedNet )
580 drcItem->SetErrorDetail( wxString::Format(
_(
"(nets %s and %s)" ),
581 ( *aInheritedNet )->GetNetname(),
587 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
593 drcItem->SetItems( aText, aZone );
603 std::map<BOARD_ITEM*, int> freePadsUsageMap;
604 std::mutex freePadsUsageMapMutex;
605 std::atomic<size_t> done( 0 );
606 size_t count =
m_board->Tracks().size();
608 REPORT_AUX( wxString::Format( wxT(
"Testing %d tracks & vias..." ), count ) );
613 [&](
const int trackIdx )
621 m_board->m_CopperItemRTreeCache->QueryColliding( track, layer, layer,
639 &&
static_cast<void*
>( track ) >
static_cast<void*
>( other ) )
656 std::lock_guard<std::mutex> lock( freePadsUsageMapMutex );
657 auto it = freePadsUsageMap.find( other );
659 if( it == freePadsUsageMap.end() )
661 freePadsUsageMap[ other ] = track->
GetNetCode();
682 auto zoneIt =
m_board->m_DRCCopperZonesByLayer.find( layer );
684 if( zoneIt !=
m_board->m_DRCCopperZonesByLayer.end() )
686 for(
ZONE* zone : zoneIt->second )
701 auto track_futures =
tp.submit_loop( 0,
m_board->Tracks().size(), testTrack,
704 while( done < count )
711 track_futures.wait();
715 track_futures.wait_for( std::chrono::milliseconds( 250 ) );
733 int padGroupIdx = padToNetTieGroupMap[
pad->GetNumber() ];
737 PAD* otherPad =
static_cast<PAD*
>( other );
739 if( padGroupIdx >= 0 && padGroupIdx == padToNetTieGroupMap[ otherPad->
GetNumber() ] )
740 testClearance = testShorting =
false;
742 if(
pad->SameLogicalPadAs( otherPad ) )
747 testClearance = testShorting =
false;
753 PAD* otherPad =
nullptr;
757 otherPad =
static_cast<PAD*
>( other );
760 otherVia =
static_cast<PCB_VIA*
>( other );
763 testClearance = testShorting =
false;
767 testClearance = testShorting =
false;
770 testClearance = testShorting =
false;
774 testClearance = testShorting =
false;
778 testClearance = testShorting =
false;
780 int padNet =
pad->GetNetCode();
781 int otherNet = otherCItem ? otherCItem->
GetNetCode() : 0;
784 if( otherNet && otherNet == padNet )
786 testClearance = testShorting =
false;
790 if( !(
pad->GetDrillSize().x > 0 )
792 && !( otherVia && otherVia->
GetDrill() > 0 ) )
797 if( !testClearance && !testShorting && !testHoles )
805 bool has_error =
false;
807 if( otherPad &&
pad->SameLogicalPadAs( otherPad ) )
817 if(
pad->GetShortNetname().StartsWith( wxS(
"unconnected-(" ) )
824 drcItem->SetErrorDetail( wxString::Format(
_(
"(nets %s and %s)" ),
827 drcItem->SetItems(
pad, otherPad );
835 if( testClearance || testShorting )
844 if(
m_drcEngine->IsNetTieExclusion(
pad->GetNetCode(), aLayer, pos, other ) )
849 else if(
actual == 0 && padNet && otherNet && testShorting )
852 drcItem->SetErrorDetail( wxString::Format(
_(
"(nets %s and %s)" ),
855 drcItem->SetItems(
pad, other );
860 else if( testClearance )
863 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
867 drcItem->SetItems(
pad, other );
880 if( shape->Collide( aOtherShape,
sub_e( aClearance ), &
actual, &pos ) )
883 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
887 drcItem->SetItems( item, otherItem );
903 if( testHoles && otherPad && otherPad->
HasHole() &&
pad->FlashLayer( aLayer ) )
913 if( testHoles &&
pad->HasHole() && otherPad && otherPad->
FlashLayer( aLayer ) )
918 doTestHole( otherPad, otherShape.get(),
pad,
pad->GetEffectiveHoleShape().get(),
clearance );
921 if( testHoles && otherVia && otherVia->
HasHole() )
939 std::atomic<size_t> done( 1 );
943 const auto fp_check =
958 std::shared_ptr<SHAPE> padShape =
pad->GetEffectiveShape( layer );
960 m_board->m_CopperItemRTreeCache->QueryColliding(
pad, layer, layer,
967 &&
static_cast<void*
>(
pad )
968 >
static_cast<void*
>( other ) )
983 auto zoneIt =
m_board->m_DRCCopperZonesByLayer.find( layer );
985 if( zoneIt !=
m_board->m_DRCCopperZonesByLayer.end() )
987 for(
ZONE* zone : zoneIt->second )
1001 size_t numFootprints =
m_board->Footprints().size();
1002 auto returns =
tp.submit_loop( 0, numFootprints, fp_check, numFootprints );
1005 for(
size_t ii = 0; ii < returns.size(); ++ii )
1007 while( returns[ii].wait_for( std::chrono::milliseconds( 250 ) ) != std::future_status::ready )
1016 size_t count =
m_board->Drawings().size();
1017 std::atomic<size_t> done( 1 );
1020 count += footprint->GraphicalItems().size() + footprint->GetFields().size();
1022 REPORT_AUX( wxString::Format( wxT(
"Testing %d graphics..." ), count ) );
1024 auto isKnockoutText =
1028 &&
static_cast<PCB_TEXT*
>( item )->IsKnockout();
1031 auto testGraphicAgainstZone =
1046 auto zoneIt =
m_board->m_DRCCopperZonesByLayer.find( layer );
1048 if( zoneIt !=
m_board->m_DRCCopperZonesByLayer.end() )
1050 for(
ZONE* zone : zoneIt->second )
1052 if( isKnockoutText( item ) )
1063 auto testCopperGraphic =
1068 m_board->m_CopperItemRTreeCache->QueryColliding( graphic, layer, layer,
1075 && graphic->GetParentFootprint()
1076 && graphic->GetParentFootprint()
1089 int graphicNet = graphic->IsConnected()
1096 if( graphicNet && graphicNet == otherNet )
1103 &&
static_cast<void*
>( graphic )
1104 >
static_cast<void*
>( other ) )
1124 (void)
tp.submit_task(
1125 [
this, item, &done, testGraphicAgainstZone, testCopperGraphic]()
1127 if( !m_drcEngine->IsCancelled() )
1129 testGraphicAgainstZone( item );
1131 if( ( item->Type() == PCB_SHAPE_T || item->Type() == PCB_BARCODE_T )
1132 && item->IsOnCopperLayer() )
1134 testCopperGraphic( static_cast<PCB_SHAPE*>( item ) );
1137 done.fetch_add( 1 );
1142 for(
FOOTPRINT* footprint : m_board->Footprints() )
1144 (void)
tp.submit_task(
1145 [
this, footprint, &done, testGraphicAgainstZone, testCopperGraphic]()
1147 for( BOARD_ITEM* item : footprint->GraphicalItems() )
1149 if( !m_drcEngine->IsCancelled() )
1151 testGraphicAgainstZone( item );
1153 if( ( item->Type() == PCB_SHAPE_T || item->Type() == PCB_BARCODE_T )
1154 && item->IsOnCopperLayer() )
1156 testCopperGraphic( static_cast<PCB_SHAPE*>( item ) );
1159 done.fetch_add( 1 );
1165 for(
PCB_FIELD* field : footprint->GetFields() )
1167 if( !m_drcEngine->IsCancelled() )
1169 testGraphicAgainstZone( field );
1170 done.fetch_add( 1 );
1178 reportProgress( done, count );
1180 if( m_drcEngine->IsCancelled() )
1183 if(
tp.wait_for( std::chrono::milliseconds( 250 ) ) )
1203 auto zoneIt =
m_board->m_DRCCopperZonesByLayer.find( layer );
1205 if( zoneIt ==
m_board->m_DRCCopperZonesByLayer.end() )
1208 for(
ZONE* zone : zoneIt->second )
1210 if( zone == teardrop )
1235 std::vector<std::map<PCB_LAYER_ID, std::vector<SEG>>> poly_segments(
m_board->m_DRCCopperZones.size() );
1236 std::vector<std::map<PCB_LAYER_ID, SEG_RTREE>> seg_rtrees(
m_board->m_DRCCopperZones.size() );
1239 std::atomic<size_t> done( 0 );
1242 auto reportZoneZoneViolation =
1246 std::shared_ptr<DRC_ITEM> drcItem;
1248 if( constraint.IsNull() )
1251 drcItem->SetErrorDetail(
_(
"(intersecting zones must have distinct priorities)" ) );
1252 drcItem->SetItems( zoneA, zoneB );
1258 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
1259 constraint.GetName(),
1260 constraint.GetValue().Min(),
1261 std::max(
actual, 0 ) ) );
1262 drcItem->SetItems( zoneA, zoneB );
1263 drcItem->SetViolatingRule( constraint.GetParentRule() );
1269 [
this, testClearance, testIntersects, reportZoneZoneViolation,
1270 &poly_segments, &seg_rtrees, &done]
1271 (
int zoneA_idx,
int zoneB_idx,
bool sameNet,
PCB_LAYER_ID layer ) ->
void
1273 ZONE* zoneA =
m_board->m_DRCCopperZones[zoneA_idx];
1274 ZONE* zoneB =
m_board->m_DRCCopperZones[zoneB_idx];
1278 if( sameNet && testIntersects )
1283 if( zoneAOutline.
Collide( &zoneBOutline, 0, &
actual, &pt ) )
1285 done.fetch_add( 1 );
1290 else if( !sameNet && testClearance )
1297 std::vector<SEG>& refSegments = poly_segments[zoneA_idx][layer];
1298 std::vector<SEG>& testSegments = poly_segments[zoneB_idx][layer];
1300 auto testIt = seg_rtrees[zoneB_idx].find( layer );
1302 if( testIt != seg_rtrees[zoneB_idx].
end() && !testIt->second.empty() )
1304 const SEG_RTREE& testTree = testIt->second;
1306 for(
SEG& refSegment : refSegments )
1308 int minX = std::min( refSegment.A.x, refSegment.B.x ) -
clearance;
1309 int minY = std::min( refSegment.A.y, refSegment.B.y ) -
clearance;
1310 int maxX = std::max( refSegment.A.x, refSegment.B.x ) +
clearance;
1311 int maxY = std::max( refSegment.A.y, refSegment.B.y ) +
clearance;
1312 int qmin[2] = { minX, minY };
1313 int qmax[2] = { maxX, maxY };
1316 auto visitor = [&](
size_t segIdx ) ->
bool
1318 SEG& testSegment = testSegments[segIdx];
1319 int64_t dist_sq = 0;
1322 refSegment.NearestPoints( testSegment, pt, other_pt, dist_sq );
1323 actual = std::floor( std::sqrt( dist_sq ) + 0.5 );
1334 testTree.Search( qmin, qmax, visitor );
1338 done.fetch_add( 1 );
1339 reportZoneZoneViolation( zoneA, zoneB, pt,
actual, constraint,
1348 done.fetch_add( 1 );
1352 std::map<PCB_LAYER_ID, std::vector<size_t>> zone_idx_by_layer;
1354 for (
size_t ii = 0; ii <
m_board->m_DRCCopperZones.size(); ii++ )
1367 zone_idx_by_layer[layer].push_back( ii );
1374 if( !
m_board->IsLayerEnabled( layer ) )
1377 for(
size_t ii : zone_idx_by_layer[layer] )
1381 std::vector<SEG>& zone_layer_poly_segs = poly_segments[ii][layer];
1382 zone_layer_poly_segs.reserve( poly->FullPointCount() );
1384 for(
auto it = poly->IterateSegmentsWithHoles(); it; it++ )
1388 if( seg.
A.
x > seg.
B.
x )
1391 zone_layer_poly_segs.push_back( seg );
1394 SEG_RTREE::Builder builder;
1395 builder.Reserve( zone_layer_poly_segs.size() );
1397 for(
size_t si = 0; si < zone_layer_poly_segs.size(); ++si )
1399 const SEG& seg = zone_layer_poly_segs[si];
1400 int smin[2] = { std::min( seg.
A.
x, seg.
B.
x ), std::min( seg.
A.
y, seg.
B.
y ) };
1401 int smax[2] = { std::max( seg.
A.
x, seg.
B.
x ), std::max( seg.
A.
y, seg.
B.
y ) };
1402 builder.Add( smin, smax, si );
1405 seg_rtrees[ii][layer] = builder.Build();
1409 for(
auto it_a = zone_idx_by_layer[layer].begin(); it_a != zone_idx_by_layer[layer].end(); ++it_a )
1414 for(
auto it_a2 = std::next( it_a ); it_a2 != zone_idx_by_layer[layer].end(); ++it_a2 )
1416 size_t ia2 = *it_a2;
1440 polyA = &zoneAOutline;
1441 polyB = &zoneBOutline;
1445 polyA = zoneA->
GetFill( layer );
1446 polyB = zoneB->
GetFill( layer );
1449 if( !polyA || !polyB
1454 (void)
tp.submit_task(
1455 [checkZones, ia, ia2, sameNet, layer]()
1457 checkZones( ia, ia2, sameNet, layer );
1470 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.
int sub_e(int aClearance)
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
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)
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.
PAD_ATTRIB GetAttribute() const
const wxString & GetNumber() const
VECTOR2I GetPosition() const override
VECTOR2I GetDrillSize() const
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,...
void BuildBBoxCaches() const
Construct BBoxCaches for Contains(), below.
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)
SHAPE_POLY_SET GetBoardOutline() const
bool IsTeardropArea() const
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
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