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;