Allow solder mask aperture objects to inherit nets during DRC.
The issue is that object A (the solder mask aperture object) can bridge objects B and C which have different nets. Since we only do object-to-object compares we don't find this. By allowing object A to inherit the first net it collides with (either object B's or object C's), we'll generate a violation with the second collision. Fixes https://gitlab.com/kicad/code/kicad/issues/10189
This commit is contained in:
parent
2fdbc41b8f
commit
b70cf1473f
|
@ -97,6 +97,11 @@ private:
|
|||
std::vector<ZONE*> m_copperZones;
|
||||
|
||||
std::map< std::tuple<BOARD_ITEM*, BOARD_ITEM*, PCB_LAYER_ID>, int> m_checkedPairs;
|
||||
|
||||
// Shapes used to define solder mask apertures don't have nets, so we assign them the
|
||||
// first net that bridges their aperture (after which any other nets will generate
|
||||
// violations).
|
||||
std::map< std::pair<BOARD_ITEM*, PCB_LAYER_ID>, int> m_maskApertureNetMap;
|
||||
};
|
||||
|
||||
|
||||
|
@ -290,6 +295,17 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testSilkToMaskClearance()
|
|||
}
|
||||
|
||||
|
||||
bool isMaskAperture( BOARD_ITEM* aItem )
|
||||
{
|
||||
static const LSET saved( 2, F_Mask, B_Mask );
|
||||
|
||||
LSET maskLayers = aItem->GetLayerSet() & saved;
|
||||
LSET otherLayers = aItem->GetLayerSet() & ~saved;
|
||||
|
||||
return maskLayers.count() > 0 && otherLayers.count() == 0;
|
||||
}
|
||||
|
||||
|
||||
void DRC_TEST_PROVIDER_SOLDER_MASK::testItemAgainstItems( BOARD_ITEM* aItem,
|
||||
const EDA_RECT& aItemBBox,
|
||||
PCB_LAYER_ID aRefLayer,
|
||||
|
@ -349,6 +365,11 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testItemAgainstItems( BOARD_ITEM* aItem,
|
|||
PAD* otherPad = dynamic_cast<PAD*>( other );
|
||||
PCB_VIA* otherVia = dynamic_cast<PCB_VIA*>( other );
|
||||
auto otherShape = other->GetEffectiveShape( aTargetLayer );
|
||||
int otherNet = -1;
|
||||
|
||||
if( other->IsConnected() )
|
||||
otherNet = static_cast<BOARD_CONNECTED_ITEM*>( other )->GetNetCode();
|
||||
|
||||
int actual;
|
||||
VECTOR2I pos;
|
||||
int clearance = 0;
|
||||
|
@ -376,6 +397,28 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testItemAgainstItems( BOARD_ITEM* aItem,
|
|||
|
||||
if( itemShape->Collide( otherShape.get(), clearance, &actual, &pos ) )
|
||||
{
|
||||
if( isMaskAperture( aItem ) )
|
||||
{
|
||||
std::pair<BOARD_ITEM*, PCB_LAYER_ID> key = { aItem, aRefLayer };
|
||||
|
||||
if( m_maskApertureNetMap.count( key ) == 0 )
|
||||
m_maskApertureNetMap[ key ] = otherNet;
|
||||
|
||||
if( m_maskApertureNetMap.at( key ) == otherNet && otherNet > 0 )
|
||||
return true;
|
||||
}
|
||||
|
||||
if( isMaskAperture( other ) )
|
||||
{
|
||||
std::pair<BOARD_ITEM*, PCB_LAYER_ID> key = { other, aRefLayer };
|
||||
|
||||
if( m_maskApertureNetMap.count( key ) == 0 )
|
||||
m_maskApertureNetMap[ key ] = itemNet;
|
||||
|
||||
if( m_maskApertureNetMap.at( key ) == itemNet && itemNet > 0 )
|
||||
return true;
|
||||
}
|
||||
|
||||
auto drce = DRC_ITEM::Create( DRCE_SOLDERMASK_BRIDGE );
|
||||
|
||||
if( aTargetLayer == F_Mask )
|
||||
|
@ -410,9 +453,13 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testMaskItemAgainstZones( BOARD_ITEM* aItem,
|
|||
if( !zone->GetLayerSet().test( aTargetLayer ) )
|
||||
continue;
|
||||
|
||||
if( zone->GetNetCode() && aItem->IsConnected() )
|
||||
int zoneNet = zone->GetNetCode();
|
||||
|
||||
if( aItem->IsConnected() )
|
||||
{
|
||||
if( zone->GetNetCode() == static_cast<BOARD_CONNECTED_ITEM*>( aItem )->GetNetCode() )
|
||||
BOARD_CONNECTED_ITEM* connectedItem = static_cast<BOARD_CONNECTED_ITEM*>( aItem );
|
||||
|
||||
if( zoneNet == connectedItem->GetNetCode() && zoneNet > 0 )
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -441,6 +488,17 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testMaskItemAgainstZones( BOARD_ITEM* aItem,
|
|||
if( zoneTree && zoneTree->QueryColliding( aItemBBox, itemShape.get(), aTargetLayer,
|
||||
clearance, &actual, &pos ) )
|
||||
{
|
||||
if( isMaskAperture( aItem ) )
|
||||
{
|
||||
std::pair<BOARD_ITEM*, PCB_LAYER_ID> key = { aItem, aMaskLayer };
|
||||
|
||||
if( m_maskApertureNetMap.count( key ) == 0 )
|
||||
m_maskApertureNetMap[ key ] = zoneNet;
|
||||
|
||||
if( m_maskApertureNetMap.at( key ) == zoneNet && zoneNet > 0 )
|
||||
continue;
|
||||
}
|
||||
|
||||
auto drce = DRC_ITEM::Create( DRCE_SOLDERMASK_BRIDGE );
|
||||
|
||||
if( aMaskLayer == F_Mask )
|
||||
|
|
Loading…
Reference in New Issue