Keep item ordering as much as possible

The ordering goes first by type and then by uuid.  In the case of
DRAWSEGMENT and EDGE_MODULE, we also sort by shape type before UUID.

Fixes https://gitlab.com/kicad/code/kicad/issues/4068
This commit is contained in:
Seth Hillbrand 2020-07-24 15:08:36 -07:00
parent 2af6d01fdf
commit 0a5f11fb37
9 changed files with 133 additions and 12 deletions

View File

@ -341,6 +341,11 @@ public:
virtual void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, virtual void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
int aClearanceValue, int aError = ARC_LOW_DEF, bool ignoreLineWidth = false ) const; int aClearanceValue, int aError = ARC_LOW_DEF, bool ignoreLineWidth = false ) const;
struct ptr_cmp
{
bool operator() ( const BOARD_ITEM* a, const BOARD_ITEM* b ) const;
};
protected: protected:
/** /**
* Helper function * Helper function

View File

@ -139,6 +139,17 @@ void BOARD_ITEM::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBu
}; };
bool BOARD_ITEM::ptr_cmp::operator() ( const BOARD_ITEM* a, const BOARD_ITEM* b ) const
{
if( a->Type() != b->Type() )
return a->Type() < b->Type();
if( a->GetLayer() != b->GetLayer() )
return a->GetLayer() < b->GetLayer();
return a->m_Uuid < b->m_Uuid;
}
static struct BOARD_ITEM_DESC static struct BOARD_ITEM_DESC
{ {
BOARD_ITEM_DESC() BOARD_ITEM_DESC()

View File

@ -1178,6 +1178,27 @@ void DRAWSEGMENT::SwapData( BOARD_ITEM* aImage )
} }
bool DRAWSEGMENT::cmp_drawings::operator()( const BOARD_ITEM* aFirst, const BOARD_ITEM* aSecond ) const
{
if( aFirst->Type() != aSecond->Type() )
return aFirst->Type() < aSecond->Type();
if( aFirst->GetLayer() != aSecond->GetLayer() )
return aFirst->GetLayer() < aSecond->GetLayer();
if( aFirst->Type() == PCB_LINE_T )
{
const DRAWSEGMENT* dwgA = static_cast<const DRAWSEGMENT*>( aFirst );
const DRAWSEGMENT* dwgB = static_cast<const DRAWSEGMENT*>( aSecond );
if( dwgA->GetShape() != dwgB->GetShape() )
return dwgA->GetShape() < dwgB->GetShape();
}
return aFirst->m_Uuid < aSecond->m_Uuid;
}
static struct DRAWSEGMENT_DESC static struct DRAWSEGMENT_DESC
{ {
DRAWSEGMENT_DESC() DRAWSEGMENT_DESC()

View File

@ -297,6 +297,11 @@ public:
virtual void SwapData( BOARD_ITEM* aImage ) override; virtual void SwapData( BOARD_ITEM* aImage ) override;
struct cmp_drawings
{
bool operator()( const BOARD_ITEM* aFirst, const BOARD_ITEM* aSecond ) const;
};
#if defined(DEBUG) #if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
#endif #endif

View File

@ -1621,6 +1621,36 @@ bool MODULE::HasNonSMDPins() const
} }
bool MODULE::cmp_drawings::operator()( const BOARD_ITEM* aFirst, const BOARD_ITEM* aSecond ) const
{
if( aFirst->Type() != aSecond->Type() )
return aFirst->Type() < aSecond->Type();
if( aFirst->GetLayer() != aSecond->GetLayer() )
return aFirst->GetLayer() < aSecond->GetLayer();
if( aFirst->Type() == PCB_MODULE_EDGE_T )
{
const EDGE_MODULE* dwgA = static_cast<const EDGE_MODULE*>( aFirst );
const EDGE_MODULE* dwgB = static_cast<const EDGE_MODULE*>( aSecond );
if( dwgA->GetShape() != dwgB->GetShape() )
return dwgA->GetShape() < dwgB->GetShape();
}
return aFirst->m_Uuid < aSecond->m_Uuid;
}
bool MODULE::cmp_pads::operator()( const D_PAD* aFirst, const D_PAD* aSecond ) const
{
if( aFirst->GetName() != aSecond->GetName() )
return StrNumCmp( aFirst->GetName(), aSecond->GetName() ) < 0;
return aFirst->m_Uuid < aSecond->m_Uuid;
}
static struct MODULE_DESC static struct MODULE_DESC
{ {
MODULE_DESC() MODULE_DESC()

View File

@ -680,6 +680,17 @@ public:
virtual void SwapData( BOARD_ITEM* aImage ) override; virtual void SwapData( BOARD_ITEM* aImage ) override;
struct cmp_drawings
{
bool operator()( const BOARD_ITEM* aFirst, const BOARD_ITEM* aSecond ) const;
};
struct cmp_pads
{
bool operator()( const D_PAD* aFirst, const D_PAD* aSecond ) const;
};
#if defined(DEBUG) #if defined(DEBUG)
virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
#endif #endif

View File

@ -939,6 +939,21 @@ double ARC::GetArcAngleEnd() const
} }
bool TRACK::cmp_tracks::operator() ( const TRACK* a, const TRACK* b ) const
{
if( a->GetNetCode() != b->GetNetCode() )
return a->GetNetCode() < b->GetNetCode();
if( a->GetLayer() != b->GetLayer() )
return a->GetLayer() < b->GetLayer();
if( a->Type() != b->Type() )
return a->Type() < b->Type();
return a->m_Uuid < b->m_Uuid;
}
#if defined(DEBUG) #if defined(DEBUG)
wxString TRACK::ShowState( int stateBits ) wxString TRACK::ShowState( int stateBits )

View File

@ -237,6 +237,11 @@ public:
return true; return true;
} }
struct cmp_tracks
{
bool operator()( const TRACK* aFirst, const TRACK* aSecond ) const;
};
#if defined (DEBUG) #if defined (DEBUG)
virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }

View File

@ -601,34 +601,44 @@ void PCB_IO::formatHeader( BOARD* aBoard, int aNestLevel ) const
void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const
{ {
std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_modules( aBoard->Modules().begin(),
aBoard->Modules().end() );
std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_drawings( aBoard->Drawings().begin(),
aBoard->Drawings().end() );
std::set<TRACK*, TRACK::cmp_tracks> sorted_tracks( aBoard->Tracks().begin(),
aBoard->Tracks().end() );
std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_zones( aBoard->Zones().begin(),
aBoard->Zones().end() );
formatHeader( aBoard, aNestLevel ); formatHeader( aBoard, aNestLevel );
// Save the modules. // Save the modules.
for( auto module : aBoard->Modules() ) for( auto module : sorted_modules )
{ {
Format( module, aNestLevel ); Format( module, aNestLevel );
m_out->Print( 0, "\n" ); m_out->Print( 0, "\n" );
} }
// Save the graphical items on the board (not owned by a module) // Save the graphical items on the board (not owned by a module)
for( auto item : aBoard->Drawings() ) for( auto item : sorted_drawings )
Format( item, aNestLevel ); Format( item, aNestLevel );
if( aBoard->Drawings().size() ) if( sorted_drawings.size() )
m_out->Print( 0, "\n" ); m_out->Print( 0, "\n" );
// Do not save MARKER_PCBs, they can be regenerated easily. // Do not save MARKER_PCBs, they can be regenerated easily.
// Save the tracks and vias. // Save the tracks and vias.
for( auto track : aBoard->Tracks() ) for( auto track : sorted_tracks )
Format( track, aNestLevel ); Format( track, aNestLevel );
if( aBoard->Tracks().size() ) if( sorted_tracks.size() )
m_out->Print( 0, "\n" ); m_out->Print( 0, "\n" );
// Save the polygon (which are the newer technology) zones. // Save the polygon (which are the newer technology) zones.
for( int i = 0; i < aBoard->GetAreaCount(); ++i ) for( auto zone : sorted_zones )
Format( aBoard->GetArea( i ), aNestLevel ); Format( zone, aNestLevel );
} }
@ -983,17 +993,25 @@ void PCB_IO::format( MODULE* aModule, int aNestLevel ) const
Format( (BOARD_ITEM*) &aModule->Reference(), aNestLevel+1 ); Format( (BOARD_ITEM*) &aModule->Reference(), aNestLevel+1 );
Format( (BOARD_ITEM*) &aModule->Value(), aNestLevel+1 ); Format( (BOARD_ITEM*) &aModule->Value(), aNestLevel+1 );
std::set<D_PAD*, MODULE::cmp_pads> sorted_pads( aModule->Pads().begin(),
aModule->Pads().end() );
std::set<BOARD_ITEM*, MODULE::cmp_drawings> sorted_drawings( aModule->GraphicalItems().begin(),
aModule->GraphicalItems().end() );
std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_zones( aModule->Zones().begin(),
aModule->Zones().end() );
// Save drawing elements. // Save drawing elements.
for( auto gr : aModule->GraphicalItems() )
for( auto gr : sorted_drawings )
Format( gr, aNestLevel+1 ); Format( gr, aNestLevel+1 );
// Save pads. // Save pads.
for( auto pad : aModule->Pads() ) for( auto pad : sorted_pads )
format( pad, aNestLevel+1 ); Format( pad, aNestLevel+1 );
// Save zones. // Save zones.
for( auto zone : aModule->Zones() ) for( auto zone : sorted_zones )
format( zone, aNestLevel + 1 ); Format( zone, aNestLevel + 1 );
// Save 3D info. // Save 3D info.
auto bs3D = aModule->Models().begin(); auto bs3D = aModule->Models().begin();