int ROUTER_TOOL::onViaCommand( const TOOL_EVENT& aEvent ) { const int actViaFlags = aEvent.Parameter<intptr_t>(); VIATYPE_T viaType = getViaTypeFromFlags( actViaFlags ); const bool selectLayer = actViaFlags & VIA_ACTION_FLAGS::SELECT_LAYER; BOARD_DESIGN_SETTINGS& bds = board()->GetDesignSettings(); const int layerCount = bds.GetCopperLayerCount(); int currentLayer = m_router->GetCurrentLayer(); PCB_LAYER_ID pairTop = frame()->GetScreen()->m_Route_Layer_TOP; PCB_LAYER_ID pairBottom = frame()->GetScreen()->m_Route_Layer_BOTTOM; PNS::SIZES_SETTINGS sizes = m_router->Sizes(); // ask the user for a target layer PCB_LAYER_ID targetLayer = UNDEFINED_LAYER; if( selectLayer ) { wxPoint dlgPosition = wxGetMousePosition(); targetLayer = frame()->SelectLayer( static_cast<PCB_LAYER_ID>( currentLayer ), LSET::AllNonCuMask(), dlgPosition ); } // fixme: P&S supports more than one fixed layer pair. Update the dialog? sizes.ClearLayerPairs(); if( !m_router->IsPlacingVia() ) { // Cannot place microvias or blind vias if not allowed (obvious) if( ( viaType == VIA_BLIND_BURIED ) && ( !bds.m_BlindBuriedViaAllowed ) ) { DisplayError( frame(), _( "Blind/buried vias have to be enabled in the design settings." ) ); return false; } if( ( viaType == VIA_MICROVIA ) && ( !bds.m_MicroViasAllowed ) ) { DisplayError( frame(), _( "Microvias have to be enabled in the design settings." ) ); return false; } // Can only place through vias on 2-layer boards if( ( viaType != VIA_THROUGH ) && ( layerCount <= 2 ) ) { DisplayError( frame(), _( "Only through vias are allowed on 2 layer boards." ) ); return false; } // Can only place microvias if we're on an outer layer, or directly adjacent to one if( ( viaType == VIA_MICROVIA ) && ( currentLayer > In1_Cu ) && ( currentLayer < layerCount - 2 ) ) { DisplayError( frame(), _( "Microvias can be placed only between the outer layers " \ "(F.Cu/B.Cu) and the ones directly adjacent to them." ) ); return false; } } // Convert blind/buried via to a through hole one, if it goes through all layers if( viaType == VIA_BLIND_BURIED && ( ( currentLayer == B_Cu ) || ( currentLayer == F_Cu ) ) && ( ( pairTop == B_Cu && pairBottom == F_Cu ) || ( pairTop == F_Cu && pairBottom == B_Cu ) ) ) { viaType = VIA_THROUGH; } switch( viaType ) { case VIA_THROUGH: sizes.SetViaDiameter( bds.GetCurrentViaSize() ); sizes.SetViaDrill( bds.GetCurrentViaDrill() ); if( targetLayer != UNDEFINED_LAYER ) { // go from the current layer to the chosen layer sizes.AddLayerPair( currentLayer, targetLayer ); } else { // use the default layer pair sizes.AddLayerPair( pairTop, pairBottom ); } break; case VIA_MICROVIA: sizes.SetViaDiameter( bds.GetCurrentMicroViaSize() ); sizes.SetViaDrill( bds.GetCurrentMicroViaDrill() ); wxASSERT_MSG( !selectLayer, "Unexpected select layer for microvia (microvia layers are implicit)" ); if( currentLayer == F_Cu || currentLayer == In1_Cu ) { // front-side microvia sizes.AddLayerPair( F_Cu, In1_Cu ); } else if( currentLayer == B_Cu || currentLayer == layerCount - 2 ) { // back-side microvia sizes.AddLayerPair( B_Cu, layerCount - 2 ); } else { wxASSERT_MSG( false, "Invalid layer pair for microvia (must be on or adjacent to an outer layer)" ); } break; case VIA_BLIND_BURIED: sizes.SetViaDiameter( bds.GetCurrentViaSize() ); sizes.SetViaDrill( bds.GetCurrentViaDrill() ); if( targetLayer != UNDEFINED_LAYER ) { // go directly to the user specified layer sizes.AddLayerPair( currentLayer, targetLayer ); } else { if( currentLayer == pairTop || currentLayer == pairBottom ) { // the current layer is on the defined layer pair, // swap to the other side sizes.AddLayerPair( pairTop, pairBottom ); } else { // the current layer is not part of the current layer pair, // so fallback and swap to the top layer of the pair by default sizes.AddLayerPair( pairTop, currentLayer ); } } break; default: wxASSERT( false ); break; } sizes.SetViaType( viaType ); m_router->UpdateSizes( sizes ); m_router->ToggleViaPlacement(); if( m_router->RoutingInProgress() ) updateEndItem( aEvent ); else updateStartItem( aEvent ); m_router->Move( m_endSnapPoint, m_endItem ); // refresh return 0; }
bool ROUTER_TOOL::onViaCommand( TOOL_EVENT& aEvent, VIATYPE_T aType ) { BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); const int layerCount = bds.GetCopperLayerCount(); int currentLayer = m_router->GetCurrentLayer(); LAYER_ID pairTop = m_frame->GetScreen()->m_Route_Layer_TOP; LAYER_ID pairBottom = m_frame->GetScreen()->m_Route_Layer_BOTTOM; PNS::SIZES_SETTINGS sizes = m_router->Sizes(); // fixme: P&S supports more than one fixed layer pair. Update the dialog? sizes.ClearLayerPairs(); if( !m_router->IsPlacingVia() ) { // Cannot place microvias or blind vias if not allowed (obvious) if( ( aType == VIA_BLIND_BURIED ) && ( !bds.m_BlindBuriedViaAllowed ) ) { DisplayError( m_frame, _( "Blind/buried vias have to be enabled in the design settings." ) ); return false; } if( ( aType == VIA_MICROVIA ) && ( !bds.m_MicroViasAllowed ) ) { DisplayError( m_frame, _( "Microvias have to be enabled in the design settings." ) ); return false; } // Can only place through vias on 2-layer boards if( ( aType != VIA_THROUGH ) && ( layerCount <= 2 ) ) { DisplayError( m_frame, _( "Only through vias are allowed on 2 layer boards." ) ); return false; } // Can only place microvias if we're on an outer layer, or directly adjacent to one if( ( aType == VIA_MICROVIA ) && ( currentLayer > In1_Cu ) && ( currentLayer < layerCount - 2 ) ) { DisplayError( m_frame, _( "Microvias can be placed only between the outer layers " \ "(F.Cu/B.Cu) and the ones directly adjacent to them." ) ); return false; } } // Convert blind/buried via to a through hole one, if it goes through all layers if( aType == VIA_BLIND_BURIED && ( ( currentLayer == B_Cu ) || ( currentLayer == F_Cu ) ) && ( ( pairTop == B_Cu && pairBottom == F_Cu ) || ( pairTop == F_Cu && pairBottom == B_Cu ) ) ) { aType = VIA_THROUGH; } switch( aType ) { case VIA_THROUGH: sizes.SetViaDiameter( bds.GetCurrentViaSize() ); sizes.SetViaDrill( bds.GetCurrentViaDrill() ); sizes.AddLayerPair( pairTop, pairBottom ); break; case VIA_MICROVIA: sizes.SetViaDiameter( bds.GetCurrentMicroViaSize() ); sizes.SetViaDrill( bds.GetCurrentMicroViaDrill() ); if( currentLayer == F_Cu || currentLayer == In1_Cu ) sizes.AddLayerPair( F_Cu, In1_Cu ); else if( currentLayer == B_Cu || currentLayer == layerCount - 2 ) sizes.AddLayerPair( B_Cu, layerCount - 2 ); else wxASSERT( false ); break; case VIA_BLIND_BURIED: sizes.SetViaDiameter( bds.GetCurrentViaSize() ); sizes.SetViaDrill( bds.GetCurrentViaDrill() ); if( currentLayer == pairTop || currentLayer == pairBottom ) sizes.AddLayerPair( pairTop, pairBottom ); else sizes.AddLayerPair( pairTop, currentLayer ); break; default: wxASSERT( false ); break; } sizes.SetViaType( aType ); m_router->UpdateSizes( sizes ); m_router->ToggleViaPlacement(); updateEndItem( aEvent ); m_router->Move( m_endSnapPoint, m_endItem ); // refresh return false; }