Modify TRACKS_CLEANER to use BOARD_COMMIT

This commit is contained in:
Maciej Suminski 2016-11-28 15:31:28 +01:00
parent abb3524563
commit bb1390e2f1
1 changed files with 49 additions and 84 deletions

View File

@ -37,16 +37,15 @@
#include <class_track.h>
#include <connect.h>
#include <dialog_cleaning_options.h>
#include <ratsnest_data.h>
#include <board_commit.h>
#include <tuple>
// Helper class used to clean tracks and vias
class TRACKS_CLEANER: CONNECTIONS
{
private:
BOARD *m_Brd;
public:
TRACKS_CLEANER( BOARD * aPcb );
TRACKS_CLEANER( BOARD* aPcb, BOARD_COMMIT& aCommit );
/**
* the cleanup function.
@ -119,6 +118,10 @@ private:
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 );
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,
dlg.m_mergeSegments, dlg.m_deleteUnconnectedSegm );
@ -143,17 +147,11 @@ void PCB_EDIT_FRAME::Clean_Pcb()
if( modified )
{
// Clear undo and redo lists to avoid inconsistencies between lists
GetScreen()->ClearUndoRedoList();
SetCurItem( NULL );
commit.Push( _( "Board cleanup" ) );
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 );
}
@ -213,13 +211,16 @@ bool TRACKS_CLEANER::CleanupBoard( bool aRemoveMisConnected,
}
}
for( auto track : m_removed )
m_commit.Remove( track );
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
BuildPadsList();
}
@ -227,10 +228,10 @@ TRACKS_CLEANER::TRACKS_CLEANER( BOARD * aPcb ): CONNECTIONS( aPcb )
void TRACKS_CLEANER::buildTrackConnectionInfo()
{
BuildTracksCandidatesList( m_Brd->m_Track, NULL);
BuildTracksCandidatesList( m_brd->m_Track, NULL );
// 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->end = NULL;
@ -271,7 +272,7 @@ bool TRACKS_CLEANER::removeBadTrackSegments()
// Rebuild physical connections.
// the list of physical connected items to a given item is in
// 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.
SearchTracksConnectedToPads();
@ -279,7 +280,7 @@ bool TRACKS_CLEANER::removeBadTrackSegments()
TRACK* segment;
// 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 );
GetConnectedTracks( segment );
@ -287,7 +288,7 @@ bool TRACKS_CLEANER::removeBadTrackSegments()
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 );
@ -308,28 +309,27 @@ bool TRACKS_CLEANER::removeBadTrackSegments()
// Remove tracks having a flagged segment
TRACK* next;
for( segment = m_Brd->m_Track; segment; segment = next )
for( segment = m_brd->m_Track; segment; segment = next )
{
next = segment->Next();
if( segment->GetState( FLAG0 ) ) // Segment is flagged to be removed
{
isModified = true;
segment->ViewRelease();
m_Brd->Remove( segment );
delete segment; // TODO: See if it can be put in undo list
m_removed.insert( segment );
}
}
if( isModified )
{ // some pointers are invalid. Clear the m_TracksConnected list,
// 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();
}
m_Brd->m_Status_Pcb = 0;
m_brd->m_Status_Pcb = 0;
}
return isModified;
@ -341,19 +341,13 @@ bool TRACKS_CLEANER::remove_duplicates_of_via( const VIA *aVia )
bool modified = false;
// Search and delete others vias at same location
VIA* next_via;
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() ) )
{
// delete via
m_Brd->GetRatsnest()->Remove( alt_via );
alt_via->ViewRelease();
alt_via->DeleteStructure();
m_removed.insert( alt_via );
modified = true;
}
}
@ -365,7 +359,7 @@ bool TRACKS_CLEANER::clean_vias()
{
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() ) )
{
// 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 )
{
// redundant: delete the via
m_Brd->GetRatsnest()->Remove( via );
via->ViewRelease();
via->DeleteStructure();
m_removed.insert( via );
modified = true;
break;
}
@ -422,7 +414,7 @@ const ZONE_CONTAINER* TRACKS_CLEANER::zoneForTrackEndpoint( const TRACK* aTrack,
bottom_layer = top_layer;
}
return m_Brd->HitTestForAnyFilledArea( aTrack->GetEndPoint( aEndPoint ),
return m_brd->HitTestForAnyFilledArea( aTrack->GetEndPoint( aEndPoint ),
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
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
if( !other && !zoneForTrackEndpoint( via, aEndPoint ) )
@ -475,7 +467,7 @@ bool TRACKS_CLEANER::testTrackEndpointDangling( TRACK* aTrack, ENDPOINT_T aEndPo
*/
bool TRACKS_CLEANER::deleteDanglingTracks()
{
if( m_Brd->m_Track == NULL )
if( m_brd->m_Track == NULL )
return false;
bool modified = false;
@ -484,12 +476,9 @@ bool TRACKS_CLEANER::deleteDanglingTracks()
do // Iterate when at least one track is deleted
{
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
/* if a track endpoint is not connected to a pad, test if
@ -509,14 +498,9 @@ bool TRACKS_CLEANER::deleteDanglingTracks()
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
* now perhaps is not connected and should be deleted */
item_erased = true;
tie( std::ignore, flag_erase ) = m_removed.insert( track );
modified = true;
}
}
@ -529,19 +513,14 @@ bool TRACKS_CLEANER::deleteDanglingTracks()
// Delete null length track segments
bool TRACKS_CLEANER::delete_null_segments()
{
TRACK *nextsegment;
bool modified = false;
// 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
{
m_Brd->GetRatsnest()->Remove( segment );
segment->ViewRelease();
segment->DeleteStructure();
m_removed.insert( segment );
modified = true;
}
}
@ -554,11 +533,8 @@ bool TRACKS_CLEANER::remove_duplicates_of_track( const TRACK *aTrack )
{
bool modified = false;
TRACK *nextsegment;
for( TRACK *other = aTrack->Next(); other; other = nextsegment )
for( TRACK *other = aTrack->Next(); other; other = other->Next() )
{
nextsegment = other->Next();
// New netcode, break out (can't be there any other)
if( aTrack->GetNetCode() != other->GetNetCode() )
break;
@ -573,9 +549,7 @@ bool TRACKS_CLEANER::remove_duplicates_of_track( const TRACK *aTrack )
( ( aTrack->GetStart() == other->GetEnd() ) &&
( aTrack->GetEnd() == other->GetStart() ) ) )
{
m_Brd->GetRatsnest()->Remove( other );
other->ViewRelease();
other->DeleteStructure();
m_removed.insert( other );
modified = true;
}
}
@ -608,7 +582,7 @@ bool TRACKS_CLEANER::merge_collinear_of_track( TRACK* aSegment )
{
// There can be only one segment connected
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 );
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
if( segDelete )
{
m_Brd->GetRatsnest()->Remove( segDelete );
segDelete->ViewRelease();
segDelete->DeleteStructure();
m_removed.insert( segDelete );
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
// (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 );
// merge collinear segments:
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();
@ -801,24 +773,17 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks()
{
// Old model has to be refreshed, GAL normally does not keep updating it
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 );
if( isModified )
{
// Clear undo and redo lists to avoid inconsistencies between lists
GetScreen()->ClearUndoRedoList();
SetCurItem( NULL );
// There is a chance that some of tracks have changed,
// so rebuild ratsnest from scratch
if( IsGalCanvasActive() )
GetBoard()->GetRatsnest()->ProcessBoard();
commit.Push( _( "Board cleanup" ) );
Compile_Ratsnest( NULL, true );
OnModify();
}
m_canvas->Refresh( true );