From 45a8e4da74332d93fc206fc229929f10f5d09b0e Mon Sep 17 00:00:00 2001 From: Andrew Zonenberg Date: Tue, 30 Sep 2014 16:46:19 +0200 Subject: [PATCH] pns_router: Support for blind/buried vias. --- pcbnew/router/pns_line_placer.cpp | 23 ++++++++++++----------- pcbnew/router/pns_line_placer.h | 6 +++++- pcbnew/router/pns_router.cpp | 24 ++++++++++++++++++++++-- pcbnew/router/pns_router.h | 18 +++++++++--------- pcbnew/router/pns_routing_settings.h | 2 +- pcbnew/router/pns_via.h | 7 +++++++ pcbnew/router/router_tool.cpp | 24 +++++++++++++++++++++++- 7 files changed, 79 insertions(+), 25 deletions(-) diff --git a/pcbnew/router/pns_line_placer.cpp b/pcbnew/router/pns_line_placer.cpp index c967008b74..933be48750 100644 --- a/pcbnew/router/pns_line_placer.cpp +++ b/pcbnew/router/pns_line_placer.cpp @@ -60,11 +60,12 @@ void PNS_LINE_PLACER::setWorld ( PNS_NODE* aWorld ) } -void PNS_LINE_PLACER::AddVia( bool aEnabled, int aDiameter, int aDrill ) +void PNS_LINE_PLACER::AddVia( bool aEnabled, int aDiameter, int aDrill, VIATYPE_T aType ) { m_viaDiameter = aDiameter; m_viaDrill = aDrill; m_placingVia = aEnabled; + m_viaType = aType; } @@ -73,7 +74,7 @@ void PNS_LINE_PLACER::startPlacement( const VECTOR2I& aStart, int aNet, int aWid assert( m_world != NULL ); m_direction = m_initial_direction; - TRACE( 1, "world %p, intitial-direction %s layer %d\n", + TRACE( 1, "world %p, initial-direction %s layer %d\n", m_world % m_direction.Format().c_str() % aLayer ); m_head.SetNet( aNet ); m_tail.SetNet( aNet ); @@ -379,8 +380,8 @@ bool PNS_LINE_PLACER::handleViaPlacement( PNS_LINE& aHead ) if( !m_placingVia ) return true; - PNS_LAYERSET allLayers( 0, MAX_CU_LAYERS - 1 ); - PNS_VIA v( aHead.CPoint( -1 ), allLayers, m_viaDiameter, m_viaDrill, aHead.Net() ); + PNS_LAYERSET layers( Settings().GetLayerTop(), Settings().GetLayerBottom() ); + PNS_VIA v( aHead.CPoint( -1 ), layers, m_viaDiameter, m_viaDrill, aHead.Net(), m_viaType ); VECTOR2I force; VECTOR2I lead = aHead.CPoint( -1 ) - aHead.CPoint( 0 ); @@ -439,8 +440,8 @@ bool PNS_LINE_PLACER::rhWalkOnly( const VECTOR2I& aP, PNS_LINE& aNewHead ) } else if( m_placingVia && viaOk ) { - PNS_LAYERSET allLayers( 0, MAX_CU_LAYERS - 1 ); - PNS_VIA v1( walkFull.CPoint( -1 ), allLayers, m_viaDiameter, m_viaDrill ); + PNS_LAYERSET layers( Settings().GetLayerTop(), Settings().GetLayerBottom() ); + PNS_VIA v1( walkFull.CPoint( -1 ), layers, m_viaDiameter, m_viaDrill, -1, m_viaType ); walkFull.AppendVia( v1 ); } @@ -464,8 +465,8 @@ bool PNS_LINE_PLACER::rhMarkObstacles( const VECTOR2I& aP, PNS_LINE& aNewHead ) if( m_placingVia ) { - PNS_LAYERSET allLayers( 0, MAX_CU_LAYERS - 1 ); - PNS_VIA v1( m_head.CPoint( -1 ), allLayers, m_viaDiameter, m_viaDrill ); + PNS_LAYERSET layers( Settings().GetLayerTop(), Settings().GetLayerBottom() ); + PNS_VIA v1( m_head.CPoint( -1 ), layers, m_viaDiameter, m_viaDrill, -1, m_viaType ); m_head.AppendVia( v1 ); } @@ -507,9 +508,9 @@ bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead ) if( m_placingVia ) { - PNS_LAYERSET allLayers( 0, MAX_CU_LAYERS - 1 ); - PNS_VIA v1( l.CPoint( -1 ), allLayers, m_viaDiameter, m_viaDrill ); - PNS_VIA v2( l2.CPoint( -1 ), allLayers, m_viaDiameter, m_viaDrill ); + PNS_LAYERSET layers( Settings().GetLayerTop(), Settings().GetLayerBottom() ); + PNS_VIA v1( l.CPoint( -1 ), layers, m_viaDiameter, m_viaDrill, -1, m_viaType ); + PNS_VIA v2( l2.CPoint( -1 ), layers, m_viaDiameter, m_viaDrill, -1, m_viaType ); l.AppendVia( v1 ); l2.AppendVia( v2 ); diff --git a/pcbnew/router/pns_line_placer.h b/pcbnew/router/pns_line_placer.h index 4d126866ea..dfbb1bb619 100644 --- a/pcbnew/router/pns_line_placer.h +++ b/pcbnew/router/pns_line_placer.h @@ -84,8 +84,9 @@ public: * @param aEnabled if true, a via is attached during placement * @param aDiameter diameter of the via * @param aDrill drill of the via + * @param aType Type of the via */ - void AddVia( bool aEnabled, int aDiameter, int aDrill ); + void AddVia( bool aEnabled, int aDiameter, int aDrill, VIATYPE_T aType ); /** * Function SetLayer() @@ -385,6 +386,9 @@ private: ///> current via drill int m_viaDrill; + + ///> current via type + VIATYPE_T m_viaType; ///> current track width int m_currentWidth; diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index 8a2d9ee59e..4dbde1ebbf 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -895,12 +895,32 @@ void PNS_ROUTER::SwitchLayer( int aLayer ) } -void PNS_ROUTER::ToggleViaPlacement() +void PNS_ROUTER::ToggleViaPlacement(VIATYPE_T type) { + const int layercount = m_board->GetDesignSettings().GetCopperLayerCount(); + + // Cannot place microvias or blind vias if not allowed (obvious) + if( ( type == VIA_BLIND_BURIED ) && ( !m_board->GetDesignSettings().m_BlindBuriedViaAllowed ) ) + return; + if( ( type == VIA_MICROVIA ) && ( !m_board->GetDesignSettings().m_MicroViasAllowed ) ) + return; + + //Can only place through vias on 2-layer boards + if( ( type != VIA_THROUGH ) && ( layercount <= 2 ) ) + return; + + //Can only place microvias if we're on an outer layer, or directly adjacent to one + if( ( type == VIA_MICROVIA ) && ( m_currentLayer > In1_Cu ) && ( m_currentLayer < layercount-2 ) ) + return; + + //Cannot place blind vias with front/back as the layer pair, this doesn't make sense + if( ( type == VIA_BLIND_BURIED ) && ( Settings().GetLayerTop() == F_Cu ) && ( Settings().GetLayerBottom() == B_Cu ) ) + return; + if( m_state == ROUTE_TRACK ) { m_placingVia = !m_placingVia; - m_placer->AddVia( m_placingVia, m_settings.GetViaDiameter(), m_settings.GetViaDrill() ); + m_placer->AddVia( m_placingVia, m_settings.GetViaDiameter(), m_settings.GetViaDrill(), type ); } } diff --git a/pcbnew/router/pns_router.h b/pcbnew/router/pns_router.h index fc22c60d16..dd6c6b9694 100644 --- a/pcbnew/router/pns_router.h +++ b/pcbnew/router/pns_router.h @@ -105,20 +105,20 @@ public: void DisplayItem( const PNS_ITEM* aItem, int aColor = -1, int aClearance = -1 ); void DisplayItems( const PNS_ITEMSET& aItems ); - + void DisplayDebugLine( const SHAPE_LINE_CHAIN& aLine, int aType = 0, int aWidth = 0 ); void DisplayDebugPoint( const VECTOR2I aPos, int aType = 0 ); void DisplayDebugBox( const BOX2I& aBox, int aType = 0, int aWidth = 0 ); void SwitchLayer( int layer ); - void ToggleViaPlacement(); + void ToggleViaPlacement( VIATYPE_T type = VIA_NOT_DEFINED ); int GetCurrentLayer() const; int GetCurrentNet() const; void DumpLog(); - + PNS_CLEARANCE_FUNC* GetClearanceFunc() const { return m_clearanceFunc; @@ -151,9 +151,9 @@ public: int GetShapshotIter() const { return m_snapshotIter; } PNS_ROUTING_SETTINGS& Settings() { return m_settings; } - + void CommitRouting( PNS_NODE* aNode ); - + /** * Returns the last changes introduced by the router (since the last time ClearLastChanges() * was called or a new track has been started). @@ -201,10 +201,10 @@ public: private: void movePlacing( const VECTOR2I& aP, PNS_ITEM* aItem ); void moveDragging( const VECTOR2I& aP, PNS_ITEM* aItem ); - + void eraseView(); void updateView( PNS_NODE* aNode, PNS_ITEMSET& aCurrent ); - + void clearViewFlags(); // optHoverItem queryHoverItemEx(const VECTOR2I& aP); @@ -224,7 +224,7 @@ private: void highlightCurrent( bool enabled ); void markViolations( PNS_NODE* aNode, PNS_ITEMSET& aCurrent, PNS_NODE::ITEM_VECTOR& aRemoved ); - + int m_currentLayer; int m_currentNet; @@ -246,7 +246,7 @@ private: KIGFX::VIEW_GROUP* m_previewItems; PNS_ITEM* m_currentEndItem; - + VECTOR2I m_currentEnd; VECTOR2I m_currentStart; VECTOR2I m_originalStart; diff --git a/pcbnew/router/pns_routing_settings.h b/pcbnew/router/pns_routing_settings.h index 0cd615cecb..a1261f7155 100644 --- a/pcbnew/router/pns_routing_settings.h +++ b/pcbnew/router/pns_routing_settings.h @@ -129,7 +129,7 @@ public: void SetLayerPair( int aLayer1, int aLayer2 ) { - if( aLayer1 > aLayer2 ) + if( aLayer1 < aLayer2 ) { m_layerTop = aLayer1; m_layerBottom = aLayer2; diff --git a/pcbnew/router/pns_via.h b/pcbnew/router/pns_via.h index e94853431e..86dc2c0503 100644 --- a/pcbnew/router/pns_via.h +++ b/pcbnew/router/pns_via.h @@ -48,6 +48,13 @@ public: m_drill = aDrill; m_shape = SHAPE_CIRCLE( aPos, aDiameter / 2 ); m_viaType = aViaType; + + //If we're a through-board via, use all layers regardless of the set passed + if( aViaType == VIA_THROUGH ) + { + PNS_LAYERSET allLayers( 0, MAX_CU_LAYERS - 1 ); + SetLayers( allLayers); + } } diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 9f699de35b..bbf758be5a 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -65,6 +65,12 @@ static TOOL_ACTION ACT_Drag( "pcbnew.InteractiveRouter.Drag", static TOOL_ACTION ACT_PlaceThroughVia( "pcbnew.InteractiveRouter.PlaceVia", AS_CONTEXT, 'V', "Place Through Via", "Adds a through-hole via at the end of currently routed track." ); +static TOOL_ACTION ACT_PlaceBlindVia( "pcbnew.InteractiveRouter.PlaceBlindVia", + AS_CONTEXT, 'Z', + "Place Blind/Buried Via", "Adds a blind or buried via at the end of currently routed track." ); +static TOOL_ACTION ACT_PlaceMicroVia( "pcbnew.InteractiveRouter.PlaceMicroVia", + AS_CONTEXT, 'Q', + "Place Microvia", "Adds a microvia at the end of currently routed track." ); static TOOL_ACTION ACT_CustomTrackWidth( "pcbnew.InteractiveRouter.CustomTrackWidth", AS_CONTEXT, 'W', "Custom Track Width", "Shows a dialog for changing the track width and via size."); @@ -209,6 +215,8 @@ public: // Add( ACT_AutoEndRoute ); // fixme: not implemented yet. Sorry. Add( ACT_Drag ); Add( ACT_PlaceThroughVia ); + Add( ACT_PlaceBlindVia ); + Add( ACT_PlaceMicroVia ); Add( ACT_SwitchPosture ); AppendSeparator(); @@ -580,7 +588,21 @@ void ROUTER_TOOL::performRouting() { m_router->Settings().SetLayerPair( frame->GetScreen()->m_Route_Layer_TOP, frame->GetScreen()->m_Route_Layer_BOTTOM ); - m_router->ToggleViaPlacement(); + m_router->ToggleViaPlacement( VIA_THROUGH ); + m_router->Move( m_endSnapPoint, m_endItem ); // refresh + } + else if( evt->IsAction( &ACT_PlaceBlindVia ) ) + { + m_router->Settings().SetLayerPair( frame->GetScreen()->m_Route_Layer_TOP, + frame->GetScreen()->m_Route_Layer_BOTTOM ); + m_router->ToggleViaPlacement( VIA_BLIND_BURIED ); + m_router->Move( m_endSnapPoint, m_endItem ); // refresh + } + else if( evt->IsAction( &ACT_PlaceMicroVia ) ) + { + m_router->Settings().SetLayerPair( frame->GetScreen()->m_Route_Layer_TOP, + frame->GetScreen()->m_Route_Layer_BOTTOM ); + m_router->ToggleViaPlacement( VIA_MICROVIA ); m_router->Move( m_endSnapPoint, m_endItem ); // refresh } else if( evt->IsAction( &ACT_SwitchPosture ) )