Centralize NPTH has-annulus processing.
Fixes https://gitlab.com/kicad/code/kicad/issues/13437
This commit is contained in:
parent
ffa86db9a9
commit
3b63d70d01
|
@ -342,8 +342,7 @@ private:
|
|||
OBJECT_2D* createPadWithDrill( const PAD* aPad, int aInflateValue );
|
||||
|
||||
void addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
|
||||
PCB_LAYER_ID aLayerId, bool aSkipNPTHPadsWihNoCopper, bool aSkipPlatedPads,
|
||||
bool aSkipNonPlatedPads );
|
||||
PCB_LAYER_ID aLayerId, bool aSkipPlatedPads, bool aSkipNonPlatedPads );
|
||||
|
||||
void addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
|
||||
PCB_LAYER_ID aLayerId );
|
||||
|
|
|
@ -490,41 +490,24 @@ OBJECT_2D* BOARD_ADAPTER::createPadWithDrill( const PAD* aPad, int aInflateValue
|
|||
|
||||
|
||||
void BOARD_ADAPTER::addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aContainer,
|
||||
PCB_LAYER_ID aLayerId, bool aSkipNPTHPadsWihNoCopper,
|
||||
bool aSkipPlatedPads, bool aSkipNonPlatedPads )
|
||||
PCB_LAYER_ID aLayerId, bool aSkipPlatedPads, bool aSkipNonPlatedPads )
|
||||
{
|
||||
for( PAD* pad : aFootprint->Pads() )
|
||||
{
|
||||
if( !pad->IsOnLayer( aLayerId ) )
|
||||
continue;
|
||||
|
||||
// Skip pad annulus when not connected on this layer (if removing is enabled)
|
||||
if( !pad->FlashLayer( aLayerId ) && IsCopperLayer( aLayerId ) )
|
||||
continue;
|
||||
|
||||
// NPTH pads are not drawn on layers if the shape size and pos is the same as their hole:
|
||||
if( aSkipNPTHPadsWihNoCopper && ( pad->GetAttribute() == PAD_ATTRIB::NPTH ) )
|
||||
if( IsCopperLayer( aLayerId ) )
|
||||
{
|
||||
if( pad->GetDrillSize() == pad->GetSize() && pad->GetOffset() == VECTOR2I( 0, 0 ) )
|
||||
{
|
||||
switch( pad->GetShape() )
|
||||
{
|
||||
case PAD_SHAPE::CIRCLE:
|
||||
if( pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
|
||||
continue;
|
||||
// Skip pad annulus when there isn't one (note: this is more discerning than
|
||||
// pad->IsOnLayer(), which doesn't check for NPTH pads with holes that consume
|
||||
// the entire pad).
|
||||
if( !pad->IsOnCopperLayer() )
|
||||
continue;
|
||||
|
||||
break;
|
||||
|
||||
case PAD_SHAPE::OVAL:
|
||||
if( pad->GetDrillShape() != PAD_DRILL_SHAPE_CIRCLE )
|
||||
continue;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Skip pad annulus when not connected on this layer (if removing is enabled)
|
||||
if( !pad->FlashLayer( aLayerId ) )
|
||||
continue;
|
||||
}
|
||||
|
||||
VECTOR2I margin( 0, 0 );
|
||||
|
|
|
@ -525,9 +525,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
|||
// ADD PADS
|
||||
for( FOOTPRINT* footprint : m_board->Footprints() )
|
||||
{
|
||||
// Note: NPTH pads are not drawn on copper layers when the pad has the same shape
|
||||
// as its hole
|
||||
addPads( footprint, layerContainer, layer, true, renderPlatedPadsAsPlated, false );
|
||||
addPads( footprint, layerContainer, layer, renderPlatedPadsAsPlated, false );
|
||||
|
||||
// Micro-wave footprints may have items on copper layers
|
||||
addFootprintShapes( footprint, layerContainer, layer );
|
||||
|
@ -539,8 +537,8 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
|||
// ADD PLATED PADS
|
||||
for( FOOTPRINT* footprint : m_board->Footprints() )
|
||||
{
|
||||
addPads( footprint, m_platedPadsFront, F_Cu, true, false, true );
|
||||
addPads( footprint, m_platedPadsBack, B_Cu, true, false, true );
|
||||
addPads( footprint, m_platedPadsFront, F_Cu, false, true );
|
||||
addPads( footprint, m_platedPadsBack, B_Cu, false, true );
|
||||
}
|
||||
|
||||
m_platedPadsFront->BuildBVH();
|
||||
|
@ -995,7 +993,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
|||
}
|
||||
else
|
||||
{
|
||||
addPads( footprint, layerContainer, layer, false, false, false );
|
||||
addPads( footprint, layerContainer, layer, false, false );
|
||||
}
|
||||
|
||||
addFootprintShapes( footprint, layerContainer, layer );
|
||||
|
|
|
@ -766,6 +766,38 @@ VECTOR2I PAD::ShapePos() const
|
|||
}
|
||||
|
||||
|
||||
bool PAD::IsOnCopperLayer() const
|
||||
{
|
||||
if( GetAttribute() == PAD_ATTRIB::NPTH )
|
||||
{
|
||||
// NPTH pads have no plated hole cylinder. If their annular ring size is 0 or
|
||||
// negative, then they have no annular ring either.
|
||||
|
||||
switch( GetShape() )
|
||||
{
|
||||
case PAD_SHAPE::CIRCLE:
|
||||
if( m_offset == VECTOR2I( 0, 0 ) && m_size.x <= m_drill.x )
|
||||
return false;
|
||||
|
||||
break;
|
||||
|
||||
case PAD_SHAPE::OVAL:
|
||||
if( m_offset == VECTOR2I( 0, 0 ) && m_size.x <= m_drill.x && m_size.y <= m_drill.y )
|
||||
return false;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
// We could subtract the hole polygon from the shape polygon for these, but it
|
||||
// would be expensive and we're probably well out of the common use cases....
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ( GetLayerSet() & LSET::AllCuMask() ).any();
|
||||
}
|
||||
|
||||
|
||||
int PAD::GetLocalClearanceOverrides( wxString* aSource ) const
|
||||
{
|
||||
// A pad can have specific clearance that overrides its NETCLASS clearance value
|
||||
|
@ -817,13 +849,9 @@ int PAD::GetOwnClearance( PCB_LAYER_ID aLayer, wxString* aSource ) const
|
|||
|
||||
int PAD::GetSolderMaskExpansion() const
|
||||
{
|
||||
// The pad inherits the margin only to calculate a default shape,
|
||||
// therefore only if it is also a copper layer
|
||||
// Pads defined only on mask layers (and perhaps on other tech layers) use the shape
|
||||
// defined by the pad settings only
|
||||
bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
|
||||
|
||||
if( !isOnCopperLayer )
|
||||
if( !IsOnCopperLayer() )
|
||||
return 0;
|
||||
|
||||
int margin = m_localSolderMaskMargin;
|
||||
|
@ -862,13 +890,9 @@ int PAD::GetSolderMaskExpansion() const
|
|||
|
||||
VECTOR2I PAD::GetSolderPasteMargin() const
|
||||
{
|
||||
// The pad inherits the margin only to calculate a default shape,
|
||||
// therefore only if it is also a copper layer.
|
||||
// Pads defined only on mask layers (and perhaps on other tech layers) use the shape
|
||||
// defined by the pad settings only
|
||||
bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
|
||||
|
||||
if( !isOnCopperLayer )
|
||||
if( !IsOnCopperLayer() )
|
||||
return VECTOR2I( 0, 0 );
|
||||
|
||||
int margin = m_localSolderPasteMargin;
|
||||
|
|
|
@ -239,10 +239,7 @@ public:
|
|||
/**
|
||||
* @return true if the pad is on any copper layer, false otherwise.
|
||||
*/
|
||||
bool IsOnCopperLayer() const override
|
||||
{
|
||||
return ( GetLayerSet() & LSET::AllCuMask() ) != 0;
|
||||
}
|
||||
bool IsOnCopperLayer() const override;
|
||||
|
||||
void SetY( int y ) { m_pos.y = y; SetDirty(); }
|
||||
void SetX( int x ) { m_pos.x = x; SetDirty(); }
|
||||
|
|
|
@ -310,6 +310,9 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
|||
}
|
||||
}
|
||||
|
||||
if( onCopperLayer && !pad->IsOnCopperLayer() )
|
||||
continue;
|
||||
|
||||
/// pads not connected to copper are optionally not drawn
|
||||
if( onCopperLayer && !pad->FlashLayer( aLayerMask ) )
|
||||
continue;
|
||||
|
|
|
@ -726,9 +726,7 @@ void BRDITEMS_PLOTTER::PlotFilledAreas( const ZONE* aZone, PCB_LAYER_ID aLayer,
|
|||
|
||||
GBR_METADATA gbr_metadata;
|
||||
|
||||
bool isOnCopperLayer = aZone->IsOnCopperLayer();
|
||||
|
||||
if( isOnCopperLayer )
|
||||
if( aZone->IsOnCopperLayer() )
|
||||
{
|
||||
gbr_metadata.SetNetName( aZone->GetNetname() );
|
||||
gbr_metadata.SetCopper( true );
|
||||
|
|
|
@ -254,31 +254,9 @@ bool PNS_PCBNEW_RULE_RESOLVER::IsNetTieExclusion( const PNS::ITEM* aItem,
|
|||
|
||||
bool isCopper( const PNS::ITEM* aItem )
|
||||
{
|
||||
BOARD_ITEM* parent = aItem->Parent();
|
||||
const BOARD_ITEM *parent = aItem->Parent();
|
||||
|
||||
if( parent && parent->Type() == PCB_PAD_T )
|
||||
{
|
||||
PAD* pad = static_cast<PAD*>( parent );
|
||||
|
||||
if( !pad->IsOnCopperLayer() )
|
||||
return false;
|
||||
|
||||
if( pad->GetAttribute() != PAD_ATTRIB::NPTH )
|
||||
return true;
|
||||
|
||||
// round NPTH with a hole size >= pad size are not on a copper layer
|
||||
// All other NPTH are seen on copper layers
|
||||
// This is a basic criteria, but probably enough for a NPTH
|
||||
if( pad->GetShape() == PAD_SHAPE::CIRCLE )
|
||||
{
|
||||
if( pad->GetSize().x <= pad->GetDrillSize().x )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
return !parent || parent->IsOnCopperLayer();
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue