70 virtual bool Run()
override;
72 virtual const wxString
GetName()
const override {
return wxT(
"edge_clearance" ); }
96 const std::vector<COPPER_ITEM_UNITS>& aCopperItems );
131 disposition = elem_disposition;
133 else if( disposition != elem_disposition )
156 for(
int outlineIdx = 1; outlineIdx < aBoardOutline.
OutlineCount(); ++outlineIdx )
161 nearestEdgePt = otherEdgePt;
166 if( edge->HitTest( nearestEdgePt,
m_epsilon ) )
177 int minClearance = constraint.GetValue().Min();
184 if( minClearance > 0 )
186 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
187 constraint.GetName(),
192 drcItem->SetItems( nearestEdge->
m_Uuid, aItem->
m_Uuid );
193 drcItem->SetViolatingRule( constraint.GetParentRule() );
202 drcItem->SetErrorMessage(
_(
"Silkscreen outside board edge" ) );
204 drcItem->SetItems( aItem->
m_Uuid );
219 int minClearance = constraint.GetValue().Min();
232 if( castellatedPad->GetEffectiveHoleShape()->Collide( pos ) )
253 if( minClearance > 0 )
255 drcItem->SetErrorDetail(
formatMsg(
_(
"(%s clearance %s; actual %s)" ),
256 constraint.GetName(),
262 drcItem->SetViolatingRule( constraint.GetParentRule() );
283 const std::vector<COPPER_ITEM_UNITS>& aCopperItems )
298 [&](
const int idx ) ->
size_t
305 for(
size_t ii = copperItem.
first; ii < copperItem.
last; ++ii )
307 if( outline.
Collide( aWorkUnits[ii].shape.get() ) )
318 drcItem->SetItems( item );
324 auto futures =
tp.submit_loop( 0, aCopperItems.size(), testItem );
335 if( !
reportPhase(
_(
"Checking copper to board edge clearances..." ) ) )
340 if( !
reportPhase(
_(
"Checking silk to board edge clearances..." ) ) )
345 REPORT_AUX( wxT(
"Edge clearance violations ignored. Tests not run." ) );
364 std::vector<std::unique_ptr<PCB_SHAPE>> edges;
386 edges.back()->SetStart( segment->GetStart() );
387 edges.back()->SetEnd( segment->GetEnd() );
388 edges.back()->SetStroke( stroke );
394 edges.back()->SetArcGeometry( arc->GetP0(), arc->GetArcMid(), arc->GetP1() );
395 edges.back()->SetStroke( stroke );
400 wxString::Format(
"Unexpected effective shape type %d for rounded rectangle",
401 (
int) subshape->Type() ) );
410 edges.back()->SetEndX( shape->
GetStartX() );
411 edges.back()->SetStroke( stroke );
414 edges.back()->SetEndY( shape->
GetStartY() );
415 edges.back()->SetStroke( stroke );
418 edges.back()->SetStartX( shape->
GetEndX() );
419 edges.back()->SetStroke( stroke );
422 edges.back()->SetStartY( shape->
GetEndY() );
423 edges.back()->SetStroke( stroke );
438 edges.back()->SetStart( seg.
A );
439 edges.back()->SetEnd( seg.
B );
440 edges.back()->SetStroke( stroke );
446 edges.back()->SetStroke( stroke );
452 for(
const std::unique_ptr<PCB_SHAPE>& edge : edges )
456 if( edge->IsOnLayer( layer ) )
463 for(
PAD*
pad : footprint->Pads() )
478 std::vector<WORK_UNIT> workUnits;
479 std::vector<COPPER_ITEM_UNITS> copperItems;
490 if(
static_cast<ZONE*
>( item )->GetIsRuleArea() )
505 std::vector<PCB_LAYER_ID> layersToTest;
507 switch( item->
Type() )
510 layersToTest =
static_cast<PAD*
>( item )->Padstack().UniqueLayers();
514 layersToTest =
static_cast<PCB_VIA*
>( item )->Padstack().UniqueLayers();
519 layersToTest.push_back( layer );
527 size_t firstUnit = workUnits.size();
537 copperItems.push_back( { item, firstUnit, workUnits.size() } );
542 std::atomic<size_t> done( 0 );
543 size_t count = workUnits.size();
545 auto processWorkUnit =
546 [&](
const int idx ) ->
size_t
557 if( !testCopper && !testSilk )
573 return testAgainstEdge( item, wu.shape.get(),
575 EDGE_CLEARANCE_CONSTRAINT,
576 DRCE_EDGE_CLEARANCE );
588 return testAgainstEdge( item, wu.shape.get(),
590 SILK_CLEARANCE_CONSTRAINT,
591 DRCE_SILK_EDGE_CLEARANCE );
600 bool needsResolution =
false;
606 if( inserted || it->second ==
UNKNOWN )
609 needsResolution =
true;
613 if( needsResolution &&
m_board->BoardOutline()->HasOutline() )
616 m_board->BoardOutline()->GetOutline() );
625 size_t numBlocks = count;
626 auto futures =
tp.submit_loop( 0, count, processWorkUnit, numBlocks );
628 while( done < count )
634 for(
auto& f : futures )
640 futures.wait_for( std::chrono::milliseconds( 250 ) );
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 VECTOR2I GetCenter() const
This defaults to the center of the bounding box if not overridden.
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
virtual bool IsOnCopperLayer() 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.
const MINOPTMAX< int > & GetValue() 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.
DRC_TEST_PROVIDER_EDGE_CLEARANCE()
int m_largestEdgeClearance
void resolveSilkDisposition(BOARD_ITEM *aItem, const SHAPE *aItemShape, const SHAPE_POLY_SET &aBoardOutline)
virtual bool Run() override
Run this provider against the given PCB with configured options (if any).
std::set< std::tuple< KIID, KIID, VECTOR2I > > m_emittedEdgeReports
void testCopperOutsideBoard(const std::vector< WORK_UNIT > &aWorkUnits, const std::vector< COPPER_ITEM_UNITS > &aCopperItems)
virtual ~DRC_TEST_PROVIDER_EDGE_CLEARANCE()=default
std::map< BOARD_ITEM *, SILK_DISPOSITION > m_silkDisposition
std::mutex m_emittedMutex
virtual const wxString GetName() const override
bool testAgainstEdge(BOARD_ITEM *item, SHAPE *itemShape, PCB_LAYER_ID shapeLayer, BOARD_ITEM *other, DRC_CONSTRAINT_T aConstraintType, PCB_DRC_CODE aErrorCode)
std::vector< PAD * > m_castellatedPads
virtual bool reportPhase(const wxString &aStageName)
int forEachGeometryItem(const std::vector< KICAD_T > &aTypes, const LSET &aLayers, const std::function< bool(BOARD_ITEM *)> &aFunc)
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)
static std::vector< KICAD_T > s_allBasicItems
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 VECTOR2I GetPosition() const
KICAD_T Type() const
Returns the type of object.
virtual std::vector< SHAPE * > MakeEffectiveShapes(bool aEdgeOnly=false) const
Make a set of SHAPE objects representing the EDA_SHAPE.
SHAPE_POLY_SET & GetPolyShape()
int GetCornerRadius() const
LSET is a set of PCB_LAYER_IDs.
static const LSET & AllLayersMask()
STROKE_PARAMS GetStroke() const override
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
SHAPE_TYPE Type() const
Return the type of the shape.
const std::vector< SHAPE * > & Shapes() const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
const VECTOR2I NearestPoint(const VECTOR2I &aP, bool aAllowInternalShapePoints=true) const
Find a point on the line chain that is closest to point aP.
virtual size_t GetSegmentCount() const override
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
Represent a set of closed polygons.
bool IsEmpty() const
Return true if the set is empty (no polygons at all)
virtual void CacheTriangulation(bool aSimplify=false, const TASK_SUBMITTER &aSubmitter={}, bool aBuildIndexes=false)
Build a polygon triangulation, needed to draw a polygon on OpenGL and in some other calculations.
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,...
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
void BuildBBoxCaches() const
Construct BBoxCaches for Contains(), below.
int OutlineCount() const
Return the number of outlines in the set.
void Fracture(bool aSimplify=true)
Convert a set of polygons with holes to a single outline with "slits"/"fractures" connecting the oute...
bool Contains(const VECTOR2I &aP, int aSubpolyIndex=-1, int aAccuracy=0, bool aUseBBoxCaches=false) const
Return true if a given subpolygon contains the point aP.
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,...
virtual VECTOR2I Centre() const
Compute a center-of-mass of the shape.
Simple container to manage line stroke parameters.
void SetWidth(int aWidth)
constexpr extended_type SquaredDistance(const VECTOR2< T > &aVector) const
Compute the squared distance between two vectors.
Handle a list of polygons defining a copper zone.
@ SILK_CLEARANCE_CONSTRAINT
@ EDGE_CLEARANCE_CONSTRAINT
@ DRCE_SILK_EDGE_CLEARANCE
@ DRCE_COPPER_OUTSIDE_BOARD
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
PCB_LAYER_ID
A quick note on layer IDs:
static DRC_REGISTER_TEST_PROVIDER< DRC_TEST_PROVIDER_ANNULAR_WIDTH > dummy
@ CONN
Like smd, does not appear on the solder paste layer (default) Note: also has a special attribute in G...
@ CASTELLATED
a pad with a castellated through hole
@ SH_COMPOUND
compound shape, consisting of multiple simple shapes
std::shared_ptr< SHAPE > shape
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_ZONE_T
class ZONE, a copper pour area
@ 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