71 virtual bool Run()
override;
73 virtual const wxString
GetName()
const override {
return wxT(
"clearance" ); };
117 if(
m_board->m_DRCMaxClearance <= 0 )
119 REPORT_AUX( wxT(
"No Clearance constraints found. Tests not run." ) );
127 if( !
reportPhase(
_(
"Checking track & via clearances..." ) ) )
134 if( !
reportPhase(
_(
"Checking hole clearances..." ) ) )
158 if( !
reportPhase(
_(
"Checking copper graphic clearances..." ) ) )
165 if( !
reportPhase(
_(
"Checking copper graphic hole clearances..." ) ) )
173 if( !
reportPhase(
_(
"Checking copper zone clearances..." ) ) )
178 if( !
reportPhase(
_(
"Checking teardrop clearances..." ) ) )
207 bool has_error =
false;
217 if( itemNet == otherNet )
218 testClearance = testShorting =
false;
220 std::shared_ptr<SHAPE> otherShape_shared_ptr;
226 if( !
pad->FlashLayer( layer ) )
229 testClearance = testShorting =
false;
231 otherShape_shared_ptr =
pad->GetEffectiveHoleShape();
238 if( !
via->FlashLayer( layer ) )
239 otherShape_shared_ptr =
via->GetEffectiveHoleShape();
242 if( !otherShape_shared_ptr )
245 SHAPE* otherShape = otherShape_shared_ptr.get();
251 std::swap( item, other );
252 std::swap( itemShape, otherShape );
253 std::swap( itemNet, otherNet );
256 if( testClearance || testShorting )
276 drcItem->SetItems( item, other );
290 else if(
actual == 0 && otherNet && testShorting )
293 drcItem->SetErrorDetail( wxString::Format(
_(
"(nets %s and %s)" ),
295 otherNet ? otherNet->
GetNetname() :
_(
"<no net>" ) ) );
296 drcItem->SetItems( item, other );
303 else if( testClearance )
306 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
310 drcItem->SetItems( item, other );
323 std::array<BOARD_ITEM*, 2> a{ item, other };
324 std::array<BOARD_ITEM*, 2> b{ other, item };
325 std::array<NETINFO_ITEM*, 2> b_net{ otherNet, itemNet };
326 std::array<SHAPE*, 2> a_shape{ itemShape, otherShape };
328 for(
size_t ii = 0; ii < 2; ++ii )
330 std::shared_ptr<SHAPE_SEGMENT> holeShape;
334 if( b[ii]->GetLayerSet().Contains( layer ) )
335 holeShape = b[ii]->GetEffectiveHoleShape();
341 if( b[ii]->HasHole() )
342 holeShape = b[ii]->GetEffectiveHoleShape();
347 int netcode = b_net[ii] ? b_net[ii]->GetNetCode() : 0;
349 if( netcode &&
m_drcEngine->IsNetTieExclusion( netcode, layer, holeShape->Centre(), a[ii] ) )
363 :
_(
"(%s clearance %s; actual < 0)" ),
367 drcItem->SetItems( a[ii], b[ii] );
393 BOX2I worstCaseBBox = itemBBox;
405 std::set<PAD*> allowedNetTiePads;
411 if(
pad->IsOnLayer( aLayer ) )
412 allowedNetTiePads.insert(
pad );
416 if( other->IsOnLayer( aLayer ) )
417 allowedNetTiePads.insert( other );
422 if( !allowedNetTiePads.empty() )
426 for(
PAD*
pad : allowedNetTiePads )
428 if(
pad->GetBoundingBox().Intersects( itemBBox )
429 &&
pad->GetEffectiveShape( aLayer )->Collide( itemShape.get() ) )
440 if( !testClearance && !testHoles )
456 bool flashedPad =
pad->FlashLayer( aLayer );
459 if( !flashedPad && !platedHole )
460 testClearance =
false;
476 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
480 drcItem->SetItems( aItem, aZone );
486 if( testHoles && aItem->
HasHole() )
488 std::shared_ptr<SHAPE_SEGMENT> holeShape;
510 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
514 drcItem->SetItems( aItem, aZone );
538 if( !testClearance && !testShorts )
547 BOX2I worstCaseBBox = itemBBox;
561 if( *aInheritedNet ==
nullptr )
563 if( zoneTree->
QueryColliding( itemBBox, itemShape.get(), layer ) )
564 *aInheritedNet = aZone->
GetNet();
567 if( *aInheritedNet == aZone->
GetNet() )
579 std::shared_ptr<DRC_ITEM> drcItem;
581 if( testShorts &&
actual == 0 && *aInheritedNet )
584 drcItem->SetErrorDetail( wxString::Format(
_(
"(nets %s and %s)" ),
585 ( *aInheritedNet )->GetNetname(),
591 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
597 drcItem->SetItems( aText, aZone );
607 std::map<BOARD_ITEM*, int> freePadsUsageMap;
608 std::mutex freePadsUsageMapMutex;
609 std::atomic<size_t> done( 0 );
610 size_t count =
m_board->Tracks().size();
612 REPORT_AUX( wxString::Format( wxT(
"Testing %d tracks & vias..." ), count ) );
617 [&](
const int trackIdx )
625 m_board->m_CopperItemRTreeCache->QueryColliding( track, layer, layer,
643 &&
static_cast<void*
>( track ) >
static_cast<void*
>( other ) )
660 std::lock_guard<std::mutex> lock( freePadsUsageMapMutex );
661 auto it = freePadsUsageMap.find( other );
663 if( it == freePadsUsageMap.end() )
665 freePadsUsageMap[ other ] = track->
GetNetCode();
686 auto zoneIt =
m_board->m_DRCCopperZonesByLayer.find( layer );
688 if( zoneIt !=
m_board->m_DRCCopperZonesByLayer.end() )
690 for(
ZONE* zone : zoneIt->second )
705 auto track_futures =
tp.submit_loop( 0,
m_board->Tracks().size(), testTrack,
708 while( done < count )
715 track_futures.wait();
719 track_futures.wait_for( std::chrono::milliseconds( 250 ) );
737 int padGroupIdx = padToNetTieGroupMap[
pad->GetNumber() ];
741 PAD* otherPad =
static_cast<PAD*
>( other );
743 if( padGroupIdx >= 0 && padGroupIdx == padToNetTieGroupMap[ otherPad->
GetNumber() ] )
744 testClearance = testShorting =
false;
746 if(
pad->SameLogicalPadAs( otherPad ) )
751 testClearance = testShorting =
false;
757 PAD* otherPad =
nullptr;
761 otherPad =
static_cast<PAD*
>( other );
764 otherVia =
static_cast<PCB_VIA*
>( other );
767 testClearance = testShorting =
false;
771 testClearance = testShorting =
false;
774 testClearance = testShorting =
false;
778 testClearance = testShorting =
false;
782 testClearance = testShorting =
false;
784 int padNet =
pad->GetNetCode();
785 int otherNet = otherCItem ? otherCItem->
GetNetCode() : 0;
788 if( otherNet && otherNet == padNet )
790 testClearance = testShorting =
false;
794 if( !(
pad->GetDrillSize().x > 0 )
796 && !( otherVia && otherVia->
GetDrill() > 0 ) )
801 if( !testClearance && !testShorting && !testHoles )
809 bool has_error =
false;
811 if( otherPad &&
pad->SameLogicalPadAs( otherPad ) )
821 if(
pad->GetShortNetname().StartsWith( wxS(
"unconnected-(" ) )
828 drcItem->SetErrorDetail( wxString::Format(
_(
"(nets %s and %s)" ),
831 drcItem->SetItems(
pad, otherPad );
839 if( testClearance || testShorting )
848 if(
m_drcEngine->IsNetTieExclusion(
pad->GetNetCode(), aLayer, pos, other ) )
853 else if(
actual == 0 && padNet && otherNet && testShorting )
856 drcItem->SetErrorDetail( wxString::Format(
_(
"(nets %s and %s)" ),
859 drcItem->SetItems(
pad, other );
864 else if( testClearance )
867 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
871 drcItem->SetItems(
pad, other );
884 if( shape->Collide( aOtherShape,
sub_e( aClearance ), &
actual, &pos ) )
887 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
891 drcItem->SetItems( item, otherItem );
907 if( testHoles && otherPad && otherPad->
HasHole() &&
pad->FlashLayer( aLayer ) )
917 if( testHoles &&
pad->HasHole() && otherPad && otherPad->
FlashLayer( aLayer ) )
922 doTestHole( otherPad, otherShape.get(),
pad,
pad->GetEffectiveHoleShape().get(),
clearance );
925 if( testHoles && otherVia && otherVia->
HasHole() )
943 std::atomic<size_t> done( 1 );
947 const auto fp_check =
962 std::shared_ptr<SHAPE> padShape =
pad->GetEffectiveShape( layer );
964 m_board->m_CopperItemRTreeCache->QueryColliding(
pad, layer, layer,
971 &&
static_cast<void*
>(
pad )
972 >
static_cast<void*
>( other ) )
987 auto zoneIt =
m_board->m_DRCCopperZonesByLayer.find( layer );
989 if( zoneIt !=
m_board->m_DRCCopperZonesByLayer.end() )
991 for(
ZONE* zone : zoneIt->second )
1002 done.fetch_add( 1 );
1005 size_t numFootprints =
m_board->Footprints().size();
1006 auto returns =
tp.submit_loop( 0, numFootprints, fp_check, numFootprints );
1009 for(
size_t ii = 0; ii < returns.size(); ++ii )
1011 while( returns[ii].wait_for( std::chrono::milliseconds( 250 ) ) != std::future_status::ready )
1020 size_t count =
m_board->Drawings().size();
1021 std::atomic<size_t> done( 1 );
1024 count += footprint->GraphicalItems().size();
1026 REPORT_AUX( wxString::Format( wxT(
"Testing %d graphics..." ), count ) );
1028 auto isKnockoutText =
1034 auto testGraphicAgainstZone =
1049 auto zoneIt =
m_board->m_DRCCopperZonesByLayer.find( layer );
1051 if( zoneIt !=
m_board->m_DRCCopperZonesByLayer.end() )
1053 for(
ZONE* zone : zoneIt->second )
1055 if( isKnockoutText( item ) )
1066 auto testCopperGraphic =
1071 m_board->m_CopperItemRTreeCache->QueryColliding( graphic, layer, layer,
1078 && graphic->GetParentFootprint()
1079 && graphic->GetParentFootprint()
1092 int graphicNet = graphic->IsConnected()
1099 if( graphicNet && graphicNet == otherNet )
1106 &&
static_cast<void*
>( graphic )
1107 >
static_cast<void*
>( other ) )
1127 (void)
tp.submit_task(
1128 [
this, item, &done, testGraphicAgainstZone, testCopperGraphic]()
1130 if( !m_drcEngine->IsCancelled() )
1132 testGraphicAgainstZone( item );
1134 if( ( item->Type() == PCB_SHAPE_T || item->Type() == PCB_BARCODE_T )
1135 && item->IsOnCopperLayer() )
1137 testCopperGraphic( static_cast<PCB_SHAPE*>( item ) );
1140 done.fetch_add( 1 );
1145 for(
FOOTPRINT* footprint : m_board->Footprints() )
1147 (void)
tp.submit_task(
1148 [
this, footprint, &done, testGraphicAgainstZone, testCopperGraphic]()
1150 for( BOARD_ITEM* item : footprint->GraphicalItems() )
1152 if( !m_drcEngine->IsCancelled() )
1154 testGraphicAgainstZone( item );
1156 if( ( item->Type() == PCB_SHAPE_T || item->Type() == PCB_BARCODE_T )
1157 && item->IsOnCopperLayer() )
1159 testCopperGraphic( static_cast<PCB_SHAPE*>( item ) );
1162 done.fetch_add( 1 );
1170 reportProgress( done, count );
1172 if( m_drcEngine->IsCancelled() )
1175 if(
tp.wait_for( std::chrono::milliseconds( 250 ) ) )
1195 auto zoneIt =
m_board->m_DRCCopperZonesByLayer.find( layer );
1197 if( zoneIt ==
m_board->m_DRCCopperZonesByLayer.end() )
1200 for(
ZONE* zone : zoneIt->second )
1202 if( zone == teardrop )
1227 std::vector<std::map<PCB_LAYER_ID, std::vector<SEG>>> poly_segments(
m_board->m_DRCCopperZones.size() );
1228 std::vector<std::map<PCB_LAYER_ID, SEG_RTREE>> seg_rtrees(
m_board->m_DRCCopperZones.size() );
1231 std::atomic<size_t> done( 0 );
1234 auto reportZoneZoneViolation =
1238 std::shared_ptr<DRC_ITEM> drcItem;
1240 if( constraint.IsNull() )
1243 drcItem->SetErrorDetail(
_(
"(intersecting zones must have distinct priorities)" ) );
1244 drcItem->SetItems( zoneA, zoneB );
1250 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
1251 constraint.GetName(),
1252 constraint.GetValue().Min(),
1253 std::max(
actual, 0 ) ) );
1254 drcItem->SetItems( zoneA, zoneB );
1255 drcItem->SetViolatingRule( constraint.GetParentRule() );
1261 [
this, testClearance, testIntersects, reportZoneZoneViolation,
1262 &poly_segments, &seg_rtrees, &done]
1263 (
int zoneA_idx,
int zoneB_idx,
bool sameNet,
PCB_LAYER_ID layer ) ->
void
1265 ZONE* zoneA =
m_board->m_DRCCopperZones[zoneA_idx];
1266 ZONE* zoneB =
m_board->m_DRCCopperZones[zoneB_idx];
1270 if( sameNet && testIntersects )
1274 done.fetch_add( 1 );
1279 else if( !sameNet && testClearance )
1286 std::vector<SEG>& refSegments = poly_segments[zoneA_idx][layer];
1287 std::vector<SEG>& testSegments = poly_segments[zoneB_idx][layer];
1289 auto testIt = seg_rtrees[zoneB_idx].find( layer );
1291 if( testIt != seg_rtrees[zoneB_idx].
end() && !testIt->second.empty() )
1293 const SEG_RTREE& testTree = testIt->second;
1295 for(
SEG& refSegment : refSegments )
1297 int minX = std::min( refSegment.A.x, refSegment.B.x ) -
clearance;
1298 int minY = std::min( refSegment.A.y, refSegment.B.y ) -
clearance;
1299 int maxX = std::max( refSegment.A.x, refSegment.B.x ) +
clearance;
1300 int maxY = std::max( refSegment.A.y, refSegment.B.y ) +
clearance;
1301 int qmin[2] = { minX, minY };
1302 int qmax[2] = { maxX, maxY };
1305 auto visitor = [&](
size_t segIdx ) ->
bool
1307 SEG& testSegment = testSegments[segIdx];
1308 int64_t dist_sq = 0;
1311 refSegment.NearestPoints( testSegment, pt, other_pt, dist_sq );
1312 actual = std::floor( std::sqrt( dist_sq ) + 0.5 );
1323 testTree.Search( qmin, qmax, visitor );
1327 done.fetch_add( 1 );
1328 reportZoneZoneViolation( zoneA, zoneB, pt,
actual, constraint,
1337 done.fetch_add( 1 );
1341 std::map<PCB_LAYER_ID, std::vector<size_t>> zone_idx_by_layer;
1343 for (
size_t ii = 0; ii <
m_board->m_DRCCopperZones.size(); ii++ )
1356 zone_idx_by_layer[layer].push_back( ii );
1363 if( !
m_board->IsLayerEnabled( layer ) )
1366 for(
size_t ii : zone_idx_by_layer[layer] )
1370 std::vector<SEG>& zone_layer_poly_segs = poly_segments[ii][layer];
1371 zone_layer_poly_segs.reserve( poly->FullPointCount() );
1373 for(
auto it = poly->IterateSegmentsWithHoles(); it; it++ )
1377 if( seg.
A.
x > seg.
B.
x )
1380 zone_layer_poly_segs.push_back( seg );
1383 SEG_RTREE::Builder builder;
1384 builder.Reserve( zone_layer_poly_segs.size() );
1386 for(
size_t si = 0; si < zone_layer_poly_segs.size(); ++si )
1388 const SEG& seg = zone_layer_poly_segs[si];
1389 int smin[2] = { std::min( seg.
A.
x, seg.
B.
x ), std::min( seg.
A.
y, seg.
B.
y ) };
1390 int smax[2] = { std::max( seg.
A.
x, seg.
B.
x ), std::max( seg.
A.
y, seg.
B.
y ) };
1391 builder.Add( smin, smax, si );
1394 seg_rtrees[ii][layer] = builder.Build();
1398 for(
auto it_a = zone_idx_by_layer[layer].begin(); it_a != zone_idx_by_layer[layer].end(); ++it_a )
1403 for(
auto it_a2 = std::next( it_a ); it_a2 != zone_idx_by_layer[layer].end(); ++it_a2 )
1405 size_t ia2 = *it_a2;
1428 polyA = zoneA->
GetFill( layer );
1429 polyB = zoneB->
GetFill( layer );
1432 if( !polyA || !polyB
1437 (void)
tp.submit_task(
1438 [checkZones, ia, ia2, sameNet, layer]()
1440 checkZones( ia, ia2, sameNet, layer );
1453 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)
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.
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
SHAPE_POLY_SET * Outline()
SHAPE_POLY_SET * GetFill(PCB_LAYER_ID aLayer)
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_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