Browse Source

Repair missing handling of solder mask expansion on copper shapes.

master
Jeff Young 3 weeks ago
parent
commit
80ca30ac37
  1. 164
      pcbnew/drc/drc_test_provider_solder_mask.cpp
  2. 4
      pcbnew/pcb_shape.cpp
  3. 4
      pcbnew/pcb_track.cpp

164
pcbnew/drc/drc_test_provider_solder_mask.cpp

@ -103,78 +103,42 @@ private:
void DRC_TEST_PROVIDER_SOLDER_MASK::addItemToRTrees( BOARD_ITEM* aItem )
{
ZONE* solderMask = m_board->m_SolderMaskBridges;
if( aItem->Type() == PCB_ZONE_T )
for( PCB_LAYER_ID layer : { F_Mask, B_Mask } )
{
ZONE* zone = static_cast<ZONE*>( aItem );
if( !aItem->IsOnLayer( layer ) )
continue;
for( PCB_LAYER_ID layer : { F_Mask, B_Mask } )
{
if( zone->IsOnLayer( layer ) )
{
solderMask->GetFill( layer )->BooleanAdd( *zone->GetFilledPolysList( layer ) );
}
}
}
else if( aItem->Type() == PCB_PAD_T )
{
for( PCB_LAYER_ID layer : { F_Mask, B_Mask } )
{
if( aItem->IsOnLayer( layer ) )
{
PAD* pad = static_cast<PAD*>( aItem );
int clearance = ( m_webWidth / 2 ) + pad->GetSolderMaskExpansion( layer );
SHAPE_POLY_SET* solderMask = m_board->m_SolderMaskBridges->GetFill( layer );
aItem->TransformShapeToPolygon( *solderMask->GetFill( layer ), layer, clearance,
m_maxError, ERROR_OUTSIDE );
if( aItem->Type() == PCB_ZONE_T )
{
ZONE* zone = static_cast<ZONE*>( aItem );
m_itemTree->Insert( aItem, layer, m_largestClearance );
}
solderMask->BooleanAdd( *zone->GetFilledPolysList( layer ) );
}
}
else if( aItem->Type() == PCB_VIA_T )
{
for( PCB_LAYER_ID layer : { F_Mask, B_Mask } )
else
{
if( aItem->IsOnLayer( layer ) )
{
PCB_VIA* via = static_cast<PCB_VIA*>( aItem );
int clearance = ( m_webWidth / 2 ) + via->GetSolderMaskExpansion();
int clearance = m_webWidth / 2;
via->TransformShapeToPolygon( *solderMask->GetFill( layer ), layer, clearance,
m_maxError, ERROR_OUTSIDE );
if( aItem->Type() == PCB_PAD_T )
clearance += static_cast<PAD*>( aItem )->GetSolderMaskExpansion( layer );
else if( aItem->Type() == PCB_VIA_T )
clearance += static_cast<PCB_VIA*>( aItem )->GetSolderMaskExpansion();
else if( aItem->Type() == PCB_SHAPE_T )
clearance += static_cast<PCB_SHAPE*>( aItem )->GetSolderMaskExpansion();
m_itemTree->Insert( aItem, layer, m_largestClearance );
}
}
}
else if( aItem->Type() == PCB_FIELD_T || aItem->Type() == PCB_TEXT_T )
{
for( PCB_LAYER_ID layer : { F_Mask, B_Mask } )
{
if( aItem->IsOnLayer( layer ) )
if( aItem->Type() == PCB_FIELD_T || aItem->Type() == PCB_TEXT_T )
{
const PCB_TEXT* text = static_cast<const PCB_TEXT*>( aItem );
PCB_TEXT* text = static_cast<PCB_TEXT*>( aItem );
text->TransformTextToPolySet( *solderMask->GetFill( layer ),
m_webWidth / 2, m_maxError, ERROR_OUTSIDE );
m_itemTree->Insert( aItem, layer, m_largestClearance );
text->TransformTextToPolySet( *solderMask, clearance, m_maxError, ERROR_OUTSIDE );
}
}
}
else
{
for( PCB_LAYER_ID layer : { F_Mask, B_Mask } )
{
if( aItem->IsOnLayer( layer ) )
else
{
aItem->TransformShapeToPolygon( *solderMask->GetFill( layer ), layer,
m_webWidth / 2, m_maxError, ERROR_OUTSIDE );
m_itemTree->Insert( aItem, layer, m_largestClearance );
aItem->TransformShapeToPolygon( *solderMask, layer, clearance, m_maxError, ERROR_OUTSIDE );
}
m_itemTree->Insert( aItem, layer, m_largestClearance );
}
}
}
@ -461,12 +425,12 @@ bool DRC_TEST_PROVIDER_SOLDER_MASK::checkItemMask( BOARD_ITEM* aMaskItem, int aT
void DRC_TEST_PROVIDER_SOLDER_MASK::testItemAgainstItems( BOARD_ITEM* aItem, const BOX2I& aItemBBox,
PCB_LAYER_ID aRefLayer,
PCB_LAYER_ID aTargetLayer )
PCB_LAYER_ID aRefLayer, PCB_LAYER_ID aTargetLayer )
{
PAD* pad = aItem->Type() == PCB_PAD_T ? static_cast<PAD*>( aItem ) : nullptr;
PCB_VIA* via = aItem->Type() == PCB_VIA_T ? static_cast<PCB_VIA*>( aItem ) : nullptr;
int itemNet = -1;
PAD* pad = aItem->Type() == PCB_PAD_T ? static_cast<PAD*>( aItem ) : nullptr;
PCB_VIA* via = aItem->Type() == PCB_VIA_T ? static_cast<PCB_VIA*>( aItem ) : nullptr;
PCB_SHAPE* shape = aItem->Type() == PCB_SHAPE_T ? static_cast<PCB_SHAPE*>( aItem ) : nullptr;
int itemNet = -1;
if( aItem->IsConnected() )
itemNet = static_cast<BOARD_CONNECTED_ITEM*>( aItem )->GetNetCode();
@ -551,10 +515,11 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testItemAgainstItems( BOARD_ITEM* aItem, con
// Visitor:
[&]( BOARD_ITEM* other ) -> bool
{
PAD* otherPad = other->Type() == PCB_PAD_T ? static_cast<PAD*>( other ) : nullptr;
PCB_VIA* otherVia = other->Type() == PCB_VIA_T ? static_cast<PCB_VIA*>( other ) : nullptr;
auto otherShape = other->GetEffectiveShape( aTargetLayer );
int otherNet = -1;
PAD* otherPad = other->Type() == PCB_PAD_T ? static_cast<PAD*>( other ) : nullptr;
PCB_VIA* otherVia = other->Type() == PCB_VIA_T ? static_cast<PCB_VIA*>( other ) : nullptr;
PCB_SHAPE* otherShape = other->Type() == PCB_SHAPE_T ? static_cast<PCB_SHAPE*>( other ) : nullptr;
auto otherItemShape = other->GetEffectiveShape( aTargetLayer );
int otherNet = -1;
if( other->IsConnected() )
otherNet = static_cast<BOARD_CONNECTED_ITEM*>( other )->GetNetCode();
@ -575,16 +540,20 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testItemAgainstItems( BOARD_ITEM* aItem, con
}
if( pad )
clearance += pad->GetSolderMaskExpansion( PADSTACK::ALL_LAYERS );
clearance += pad->GetSolderMaskExpansion( aRefLayer );
else if( via && !via->IsTented( aRefLayer ) )
clearance += via->GetSolderMaskExpansion();
else if( shape )
clearance += shape->GetSolderMaskExpansion();
if( otherPad )
clearance += otherPad->GetSolderMaskExpansion( PADSTACK::ALL_LAYERS );
else if( otherVia && !otherVia->IsTented( aRefLayer ) )
clearance += otherPad->GetSolderMaskExpansion( aTargetLayer );
else if( otherVia && !otherVia->IsTented( aTargetLayer ) )
clearance += otherVia->GetSolderMaskExpansion();
else if( shape )
clearance += otherShape->GetSolderMaskExpansion();
if( itemShape->Collide( otherShape.get(), clearance, &actual, &pos ) )
if( itemShape->Collide( otherItemShape.get(), clearance, &actual, &pos ) )
{
wxString msg;
BOARD_ITEM* colliding = nullptr;
@ -638,11 +607,13 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testItemAgainstItems( BOARD_ITEM* aItem, con
}
void DRC_TEST_PROVIDER_SOLDER_MASK::testMaskItemAgainstZones( BOARD_ITEM* aItem,
const BOX2I& aItemBBox,
PCB_LAYER_ID aMaskLayer,
PCB_LAYER_ID aTargetLayer )
void DRC_TEST_PROVIDER_SOLDER_MASK::testMaskItemAgainstZones( BOARD_ITEM* aItem, const BOX2I& aItemBBox,
PCB_LAYER_ID aMaskLayer, PCB_LAYER_ID aTargetLayer )
{
PAD* pad = aItem->Type() == PCB_PAD_T ? static_cast<PAD*>( aItem ) : nullptr;
PCB_VIA* via = aItem->Type() == PCB_VIA_T ? static_cast<PCB_VIA*>( aItem ) : nullptr;
PCB_SHAPE* shape = aItem->Type() == PCB_SHAPE_T ? static_cast<PCB_SHAPE*>( aItem ) : nullptr;
for( ZONE* zone : m_board->m_DRCCopperZones )
{
if( !zone->GetLayerSet().test( aTargetLayer ) )
@ -661,10 +632,12 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testMaskItemAgainstZones( BOARD_ITEM* aItem,
BOX2I inflatedBBox( aItemBBox );
int clearance = m_board->GetDesignSettings().m_SolderMaskToCopperClearance;
if( aItem->Type() == PCB_PAD_T )
clearance += static_cast<PAD*>( aItem )->GetSolderMaskExpansion( PADSTACK::ALL_LAYERS );
else if( aItem->Type() == PCB_VIA_T )
clearance += static_cast<PCB_VIA*>( aItem )->GetSolderMaskExpansion();
if( pad )
clearance += pad->GetSolderMaskExpansion( aTargetLayer );
else if( via && !via->IsTented( aTargetLayer ) )
clearance += via->GetSolderMaskExpansion();
else if( shape )
clearance += shape->GetSolderMaskExpansion();
inflatedBBox.Inflate( clearance );
@ -677,8 +650,8 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testMaskItemAgainstZones( BOARD_ITEM* aItem,
std::shared_ptr<SHAPE> itemShape = aItem->GetEffectiveShape( aMaskLayer );
if( zoneTree && zoneTree->QueryColliding( aItemBBox, itemShape.get(), aTargetLayer,
clearance, &actual, &pos ) )
if( zoneTree && zoneTree->QueryColliding( aItemBBox, itemShape.get(), aTargetLayer, clearance,
&actual, &pos ) )
{
wxString msg;
BOARD_ITEM* colliding = nullptr;
@ -694,7 +667,7 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testMaskItemAgainstZones( BOARD_ITEM* aItem,
{
if( checkMaskAperture( aItem, zone, aTargetLayer, zoneNet, &colliding ) )
{
auto drce = DRC_ITEM::Create( DRCE_SOLDERMASK_BRIDGE );
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_SOLDERMASK_BRIDGE );
drce->SetErrorMessage( msg );
drce->SetItems( aItem, colliding, zone );
@ -704,7 +677,7 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testMaskItemAgainstZones( BOARD_ITEM* aItem,
}
else
{
auto drce = DRC_ITEM::Create( DRCE_SOLDERMASK_BRIDGE );
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_SOLDERMASK_BRIDGE );
drce->SetErrorMessage( msg );
drce->SetItems( aItem, zone );
@ -802,10 +775,31 @@ bool DRC_TEST_PROVIDER_SOLDER_MASK::Run()
m_maxError = m_board->GetDesignSettings().m_MaxError;
m_largestClearance = 0;
auto updateLargestClearance =
[&]( int aClearance )
{
m_largestClearance = std::max( m_largestClearance, aClearance );
};
for( FOOTPRINT* footprint : m_board->Footprints() )
{
for( PAD* pad : footprint->Pads() )
m_largestClearance = std::max( m_largestClearance, pad->GetSolderMaskExpansion( PADSTACK::ALL_LAYERS ) );
updateLargestClearance( pad->GetSolderMaskExpansion( PADSTACK::ALL_LAYERS ) );
for( BOARD_ITEM* item : footprint->GraphicalItems() )
{
if( item->Type() == PCB_SHAPE_T )
updateLargestClearance( static_cast<PCB_SHAPE*>( item )->GetSolderMaskExpansion() );
}
}
for( PCB_TRACK* track : m_board->Tracks() )
updateLargestClearance( track->GetSolderMaskExpansion() );
for( BOARD_ITEM* item : m_board->Drawings() )
{
if( item->Type() == PCB_SHAPE_T )
updateLargestClearance( static_cast<PCB_SHAPE*>( item )->GetSolderMaskExpansion() );
}
// Order is important here: m_webWidth must be added in before m_largestCourtyardClearance is

4
pcbnew/pcb_shape.cpp

@ -186,10 +186,10 @@ int PCB_SHAPE::GetSolderMaskExpansion() const
{
int margin = 0;
if( const BOARD* board = GetBoard() )
if( GetBoard() && GetBoard()->GetDesignSettings().m_DRCEngine )
{
DRC_CONSTRAINT constraint;
std::shared_ptr<DRC_ENGINE> drcEngine = board->GetDesignSettings().m_DRCEngine;
std::shared_ptr<DRC_ENGINE> drcEngine = GetBoard()->GetDesignSettings().m_DRCEngine;
constraint = drcEngine->EvalRules( SOLDER_MASK_EXPANSION_CONSTRAINT, this, nullptr, m_layer );

4
pcbnew/pcb_track.cpp

@ -1130,10 +1130,10 @@ int PCB_TRACK::GetSolderMaskExpansion() const
{
int margin = 0;
if( const BOARD* board = GetBoard() )
if( GetBoard() && GetBoard()->GetDesignSettings().m_DRCEngine )
{
DRC_CONSTRAINT constraint;
std::shared_ptr<DRC_ENGINE> drcEngine = board->GetDesignSettings().m_DRCEngine;
std::shared_ptr<DRC_ENGINE> drcEngine = GetBoard()->GetDesignSettings().m_DRCEngine;
constraint = drcEngine->EvalRules( SOLDER_MASK_EXPANSION_CONSTRAINT, this, nullptr, m_layer );

Loading…
Cancel
Save