63 virtual bool Run()
override;
65 virtual const wxString
GetName()
const override
67 return wxT(
"solder_mask_issues" );
72 return wxT(
"Tests for silkscreen being clipped by solder mask and copper being exposed "
73 "by mask apertures of other nets" );
119 ZONE* zone =
static_cast<ZONE*
>( aItem );
137 int clearance = (
m_webWidth / 2 ) +
pad->GetSolderMaskExpansion();
153 int clearance = (
m_webWidth / 2 ) +
via->GetSolderMaskExpansion();
155 via->TransformShapeToPolygon( *solderMask->
GetFill( layer ), layer, clearance,
170 text->TransformTextToPolySet( *solderMask->
GetFill( layer ),
198 const size_t progressDelta = 500;
250 const size_t progressDelta = 250;
275 if( !item->IsOnLayer( layer ) )
278 PCB_LAYER_ID maskLayer = layer == F_SilkS ? F_Mask : B_Mask;
279 BOX2I itemBBox = item->GetBoundingBox();
280 DRC_CONSTRAINT constraint = m_drcEngine->EvalRules( SILK_CLEARANCE_CONSTRAINT,
281 item, nullptr, maskLayer );
282 int clearance = constraint.GetValue().Min();
286 if( constraint.GetSeverity() == RPT_SEVERITY_IGNORE || clearance < 0 )
289 std::shared_ptr<SHAPE> itemShape = item->GetEffectiveShape( layer );
291 if( m_fullSolderMaskRTree->QueryColliding( itemBBox, itemShape.get(), maskLayer,
292 clearance, &actual, &pos ) )
294 auto drce = DRC_ITEM::Create( DRCE_SILK_CLEARANCE );
298 wxString msg = formatMsg( _(
"(%s clearance %s; actual %s)" ),
299 constraint.GetName(),
303 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) + msg );
306 drce->SetItems( item );
307 drce->SetViolatingRule( constraint.GetParentRule() );
309 reportViolation( drce, pos, layer );
326 &&
pad->GetSize().x <=
pad->GetDrillSize().x
327 &&
pad->GetSize().y <=
pad->GetDrillSize().y )
353 return maskLayers.count() > 0 && otherLayers.count() == 0;
387 if( ii->second.second == aTestNet && aTestNet > 0 )
395 PAD* alreadyEncounteredPad =
static_cast<PAD*
>( ii->second.first );
396 PAD* thisPad =
static_cast<PAD*
>( aTestItem );
402 *aCollidingItem = ii->second.first;
411 wxCHECK( fp,
false );
425 if( padNumberToGroupIdxMap[
static_cast<PAD*
>( aMaskItem )->GetNumber() ] >= 0 )
447 m_itemTree->QueryColliding( aItem, aRefLayer, aTargetLayer,
452 PAD* otherPad =
dynamic_cast<PAD*
>( other );
458 if( otherNet > 0 && otherNet == itemNet )
475 if(
pad && otherPad && (
pad->SameLogicalPadAs( otherPad )
476 ||
pad->SharesNetTieGroup( otherPad ) ) )
485 if(
static_cast<void*
>( a ) >
static_cast<void*
>( b ) )
490 if( it !=
m_checkedPairs.end() && it->second.test( aTargetLayer ) )
503 PAD* otherPad =
dynamic_cast<PAD*
>( other );
527 clearance +=
pad->GetSolderMaskExpansion();
528 else if(
via && !
via->IsTented() )
529 clearance +=
via->GetSolderMaskExpansion();
533 else if( otherVia && !otherVia->
IsTented() )
536 if( itemShape->Collide( otherShape.get(), clearance, &actual, &pos ) )
541 if( aTargetLayer ==
F_Mask )
542 msg =
_(
"Front solder mask aperture bridges items with different nets" );
544 msg =
_(
"Rear solder mask aperture bridges items with different nets" );
555 drce->SetErrorMessage( msg );
556 drce->SetItems( aItem, colliding, other );
567 drce->SetErrorMessage( msg );
568 drce->SetItems( other, colliding, aItem );
577 drce->SetErrorMessage( msg );
578 drce->SetItems( aItem, other );
591 const BOX2I& aItemBBox,
606 if( zoneNet == connectedItem->
GetNetCode() && zoneNet > 0 )
610 BOX2I inflatedBBox( aItemBBox );
614 clearance +=
static_cast<PAD*
>( aItem )->GetSolderMaskExpansion();
618 inflatedBBox.
Inflate( clearance );
629 if( zoneTree && zoneTree->
QueryColliding( aItemBBox, itemShape.get(), aTargetLayer,
630 clearance, &actual, &pos ) )
635 if( aMaskLayer ==
F_Mask )
636 msg =
_(
"Front solder mask aperture bridges items with different nets" );
638 msg =
_(
"Rear solder mask aperture bridges items with different nets" );
648 drce->SetErrorMessage( msg );
649 drce->SetItems( aItem, colliding, zone );
658 drce->SetErrorMessage( msg );
659 drce->SetItems( aItem, zone );
675 const size_t progressDelta = 250;
735 reportAux( wxT(
"Solder mask violations ignored. Tests not run." ) );
746 for(
PAD*
pad : footprint->Pads() )
769 if( !
reportPhase(
_(
"Checking solder mask to silk clearance..." ) ) )
774 if( !
reportPhase(
_(
"Checking solder mask web integrity..." ) ) )
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
Container for design settings for a BOARD object.
int m_SolderMaskToCopperClearance
bool m_AllowSoldermaskBridgesInFPs
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 void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const
Convert the item shape to a closed polygon.
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
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.
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
FOOTPRINT * GetParentFootprint() const
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Information pertinent to a Pcbnew printed circuit board.
std::vector< ZONE * > m_DRCCopperZones
FOOTPRINTS & Footprints()
std::unordered_map< ZONE *, std::unique_ptr< DRC_RTREE > > m_CopperZoneRTreeCache
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
bool Intersects(const BOX2< Vec > &aRect) const
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
bool IsErrorLimitExceeded(int error_code)
bool QueryWorstConstraint(DRC_CONSTRAINT_T aRuleId, DRC_CONSTRAINT &aConstraint)
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 const wxString GetName() const override
void testMaskItemAgainstZones(BOARD_ITEM *item, const BOX2I &itemBBox, PCB_LAYER_ID refLayer, PCB_LAYER_ID targetLayer)
bool checkMaskAperture(BOARD_ITEM *aMaskItem, BOARD_ITEM *aTestItem, PCB_LAYER_ID aTestLayer, int aTestNet, BOARD_ITEM **aCollidingItem)
std::unique_ptr< DRC_RTREE > m_itemTree
void addItemToRTrees(BOARD_ITEM *aItem)
std::unique_ptr< DRC_RTREE > m_fullSolderMaskRTree
void testSilkToMaskClearance()
virtual bool Run() override
Run this provider against the given PCB with configured options (if any).
virtual const wxString GetDescription() const override
std::unordered_map< PTR_PTR_CACHE_KEY, LSET > m_checkedPairs
bool checkItemMask(BOARD_ITEM *aMaskItem, int aTestNet)
virtual ~DRC_TEST_PROVIDER_SOLDER_MASK()
DRC_TEST_PROVIDER_SOLDER_MASK()
std::unordered_map< PTR_LAYER_CACHE_KEY, std::pair< BOARD_ITEM *, int > > m_maskApertureNetMap
void testItemAgainstItems(BOARD_ITEM *aItem, const BOX2I &aItemBBox, PCB_LAYER_ID aRefLayer, PCB_LAYER_ID aTargetLayer)
Represent a DRC "provider" which runs some DRC functions over a BOARD and spits out DRC_ITEM and posi...
static std::vector< KICAD_T > s_allBasicItemsButZones
virtual bool reportPhase(const wxString &aStageName)
int forEachGeometryItem(const std::vector< KICAD_T > &aTypes, LSET aLayers, const std::function< bool(BOARD_ITEM *)> &aFunc)
virtual bool reportProgress(int aCount, int aSize, int aDelta)
virtual void reportViolation(std::shared_ptr< DRC_ITEM > &item, const VECTOR2I &aMarkerPos, int aMarkerLayer)
static std::vector< KICAD_T > s_allBasicItems
bool isInvisibleText(const BOARD_ITEM *aItem) const
void reportAux(const wxString &aMsg)
virtual void reportRuleStatistics()
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.
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
int GetSolderMaskExpansion() const
bool SharesNetTieGroup(const PAD *aOther) const
bool IsTented() const override
int GetSolderMaskExpansion() const
void RemoveAllContours()
Remove all outlines & holes (clears) the polygon set.
@ CHAMFER_ALL_CORNERS
All angles are chamfered.
void BooleanAdd(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Perform boolean polyset union For aFastMode meaning, see function booleanOp.
void Simplify(POLYGON_MODE aFastMode)
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections) For aFastMo...
void Deflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError)
Handle a list of polygons defining a copper zone.
const std::shared_ptr< SHAPE_POLY_SET > & GetFilledPolysList(PCB_LAYER_ID aLayer) const
void CacheTriangulation(PCB_LAYER_ID aLayer=UNDEFINED_LAYER)
Create a list of triangles that "fill" the solid areas used for instance to draw these solid areas on...
const BOX2I GetBoundingBox() const override
void SetFillFlag(PCB_LAYER_ID aLayer, bool aFlag)
SHAPE_POLY_SET * GetFill(PCB_LAYER_ID aLayer)
void SetIsFilled(bool isFilled)
virtual bool IsOnLayer(PCB_LAYER_ID) const override
Test to see if this object is on the given layer.
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
@ SILK_CLEARANCE_CONSTRAINT
bool isMaskAperture(BOARD_ITEM *aItem)
bool isNullAperture(BOARD_ITEM *aItem)
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
@ 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_TEXT_T
class PCB_TEXT, text on a layer
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
@ PCB_PAD_T
class PAD, a pad in a footprint