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
This commit is contained in:
Seth Hillbrand 2021-02-07 17:06:56 -08:00
parent 356c2d3508
commit 792904557e
4 changed files with 100 additions and 3 deletions

View File

@ -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<PNS::ARC*>( aItem );
ARC* arc_board = static_cast<ARC*>( board_item );
const SHAPE_ARC* arc_shape = static_cast<const SHAPE_ARC*>( 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<PNS::SEGMENT*>( aItem );
TRACK* track = static_cast<TRACK*>( 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<VIA*>( board_item );
PNS::VIA* via = static_cast<PNS::VIA*>( 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<PAD*>( aItem->Parent() );
VECTOR2I pos = static_cast<PNS::SOLID*>( aItem )->Pos();
m_fpOffsets[ pad ].p_new = pos;
break;
}
default:
break;
}
}
void PNS_KICAD_IFACE_BASE::AddItem( PNS::ITEM* aItem )
{

View File

@ -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;

View File

@ -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 )
{
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 );
}

View File

@ -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;