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 );
|
OBJECT_2D* createPadWithDrill( const PAD* aPad, int aInflateValue );
|
||||||
|
|
||||||
void addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
|
void addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
|
||||||
PCB_LAYER_ID aLayerId, bool aSkipNPTHPadsWihNoCopper, bool aSkipPlatedPads,
|
PCB_LAYER_ID aLayerId, bool aSkipPlatedPads, bool aSkipNonPlatedPads );
|
||||||
bool aSkipNonPlatedPads );
|
|
||||||
|
|
||||||
void addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
|
void addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
|
||||||
PCB_LAYER_ID aLayerId );
|
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,
|
void BOARD_ADAPTER::addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aContainer,
|
||||||
PCB_LAYER_ID aLayerId, bool aSkipNPTHPadsWihNoCopper,
|
PCB_LAYER_ID aLayerId, bool aSkipPlatedPads, bool aSkipNonPlatedPads )
|
||||||
bool aSkipPlatedPads, bool aSkipNonPlatedPads )
|
|
||||||
{
|
{
|
||||||
for( PAD* pad : aFootprint->Pads() )
|
for( PAD* pad : aFootprint->Pads() )
|
||||||
{
|
{
|
||||||
if( !pad->IsOnLayer( aLayerId ) )
|
if( !pad->IsOnLayer( aLayerId ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Skip pad annulus when not connected on this layer (if removing is enabled)
|
if( IsCopperLayer( aLayerId ) )
|
||||||
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( pad->GetDrillSize() == pad->GetSize() && pad->GetOffset() == VECTOR2I( 0, 0 ) )
|
// 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
|
||||||
switch( pad->GetShape() )
|
// the entire pad).
|
||||||
{
|
if( !pad->IsOnCopperLayer() )
|
||||||
case PAD_SHAPE::CIRCLE:
|
continue;
|
||||||
if( pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
break;
|
// Skip pad annulus when not connected on this layer (if removing is enabled)
|
||||||
|
if( !pad->FlashLayer( aLayerId ) )
|
||||||
case PAD_SHAPE::OVAL:
|
continue;
|
||||||
if( pad->GetDrillShape() != PAD_DRILL_SHAPE_CIRCLE )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VECTOR2I margin( 0, 0 );
|
VECTOR2I margin( 0, 0 );
|
||||||
|
|
|
@ -525,9 +525,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||||
// ADD PADS
|
// ADD PADS
|
||||||
for( FOOTPRINT* footprint : m_board->Footprints() )
|
for( FOOTPRINT* footprint : m_board->Footprints() )
|
||||||
{
|
{
|
||||||
// Note: NPTH pads are not drawn on copper layers when the pad has the same shape
|
addPads( footprint, layerContainer, layer, renderPlatedPadsAsPlated, false );
|
||||||
// as its hole
|
|
||||||
addPads( footprint, layerContainer, layer, true, renderPlatedPadsAsPlated, false );
|
|
||||||
|
|
||||||
// Micro-wave footprints may have items on copper layers
|
// Micro-wave footprints may have items on copper layers
|
||||||
addFootprintShapes( footprint, layerContainer, layer );
|
addFootprintShapes( footprint, layerContainer, layer );
|
||||||
|
@ -539,8 +537,8 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||||
// ADD PLATED PADS
|
// ADD PLATED PADS
|
||||||
for( FOOTPRINT* footprint : m_board->Footprints() )
|
for( FOOTPRINT* footprint : m_board->Footprints() )
|
||||||
{
|
{
|
||||||
addPads( footprint, m_platedPadsFront, F_Cu, true, false, true );
|
addPads( footprint, m_platedPadsFront, F_Cu, false, true );
|
||||||
addPads( footprint, m_platedPadsBack, B_Cu, true, false, true );
|
addPads( footprint, m_platedPadsBack, B_Cu, false, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_platedPadsFront->BuildBVH();
|
m_platedPadsFront->BuildBVH();
|
||||||
|
@ -995,7 +993,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
addPads( footprint, layerContainer, layer, false, false, false );
|
addPads( footprint, layerContainer, layer, false, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
addFootprintShapes( footprint, layerContainer, layer );
|
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
|
int PAD::GetLocalClearanceOverrides( wxString* aSource ) const
|
||||||
{
|
{
|
||||||
// A pad can have specific clearance that overrides its NETCLASS clearance value
|
// 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
|
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
|
// Pads defined only on mask layers (and perhaps on other tech layers) use the shape
|
||||||
// defined by the pad settings only
|
// defined by the pad settings only
|
||||||
bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
|
if( !IsOnCopperLayer() )
|
||||||
|
|
||||||
if( !isOnCopperLayer )
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int margin = m_localSolderMaskMargin;
|
int margin = m_localSolderMaskMargin;
|
||||||
|
@ -862,13 +890,9 @@ int PAD::GetSolderMaskExpansion() const
|
||||||
|
|
||||||
VECTOR2I PAD::GetSolderPasteMargin() 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
|
// Pads defined only on mask layers (and perhaps on other tech layers) use the shape
|
||||||
// defined by the pad settings only
|
// defined by the pad settings only
|
||||||
bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
|
if( !IsOnCopperLayer() )
|
||||||
|
|
||||||
if( !isOnCopperLayer )
|
|
||||||
return VECTOR2I( 0, 0 );
|
return VECTOR2I( 0, 0 );
|
||||||
|
|
||||||
int margin = m_localSolderPasteMargin;
|
int margin = m_localSolderPasteMargin;
|
||||||
|
|
|
@ -239,10 +239,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* @return true if the pad is on any copper layer, false otherwise.
|
* @return true if the pad is on any copper layer, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool IsOnCopperLayer() const override
|
bool IsOnCopperLayer() const override;
|
||||||
{
|
|
||||||
return ( GetLayerSet() & LSET::AllCuMask() ) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetY( int y ) { m_pos.y = y; SetDirty(); }
|
void SetY( int y ) { m_pos.y = y; SetDirty(); }
|
||||||
void SetX( int x ) { m_pos.x = x; 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
|
/// pads not connected to copper are optionally not drawn
|
||||||
if( onCopperLayer && !pad->FlashLayer( aLayerMask ) )
|
if( onCopperLayer && !pad->FlashLayer( aLayerMask ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -726,9 +726,7 @@ void BRDITEMS_PLOTTER::PlotFilledAreas( const ZONE* aZone, PCB_LAYER_ID aLayer,
|
||||||
|
|
||||||
GBR_METADATA gbr_metadata;
|
GBR_METADATA gbr_metadata;
|
||||||
|
|
||||||
bool isOnCopperLayer = aZone->IsOnCopperLayer();
|
if( aZone->IsOnCopperLayer() )
|
||||||
|
|
||||||
if( isOnCopperLayer )
|
|
||||||
{
|
{
|
||||||
gbr_metadata.SetNetName( aZone->GetNetname() );
|
gbr_metadata.SetNetName( aZone->GetNetname() );
|
||||||
gbr_metadata.SetCopper( true );
|
gbr_metadata.SetCopper( true );
|
||||||
|
|
|
@ -254,31 +254,9 @@ bool PNS_PCBNEW_RULE_RESOLVER::IsNetTieExclusion( const PNS::ITEM* aItem,
|
||||||
|
|
||||||
bool isCopper( 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 )
|
return !parent || parent->IsOnCopperLayer();
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue