7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-21 18:33:45 +00:00

CHANGED: remove single layer restriction for uvias.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/18501
This commit is contained in:
Jeff Young 2024-08-15 16:41:54 -06:00
parent 3f2b6f7ae0
commit cbfd6ec9ea
5 changed files with 41 additions and 133 deletions

View File

@ -1095,8 +1095,7 @@ void PCB_BASE_FRAME::SetDisplayOptions( const PCB_DISPLAY_OPTIONS& aOptions, boo
{
if( PCB_VIA* via = dynamic_cast<PCB_VIA*>( aItem ) )
{
if( via->GetViaType() == VIATYPE::BLIND_BURIED
|| via->GetViaType() == VIATYPE::MICROVIA
if( via->GetViaType() != VIATYPE::THROUGH
|| via->GetRemoveUnconnected()
|| showNetNames )
{

View File

@ -413,17 +413,16 @@ COLOR4D PCB_RENDER_SETTINGS::GetColor( const BOARD_ITEM* aItem, int aLayer ) con
{
const PCB_VIA* via = static_cast<const PCB_VIA*>( aItem );
if( via->GetViaType() == VIATYPE::BLIND_BURIED
|| via->GetViaType() == VIATYPE::MICROVIA )
if( via->GetViaType() == VIATYPE::THROUGH )
{
// A blind or micro via's hole is active if it crosses the primary layer
if( via->GetLayerSet().test( primary ) == 0 )
// A through via's hole is active if any physical layer is active
if( LSET::PhysicalLayersMask().test( primary ) == 0 )
isActive = false;
}
else
{
// A through via's hole is active if any physical layer is active
if( LSET::PhysicalLayersMask().test( primary ) == 0 )
// A blind/buried or micro via's hole is active if it crosses the primary layer
if( via->GetLayerSet().test( primary ) == 0 )
isActive = false;
}

View File

@ -1260,16 +1260,16 @@ double PCB_VIA::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
if( IsHoleLayer( aLayer ) )
{
if( m_viaType == VIATYPE::BLIND_BURIED || m_viaType == VIATYPE::MICROVIA )
if( m_viaType == VIATYPE::THROUGH )
{
// Show a blind or micro via's hole if it crosses a visible layer
if( !( visible & GetLayerSet() ).any() )
// Show a through via's hole if any physical layer is shown
if( !( visible & LSET::PhysicalLayersMask() ).any() )
return HIDE;
}
else
{
// Show a through via's hole if any physical layer is shown
if( !( visible & LSET::PhysicalLayersMask() ).any() )
// Show a blind or micro via's hole if it crosses a visible layer
if( !( visible & GetLayerSet() ).any() )
return HIDE;
}

View File

@ -1022,24 +1022,6 @@ int ROUTER_TOOL::handleLayerSwitch( const TOOL_EVENT& aEvent, bool aForceVia )
if( viaType != VIATYPE::THROUGH )
not_allowed_ly.set( currentLayer );
if( viaType == VIATYPE::MICROVIA )
{
// Allows only the previous or the next layer from the current layer
int previous_layer = currentLayer == B_Cu ? layerCount - 2
: currentLayer - 1;
int next_layer = currentLayer >= layerCount-2 ? B_Cu
: currentLayer + 1;
not_allowed_ly = LSET::AllLayersMask();
if( previous_layer >= F_Cu && previous_layer != currentLayer )
not_allowed_ly.reset( previous_layer );
if( next_layer != currentLayer )
not_allowed_ly.reset( next_layer );
}
targetLayer = frame()->SelectOneLayer( static_cast<PCB_LAYER_ID>( currentLayer ),
not_allowed_ly, endPoint );
@ -1071,56 +1053,15 @@ int ROUTER_TOOL::handleLayerSwitch( const TOOL_EVENT& aEvent, bool aForceVia )
if( targetLayer == UNDEFINED_LAYER )
{
// Implicic layer selection
switch( viaType )
// Implicit layer selection
if( viaType == VIATYPE::THROUGH )
{
case VIATYPE::THROUGH:
// use the default layer pair
currentLayer = pairTop;
targetLayer = pairBottom;
break;
case VIATYPE::MICROVIA:
// Try to use the layer pair preset, if the layers are adjacent,
// because a microvia is usually restricted to 2 adjacent copper layers
if( pairTop > pairBottom ) std::swap( pairTop, pairBottom );
if( currentLayer == pairTop && pairBottom == pairTop+1 )
{
targetLayer = pairBottom;
}
else if( currentLayer == pairBottom && pairBottom == pairTop+1 )
{
targetLayer = pairTop;
}
else if( currentLayer == F_Cu || currentLayer == In1_Cu )
{
// front-side microvia
currentLayer = F_Cu;
if( layerCount > 2 ) // Ensure the inner layer In1_Cu exists
targetLayer = In1_Cu;
else
targetLayer = B_Cu;
}
else if( currentLayer == B_Cu || currentLayer == layerCount - 2 )
{
// back-side microvia
currentLayer = B_Cu,
targetLayer = (PCB_LAYER_ID) ( layerCount - 2 );
}
else
{
// This is not optimal: from an internal layer one can want to switch
// to the previous or the next internal layer
// but at this point we do not know what the user want.
targetLayer = PCB_LAYER_ID( currentLayer + 1 );
}
break;
case VIATYPE::BLIND_BURIED:
}
else
{
if( currentLayer == pairTop || currentLayer == pairBottom )
{
// the current layer is on the defined layer pair,
@ -1139,18 +1080,11 @@ int ROUTER_TOOL::handleLayerSwitch( const TOOL_EVENT& aEvent, bool aForceVia )
if( currentLayer == targetLayer )
{
WX_INFOBAR* infobar = frame()->GetInfoBar();
infobar->ShowMessageFor( _( "Blind/buried via need 2 different layers." ),
infobar->ShowMessageFor( _( "Via needs 2 different layers." ),
2000, wxICON_ERROR,
WX_INFOBAR::MESSAGE_TYPE::DRC_VIOLATION );
return 0;
}
break;
default:
wxFAIL_MSG( wxT( "unexpected via type" ) );
return 0;
break;
}
}

View File

@ -3628,57 +3628,33 @@ int DRAWING_TOOL::DrawVia( const TOOL_EVENT& aEvent )
via->SetNetCode( 0 );
via->SetViaType( bds.m_CurrentViaType );
// for microvias, the size and hole will be changed later.
via->SetWidth( bds.GetCurrentViaSize() );
via->SetDrill( bds.GetCurrentViaDrill() );
// Usual via is from copper to component.
// layer pair is B_Cu and F_Cu.
via->SetLayerPair( B_Cu, F_Cu );
PCB_LAYER_ID first_layer = m_frame->GetActiveLayer();
PCB_LAYER_ID last_layer;
// prepare switch to new active layer:
if( first_layer != m_frame->GetScreen()->m_Route_Layer_TOP )
last_layer = m_frame->GetScreen()->m_Route_Layer_TOP;
else
last_layer = m_frame->GetScreen()->m_Route_Layer_BOTTOM;
// Adjust the actual via layer pair
switch( via->GetViaType() )
if( via->GetViaType() == VIATYPE::THROUGH )
{
case VIATYPE::BLIND_BURIED:
via->SetLayerPair( first_layer, last_layer );
break;
case VIATYPE::MICROVIA: // from external to the near neighbor inner layer
{
PCB_LAYER_ID last_inner_layer =
ToLAYER_ID( ( m_board->GetCopperLayerCount() - 2 ) );
if( first_layer == B_Cu )
last_layer = last_inner_layer;
else if( first_layer == F_Cu )
last_layer = In1_Cu;
else if( first_layer == last_inner_layer )
last_layer = B_Cu;
else if( first_layer == In1_Cu )
last_layer = F_Cu;
// else error: will be removed later
via->SetLayerPair( first_layer, last_layer );
// Update diameter and hole size, which where set previously for normal vias
NETCLASS* netClass = via->GetEffectiveNetClass();
via->SetWidth( netClass->GetuViaDiameter() );
via->SetDrill( netClass->GetuViaDrill() );
via->SetLayerPair( B_Cu, F_Cu );
}
break;
else
{
PCB_LAYER_ID first_layer = m_frame->GetActiveLayer();
PCB_LAYER_ID last_layer;
default:
break;
// prepare switch to new active layer:
if( first_layer != m_frame->GetScreen()->m_Route_Layer_TOP )
last_layer = m_frame->GetScreen()->m_Route_Layer_TOP;
else
last_layer = m_frame->GetScreen()->m_Route_Layer_BOTTOM;
via->SetLayerPair( first_layer, last_layer );
}
if( via->GetViaType() == VIATYPE::MICROVIA )
{
via->SetWidth( via->GetEffectiveNetClass()->GetuViaDiameter() );
via->SetDrill( via->GetEffectiveNetClass()->GetuViaDrill() );
}
else
{
via->SetWidth( bds.GetCurrentViaSize() );
via->SetDrill( bds.GetCurrentViaDrill() );
}
return std::unique_ptr<BOARD_ITEM>( via );