From c4c329e3931fc3bdab7e15ae4619c27b58de79b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20W=C5=82ostowski?= Date: Tue, 28 Mar 2017 18:30:49 +0200 Subject: [PATCH] Connectivity: local ratsnest for both legacy & GAL. Further removal of legacy code --- .gitignore | 9 + pcbnew/class_board_connected_item.cpp | 3 +- pcbnew/class_board_connected_item.h | 44 +-- pcbnew/class_pad.cpp | 7 - pcbnew/class_track.cpp | 2 +- pcbnew/connect.cpp | 68 ---- pcbnew/connectivity.cpp | 2 + pcbnew/connectivity_algo.cpp | 14 +- pcbnew/connectivity_algo.h | 6 +- pcbnew/modules.cpp | 1 - pcbnew/ratsnest.cpp | 166 +++------ pcbnew/ratsnest_viewitem.cpp | 30 +- pcbnew/tools/common_actions.cpp | 5 - pcbnew/tools/pcb_actions.cpp | 2 +- pcbnew/tools/pcb_editor_control.cpp | 43 ++- pcbnew/zones_by_polygon.cpp | 4 +- pcbnew/zones_polygons_test_connections.cpp | 409 --------------------- 17 files changed, 131 insertions(+), 684 deletions(-) delete mode 100644 pcbnew/zones_polygons_test_connections.cpp diff --git a/.gitignore b/.gitignore index baa0dc8ec1..31959b3d85 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,12 @@ demos/**/_autosave-* .*.swp *~ .DS_Store +*.png +*.kiface +*.o +*.a +*.cmake +*.orig +*.rej +*.so +*.old \ No newline at end of file diff --git a/pcbnew/class_board_connected_item.cpp b/pcbnew/class_board_connected_item.cpp index d33a100c47..0a993978c7 100644 --- a/pcbnew/class_board_connected_item.cpp +++ b/pcbnew/class_board_connected_item.cpp @@ -37,8 +37,7 @@ #include BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ) : - BOARD_ITEM( aParent, idtype ), m_netinfo( &NETINFO_LIST::ORPHANED_ITEM ), - m_Subnet( 0 ), m_ZoneSubnet( 0 ) + BOARD_ITEM( aParent, idtype ), m_netinfo( &NETINFO_LIST::ORPHANED_ITEM ) { } diff --git a/pcbnew/class_board_connected_item.h b/pcbnew/class_board_connected_item.h index df907fb00d..c3edfee71a 100644 --- a/pcbnew/class_board_connected_item.h +++ b/pcbnew/class_board_connected_item.h @@ -116,34 +116,6 @@ public: */ bool SetNetCode( int aNetCode, bool aNoAssert=false ); - /** - * Function GetSubNet - * @return int - the sub net code. - */ - int GetSubNet() const - { - return m_Subnet; - } - - void SetSubNet( int aSubNetCode ) - { - m_Subnet = aSubNetCode; - } - - /** - * Function GetZoneSubNet - * @return int - the sub net code in zone connections. - */ - int GetZoneSubNet() const - { - return m_ZoneSubnet; - } - - void SetZoneSubNet( int aSubNetCode ) - { - m_ZoneSubnet = aSubNetCode; - } - /** * Function GetNetname * @return wxString - the full netname @@ -189,17 +161,23 @@ public: */ wxString GetNetClassName() const; + void SetLocalRatsnestVisible( bool aVisible ) + { + m_localRatsnestVisible = aVisible; + } + + bool GetLocalRatsnestVisible() const + { + return m_localRatsnestVisible; + } + protected: /// Stores all informations about the net that item belongs to NETINFO_ITEM* m_netinfo; private: - int m_Subnet; /* In rastnest routines : for the current net, block number - * (number common to the current connected items found) - */ - int m_ZoneSubnet; // used in rastnest computations : for the current net, - // handle cluster number in zone connection + bool m_localRatsnestVisible; }; diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index 8004009fa0..fc1dd927b1 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -658,13 +658,6 @@ void D_PAD::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM>& aList ) aList.push_back( MSG_PANEL_ITEM( _( "Net" ), GetNetname(), DARKCYAN ) ); - /* For test and debug only: display m_physical_connexion and - * m_logical_connexion */ -#if 1 // Used only to debug connectivity calculations - Line.Printf( wxT( "%d-%d-%d " ), GetSubRatsnest(), GetSubNet(), GetZoneSubNet() ); - aList.push_back( MSG_PANEL_ITEM( wxT( "L-P-Z" ), Line, DARKGREEN ) ); -#endif - board = GetBoard(); aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index 36d6f489cf..a31d4bf919 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -1094,7 +1094,7 @@ void TRACK::GetMsgPanelInfoBase_Common( std::vector< MSG_PANEL_ITEM >& aList ) aList.push_back( MSG_PANEL_ITEM( _( "NetName" ), msg, RED ) ); // Display net code : (useful in test or debug) - msg.Printf( wxT( "%d.%d" ), GetNetCode(), GetSubNet() ); + msg.Printf( wxT( "%d" ), GetNetCode() ); aList.push_back( MSG_PANEL_ITEM( _( "NetCode" ), msg, RED ) ); } diff --git a/pcbnew/connect.cpp b/pcbnew/connect.cpp index 8eda6d924d..7000dca240 100644 --- a/pcbnew/connect.cpp +++ b/pcbnew/connect.cpp @@ -95,72 +95,4 @@ static void RebuildTrackChain( BOARD* pcb ) void PCB_BASE_FRAME::TestNetConnection( wxDC* aDC, int aNetCode ) { -#if 0 - // Skip dummy net -1, and "not connected" net 0 (grouping all not connected pads) - if( aNetCode <= 0 ) - return; - - if( (m_Pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 ) - Compile_Ratsnest( aDC, true ); - - // Clear the cluster identifier (subnet) of pads for this net - // Pads are grouped by netcode (and in netname alphabetic order) - for( unsigned i = 0; i < m_Pcb->GetPadCount(); ++i ) - { - D_PAD* pad = m_Pcb->GetPad(i); - - if( m_Pcb->GetPad(i)->GetNetCode() == aNetCode ) - pad->SetSubNet( 0 ); - } - - m_Pcb->Test_Connections_To_Copper_Areas( aNetCode ); - - // Search for the first and the last segment relative to the given net code - if( m_Pcb->m_Track ) - { - CONNECTIONS connections( m_Pcb ); - - TRACK* lastTrack = NULL; - TRACK* firstTrack = m_Pcb->m_Track.GetFirst()->GetStartNetCode( aNetCode ); - - if( firstTrack ) - lastTrack = firstTrack->GetEndNetCode( aNetCode ); - - if( firstTrack && lastTrack ) // i.e. if there are segments - { - connections.Build_CurrNet_SubNets_Connections( firstTrack, lastTrack, aNetCode ); - } - } - - Merge_SubNets_Connected_By_CopperAreas( m_Pcb, aNetCode ); - - // rebuild the active ratsnest for this net - DrawGeneralRatsnest( aDC, aNetCode ); - TestForActiveLinksInRatsnest( aNetCode ); - DrawGeneralRatsnest( aDC, aNetCode ); - - // Display results - wxString msg; - int net_notconnected_count = 0; - NETINFO_ITEM* net = m_Pcb->FindNet( aNetCode ); - - if( net ) // Should not occur, but ... - { - for( unsigned ii = net->m_RatsnestStartIdx; ii < net->m_RatsnestEndIdx; ii++ ) - { - if( m_Pcb->m_FullRatsnest[ii].IsActive() ) - net_notconnected_count++; - } - - msg.Printf( wxT( "links %d nc %d net %d: not conn %d" ), - m_Pcb->GetRatsnestsCount(), m_Pcb->GetUnconnectedNetCount(), aNetCode, - net_notconnected_count ); - } - else - msg.Printf( wxT( "net not found: netcode %d" ), aNetCode ); - - SetStatusText( msg ); - - return; -#endif } diff --git a/pcbnew/connectivity.cpp b/pcbnew/connectivity.cpp index 961e848a39..fe2a884dbc 100644 --- a/pcbnew/connectivity.cpp +++ b/pcbnew/connectivity.cpp @@ -285,6 +285,8 @@ const std::vector& CONNECTIVITY_DATA::GetDynamicRatsnest() cons void CONNECTIVITY_DATA::ClearDynamicRatsnest() { + m_connAlgo->ForEachAnchor( [] (CN_ANCHOR_PTR anchor ) { anchor->SetNoLine( false ); } ); + m_dynamicConnectivity.reset(); m_dynamicRatsnest.clear(); } diff --git a/pcbnew/connectivity_algo.cpp b/pcbnew/connectivity_algo.cpp index 43067fbb0d..5959059d2a 100644 --- a/pcbnew/connectivity_algo.cpp +++ b/pcbnew/connectivity_algo.cpp @@ -480,7 +480,7 @@ void CN_CONNECTIVITY_ALGO::searchConnections( bool aIncludeZones ) auto zoneItem = static_cast (item); auto searchZones = std::bind( checkForConnection, _1, zoneItem ); - if( zoneItem->Dirty() ) + if( zoneItem->Dirty() || m_padList.IsDirty() || m_trackList.IsDirty() || m_viaList.IsDirty() ) { totalDirtyCount++; m_viaList.FindNearby( zoneItem->BBox(), searchZones ); @@ -901,3 +901,15 @@ void CN_CONNECTIVITY_ALGO::Clear() m_zoneList.Clear(); } + +void CN_CONNECTIVITY_ALGO::ForEachAnchor( std::function aFunc ) +{ + for ( auto anchor : m_padList.Anchors() ) + aFunc( anchor ); + for ( auto anchor : m_viaList.Anchors() ) + aFunc( anchor ); + for ( auto anchor : m_trackList.Anchors() ) + aFunc( anchor ); + for ( auto anchor : m_zoneList.Anchors() ) + aFunc( anchor ); +} diff --git a/pcbnew/connectivity_algo.h b/pcbnew/connectivity_algo.h index e9f1977e0c..c8e1df945d 100644 --- a/pcbnew/connectivity_algo.h +++ b/pcbnew/connectivity_algo.h @@ -179,7 +179,7 @@ public: { return m_target->Pos(); } - + private: CN_ANCHOR_PTR m_source; CN_ANCHOR_PTR m_target; @@ -504,6 +504,8 @@ public: ITER begin() { return m_items.begin(); }; ITER end() { return m_items.end(); }; + std::vector& Anchors() { return m_anchors; } + template void FindNearby( VECTOR2I aPosition, int aDistMax, T aFunc, bool aDirtyOnly = false ); @@ -940,6 +942,8 @@ public: const CLUSTERS& GetClusters(); int GetUnconnectedCount(); + + void ForEachAnchor( std::function aFunc ); }; bool operator<( const CN_ANCHOR_PTR a, const CN_ANCHOR_PTR b ); diff --git a/pcbnew/modules.cpp b/pcbnew/modules.cpp index f7679731c8..2fd5046fb9 100644 --- a/pcbnew/modules.cpp +++ b/pcbnew/modules.cpp @@ -296,7 +296,6 @@ void PCB_EDIT_FRAME::Change_Side_Module( MODULE* Module, wxDC* DC ) if( !Module->IsMoving() ) /* This is a simple flip, no other edition in progress */ { - GetBoard()->m_Status_Pcb &= ~( LISTE_RATSNEST_ITEM_OK | CONNEXION_OK ); if( DC ) { diff --git a/pcbnew/ratsnest.cpp b/pcbnew/ratsnest.cpp index 2907857696..3089a62dd2 100644 --- a/pcbnew/ratsnest.cpp +++ b/pcbnew/ratsnest.cpp @@ -97,30 +97,31 @@ void PCB_BASE_FRAME::DrawGeneralRatsnest( wxDC* aDC, int aNetcode ) auto connectivity = m_Pcb->GetConnectivity(); - COLOR4D color = g_ColorsSettings.GetItemColor(LAYER_RATSNEST); + COLOR4D color = g_ColorsSettings.GetItemColor( LAYER_RATSNEST ); for( int i = 1; i < connectivity->GetNetCount(); ++i ) { - RN_NET* net = connectivity->GetRatsnestForNet( i ); + RN_NET* net = connectivity->GetRatsnestForNet( i ); - if( ( aNetcode <= 0 ) || ( aNetcode == i ) ) + if( ( aNetcode <= 0 ) || ( aNetcode == i ) ) + { + for( const auto& edge : net->GetEdges() ) { - for ( const auto& edge : net->GetEdges() ) - { - if ( edge.IsVisible() ) - { - auto s = edge.GetSourcePos(); - auto d = edge.GetTargetPos(); - auto sn = edge.GetSourceNode(); - auto dn = edge.GetTargetNode(); + auto s = edge.GetSourcePos(); + auto d = edge.GetTargetPos(); + auto sn = edge.GetSourceNode(); + auto dn = edge.GetTargetNode(); - if ( !sn->GetNoLine() && !dn->GetNoLine() ) - GRLine( m_canvas->GetClipBox(), aDC, wxPoint(s.x, s.y), wxPoint(d.x, d.y), 0, color ); - } - } + bool enable = !sn->GetNoLine() && !dn->GetNoLine(); + bool show = sn->Parent()->GetLocalRatsnestVisible() + || dn->Parent()->GetLocalRatsnestVisible(); + + if( enable && show ) + GRLine( m_canvas->GetClipBox(), aDC, wxPoint( s.x, s.y ), wxPoint( d.x, + d.y ), 0, color ); } + } } - } @@ -133,7 +134,8 @@ void PCB_BASE_FRAME::TraceModuleRatsNest( wxDC* DC ) for( const auto& l : GetBoard()->GetConnectivity()->GetDynamicRatsnest() ) { - GRLine( m_canvas->GetClipBox(), DC, wxPoint(l.a.x, l.a.y), wxPoint(l.b.x, l.b.y), 0, tmpcolor ); + GRLine( m_canvas->GetClipBox(), DC, wxPoint( l.a.x, l.a.y ), wxPoint( l.b.x, + l.b.y ), 0, tmpcolor ); } } @@ -153,8 +155,8 @@ void PCB_BASE_FRAME::TraceModuleRatsNest( wxDC* DC ) * drawn */ - static wxPoint s_CursorPos; // Coordinate of the moving point (mouse cursor and - // end of current track segment) +static wxPoint s_CursorPos; // Coordinate of the moving point (mouse cursor and + // end of current track segment) /* Function BuildAirWiresTargetsList * Build a list of candidates that can be a coonection point @@ -163,11 +165,11 @@ void PCB_BASE_FRAME::TraceModuleRatsNest( wxDC* DC ) * from the current new track to candidates during track creation */ -static BOARD_CONNECTED_ITEM *s_ref = nullptr; +static BOARD_CONNECTED_ITEM* s_ref = nullptr; static int s_refNet = -1; void PCB_BASE_FRAME::BuildAirWiresTargetsList( BOARD_CONNECTED_ITEM* aItemRef, - const wxPoint& aPosition, int aNet ) + const wxPoint& aPosition, int aNet ) { s_CursorPos = aPosition; // needed for sort_by_distance s_ref = aItemRef; @@ -175,25 +177,24 @@ void PCB_BASE_FRAME::BuildAirWiresTargetsList( BOARD_CONNECTED_ITEM* aItemRef, } +static MODULE movedModule( nullptr ); - -static MODULE movedModule(nullptr); - -void PCB_BASE_FRAME::build_ratsnest_module( MODULE *mod, wxPoint aMoveVector ) +void PCB_BASE_FRAME::build_ratsnest_module( MODULE* mod, wxPoint aMoveVector ) { auto connectivity = GetBoard()->GetConnectivity(); + movedModule = *mod; movedModule.Move( -aMoveVector ); connectivity->ClearDynamicRatsnest(); - connectivity->BlockRatsnestItems( {mod} ); - connectivity->ComputeDynamicRatsnest( {&movedModule} ); + connectivity->BlockRatsnestItems( { mod } ); + connectivity->ComputeDynamicRatsnest( { &movedModule } ); } void PCB_BASE_FRAME::TraceAirWiresToTargets( wxDC* aDC ) { auto connectivity = GetBoard()->GetConnectivity(); - DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions(); + DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*) GetDisplayOptions(); auto targets = connectivity->NearestUnconnectedTargets( s_ref, s_CursorPos, s_refNet ); @@ -202,23 +203,23 @@ void PCB_BASE_FRAME::TraceAirWiresToTargets( wxDC* aDC ) GRSetDrawMode( aDC, GR_XOR ); - for (int i = 0; i < std::min( (int)displ_opts->m_MaxLinksShowed, (int)targets.size() ); i++) + for( int i = 0; i < std::min( (int) displ_opts->m_MaxLinksShowed, (int) targets.size() ); i++ ) { auto p = targets[i]; - GRLine( m_canvas->GetClipBox(), aDC, s_CursorPos, wxPoint(p.x, p.y), 0, YELLOW ); + GRLine( m_canvas->GetClipBox(), aDC, s_CursorPos, wxPoint( p.x, p.y ), 0, YELLOW ); } - } + // Redraw in XOR mode the outlines of the module. void MODULE::DrawOutlinesWhenMoving( EDA_DRAW_PANEL* panel, wxDC* DC, - const wxPoint& aMoveVector ) + const wxPoint& aMoveVector ) { - int pad_fill_tmp; + int pad_fill_tmp; D_PAD* pt_pad; DrawEdgesOnly( panel, DC, aMoveVector, GR_XOR ); - DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions(); + DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*) panel->GetDisplayOptions(); // Show pads in sketch mode to speedu up drawings pad_fill_tmp = displ_opts->m_DisplayPadFill; @@ -239,101 +240,18 @@ void MODULE::DrawOutlinesWhenMoving( EDA_DRAW_PANEL* panel, wxDC* DC, } } + void PCB_EDIT_FRAME::Show_1_Ratsnest( EDA_ITEM* item, wxDC* DC ) { - if( GetBoard()->IsElementVisible(RATSNEST_VISIBLE) ) - return; - - Compile_Ratsnest( DC, true ); - - printf("show1r: %p\n", item); - - auto connectivity = GetBoard()->GetConnectivity(); - - -// FIXME - -#if 0 - if( item ) + if( item->Type() == PCB_MODULE_T ) { - if( item->Type() == PCB_PAD_T ) + auto mod = static_cast (item); + + for( auto pad : mod->PadsIter() ) { - pt_pad = (D_PAD*) item; - Module = pt_pad->GetParent(); + pad->SetLocalRatsnestVisible( true ); } - if( pt_pad ) // Displaying the ratsnest of the corresponding net. - { - SetMsgPanel( pt_pad ); - - for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ ) - { - RATSNEST_ITEM* net = &GetBoard()->m_FullRatsnest[ii]; - - if( net->GetNet() == pt_pad->GetNetCode() ) - { - if( ( net->m_Status & CH_VISIBLE ) != 0 ) - continue; - - net->m_Status |= CH_VISIBLE; - - if( ( net->m_Status & CH_ACTIF ) == 0 ) - continue; - - net->Draw( m_canvas, DC, GR_XOR, wxPoint( 0, 0 ) ); - } - } - } - else - { - if( item->Type() == PCB_MODULE_TEXT_T ) - { - if( item->GetParent() && ( item->GetParent()->Type() == PCB_MODULE_T ) ) - Module = static_cast( item->GetParent() ); - } - else if( item->Type() == PCB_MODULE_T ) - { - Module = static_cast( item ); - } - - if( Module ) - { - SetMsgPanel( Module ); - pt_pad = Module->Pads(); - - for( ; pt_pad != NULL; pt_pad = pt_pad->Next() ) - { - for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ ) - { - RATSNEST_ITEM* net = &GetBoard()->m_FullRatsnest[ii]; - - if( ( net->m_PadStart == pt_pad ) || ( net->m_PadEnd == pt_pad ) ) - { - if( net->m_Status & CH_VISIBLE ) - continue; - - net->m_Status |= CH_VISIBLE; - - if( (net->m_Status & CH_ACTIF) == 0 ) - continue; - - net->Draw( m_canvas, DC, GR_XOR, wxPoint( 0, 0 ) ); - } - } - } - - pt_pad = NULL; - } - } + m_canvas->Refresh(); } - - // Erase if no pad or module has been selected. - if( ( pt_pad == NULL ) && ( Module == NULL ) ) - { - DrawGeneralRatsnest( DC ); - - for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ ) - GetBoard()->m_FullRatsnest[ii].m_Status &= ~CH_VISIBLE; - } - #endif } diff --git a/pcbnew/ratsnest_viewitem.cpp b/pcbnew/ratsnest_viewitem.cpp index 71403ec9a5..704eb51e8a 100644 --- a/pcbnew/ratsnest_viewitem.cpp +++ b/pcbnew/ratsnest_viewitem.cpp @@ -55,16 +55,9 @@ const BOX2I RATSNEST_VIEWITEM::ViewBBox() const return bbox; } -#include -std::vector delEdges; - -void clearDEdges() { delEdges.clear(); } -void addDEdge ( SEG edge ) { delEdges.push_back(edge); } - - void RATSNEST_VIEWITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const { - static const double crossSize = 100000.0; + constexpr int CROSS_SIZE = 200000; auto gal = aView->GetGAL(); gal->SetIsStroke( true ); @@ -76,23 +69,19 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const int highlightedNet = rs->GetHighlightNetCode(); gal->SetStrokeColor( color.Brightened( 0.8 ) ); - for (auto s : delEdges) - gal->DrawLine( s.A, s.B ); - // Draw the "dynamic" ratsnest (i.e. for objects that may be currently being moved) for( const auto& l : m_data->GetDynamicRatsnest() ) { if ( l.a == l.b ) { - gal->DrawLine( VECTOR2I( l.a.x - crossSize, l.a.y - crossSize ), VECTOR2I( l.b.x + crossSize, l.b.y + crossSize ) ); - gal->DrawLine( VECTOR2I( l.a.x - crossSize, l.a.y + crossSize ), VECTOR2I( l.b.x + crossSize, l.b.y - crossSize ) ); + gal->DrawLine( VECTOR2I( l.a.x - CROSS_SIZE, l.a.y - CROSS_SIZE ), VECTOR2I( l.b.x + CROSS_SIZE, l.b.y + CROSS_SIZE ) ); + gal->DrawLine( VECTOR2I( l.a.x - CROSS_SIZE, l.a.y + CROSS_SIZE ), VECTOR2I( l.b.x + CROSS_SIZE, l.b.y - CROSS_SIZE ) ); } else { gal->DrawLine( l.a, l.b ); } } - // Dynamic ratsnest (for e.g. dragged items) for( int i = 1; i < m_data->GetNetCount(); ++i ) { RN_NET* net = m_data->GetRatsnestForNet( i ); @@ -103,20 +92,21 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const for( const auto& edge : net->GetUnconnected() ) { - if ( !edge.IsVisible() ) - continue; - + //if ( !edge.IsVisible() ) + // continue; + const auto& sourceNode = edge.GetSourceNode(); const auto& targetNode = edge.GetTargetNode(); const VECTOR2I source( sourceNode->Pos() ); const VECTOR2I target( targetNode->Pos() ); - if ( !sourceNode->GetNoLine() && !targetNode->GetNoLine() ) + bool enable = !sourceNode->GetNoLine() && !targetNode->GetNoLine(); + bool show = sourceNode->Parent()->GetLocalRatsnestVisible() || targetNode->Parent()->GetLocalRatsnestVisible(); + + if ( enable && show ) { if ( source == target ) { - constexpr int CROSS_SIZE = 200000; - gal->DrawLine( VECTOR2I( source.x - CROSS_SIZE, source.y - CROSS_SIZE ), VECTOR2I( source.x + CROSS_SIZE, source.y + CROSS_SIZE ) ); gal->DrawLine( VECTOR2I( source.x - CROSS_SIZE, source.y + CROSS_SIZE ), VECTOR2I( source.x + CROSS_SIZE, source.y - CROSS_SIZE ) ); } diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index e4f35c0b14..eee78402c8 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -588,11 +588,6 @@ TOOL_ACTION COMMON_ACTIONS::toBeDone( "pcbnew.Control.toBeDone", AS_GLOBAL, 0, // dialog saying it is not implemented yet "", "" ); // so users are aware of that -TOOL_ACTION COMMON_ACTIONS::showLocalRatsnest( "pcbnew.Control.showLocalRatsnest", - AS_GLOBAL, 0, - "", "" ); - - TOOL_ACTION COMMON_ACTIONS::routerActivateSingle( "pcbnew.InteractiveRouter.SingleTrack", AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ADD_NEW_TRACK ), _( "Interactive Router (Single Tracks)" ), diff --git a/pcbnew/tools/pcb_actions.cpp b/pcbnew/tools/pcb_actions.cpp index f1830c3f12..6cd3d0437c 100644 --- a/pcbnew/tools/pcb_actions.cpp +++ b/pcbnew/tools/pcb_actions.cpp @@ -162,7 +162,7 @@ boost::optional PCB_ACTIONS::TranslateLegacyId( int aId ) return PCB_ACTIONS::appendBoard.MakeEvent(); case ID_PCB_SHOW_1_RATSNEST_BUTT: - return PCB_ACTIONS::toBeDone.MakeEvent(); + return PCB_ACTIONS::showLocalRatsnest.MakeEvent(); case ID_PCB_MUWAVE_TOOL_GAP_CMD: return PCB_ACTIONS::microwaveCreateGap.MakeEvent(); diff --git a/pcbnew/tools/pcb_editor_control.cpp b/pcbnew/tools/pcb_editor_control.cpp index 3baeb7ee92..22d9abe099 100644 --- a/pcbnew/tools/pcb_editor_control.cpp +++ b/pcbnew/tools/pcb_editor_control.cpp @@ -148,6 +148,10 @@ TOOL_ACTION PCB_ACTIONS::highlightNetCursor( "pcbnew.EditorControl.highlightNetC AS_GLOBAL, 0, "", "" ); +TOOL_ACTION PCB_ACTIONS::showLocalRatsnest( "pcbnew.Control.showLocalRatsnest", + AS_GLOBAL, 0, + "", "" ); + class ZONE_CONTEXT_MENU : public CONTEXT_MENU { @@ -484,7 +488,7 @@ int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent ) controls->SetSnapping( false ); controls->SetAutoPan( false ); controls->CaptureCursor( false ); - + view->Remove( &preview ); m_frame->SetNoToolSelected(); @@ -1058,25 +1062,45 @@ int PCB_EDITOR_CONTROL::HighlightNetCursor( const TOOL_EVENT& aEvent ) return 0; } -static bool showLocalRatsnest( KIGFX::VIEW* aView, PCB_BASE_FRAME* aFrame, - KIGFX::ORIGIN_VIEWITEM* aItem, const VECTOR2D& aPosition ) +static bool showLocalRatsnest( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition ) { - aFrame->SetAuxOrigin( wxPoint( aPosition.x, aPosition.y ) ); - aItem->SetPosition( aPosition ); - aView->MarkDirty(); + auto selectionTool = aToolMgr->GetTool(); + + aToolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); + aToolMgr->RunAction( PCB_ACTIONS::selectionCursor, true ); + + const SELECTION& selection = selectionTool->GetSelection(); + + if( selection.Empty() ) + return true; + + for ( auto item : selection ) + { + if ( item->Type() == PCB_MODULE_T ) + { + for ( auto pad : static_cast (item)->PadsIter() ) + { + pad->SetLocalRatsnestVisible( true ); + } + } + } return true; } int PCB_EDITOR_CONTROL::ShowLocalRatsnest( const TOOL_EVENT& aEvent ) { + printf("ShowLocalRTool!\n"); + Activate(); + + auto picker = m_toolMgr->GetTool(); assert( picker ); m_frame->SetToolID( ID_PCB_SHOW_1_RATSNEST_BUTT, wxCURSOR_PENCIL, _( "Pick Components for Local Ratsnest" ) ); - //picker->SetClickHandler( std::bind( showLocalRatsnest, m_toolMgr, _1 ) ); + picker->SetClickHandler( std::bind( showLocalRatsnest, m_toolMgr, _1 ) ); picker->SetSnapping( false ); picker->Activate(); Wait(); @@ -1086,7 +1110,7 @@ int PCB_EDITOR_CONTROL::ShowLocalRatsnest( const TOOL_EVENT& aEvent ) int PCB_EDITOR_CONTROL::UpdateSelectionRatsnest( const TOOL_EVENT& aEvent ) { - SELECTION_TOOL* selTool = m_toolMgr->GetTool(); +/* SELECTION_TOOL* selTool = m_toolMgr->GetTool(); const SELECTION& selection = selTool->GetSelection(); RN_DATA* ratsnest = getModel()->GetRatsnest(); @@ -1099,7 +1123,7 @@ int PCB_EDITOR_CONTROL::UpdateSelectionRatsnest( const TOOL_EVENT& aEvent ) ratsnest->AddSimple( static_cast( item ) ); } - return 0; + return 0;*/ } @@ -1132,6 +1156,7 @@ void PCB_EDITOR_CONTROL::SetTransitions() Go( &PCB_EDITOR_CONTROL::DrillOrigin, PCB_ACTIONS::drillOrigin.MakeEvent() ); Go( &PCB_EDITOR_CONTROL::HighlightNet, PCB_ACTIONS::highlightNet.MakeEvent() ); Go( &PCB_EDITOR_CONTROL::HighlightNetCursor, PCB_ACTIONS::highlightNetCursor.MakeEvent() ); + Go( &PCB_EDITOR_CONTROL::ShowLocalRatsnest, PCB_ACTIONS::showLocalRatsnest.MakeEvent() ); Go( &PCB_EDITOR_CONTROL::UpdateSelectionRatsnest, PCB_ACTIONS::selectionModified.MakeEvent() ); } diff --git a/pcbnew/zones_by_polygon.cpp b/pcbnew/zones_by_polygon.cpp index d0fe404ff5..39c3bb9dcd 100644 --- a/pcbnew/zones_by_polygon.cpp +++ b/pcbnew/zones_by_polygon.cpp @@ -45,7 +45,7 @@ #include #include #include -#include +#include // Outline creation: static void Abort_Zone_Create_Outline( EDA_DRAW_PANEL* Panel, wxDC* DC ); @@ -951,12 +951,12 @@ void PCB_EDIT_FRAME::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* aZone ) if( zone->IsFilled() ) { Fill_Zone( zone ); - GetBoard()->GetRatsnest()->Recalculate( zone->GetNetCode() ); } } commit.Stage( s_PickedList ); commit.Push( _( "Modify zone properties" ) ); + GetBoard()->GetConnectivity()->RecalculateRatsnest(); s_PickedList.ClearItemsList(); // s_ItemsListPicker is no longer owner of picked items } diff --git a/pcbnew/zones_polygons_test_connections.cpp b/pcbnew/zones_polygons_test_connections.cpp deleted file mode 100644 index f0177fe879..0000000000 --- a/pcbnew/zones_polygons_test_connections.cpp +++ /dev/null @@ -1,409 +0,0 @@ -/** - * @file zones_polygons_test_connections.cpp - */ - -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr - * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you may find one here: - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * or you may search the http://www.gnu.org website for the version 2 license, - * or you may write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include // sort - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -static bool CmpZoneSubnetValue( const BOARD_CONNECTED_ITEM* a, const BOARD_CONNECTED_ITEM* b ); - -void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode ); - -// This helper function sort a list of zones by netcode, -// and for a given netcode by zone size -// zone size = size of the m_FilledPolysList buffer -bool sort_areas( const ZONE_CONTAINER* ref, const ZONE_CONTAINER* tst ) -{ - if( ref->GetNetCode() == tst->GetNetCode() ) - return ref->GetFilledPolysList().TotalVertices() < - tst->GetFilledPolysList().TotalVertices(); - else - return ref->GetNetCode() < tst->GetNetCode(); -} - -/** - * Function Test_Connection_To_Copper_Areas - * init .m_ZoneSubnet parameter in tracks and pads according to the connections to areas found - * @param aNetcode = netcode to analyse. if -1, analyse all nets - */ -void BOARD::Test_Connections_To_Copper_Areas( int aNetcode ) -{ - // list of pads and tracks candidates on this layer and on this net. - // It is static to avoid multiple memory realloc. - static std::vector candidates; - - // clear .m_ZoneSubnet parameter for pads - for( MODULE* module = m_Modules; module; module = module->Next() ) - { - for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) - if( aNetcode < 0 || aNetcode == pad->GetNetCode() ) - pad->SetZoneSubNet( 0 ); - } - - // clear .m_ZoneSubnet parameter for tracks and vias - for( TRACK* track = m_Track; track; track = track->Next() ) - { - if( aNetcode < 0 || aNetcode == track->GetNetCode() ) - track->SetZoneSubNet( 0 ); - } - - // examine all zones, net by net: - int subnet = 0; - - // Build zones candidates list - std::vector zones_candidates; - - zones_candidates.reserve( GetAreaCount() ); - - for( int index = 0; index < GetAreaCount(); index++ ) - { - ZONE_CONTAINER* zone = GetArea( index ); - - if( !zone->IsOnCopperLayer() ) - continue; - - if( aNetcode >= 0 && aNetcode != zone->GetNetCode() ) - continue; - - if( zone->GetFilledPolysList().IsEmpty() ) - continue; - - zones_candidates.push_back( zone ); - } - - // sort them by netcode then vertices count. - // For a given net, examine the smaller zones first slightly speed up calculation - // (25% faster) - // this is only noticeable with very large boards and depends on board zones topology - // This is due to the fact some items are connected by small zones ares, - // before examining large zones areas and these items are not tested after a connection is found - sort( zones_candidates.begin(), zones_candidates.end(), sort_areas ); - - int oldnetcode = -1; - for( unsigned idx = 0; idx < zones_candidates.size(); idx++ ) - { - ZONE_CONTAINER* zone = zones_candidates[idx]; - - int netcode = zone->GetNetCode(); - - // Build a list of candidates connected to the net: - // At this point, layers are not considered, because areas on different layers can - // be connected by a via or a pad. - // (because zones are sorted by netcode, there is made only once per net) - NETINFO_ITEM* net = FindNet( netcode ); - - wxASSERT( net ); - if( net == NULL ) - continue; - - if( oldnetcode != netcode ) - { - oldnetcode = netcode; - candidates.clear(); - - // Build the list of pads candidates connected to the net: - candidates.reserve( net->m_PadInNetList.size() ); - - for( unsigned ii = 0; ii < net->m_PadInNetList.size(); ii++ ) - candidates.push_back( net->m_PadInNetList[ii] ); - - // If we have any tracks... - if( m_Track.GetCount() > 0 ) - { - // Build the list of track candidates connected to the net: - TRACK* track = m_Track.GetFirst()->GetStartNetCode( netcode ); - - for( ; track; track = track->Next() ) - { - if( track->GetNetCode() != netcode ) - break; - - candidates.push_back( track ); - } - } - } - - // test if a candidate is inside a filled area of this zone - const SHAPE_POLY_SET& polysList = zone->GetFilledPolysList(); - - for( int outline = 0; outline < polysList.OutlineCount(); outline++ ) - { - subnet++; - - for( unsigned ic = 0; ic < candidates.size(); ic++ ) - { - // test if this area is connected to a board item: - BOARD_CONNECTED_ITEM* item = candidates[ic]; - - if( item->GetZoneSubNet() == subnet ) // Already merged - continue; - - if( !item->IsOnLayer( zone->GetLayer() ) ) - continue; - - wxPoint pos1, pos2; - - if( item->Type() == PCB_PAD_T ) - { - // For pads we use the shape position instead of - // the pad position, because the zones are connected - // to the center of the shape, not the pad position - // (this is important for pads with thermal relief) - pos1 = pos2 = ( (D_PAD*) item )->ShapePos(); - } - else if( item->Type() == PCB_VIA_T ) - { - const VIA *via = static_cast( item ); - pos1 = via->GetStart(); - pos2 = pos1; - } - else if( item->Type() == PCB_TRACE_T ) - { - const TRACK *trk = static_cast( item ); - pos1 = trk->GetStart(); - pos2 = trk->GetEnd(); - } - else - { - continue; - } - - bool connected = false; - - if( polysList.Contains( VECTOR2I( pos1.x, pos1.y ), outline ) ) - connected = true; - - if( !connected && ( pos1 != pos2 ) ) - { - if( polysList.Contains( VECTOR2I( pos2.x, pos2.y ), outline ) ) - connected = true; - } - - if( connected ) - { - // Set ZoneSubnet to the current subnet value. - // If the previous subnet is not 0, merge all items with old subnet - // to the new one - int old_subnet = item->GetZoneSubNet(); - item->SetZoneSubNet( subnet ); - - // Merge previous subnet with the current - if( (old_subnet > 0) && (old_subnet != subnet) ) - { - for( unsigned jj = 0; jj < candidates.size(); jj++ ) - { - BOARD_CONNECTED_ITEM* item_to_merge = candidates[jj]; - - if( old_subnet == item_to_merge->GetZoneSubNet() ) - { - item_to_merge->SetZoneSubNet( subnet ); - } - } - } // End if ( old_subnet > 0 ) - } // End if( connected ) - } - } - } // End read all zones candidates -} - - -/** - * Function Merge_SubNets_Connected_By_CopperAreas(BOARD* aPcb) - * Calls Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode ) for each - * netcode found in zone list - * @param aPcb = the current board - */ -void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb ) -{ - for( int index = 0; index < aPcb->GetAreaCount(); index++ ) - { - ZONE_CONTAINER* zone = aPcb->GetArea( index ); - - if ( ! zone->IsOnCopperLayer() ) - continue; - - if ( zone->GetNetCode() <= 0 ) - continue; - - Merge_SubNets_Connected_By_CopperAreas( aPcb, zone->GetNetCode() ); - } -} - - -/** - * Function Merge_SubNets_Connected_By_CopperAreas(BOARD* aPcb, int aNetcode) - * Used after connections by tracks calculations - * Merge subnets, in tracks ans pads when they are connected by a filled copper area - * for pads, this is the .m_physical_connexion member which is tested and modified - * for tracks, this is the .m_Subnet member which is tested and modified - * these members are block numbers (or cluster numbers) for a given net, - * calculated by Build_Pads_Info_Connections_By_Tracks() - * The result is merging 2 blocks (or subnets) - * @param aPcb = the current board - * @param aNetcode = netcode to consider - */ -void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode ) -{ - // Ensure a zone with the given netcode exists: examine all zones: - bool found = false; - - for( int index = 0; index < aPcb->GetAreaCount(); index++ ) - { - ZONE_CONTAINER* zone = aPcb->GetArea( index ); - - if( aNetcode == zone->GetNetCode() ) - { - found = true; - break; - } - } - - if( !found ) // No zone with this netcode, therefore no connection by zone - return; - - // list of pads and tracks candidates to test: - // It is static to avoid multiple memory realloc. - static std::vector Candidates; - Candidates.clear(); - - // Build the list of pads candidates connected to the net: - NETINFO_ITEM* net = aPcb->FindNet( aNetcode ); - wxASSERT( net ); - Candidates.reserve( net->m_PadInNetList.size() ); - for( unsigned ii = 0; ii < net->m_PadInNetList.size(); ii++ ) - Candidates.push_back( net->m_PadInNetList[ii] ); - - // Build the list of track candidates connected to the net: - TRACK* track; - - if( aPcb->m_Track.GetCount() > 0 ) - { - track = aPcb->m_Track.GetFirst()->GetStartNetCode( aNetcode ); - - for( ; track; track = track->Next() ) - { - if( track->GetNetCode() != aNetcode ) - break; - - Candidates.push_back( track ); - } - } - - if( Candidates.size() == 0 ) - return; - - int next_subnet_free_number = 0; - for( unsigned ii = 0; ii < Candidates.size(); ii++ ) - { - int subnet = Candidates[ii]->GetSubNet(); - next_subnet_free_number = std::max( next_subnet_free_number, subnet ); - } - - next_subnet_free_number++; // This is a subnet we can use with not connected items - // by tracks, but connected by zone. - - // Sort by zone_subnet: - sort( Candidates.begin(), Candidates.end(), CmpZoneSubnetValue ); - - // Some items can be not connected, but they can be connected to a filled area: - // give them a subnet common to these items connected only by the area, - // and not already used. - // a value like next_subnet_free_number+zone_subnet is right - for( unsigned jj = 0; jj < Candidates.size(); jj++ ) - { - BOARD_CONNECTED_ITEM* item = Candidates[jj]; - if ( item->GetSubNet() == 0 && (item->GetZoneSubNet() > 0) ) - { - item->SetSubNet( next_subnet_free_number + item->GetZoneSubNet() ); - } - } - - // Now, for each zone subnet, we search for 2 items with different subnets. - // if found, the 2 subnet are merged in the whole candidate list. - int old_subnet = 0; - int old_zone_subnet = 0; - for( unsigned ii = 0; ii < Candidates.size(); ii++ ) - { - BOARD_CONNECTED_ITEM* item = Candidates[ii]; - int zone_subnet = item->GetZoneSubNet(); - - if( zone_subnet == 0 ) // Not connected by a filled area, skip it - continue; - - int subnet = item->GetSubNet(); - - if( zone_subnet != old_zone_subnet ) // a new zone subnet is found - { - old_subnet = subnet; - old_zone_subnet = zone_subnet; - continue; - } - - // 2 successive items already from the same cluster: nothing to do - if( subnet == old_subnet ) - continue; - - // Here we have 2 items connected by the same area have 2 differents subnets: merge subnets - if( (subnet > old_subnet) || ( subnet <= 0) ) - std::swap( subnet, old_subnet ); - - for( unsigned jj = 0; jj < Candidates.size(); jj++ ) - { - BOARD_CONNECTED_ITEM * item_to_merge = Candidates[jj]; - - if( item_to_merge->GetSubNet() == old_subnet ) - item_to_merge->SetSubNet( subnet ); - } - - old_subnet = subnet; - } -} - - -/* Compare function used for sorting candidates by increasing zone subnet - */ -static bool CmpZoneSubnetValue( const BOARD_CONNECTED_ITEM* a, const BOARD_CONNECTED_ITEM* b ) -{ - int asubnet, bsubnet; - - asubnet = a->GetZoneSubNet(); - bsubnet = b->GetZoneSubNet(); - - return asubnet < bsubnet; -}