From a3941b1deca284f895862e455508fed1b76ca5bf Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 27 Feb 2018 18:02:10 +0100 Subject: [PATCH] Eagle import plugin: remap zones/tracks/vias using net name remapping There are a few steps to assign correct nets to zones/track/vias: - create a net name to pad map - perform 2 stage netlist update (fix timestamps and then references) - compare new net names with the previously created net map, save the differences as a old net to new net map - remap zones/tracks/vias using the map created in the previous step The main advantage here is it correctly handles unnamed nets (i.e. ones without any net labels attached), which might be changed by KiCad netlist generator. --- pcbnew/files.cpp | 90 +++++++++++++++++++++++++++-------------- pcbnew/pcb_edit_frame.h | 4 +- 2 files changed, 61 insertions(+), 33 deletions(-) diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index dbaff26777..63d81139f5 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -897,6 +897,17 @@ bool PCB_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType ) } + // Store net names for all pads, to create net remap information + std::unordered_map netMap; + + for( const auto& pad : GetBoard()->GetPads() ) + { + NETINFO_ITEM* netinfo = pad->GetNet(); + + if( netinfo->GetNet() > 0 && !netinfo->GetNetname().IsEmpty() ) + netMap[pad] = netinfo->GetNetname(); + } + // Two stage netlist update: // - first, assign valid timestamps to footprints (no reannotation) // - second, perform schematic annotation and update footprint references @@ -906,7 +917,25 @@ bool PCB_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType ) Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_PCB_UPDATE_REQUEST, "quiet-annotate;by-timestamp", this ); - fixEagleNets(); + std::unordered_map netRemap; + + // Compare the old net names with the new net names and create a net map + for( const auto& pad : GetBoard()->GetPads() ) + { + auto it = netMap.find( pad ); + + if( it == netMap.end() ) + continue; + + NETINFO_ITEM* netinfo = pad->GetNet(); + + // Net name has changed, create a remap entry + if( netinfo->GetNet() > 0 && netMap[pad] != netinfo->GetNetname() ) + netRemap[netMap[pad]] = netinfo->GetNetname(); + } + + if( !netRemap.empty() ) + fixEagleNets( netRemap ); return true; } @@ -921,52 +950,51 @@ bool PCB_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType ) } -bool PCB_EDIT_FRAME::fixEagleNets() +bool PCB_EDIT_FRAME::fixEagleNets( const std::unordered_map& aRemap ) { - KIWAY_PLAYER* schematicFrame = Kiway().Player( FRAME_SCH, false ); + bool result = true; + BOARD* board = GetBoard(); - // if the schematic file was also loaded. Fix any instances of ophaned zones and vias. - if( !schematicFrame ) - return false; - - // Get list of nets from schematic. - wxArrayString nets = schematicFrame->ListNets(); - - // perform netlist matching to prevent ophaned zones. - for( auto zone : GetBoard()->Zones() ) + // perform netlist matching to prevent orphaned zones. + for( auto zone : board->Zones() ) { - wxString zoneNet = zone->GetNet()->GetNetname(); - wxString localNet = "/" + zoneNet; + auto it = aRemap.find( zone->GetNet()->GetNetname() ); - for( unsigned int i = 0; i < nets.GetCount(); i++ ) + if( it != aRemap.end() ) { - if( nets[i].EndsWith( localNet ) ) - { - NETINFO_ITEM* net = GetBoard()->FindNet( nets[i] ); + NETINFO_ITEM* net = board->FindNet( it->second ); - if( net ) - zone->SetNetCode( net->GetNet() ); + if( !net ) + { + wxFAIL; + result = false; + continue; } + + zone->SetNet( net ); } } - // perform netlist matching to prevent ophaned tracks/vias. - for( auto track : GetBoard()->Tracks() ) + + // perform netlist matching to prevent orphaned tracks/vias. + for( auto track : board->Tracks() ) { - wxString trackNet = track->GetNet()->GetNetname(); - wxString localNet = "/" + trackNet; + auto it = aRemap.find( track->GetNet()->GetNetname() ); - for( unsigned int i = 0; i < nets.GetCount(); i++ ) + if( it != aRemap.end() ) { - if( nets[i].EndsWith( localNet ) ) - { - NETINFO_ITEM* net = GetBoard()->FindNet( nets[i] ); + NETINFO_ITEM* net = board->FindNet( it->second ); - if( net ) - track->SetNetCode( net->GetNet() ); + if( !net ) + { + wxFAIL; + result = false; + continue; } + + track->SetNet( net ); } } - return true; + return result; } diff --git a/pcbnew/pcb_edit_frame.h b/pcbnew/pcb_edit_frame.h index b2d5d1e31a..898a21e03f 100644 --- a/pcbnew/pcb_edit_frame.h +++ b/pcbnew/pcb_edit_frame.h @@ -24,7 +24,7 @@ #ifndef WXPCB_STRUCT_H_ #define WXPCB_STRUCT_H_ - +#include #include "pcb_base_edit_frame.h" #include "config_params.h" #include "undo_redo_container.h" @@ -243,7 +243,7 @@ protected: /** * Rematch orphaned zones and vias to schematic nets. */ - bool fixEagleNets(); + bool fixEagleNets( const std::unordered_map& aRemap ); // protected so that PCB::IFACE::CreateWindow() is the only factory. PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent );