From 792904557e0f755e36456d454fad11577c9fb99a Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Sun, 7 Feb 2021 17:06:56 -0800 Subject: [PATCH] Remember Parent data when routing Keeps parent information such as UUID and pad removal options for elements that are just updated in routing rather than created fresh or fully destroyed. Fixes https://gitlab.com/kicad/code/kicad/issues/7460 --- pcbnew/router/pns_kicad_iface.cpp | 67 +++++++++++++++++++++++++++++++ pcbnew/router/pns_kicad_iface.h | 2 + pcbnew/router/pns_router.cpp | 33 +++++++++++++-- pcbnew/router/pns_router.h | 1 + 4 files changed, 100 insertions(+), 3 deletions(-) diff --git a/pcbnew/router/pns_kicad_iface.cpp b/pcbnew/router/pns_kicad_iface.cpp index cfd85d6153..9944d7bf22 100644 --- a/pcbnew/router/pns_kicad_iface.cpp +++ b/pcbnew/router/pns_kicad_iface.cpp @@ -1417,6 +1417,73 @@ void PNS_KICAD_IFACE::RemoveItem( PNS::ITEM* aItem ) } +void PNS_KICAD_IFACE_BASE::UpdateItem( PNS::ITEM* aItem ) +{ + +} + + +void PNS_KICAD_IFACE::UpdateItem( PNS::ITEM* aItem ) +{ + BOARD_ITEM* board_item = aItem->Parent(); + + m_commit->Modify( board_item ); + + switch( aItem->Kind() ) + { + case PNS::ITEM::ARC_T: + { + PNS::ARC* arc = static_cast( aItem ); + ARC* arc_board = static_cast( board_item ); + const SHAPE_ARC* arc_shape = static_cast( arc->Shape() ); + arc_board->SetStart( wxPoint( arc_shape->GetP0() ) ); + arc_board->SetEnd( wxPoint( arc_shape->GetP1() ) ); + arc_board->SetMid( wxPoint( arc_shape->GetArcMid() ) ); + arc_board->SetWidth( arc->Width() ); + break; + } + + case PNS::ITEM::SEGMENT_T: + { + PNS::SEGMENT* seg = static_cast( aItem ); + TRACK* track = static_cast( board_item ); + const SEG& s = seg->Seg(); + track->SetStart( wxPoint( s.A.x, s.A.y ) ); + track->SetEnd( wxPoint( s.B.x, s.B.y ) ); + track->SetWidth( seg->Width() ); + break; + } + + case PNS::ITEM::VIA_T: + { + VIA* via_board = static_cast( board_item ); + PNS::VIA* via = static_cast( aItem ); + via_board->SetPosition( wxPoint( via->Pos().x, via->Pos().y ) ); + via_board->SetWidth( via->Diameter() ); + via_board->SetDrill( via->Drill() ); + via_board->SetNetCode( via->Net() > 0 ? via->Net() : 0 ); + via_board->SetViaType( via->ViaType() ); // MUST be before SetLayerPair() + via_board->SetIsFree( via->IsFree() ); + via_board->SetLayerPair( ToLAYER_ID( via->Layers().Start() ), + ToLAYER_ID( via->Layers().End() ) ); + break; + } + + case PNS::ITEM::SOLID_T: + { + PAD* pad = static_cast( aItem->Parent() ); + VECTOR2I pos = static_cast( aItem )->Pos(); + + m_fpOffsets[ pad ].p_new = pos; + break; + } + + default: + break; + } +} + + void PNS_KICAD_IFACE_BASE::AddItem( PNS::ITEM* aItem ) { diff --git a/pcbnew/router/pns_kicad_iface.h b/pcbnew/router/pns_kicad_iface.h index cae30f2203..d909b148fc 100644 --- a/pcbnew/router/pns_kicad_iface.h +++ b/pcbnew/router/pns_kicad_iface.h @@ -62,6 +62,7 @@ public: void DisplayItem( const PNS::ITEM* aItem, int aClearance, bool aEdit = false ) override {} void DisplayRatline( const SHAPE_LINE_CHAIN& aRatline, int aColor = -1 ) override {} void AddItem( PNS::ITEM* aItem ) override; + void UpdateItem( PNS::ITEM* aItem ) override; void RemoveItem( PNS::ITEM* aItem ) override; void Commit() override {} bool ImportSizes( PNS::SIZES_SETTINGS& aSizes, PNS::ITEM* aStartItem, int aNet ) override; @@ -120,6 +121,7 @@ public: void DisplayRatline( const SHAPE_LINE_CHAIN& aRatline, int aColor = -1 ) override; void Commit() override; void AddItem( PNS::ITEM* aItem ) override; + void UpdateItem( PNS::ITEM* aItem ) override; void RemoveItem( PNS::ITEM* aItem ) override; void UpdateNet( int aNetCode ) override; diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index f00716c42e..7df980fcb5 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -331,7 +331,7 @@ bool ROUTER::isStartingPointRoutable( const VECTOR2I& aWhere, ITEM* aStartItem, } bool ROUTER::StartRouting( const VECTOR2I& aP, ITEM* aStartItem, int aLayer ) -{ +{ if( !isStartingPointRoutable( aP, aStartItem, aLayer ) ) return false; @@ -558,16 +558,43 @@ void ROUTER::CommitRouting( NODE* aNode ) if( m_state == ROUTE_TRACK && !m_placer->HasPlacedAnything() ) return; - NODE::ITEM_VECTOR removed, added; + NODE::ITEM_VECTOR removed; + NODE::ITEM_VECTOR added; + NODE::ITEM_VECTOR changed; aNode->GetUpdatedItems( removed, added ); for( ITEM* item : removed ) - m_iface->RemoveItem( item ); + { + bool is_changed = false; + + // Items in remove/add that share the same parent are just updated versions + // We move them to the updated vector to preserve attributes such as UUID and pad data + if( item->Parent() ) + { + for( NODE::ITEM_VECTOR::iterator added_it = added.begin(); + added_it != added.end(); ++added_it ) + { + if( ( *added_it )->Parent() && ( *added_it )->Parent() == item->Parent() ) + { + changed.push_back( *added_it ); + added.erase( added_it ); + is_changed = true; + break; + } + } + } + + if( !is_changed ) + m_iface->RemoveItem( item ); + } for( ITEM* item : added ) m_iface->AddItem( item ); + for( ITEM* item : changed ) + m_iface->UpdateItem( item ); + m_iface->Commit(); m_world->Commit( aNode ); } diff --git a/pcbnew/router/pns_router.h b/pcbnew/router/pns_router.h index 5914e9027c..6c49920569 100644 --- a/pcbnew/router/pns_router.h +++ b/pcbnew/router/pns_router.h @@ -97,6 +97,7 @@ enum DRAG_MODE virtual void SyncWorld( NODE* aNode ) = 0; virtual void AddItem( ITEM* aItem ) = 0; + virtual void UpdateItem( ITEM* aItem ) = 0; virtual void RemoveItem( ITEM* aItem ) = 0; virtual bool IsAnyLayerVisible( const LAYER_RANGE& aLayer ) const = 0; virtual bool IsItemVisible( const PNS::ITEM* aItem ) const = 0;