Modify TRACKS_CLEANER to use BOARD_COMMIT
This commit is contained in:
parent
abb3524563
commit
bb1390e2f1
133
pcbnew/clean.cpp
133
pcbnew/clean.cpp
|
@ -37,16 +37,15 @@
|
||||||
#include <class_track.h>
|
#include <class_track.h>
|
||||||
#include <connect.h>
|
#include <connect.h>
|
||||||
#include <dialog_cleaning_options.h>
|
#include <dialog_cleaning_options.h>
|
||||||
#include <ratsnest_data.h>
|
#include <board_commit.h>
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
// Helper class used to clean tracks and vias
|
// Helper class used to clean tracks and vias
|
||||||
class TRACKS_CLEANER: CONNECTIONS
|
class TRACKS_CLEANER: CONNECTIONS
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
BOARD *m_Brd;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TRACKS_CLEANER( BOARD * aPcb );
|
TRACKS_CLEANER( BOARD* aPcb, BOARD_COMMIT& aCommit );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the cleanup function.
|
* the cleanup function.
|
||||||
|
@ -119,6 +118,10 @@ private:
|
||||||
ENDPOINT_T aEndPoint );
|
ENDPOINT_T aEndPoint );
|
||||||
|
|
||||||
bool testTrackEndpointDangling( TRACK* aTrack, ENDPOINT_T aEndPoint );
|
bool testTrackEndpointDangling( TRACK* aTrack, ENDPOINT_T aEndPoint );
|
||||||
|
|
||||||
|
BOARD* m_brd;
|
||||||
|
BOARD_COMMIT& m_commit;
|
||||||
|
std::set<TRACK*> m_removed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -135,7 +138,8 @@ void PCB_EDIT_FRAME::Clean_Pcb()
|
||||||
Compile_Ratsnest( NULL, false );
|
Compile_Ratsnest( NULL, false );
|
||||||
|
|
||||||
wxBusyCursor( dummy );
|
wxBusyCursor( dummy );
|
||||||
TRACKS_CLEANER cleaner( GetBoard() );
|
BOARD_COMMIT commit( this );
|
||||||
|
TRACKS_CLEANER cleaner( GetBoard(), commit );
|
||||||
|
|
||||||
bool modified = cleaner.CleanupBoard( dlg.m_deleteShortCircuits, dlg.m_cleanVias,
|
bool modified = cleaner.CleanupBoard( dlg.m_deleteShortCircuits, dlg.m_cleanVias,
|
||||||
dlg.m_mergeSegments, dlg.m_deleteUnconnectedSegm );
|
dlg.m_mergeSegments, dlg.m_deleteUnconnectedSegm );
|
||||||
|
@ -143,17 +147,11 @@ void PCB_EDIT_FRAME::Clean_Pcb()
|
||||||
if( modified )
|
if( modified )
|
||||||
{
|
{
|
||||||
// Clear undo and redo lists to avoid inconsistencies between lists
|
// Clear undo and redo lists to avoid inconsistencies between lists
|
||||||
GetScreen()->ClearUndoRedoList();
|
|
||||||
SetCurItem( NULL );
|
SetCurItem( NULL );
|
||||||
|
commit.Push( _( "Board cleanup" ) );
|
||||||
Compile_Ratsnest( NULL, true );
|
Compile_Ratsnest( NULL, true );
|
||||||
OnModify();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// There is a chance that some of tracks have changed their nets,
|
|
||||||
// so rebuild ratsnest from scratch
|
|
||||||
if( IsGalCanvasActive() )
|
|
||||||
GetBoard()->GetRatsnest()->ProcessBoard();
|
|
||||||
|
|
||||||
m_canvas->Refresh( true );
|
m_canvas->Refresh( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,13 +211,16 @@ bool TRACKS_CLEANER::CleanupBoard( bool aRemoveMisConnected,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for( auto track : m_removed )
|
||||||
|
m_commit.Remove( track );
|
||||||
|
|
||||||
return modified;
|
return modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACKS_CLEANER::TRACKS_CLEANER( BOARD * aPcb ): CONNECTIONS( aPcb )
|
|
||||||
{
|
|
||||||
m_Brd = aPcb;
|
|
||||||
|
|
||||||
|
TRACKS_CLEANER::TRACKS_CLEANER( BOARD* aPcb, BOARD_COMMIT& aCommit )
|
||||||
|
: CONNECTIONS( aPcb ), m_brd( aPcb ), m_commit( aCommit )
|
||||||
|
{
|
||||||
// Be sure pad list is up to date
|
// Be sure pad list is up to date
|
||||||
BuildPadsList();
|
BuildPadsList();
|
||||||
}
|
}
|
||||||
|
@ -227,10 +228,10 @@ TRACKS_CLEANER::TRACKS_CLEANER( BOARD * aPcb ): CONNECTIONS( aPcb )
|
||||||
|
|
||||||
void TRACKS_CLEANER::buildTrackConnectionInfo()
|
void TRACKS_CLEANER::buildTrackConnectionInfo()
|
||||||
{
|
{
|
||||||
BuildTracksCandidatesList( m_Brd->m_Track, NULL);
|
BuildTracksCandidatesList( m_brd->m_Track, NULL );
|
||||||
|
|
||||||
// clear flags and variables used in cleanup
|
// clear flags and variables used in cleanup
|
||||||
for( TRACK *track = m_Brd->m_Track; track != NULL; track = track->Next() )
|
for( TRACK* track = m_brd->m_Track; track != NULL; track = track->Next() )
|
||||||
{
|
{
|
||||||
track->start = NULL;
|
track->start = NULL;
|
||||||
track->end = NULL;
|
track->end = NULL;
|
||||||
|
@ -271,7 +272,7 @@ bool TRACKS_CLEANER::removeBadTrackSegments()
|
||||||
// Rebuild physical connections.
|
// Rebuild physical connections.
|
||||||
// the list of physical connected items to a given item is in
|
// the list of physical connected items to a given item is in
|
||||||
// m_PadsConnected and m_TracksConnected members of each item
|
// m_PadsConnected and m_TracksConnected members of each item
|
||||||
BuildTracksCandidatesList( m_Brd->m_Track );
|
BuildTracksCandidatesList( m_brd->m_Track );
|
||||||
|
|
||||||
// build connections between track segments and pads.
|
// build connections between track segments and pads.
|
||||||
SearchTracksConnectedToPads();
|
SearchTracksConnectedToPads();
|
||||||
|
@ -279,7 +280,7 @@ bool TRACKS_CLEANER::removeBadTrackSegments()
|
||||||
TRACK* segment;
|
TRACK* segment;
|
||||||
|
|
||||||
// build connections between track ends
|
// build connections between track ends
|
||||||
for( segment = m_Brd->m_Track; segment; segment = segment->Next() )
|
for( segment = m_brd->m_Track; segment; segment = segment->Next() )
|
||||||
{
|
{
|
||||||
SearchConnectedTracks( segment );
|
SearchConnectedTracks( segment );
|
||||||
GetConnectedTracks( segment );
|
GetConnectedTracks( segment );
|
||||||
|
@ -287,7 +288,7 @@ bool TRACKS_CLEANER::removeBadTrackSegments()
|
||||||
|
|
||||||
bool isModified = false;
|
bool isModified = false;
|
||||||
|
|
||||||
for( segment = m_Brd->m_Track; segment; segment = segment->Next() )
|
for( segment = m_brd->m_Track; segment; segment = segment->Next() )
|
||||||
{
|
{
|
||||||
segment->SetState( FLAG0, false );
|
segment->SetState( FLAG0, false );
|
||||||
|
|
||||||
|
@ -308,28 +309,27 @@ bool TRACKS_CLEANER::removeBadTrackSegments()
|
||||||
|
|
||||||
// Remove tracks having a flagged segment
|
// Remove tracks having a flagged segment
|
||||||
TRACK* next;
|
TRACK* next;
|
||||||
for( segment = m_Brd->m_Track; segment; segment = next )
|
|
||||||
|
for( segment = m_brd->m_Track; segment; segment = next )
|
||||||
{
|
{
|
||||||
next = segment->Next();
|
next = segment->Next();
|
||||||
|
|
||||||
if( segment->GetState( FLAG0 ) ) // Segment is flagged to be removed
|
if( segment->GetState( FLAG0 ) ) // Segment is flagged to be removed
|
||||||
{
|
{
|
||||||
isModified = true;
|
isModified = true;
|
||||||
segment->ViewRelease();
|
m_removed.insert( segment );
|
||||||
m_Brd->Remove( segment );
|
|
||||||
delete segment; // TODO: See if it can be put in undo list
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( isModified )
|
if( isModified )
|
||||||
{ // some pointers are invalid. Clear the m_TracksConnected list,
|
{ // some pointers are invalid. Clear the m_TracksConnected list,
|
||||||
// to avoid any issue
|
// to avoid any issue
|
||||||
for( segment = m_Brd->m_Track; segment; segment = segment->Next() )
|
for( segment = m_brd->m_Track; segment; segment = segment->Next() )
|
||||||
{
|
{
|
||||||
segment->m_TracksConnected.clear();
|
segment->m_TracksConnected.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Brd->m_Status_Pcb = 0;
|
m_brd->m_Status_Pcb = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return isModified;
|
return isModified;
|
||||||
|
@ -341,19 +341,13 @@ bool TRACKS_CLEANER::remove_duplicates_of_via( const VIA *aVia )
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
|
|
||||||
// Search and delete others vias at same location
|
// Search and delete others vias at same location
|
||||||
VIA* next_via;
|
|
||||||
for( VIA* alt_via = GetFirstVia( aVia->Next() ); alt_via != NULL;
|
for( VIA* alt_via = GetFirstVia( aVia->Next() ); alt_via != NULL;
|
||||||
alt_via = next_via )
|
alt_via = GetFirstVia( alt_via->Next() ) )
|
||||||
{
|
{
|
||||||
next_via = GetFirstVia( alt_via->Next() );
|
if( ( alt_via->GetViaType() == VIA_THROUGH ) &&
|
||||||
|
( alt_via->GetStart() == aVia->GetStart() ) )
|
||||||
if( (alt_via->GetViaType() == VIA_THROUGH) &&
|
|
||||||
(alt_via->GetStart() == aVia->GetStart()) )
|
|
||||||
{
|
{
|
||||||
// delete via
|
m_removed.insert( alt_via );
|
||||||
m_Brd->GetRatsnest()->Remove( alt_via );
|
|
||||||
alt_via->ViewRelease();
|
|
||||||
alt_via->DeleteStructure();
|
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -365,7 +359,7 @@ bool TRACKS_CLEANER::clean_vias()
|
||||||
{
|
{
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
|
|
||||||
for( VIA* via = GetFirstVia( m_Brd->m_Track ); via != NULL;
|
for( VIA* via = GetFirstVia( m_brd->m_Track ); via != NULL;
|
||||||
via = GetFirstVia( via->Next() ) )
|
via = GetFirstVia( via->Next() ) )
|
||||||
{
|
{
|
||||||
// Correct via m_End defects (if any), should never happen
|
// Correct via m_End defects (if any), should never happen
|
||||||
|
@ -392,9 +386,7 @@ bool TRACKS_CLEANER::clean_vias()
|
||||||
if( ( pad->GetLayerSet() & all_cu ) == all_cu )
|
if( ( pad->GetLayerSet() & all_cu ) == all_cu )
|
||||||
{
|
{
|
||||||
// redundant: delete the via
|
// redundant: delete the via
|
||||||
m_Brd->GetRatsnest()->Remove( via );
|
m_removed.insert( via );
|
||||||
via->ViewRelease();
|
|
||||||
via->DeleteStructure();
|
|
||||||
modified = true;
|
modified = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -422,7 +414,7 @@ const ZONE_CONTAINER* TRACKS_CLEANER::zoneForTrackEndpoint( const TRACK* aTrack,
|
||||||
bottom_layer = top_layer;
|
bottom_layer = top_layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_Brd->HitTestForAnyFilledArea( aTrack->GetEndPoint( aEndPoint ),
|
return m_brd->HitTestForAnyFilledArea( aTrack->GetEndPoint( aEndPoint ),
|
||||||
top_layer, bottom_layer, aTrack->GetNetCode() );
|
top_layer, bottom_layer, aTrack->GetNetCode() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,7 +447,7 @@ bool TRACKS_CLEANER::testTrackEndpointDangling( TRACK* aTrack, ENDPOINT_T aEndPo
|
||||||
// search for another segment following the via
|
// search for another segment following the via
|
||||||
aTrack->SetState( BUSY, true );
|
aTrack->SetState( BUSY, true );
|
||||||
|
|
||||||
other = via->GetTrack( m_Brd->m_Track, NULL, aEndPoint, true, false );
|
other = via->GetTrack( m_brd->m_Track, NULL, aEndPoint, true, false );
|
||||||
|
|
||||||
// There is a via on the start but it goes nowhere
|
// There is a via on the start but it goes nowhere
|
||||||
if( !other && !zoneForTrackEndpoint( via, aEndPoint ) )
|
if( !other && !zoneForTrackEndpoint( via, aEndPoint ) )
|
||||||
|
@ -475,7 +467,7 @@ bool TRACKS_CLEANER::testTrackEndpointDangling( TRACK* aTrack, ENDPOINT_T aEndPo
|
||||||
*/
|
*/
|
||||||
bool TRACKS_CLEANER::deleteDanglingTracks()
|
bool TRACKS_CLEANER::deleteDanglingTracks()
|
||||||
{
|
{
|
||||||
if( m_Brd->m_Track == NULL )
|
if( m_brd->m_Track == NULL )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
|
@ -484,12 +476,9 @@ bool TRACKS_CLEANER::deleteDanglingTracks()
|
||||||
do // Iterate when at least one track is deleted
|
do // Iterate when at least one track is deleted
|
||||||
{
|
{
|
||||||
item_erased = false;
|
item_erased = false;
|
||||||
TRACK* next_track;
|
|
||||||
|
|
||||||
for( TRACK *track = m_Brd->m_Track; track != NULL; track = next_track )
|
for( TRACK* track = m_brd->m_Track; track != NULL; track = track->Next() )
|
||||||
{
|
{
|
||||||
next_track = track->Next();
|
|
||||||
|
|
||||||
bool flag_erase = false; // Start without a good reason to erase it
|
bool flag_erase = false; // Start without a good reason to erase it
|
||||||
|
|
||||||
/* if a track endpoint is not connected to a pad, test if
|
/* if a track endpoint is not connected to a pad, test if
|
||||||
|
@ -509,14 +498,9 @@ bool TRACKS_CLEANER::deleteDanglingTracks()
|
||||||
|
|
||||||
if( flag_erase )
|
if( flag_erase )
|
||||||
{
|
{
|
||||||
// remove segment from board
|
|
||||||
m_Brd->GetRatsnest()->Remove( track );
|
|
||||||
track->ViewRelease();
|
|
||||||
track->DeleteStructure();
|
|
||||||
|
|
||||||
/* keep iterating, because a track connected to the deleted track
|
/* keep iterating, because a track connected to the deleted track
|
||||||
* now perhaps is not connected and should be deleted */
|
* now perhaps is not connected and should be deleted */
|
||||||
item_erased = true;
|
tie( std::ignore, flag_erase ) = m_removed.insert( track );
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -529,19 +513,14 @@ bool TRACKS_CLEANER::deleteDanglingTracks()
|
||||||
// Delete null length track segments
|
// Delete null length track segments
|
||||||
bool TRACKS_CLEANER::delete_null_segments()
|
bool TRACKS_CLEANER::delete_null_segments()
|
||||||
{
|
{
|
||||||
TRACK *nextsegment;
|
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
|
|
||||||
// Delete null segments
|
// Delete null segments
|
||||||
for( TRACK *segment = m_Brd->m_Track; segment; segment = nextsegment )
|
for( TRACK* segment = m_brd->m_Track; segment; segment = segment->Next() )
|
||||||
{
|
{
|
||||||
nextsegment = segment->Next();
|
|
||||||
|
|
||||||
if( segment->IsNull() ) // Length segment = 0; delete it
|
if( segment->IsNull() ) // Length segment = 0; delete it
|
||||||
{
|
{
|
||||||
m_Brd->GetRatsnest()->Remove( segment );
|
m_removed.insert( segment );
|
||||||
segment->ViewRelease();
|
|
||||||
segment->DeleteStructure();
|
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -554,11 +533,8 @@ bool TRACKS_CLEANER::remove_duplicates_of_track( const TRACK *aTrack )
|
||||||
{
|
{
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
|
|
||||||
TRACK *nextsegment;
|
for( TRACK *other = aTrack->Next(); other; other = other->Next() )
|
||||||
for( TRACK *other = aTrack->Next(); other; other = nextsegment )
|
|
||||||
{
|
{
|
||||||
nextsegment = other->Next();
|
|
||||||
|
|
||||||
// New netcode, break out (can't be there any other)
|
// New netcode, break out (can't be there any other)
|
||||||
if( aTrack->GetNetCode() != other->GetNetCode() )
|
if( aTrack->GetNetCode() != other->GetNetCode() )
|
||||||
break;
|
break;
|
||||||
|
@ -573,9 +549,7 @@ bool TRACKS_CLEANER::remove_duplicates_of_track( const TRACK *aTrack )
|
||||||
( ( aTrack->GetStart() == other->GetEnd() ) &&
|
( ( aTrack->GetStart() == other->GetEnd() ) &&
|
||||||
( aTrack->GetEnd() == other->GetStart() ) ) )
|
( aTrack->GetEnd() == other->GetStart() ) ) )
|
||||||
{
|
{
|
||||||
m_Brd->GetRatsnest()->Remove( other );
|
m_removed.insert( other );
|
||||||
other->ViewRelease();
|
|
||||||
other->DeleteStructure();
|
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -608,7 +582,7 @@ bool TRACKS_CLEANER::merge_collinear_of_track( TRACK* aSegment )
|
||||||
{
|
{
|
||||||
// There can be only one segment connected
|
// There can be only one segment connected
|
||||||
other->SetState( BUSY, true );
|
other->SetState( BUSY, true );
|
||||||
TRACK *yet_another = aSegment->GetTrack( m_Brd->m_Track, NULL,
|
TRACK* yet_another = aSegment->GetTrack( m_brd->m_Track, NULL,
|
||||||
endpoint, true, false );
|
endpoint, true, false );
|
||||||
other->SetState( BUSY, false );
|
other->SetState( BUSY, false );
|
||||||
|
|
||||||
|
@ -621,9 +595,7 @@ bool TRACKS_CLEANER::merge_collinear_of_track( TRACK* aSegment )
|
||||||
// Merge succesful, the other one has to go away
|
// Merge succesful, the other one has to go away
|
||||||
if( segDelete )
|
if( segDelete )
|
||||||
{
|
{
|
||||||
m_Brd->GetRatsnest()->Remove( segDelete );
|
m_removed.insert( segDelete );
|
||||||
segDelete->ViewRelease();
|
|
||||||
segDelete->DeleteStructure();
|
|
||||||
merged_this = true;
|
merged_this = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -646,13 +618,13 @@ bool TRACKS_CLEANER::clean_segments()
|
||||||
|
|
||||||
// Delete redundant segments, i.e. segments having the same end points and layers
|
// Delete redundant segments, i.e. segments having the same end points and layers
|
||||||
// (can happens when blocks are copied on themselve)
|
// (can happens when blocks are copied on themselve)
|
||||||
for( TRACK *segment = m_Brd->m_Track; segment; segment = segment->Next() )
|
for( TRACK* segment = m_brd->m_Track; segment; segment = segment->Next() )
|
||||||
modified |= remove_duplicates_of_track( segment );
|
modified |= remove_duplicates_of_track( segment );
|
||||||
|
|
||||||
// merge collinear segments:
|
// merge collinear segments:
|
||||||
TRACK* nextsegment;
|
TRACK* nextsegment;
|
||||||
|
|
||||||
for( TRACK *segment = m_Brd->m_Track; segment; segment = nextsegment )
|
for( TRACK* segment = m_brd->m_Track; segment; segment = nextsegment )
|
||||||
{
|
{
|
||||||
nextsegment = segment->Next();
|
nextsegment = segment->Next();
|
||||||
|
|
||||||
|
@ -801,24 +773,17 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks()
|
||||||
{
|
{
|
||||||
// Old model has to be refreshed, GAL normally does not keep updating it
|
// Old model has to be refreshed, GAL normally does not keep updating it
|
||||||
Compile_Ratsnest( NULL, false );
|
Compile_Ratsnest( NULL, false );
|
||||||
|
BOARD_COMMIT commit( this );
|
||||||
|
|
||||||
TRACKS_CLEANER cleaner( GetBoard() );
|
TRACKS_CLEANER cleaner( GetBoard(), commit );
|
||||||
|
|
||||||
bool isModified = cleaner.CleanupBoard( true, false, false, false );
|
bool isModified = cleaner.CleanupBoard( true, false, false, false );
|
||||||
|
|
||||||
if( isModified )
|
if( isModified )
|
||||||
{
|
{
|
||||||
// Clear undo and redo lists to avoid inconsistencies between lists
|
// Clear undo and redo lists to avoid inconsistencies between lists
|
||||||
GetScreen()->ClearUndoRedoList();
|
|
||||||
SetCurItem( NULL );
|
SetCurItem( NULL );
|
||||||
|
commit.Push( _( "Board cleanup" ) );
|
||||||
// There is a chance that some of tracks have changed,
|
|
||||||
// so rebuild ratsnest from scratch
|
|
||||||
if( IsGalCanvasActive() )
|
|
||||||
GetBoard()->GetRatsnest()->ProcessBoard();
|
|
||||||
|
|
||||||
Compile_Ratsnest( NULL, true );
|
Compile_Ratsnest( NULL, true );
|
||||||
OnModify();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_canvas->Refresh( true );
|
m_canvas->Refresh( true );
|
||||||
|
|
Loading…
Reference in New Issue