clean.cpp: better code.

This commit is contained in:
jean-pierre charras 2016-09-30 18:33:46 +02:00
parent 9d258ba921
commit 67faa5e656
1 changed files with 134 additions and 87 deletions

View File

@ -58,11 +58,14 @@ public:
* @param aDeleteUnconnected = true to remove dangling tracks * @param aDeleteUnconnected = true to remove dangling tracks
* (short circuits) * (short circuits)
*/ */
bool CleanupBoard( PCB_EDIT_FRAME *aFrame, bool aCleanVias, bool CleanupBoard( bool aCleanVias, bool aRemoveMisConnected,
bool aRemoveMisConnected,
bool aMergeSegments, bool aDeleteUnconnected ); bool aMergeSegments, bool aDeleteUnconnected );
private: private:
/* finds and remove all track segments which are connected to more than one net.
* (short circuits)
*/
bool removeBadTrackSegments();
/** /**
* Removes redundant vias like vias at same location * Removes redundant vias like vias at same location
@ -133,8 +136,17 @@ void PCB_EDIT_FRAME::Clean_Pcb()
wxBusyCursor( dummy ); wxBusyCursor( dummy );
TRACKS_CLEANER cleaner( GetBoard() ); TRACKS_CLEANER cleaner( GetBoard() );
cleaner.CleanupBoard( this, 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 );
if( modified )
{
// Clear undo and redo lists to avoid inconsistencies between lists
GetScreen()->ClearUndoRedoList();
SetCurItem( NULL );
Compile_Ratsnest( NULL, true );
OnModify();
}
// There is a chance that some of tracks have changed their nets, // There is a chance that some of tracks have changed their nets,
// so rebuild ratsnest from scratch // so rebuild ratsnest from scratch
@ -151,12 +163,13 @@ void PCB_EDIT_FRAME::Clean_Pcb()
* - vias on pad * - vias on pad
* - null length segments * - null length segments
*/ */
bool TRACKS_CLEANER::CleanupBoard( PCB_EDIT_FRAME *aFrame, bool TRACKS_CLEANER::CleanupBoard( bool aRemoveMisConnected,
bool aRemoveMisConnected,
bool aCleanVias, bool aCleanVias,
bool aMergeSegments, bool aMergeSegments,
bool aDeleteUnconnected ) bool aDeleteUnconnected )
{ {
buildTrackConnectionInfo();
bool modified = false; bool modified = false;
// delete redundant vias // delete redundant vias
@ -164,31 +177,39 @@ bool TRACKS_CLEANER::CleanupBoard( PCB_EDIT_FRAME *aFrame,
modified |= clean_vias(); modified |= clean_vias();
// Remove null segments and intermediate points on aligned segments // Remove null segments and intermediate points on aligned segments
// If not asked, remove null segments only if remove misconnected is asked
if( aMergeSegments ) if( aMergeSegments )
modified |= clean_segments(); modified |= clean_segments();
else if( aRemoveMisConnected )
modified |= delete_null_segments();
if( aRemoveMisConnected ) if( aRemoveMisConnected )
modified |= aFrame->RemoveMisConnectedTracks();
// Delete dangling tracks
if( aDeleteUnconnected && deleteDanglingTracks() )
{ {
modified = true ; if( removeBadTrackSegments() )
{
modified = true;
// Removed tracks can leave aligned segments // Refresh track connection info
// (when a T was formed by tracks and the "vertical" segment buildTrackConnectionInfo();
// is removed) }
if( aMergeSegments )
clean_segments();
} }
if( modified ) // Delete dangling tracks
if( aDeleteUnconnected )
{ {
// Clear undo and redo lists to avoid inconsistencies between lists if( modified ) // Refresh track connection info
aFrame->GetScreen()->ClearUndoRedoList(); buildTrackConnectionInfo();
aFrame->SetCurItem( NULL );
aFrame->Compile_Ratsnest( NULL, true ); if( deleteDanglingTracks() )
aFrame->OnModify(); {
modified = true ;
// Removed tracks can leave aligned segments
// (when a T was formed by tracks and the "vertical" segment
// is removed)
if( aMergeSegments )
clean_segments();
}
} }
return modified; return modified;
@ -198,9 +219,8 @@ TRACKS_CLEANER::TRACKS_CLEANER( BOARD * aPcb ): CONNECTIONS( aPcb )
{ {
m_Brd = aPcb; m_Brd = aPcb;
// Build connections info // Be sure pad list is up to date
BuildPadsList(); BuildPadsList();
buildTrackConnectionInfo();
} }
void TRACKS_CLEANER::buildTrackConnectionInfo() void TRACKS_CLEANER::buildTrackConnectionInfo()
@ -241,6 +261,79 @@ void TRACKS_CLEANER::buildTrackConnectionInfo()
} }
} }
bool TRACKS_CLEANER::removeBadTrackSegments()
{
// The rastsnet is expected to be up to date (Compile_Ratsnest was called)
// 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 );
// build connections between track segments and pads.
SearchTracksConnectedToPads();
TRACK* segment;
// build connections between track ends
for( segment = m_Brd->m_Track; segment; segment = segment->Next() )
{
SearchConnectedTracks( segment );
GetConnectedTracks( segment );
}
bool isModified = false;
for( segment = m_Brd->m_Track; segment; segment = segment->Next() )
{
segment->SetState( FLAG0, false );
for( unsigned ii = 0; ii < segment->m_PadsConnected.size(); ++ii )
{
if( segment->GetNetCode() != segment->m_PadsConnected[ii]->GetNetCode() )
segment->SetState( FLAG0, true );
}
for( unsigned ii = 0; ii < segment->m_TracksConnected.size(); ++ii )
{
TRACK* tested = segment->m_TracksConnected[ii];
if( segment->GetNetCode() != tested->GetNetCode() && !tested->GetState( FLAG0 ) )
segment->SetState( FLAG0, true );
}
}
// Remove tracks having a flagged segment
TRACK* 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
}
}
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() )
{
segment->m_TracksConnected.clear();
}
m_Brd->m_Status_Pcb = 0;
}
return isModified;
}
bool TRACKS_CLEANER::remove_duplicates_of_via( const VIA *aVia ) bool TRACKS_CLEANER::remove_duplicates_of_via( const VIA *aVia )
{ {
bool modified = false; bool modified = false;
@ -693,75 +786,29 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK*
bool PCB_EDIT_FRAME::RemoveMisConnectedTracks() bool PCB_EDIT_FRAME::RemoveMisConnectedTracks()
{ {
/* finds all track segments which are connected to more than one net. // Old model has to be refreshed, GAL normally does not keep updating it
* When such a bad segment is found, it is flagged.
* All flagged segments are removed.
*/
Compile_Ratsnest( NULL, false ); Compile_Ratsnest( NULL, false );
// Rebuild physical connections. TRACKS_CLEANER cleaner( GetBoard() );
// the list of physical connected items to a given item is in
// m_PadsConnected and m_TracksConnected members of each item
CONNECTIONS connections( GetBoard() );
connections.BuildPadsList();
connections.BuildTracksCandidatesList(GetBoard()->m_Track);
// build connections between track segments and pads. bool isModified = cleaner.CleanupBoard( true, false, false, false );
connections.SearchTracksConnectedToPads();
TRACK* segment;
// build connections between track ends
for( segment = GetBoard()->m_Track; segment; segment = segment->Next() )
{
connections.SearchConnectedTracks( segment );
connections.GetConnectedTracks( segment );
}
bool isModified = false;
for( segment = GetBoard()->m_Track; segment; segment = segment->Next() )
{
segment->SetState( FLAG0, false );
for( unsigned ii = 0; ii < segment->m_PadsConnected.size(); ++ii )
{
if( segment->GetNetCode() != segment->m_PadsConnected[ii]->GetNetCode() )
segment->SetState( FLAG0, true );
}
for( unsigned ii = 0; ii < segment->m_TracksConnected.size(); ++ii )
{
TRACK* tested = segment->m_TracksConnected[ii];
if( segment->GetNetCode() != tested->GetNetCode() && !tested->GetState( FLAG0 ) )
segment->SetState( FLAG0, true );
}
}
// Remove tracks having a flagged segment
TRACK* next;
for( segment = GetBoard()->m_Track; segment; segment = next )
{
next = segment->Next();
if( segment->GetState( FLAG0 ) ) // Segment is flagged to be removed
{
isModified = true;
GetBoard()->m_Status_Pcb = 0;
GetBoard()->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, {
// to avoid any issue // Clear undo and redo lists to avoid inconsistencies between lists
for( segment = GetBoard()->m_Track; segment; segment = segment->Next() ) GetScreen()->ClearUndoRedoList();
{ SetCurItem( NULL );
segment->m_TracksConnected.clear();
} // There is a chance that some of tracks have changed,
// so rebuild ratsnest from scratch
if( IsGalCanvasActive() )
GetBoard()->GetRatsnest()->ProcessBoard();
Compile_Ratsnest( NULL, true );
OnModify();
} }
m_canvas->Refresh( true );
return isModified; return isModified;
} }