70 virtual bool Run()
override;
72 virtual const wxString
GetName()
const override {
return wxT(
"clearance" ); };
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..." ) ) )
158 if( !
reportPhase(
_(
"Checking copper zone clearances..." ) ) )
187 bool has_error =
false;
192 net = connectedItem->GetNet();
197 otherNet = connectedItem->GetNet();
200 SHAPE* otherShape = otherShapeStorage.get();
206 if(
pad->GetAttribute() == PAD_ATTRIB::NPTH && !
pad->FlashLayer( layer ) )
207 testClearance = testShorting =
false;
210 if( testClearance || testShorting )
222 std::swap( item, other );
223 std::swap( itemShape, otherShape );
224 std::swap( net, otherNet );
239 drcItem->SetItems( item, other );
255 else if(
actual == 0 && otherNet && testShorting )
260 msg.Printf(
_(
"(nets %s and %s)" ),
262 otherNet ? otherNet->
GetNetname() :
_(
"<no net>" ) );
264 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
265 drce->SetItems( item, other );
273 else if( testClearance )
276 wxString msg =
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
281 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
282 drce->SetItems( item, other );
296 std::array<BOARD_ITEM*, 2> a{ item, other };
297 std::array<BOARD_ITEM*, 2> b{ other, item };
298 std::array<SHAPE*, 2> a_shape{ itemShape, otherShape };
300 for(
size_t ii = 0; ii < 2; ++ii )
302 std::shared_ptr<SHAPE_SEGMENT> holeShape;
306 if( !(
dynamic_cast<PCB_TRACK*
>( a[ii] ) ) || !b[ii]->HasHole() )
311 if( b[ii]->GetLayerSet().Contains( layer ) )
312 holeShape = b[ii]->GetEffectiveHoleShape();
316 holeShape = b[ii]->GetEffectiveHoleShape();
331 :
_(
"(%s clearance %s; actual < 0)" ),
336 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
337 drce->SetItems( a[ii], b[ii] );
364 BOX2I worstCaseBBox = itemBBox;
376 std::set<PAD*> allowedNetTiePads;
382 if(
pad->IsOnLayer( aLayer ) )
383 allowedNetTiePads.insert(
pad );
387 if( other->IsOnLayer( aLayer ) )
388 allowedNetTiePads.insert( other );
393 if( !allowedNetTiePads.empty() )
397 for(
PAD*
pad : allowedNetTiePads )
399 if(
pad->GetBoundingBox().Intersects( itemBBox )
400 &&
pad->GetEffectiveShape( aLayer )->Collide( itemShape.get() ) )
411 if( !testClearance && !testHoles )
427 bool flashedPad =
pad->FlashLayer( aLayer );
428 bool platedHole =
pad->HasHole() &&
pad->GetAttribute() == PAD_ATTRIB::PTH;
430 if( !flashedPad && !platedHole )
431 testClearance =
false;
442 std::shared_ptr<SHAPE> itemShape = aItem->
GetEffectiveShape( aLayer, FLASHING::DEFAULT );
448 wxString msg =
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
453 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
454 drce->SetItems( aItem, aZone );
460 if( testHoles && aItem->
HasHole() )
462 std::shared_ptr<SHAPE_SEGMENT> holeShape;
486 wxString msg =
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
491 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
492 drce->SetItems( aItem, aZone );
514 if( !testClearance && !testShorts )
523 BOX2I worstCaseBBox = itemBBox;
535 std::shared_ptr<SHAPE> itemShape = aText->
GetEffectiveShape( layer, FLASHING::DEFAULT );
537 if( *aInheritedNet ==
nullptr )
539 if( zoneTree->
QueryColliding( itemBBox, itemShape.get(), layer ) )
540 *aInheritedNet = aZone->
GetNet();
543 if( *aInheritedNet == aZone->
GetNet() )
556 std::shared_ptr<DRC_ITEM> drce;
559 if( testShorts &&
actual == 0 && *aInheritedNet )
562 msg.Printf(
_(
"(nets %s and %s)" ),
563 ( *aInheritedNet )->GetNetname(),
569 msg =
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
575 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
576 drce->SetItems( aText, aZone );
586 std::map<BOARD_ITEM*, int> freePadsUsageMap;
587 std::unordered_map<PTR_PTR_CACHE_KEY, LAYERS_CHECKED> checkedPairs;
588 std::mutex checkedPairsMutex;
589 std::mutex freePadsUsageMapMutex;
590 std::atomic<size_t> done( 0 );
593 REPORT_AUX( wxString::Format( wxT(
"Testing %d tracks & vias..." ), count ) );
597 auto testTrack = [&](
const int start_idx,
const int end_idx )
599 for(
int trackIdx = start_idx; trackIdx < end_idx; ++trackIdx )
621 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
624 std::lock_guard<std::mutex> lock( checkedPairsMutex );
625 auto it = checkedPairs.find( { a, b } );
627 if( it != checkedPairs.end()
628 && ( it->second.layers.test( layer ) || ( it->second.has_error ) ) )
634 checkedPairs[ { a, b } ].layers.set( layer );
648 std::lock_guard<std::mutex> lock( freePadsUsageMapMutex );
649 auto it = freePadsUsageMap.find( other );
651 if( it == freePadsUsageMap.end() )
653 freePadsUsageMap[ other ] = track->
GetNetCode();
673 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
676 std::lock_guard<std::mutex> lock( checkedPairsMutex );
677 auto it = checkedPairs.find( { a, b } );
679 if( it != checkedPairs.end() )
680 it->second.has_error =
true;
707 while( done < count )
717 std::this_thread::sleep_for( std::chrono::milliseconds( 250 ) );
735 int padGroupIdx = padToNetTieGroupMap[
pad->GetNumber() ];
739 PAD* otherPad =
static_cast<PAD*
>( other );
741 if( padGroupIdx >= 0 && padGroupIdx == padToNetTieGroupMap[ otherPad->
GetNumber() ] )
742 testClearance = testShorting =
false;
744 if(
pad->SameLogicalPadAs( otherPad ) )
749 testClearance = testShorting =
false;
753 PAD* otherPad =
nullptr;
757 otherPad =
static_cast<PAD*
>( other );
760 otherVia =
static_cast<PCB_VIA*
>( other );
763 testClearance = testShorting =
false;
766 if(
pad->GetAttribute() == PAD_ATTRIB::NPTH && !
pad->FlashLayer( aLayer ) )
767 testClearance = testShorting =
false;
770 testClearance = testShorting =
false;
774 testClearance = testShorting =
false;
776 int padNet =
pad->GetNetCode();
777 int otherNet = otherCItem ? otherCItem->
GetNetCode() : 0;
780 if( otherNet && otherNet == padNet )
782 testClearance = testShorting =
false;
786 if( !(
pad->GetDrillSize().x > 0 )
788 && !( otherVia && otherVia->
GetDrill() > 0 ) )
793 if( !testClearance && !testShorting && !testHoles )
801 bool has_error =
false;
803 if( otherPad &&
pad->SameLogicalPadAs( otherPad ) )
813 if(
pad->GetShortNetname().StartsWith( wxS(
"unconnected-(" ) )
822 msg.Printf(
_(
"(nets %s and %s)" ),
826 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
827 drce->SetItems(
pad, otherPad );
836 if( testClearance || testShorting )
851 else if(
actual == 0 && padNet && otherNet && testShorting )
854 wxString msg = wxString::Format(
_(
"(nets %s and %s)" ),
858 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
859 drce->SetItems(
pad, other );
865 else if( testClearance )
868 wxString msg =
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
873 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
874 drce->SetItems(
pad, other );
893 if( testHoles && otherPad &&
pad->FlashLayer( aLayer ) && otherPad->
HasHole() )
900 wxString msg =
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
905 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
906 drce->SetItems(
pad, other );
914 if( testHoles && otherPad && otherPad->
FlashLayer( aLayer ) &&
pad->HasHole() )
916 if(
clearance > 0 && otherShape->Collide(
pad->GetEffectiveHoleShape().get(),
921 wxString msg =
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
926 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
927 drce->SetItems(
pad, other );
936 if( testHoles && otherVia && otherVia->
IsOnLayer( aLayer ) )
943 wxString msg =
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
948 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
949 drce->SetItems(
pad, otherVia );
963 std::atomic<size_t> done( 1 );
965 std::unordered_map<PTR_PTR_CACHE_KEY, LAYERS_CHECKED> checkedPairs;
966 std::mutex checkedPairsMutex;
970 const auto fp_check = [&](
size_t aFromIdx,
size_t aToIdx )
972 for(
size_t ii = aFromIdx; ii < aToIdx; ++ii )
983 std::shared_ptr<SHAPE> padShape =
pad->GetEffectiveShape( layer );
994 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
997 std::lock_guard<std::mutex> lock( checkedPairsMutex );
998 auto it = checkedPairs.find( { a, b } );
1000 if( it != checkedPairs.end()
1001 && ( it->second.layers.test( layer ) || it->second.has_error ) )
1007 checkedPairs[ { a, b } ].layers.set( layer );
1019 std::lock_guard<std::mutex> lock( checkedPairsMutex );
1020 auto it = checkedPairs.find( { a, b } );
1022 if( it != checkedPairs.end() )
1023 it->second.has_error =
true;
1040 done.fetch_add( 1 );
1045 auto returns =
tp.parallelize_loop( numFootprints, fp_check );
1048 for(
size_t ii = 0; ii < returns.size(); ++ii )
1050 while( returns[ii].wait_for( std::chrono::milliseconds( 250 ) ) != std::future_status::ready )
1060 std::atomic<size_t> done( 1 );
1063 count += footprint->GraphicalItems().size();
1065 REPORT_AUX( wxString::Format( wxT(
"Testing %d graphics..." ), count ) );
1067 auto isKnockoutText =
1073 auto testGraphicAgainstZone =
1089 if( isKnockoutText( item ) )
1099 std::unordered_map<PTR_PTR_CACHE_KEY, LAYERS_CHECKED> checkedPairs;
1100 std::mutex checkedPairsMutex;
1102 auto testCopperGraphic =
1113 if( otherCItem && otherCItem->GetNetCode() == aShape->GetNetCode() )
1128 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
1131 std::lock_guard<std::mutex> lock( checkedPairsMutex );
1132 auto it = checkedPairs.find( { a, b } );
1134 if( it != checkedPairs.end() && it->second.layers.test( layer ) )
1140 checkedPairs[ { a, b } ].layers.set( layer );
1155 std::future<void> retn =
tp.submit(
1160 testGraphicAgainstZone( item );
1162 if( item->Type() ==
PCB_SHAPE_T && item->IsOnCopperLayer() )
1163 testCopperGraphic(
static_cast<PCB_SHAPE*
>( item ) );
1165 done.fetch_add( 1 );
1173 for(
BOARD_ITEM* item : footprint->GraphicalItems() )
1175 testGraphicAgainstZone( item );
1177 done.fetch_add( 1 );
1185 std::future_status status = retn.wait_for( std::chrono::milliseconds( 250 ) );
1187 while( status != std::future_status::ready )
1190 status = retn.wait_for( std::chrono::milliseconds( 250 ) );
1200 std::vector<std::map<PCB_LAYER_ID, std::vector<SEG>>> poly_segments;
1204 std::atomic<size_t> done( 0 );
1210 std::shared_ptr<DRC_ITEM> drce;
1212 if( constraint.IsNull() )
1215 wxString msg =
_(
"(intersecting zones must have distinct priorities)" );
1216 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
1217 drce->SetItems( zoneA, zoneB );
1223 wxString msg =
formatMsg(
_(
"(%s clearance %s; actual %s)" ), constraint.GetName(),
1224 constraint.GetValue().Min(), std::max(
actual, 0 ) );
1226 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
1227 drce->SetItems( zoneA, zoneB );
1228 drce->SetViolatingRule( constraint.GetParentRule() );
1233 auto checkZones = [
this, testClearance, testIntersects, reportZoneZoneViolation, &poly_segments,
1234 &done](
int zoneA_idx,
int zoneB_idx,
bool sameNet,
PCB_LAYER_ID layer ) ->
void
1241 if( sameNet && testIntersects )
1245 done.fetch_add( 1 );
1250 else if( !sameNet && testClearance )
1257 std::map<VECTOR2I, int> conflictPoints;
1259 std::vector<SEG>& refSegments = poly_segments[zoneA_idx][layer];
1260 std::vector<SEG>& testSegments = poly_segments[zoneB_idx][layer];
1263 for(
SEG& refSegment : refSegments )
1266 for(
SEG& testSegment : testSegments )
1270 if( refSegment.B.x < testSegment.A.x )
1273 int64_t dist_sq = 0;
1275 refSegment.NearestPoints( testSegment, pt, other_pt, dist_sq );
1276 actual = std::floor( std::sqrt( dist_sq ) + 0.5 );
1280 done.fetch_add( 1 );
1281 reportZoneZoneViolation( zoneA, zoneB, pt,
actual, constraint, layer );
1289 done.fetch_add( 1 );
1293 std::map<PCB_LAYER_ID, std::vector<size_t>> zone_idx_by_layer;
1304 zone_idx_by_layer[layer].push_back( ii );
1314 for(
size_t ii : zone_idx_by_layer[layer] )
1318 std::vector<SEG>& zone_layer_poly_segs = poly_segments[ii][layer];
1319 zone_layer_poly_segs.reserve( poly->FullPointCount() );
1321 for(
auto it = poly->IterateSegmentsWithHoles(); it; it++ )
1325 if( seg.
A.
x > seg.
B.
x )
1328 zone_layer_poly_segs.push_back( seg );
1331 std::sort( zone_layer_poly_segs.begin(), zone_layer_poly_segs.end() );
1335 for(
auto it_a = zone_idx_by_layer[layer].begin(); it_a != zone_idx_by_layer[layer].end(); ++it_a )
1340 for(
auto it_a2 = std::next( it_a ); it_a2 != zone_idx_by_layer[layer].end(); ++it_a2 )
1342 size_t ia2 = *it_a2;
1365 polyA = zoneA->
GetFill( layer );
1366 polyB = zoneB->
GetFill( layer );
1373 tp.push_task( checkZones, ia, ia2, sameNet, layer );
1385 if(
tp.wait_for_tasks_duration( 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
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)
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)
virtual void reportViolation(std::shared_ptr< DRC_ITEM > &item, const VECTOR2I &aMarkerPos, int aMarkerLayer, DRC_CUSTOM_MARKER_HANDLER *aCustomHandler=nullptr)
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 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
@ 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)
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)