diff --git a/include/class_board_item.h b/include/class_board_item.h index 22277e4994..ac3702db6f 100644 --- a/include/class_board_item.h +++ b/include/class_board_item.h @@ -341,6 +341,11 @@ public: virtual void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, 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: /** * Helper function diff --git a/pcbnew/class_board_item.cpp b/pcbnew/class_board_item.cpp index eeeb8e0da3..4f930bfa1b 100644 --- a/pcbnew/class_board_item.cpp +++ b/pcbnew/class_board_item.cpp @@ -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 { BOARD_ITEM_DESC() diff --git a/pcbnew/class_drawsegment.cpp b/pcbnew/class_drawsegment.cpp index f4fe0fdf4e..edeae7fcee 100644 --- a/pcbnew/class_drawsegment.cpp +++ b/pcbnew/class_drawsegment.cpp @@ -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( aFirst ); + const DRAWSEGMENT* dwgB = static_cast( aSecond ); + + if( dwgA->GetShape() != dwgB->GetShape() ) + return dwgA->GetShape() < dwgB->GetShape(); + } + + return aFirst->m_Uuid < aSecond->m_Uuid; +} + + static struct DRAWSEGMENT_DESC { DRAWSEGMENT_DESC() diff --git a/pcbnew/class_drawsegment.h b/pcbnew/class_drawsegment.h index 01f0e45ab5..f2211fc045 100644 --- a/pcbnew/class_drawsegment.h +++ b/pcbnew/class_drawsegment.h @@ -297,6 +297,11 @@ public: virtual void SwapData( BOARD_ITEM* aImage ) override; + struct cmp_drawings + { + bool operator()( const BOARD_ITEM* aFirst, const BOARD_ITEM* aSecond ) const; + }; + #if defined(DEBUG) void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } #endif diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index 4411f796ee..5a8f5babf7 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -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( aFirst ); + const EDGE_MODULE* dwgB = static_cast( 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 { MODULE_DESC() diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h index cf4456d36a..bb17ac7440 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -680,6 +680,17 @@ public: 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) virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } #endif diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index ff557689a2..f485a6f6cb 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -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) wxString TRACK::ShowState( int stateBits ) diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h index f71dc4c5b4..77124fd437 100644 --- a/pcbnew/class_track.h +++ b/pcbnew/class_track.h @@ -237,6 +237,11 @@ public: return true; } + struct cmp_tracks + { + bool operator()( const TRACK* aFirst, const TRACK* aSecond ) const; + }; + #if defined (DEBUG) virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index 6dacd9af6f..442d05ec37 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -601,34 +601,44 @@ void PCB_IO::formatHeader( BOARD* aBoard, int aNestLevel ) const void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const { + + std::set sorted_modules( aBoard->Modules().begin(), + aBoard->Modules().end() ); + std::set sorted_drawings( aBoard->Drawings().begin(), + aBoard->Drawings().end() ); + std::set sorted_tracks( aBoard->Tracks().begin(), + aBoard->Tracks().end() ); + std::set sorted_zones( aBoard->Zones().begin(), + aBoard->Zones().end() ); + formatHeader( aBoard, aNestLevel ); // Save the modules. - for( auto module : aBoard->Modules() ) + for( auto module : sorted_modules ) { Format( module, aNestLevel ); m_out->Print( 0, "\n" ); } // 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 ); - if( aBoard->Drawings().size() ) + if( sorted_drawings.size() ) m_out->Print( 0, "\n" ); // Do not save MARKER_PCBs, they can be regenerated easily. // Save the tracks and vias. - for( auto track : aBoard->Tracks() ) + for( auto track : sorted_tracks ) Format( track, aNestLevel ); - if( aBoard->Tracks().size() ) + if( sorted_tracks.size() ) m_out->Print( 0, "\n" ); // Save the polygon (which are the newer technology) zones. - for( int i = 0; i < aBoard->GetAreaCount(); ++i ) - Format( aBoard->GetArea( i ), aNestLevel ); + for( auto zone : sorted_zones ) + 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->Value(), aNestLevel+1 ); + std::set sorted_pads( aModule->Pads().begin(), + aModule->Pads().end() ); + std::set sorted_drawings( aModule->GraphicalItems().begin(), + aModule->GraphicalItems().end() ); + std::set sorted_zones( aModule->Zones().begin(), + aModule->Zones().end() ); + // Save drawing elements. - for( auto gr : aModule->GraphicalItems() ) + + for( auto gr : sorted_drawings ) Format( gr, aNestLevel+1 ); // Save pads. - for( auto pad : aModule->Pads() ) - format( pad, aNestLevel+1 ); + for( auto pad : sorted_pads ) + Format( pad, aNestLevel+1 ); // Save zones. - for( auto zone : aModule->Zones() ) - format( zone, aNestLevel + 1 ); + for( auto zone : sorted_zones ) + Format( zone, aNestLevel + 1 ); // Save 3D info. auto bs3D = aModule->Models().begin();