Merge branch 'fix_1553804'

Fixes: lp:1553804
* https://bugs.launchpad.net/kicad/+bug/1553804
This commit is contained in:
Maciej Suminski 2016-11-28 15:51:29 +01:00
commit a95df8463d
5 changed files with 119 additions and 135 deletions

View File

@ -79,7 +79,7 @@ public:
enum RESET_REASON
{
RUN, ///< Tool is invoked after being inactive
MODEL_RELOAD, ///< Model changes
MODEL_RELOAD, ///< Model changes (required full reload)
GAL_SWITCH ///< Rendering engine changes
};

View File

@ -106,6 +106,9 @@ enum TOOL_ACTIONS
// Tool activation event.
TA_ACTIVATE = 0x100000,
// Model has changed (partial update).
TA_MODEL_CHANGE = 0x200000,
TA_ANY = 0xffffffff
};

View File

@ -29,11 +29,11 @@
#include <ratsnest_data.h>
#include <view/view.h>
#include <board_commit.h>
#include <boost/bind.hpp>
#include <tools/pcb_tool.h>
#include <functional>
using namespace std::placeholders;
BOARD_COMMIT::BOARD_COMMIT( PCB_TOOL* aTool )
{
m_toolMgr = aTool->GetManager();
@ -117,7 +117,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
if( boardItem->Type() == PCB_MODULE_T )
{
MODULE* mod = static_cast<MODULE*>( boardItem );
mod->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
mod->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1 ) );
}
}
else
@ -220,7 +220,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
MODULE* module = static_cast<MODULE*>( boardItem );
module->ClearFlags();
module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
module->RunOnChildren( std::bind( &KIGFX::VIEW::Remove, view, _1 ) );
view->Remove( module );
@ -263,6 +263,9 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
if( !m_editModules )
frame->SaveCopyInUndoList( undoList, UR_UNSPECIFIED );
if( TOOL_MANAGER* toolMgr = frame->GetToolManager() )
toolMgr->PostEvent( { TC_MESSAGE, TA_MODEL_CHANGE, AS_GLOBAL } );
ratsnest->Recalculate();
frame->OnModify();
frame->UpdateMsgPanel();
@ -306,7 +309,7 @@ void BOARD_COMMIT::Revert()
if( item->Type() == PCB_MODULE_T )
{
MODULE* oldModule = static_cast<MODULE*>( item );
oldModule->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
oldModule->RunOnChildren( std::bind( &KIGFX::VIEW::Remove, view, _1 ) );
}
view->Remove( item );
@ -317,8 +320,8 @@ void BOARD_COMMIT::Revert()
if( item->Type() == PCB_MODULE_T )
{
MODULE* newModule = static_cast<MODULE*>( item );
newModule->RunOnChildren( boost::bind( &EDA_ITEM::ClearFlags, _1, SELECTED ) );
newModule->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
newModule->RunOnChildren( std::bind( &EDA_ITEM::ClearFlags, _1, SELECTED ) );
newModule->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1 ) );
}
view->Add( item );
@ -330,7 +333,7 @@ void BOARD_COMMIT::Revert()
if( item->Type() == PCB_MODULE_T )
{
MODULE* oldModule = static_cast<MODULE*>( item );
oldModule->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
oldModule->RunOnChildren( std::bind( &KIGFX::VIEW::Remove, view, _1 ) );
}
view->Remove( item );
@ -345,8 +348,8 @@ void BOARD_COMMIT::Revert()
if( item->Type() == PCB_MODULE_T )
{
MODULE* newModule = static_cast<MODULE*>( item );
newModule->RunOnChildren( boost::bind( &EDA_ITEM::ClearFlags, _1, SELECTED ) );
newModule->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
newModule->RunOnChildren( std::bind( &EDA_ITEM::ClearFlags, _1, SELECTED ) );
newModule->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1 ) );
}
view->Add( item );

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.
@ -77,12 +76,12 @@ private:
* Removes all the following THT vias on the same position of the
* specified one
*/
bool remove_duplicates_of_via( const VIA *aVia );
bool remove_duplicates_of_via( const VIA* aVia );
/**
* Removes all the following duplicates tracks of the specified one
*/
bool remove_duplicates_of_track( const TRACK *aTrack );
bool remove_duplicates_of_track( const TRACK* aTrack );
/**
* Removes dangling tracks
@ -93,7 +92,7 @@ private:
bool delete_null_segments();
/// Try to merge the segment to a following collinear one
bool merge_collinear_of_track( TRACK *aSegment );
bool merge_collinear_of_track( TRACK* aSegment );
/**
* Merge collinear segments and remove duplicated and null len segments
@ -115,12 +114,17 @@ private:
TRACK* mergeCollinearSegmentIfPossible( TRACK* aTrackRef,
TRACK* aCandidate, ENDPOINT_T aEndType );
const ZONE_CONTAINER* zoneForTrackEndpoint( const TRACK *aTrack,
const ZONE_CONTAINER* zoneForTrackEndpoint( const TRACK* aTrack,
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;
};
/* Install the cleanup dialog frame to know what should be cleaned
*/
void PCB_EDIT_FRAME::Clean_Pcb()
@ -134,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 );
@ -142,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 );
}
@ -212,23 +211,27 @@ 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();
}
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;
@ -239,7 +242,7 @@ void TRACKS_CLEANER::buildTrackConnectionInfo()
// Build connections info tracks to pads
SearchTracksConnectedToPads();
for( TRACK *track = m_Brd->m_Track; track != NULL; track = track->Next() )
for( TRACK* track = m_brd->m_Track; track != NULL; track = track->Next() )
{
// Mark track if connected to pads
for( unsigned jj = 0; jj < track->m_PadsConnected.size(); jj++ )
@ -269,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();
@ -277,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 );
@ -285,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 );
@ -306,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;
@ -339,30 +341,25 @@ 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()) )
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;
}
}
return modified;
}
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
@ -383,16 +380,13 @@ bool TRACKS_CLEANER::clean_vias()
* if one through pad is found, the via can be removed */
for( unsigned ii = 0; ii < via->m_PadsConnected.size(); ++ii )
{
const D_PAD *pad = via->m_PadsConnected[ii];
const D_PAD* pad = via->m_PadsConnected[ii];
const LSET all_cu = LSET::AllCuMask();
if( (pad->GetLayerSet() & all_cu) == all_cu )
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;
}
@ -403,8 +397,9 @@ bool TRACKS_CLEANER::clean_vias()
return modified;
}
/// Utility for checking if a track/via ends on a zone
const ZONE_CONTAINER* TRACKS_CLEANER::zoneForTrackEndpoint( const TRACK *aTrack,
const ZONE_CONTAINER* TRACKS_CLEANER::zoneForTrackEndpoint( const TRACK* aTrack,
ENDPOINT_T aEndPoint )
{
// Vias are special cased, since they get a layer range, not a single one
@ -419,19 +414,20 @@ 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() );
}
/** Utility: does the endpoint unconnected processed for one endpoint of one track
* Returns true if the track must be deleted, false if not necessarily */
bool TRACKS_CLEANER::testTrackEndpointDangling( TRACK *aTrack, ENDPOINT_T aEndPoint )
bool TRACKS_CLEANER::testTrackEndpointDangling( TRACK* aTrack, ENDPOINT_T aEndPoint )
{
bool flag_erase = false;
TRACK* other = aTrack->GetTrack( m_Brd->m_Track, NULL, aEndPoint, true, false );
TRACK* other = aTrack->GetTrack( m_brd->m_Track, NULL, aEndPoint, true, false );
if( (other == NULL) && (zoneForTrackEndpoint( aTrack, aEndPoint ) == NULL) )
if( !other && !zoneForTrackEndpoint( aTrack, aEndPoint ) )
flag_erase = true; // Start endpoint is neither on pad, zone or other track
else // segment, via or zone connected to this end
{
@ -451,11 +447,10 @@ 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 == NULL) &&
(zoneForTrackEndpoint( via, aEndPoint ) == NULL) )
if( !other && !zoneForTrackEndpoint( via, aEndPoint ) )
flag_erase = true;
aTrack->SetState( BUSY, false );
@ -465,13 +460,14 @@ bool TRACKS_CLEANER::testTrackEndpointDangling( TRACK *aTrack, ENDPOINT_T aEndPo
return flag_erase;
}
/* Delete dangling tracks
* Vias:
* If a via is only connected to a dangling track, it also will be removed
*/
bool TRACKS_CLEANER::deleteDanglingTracks()
{
if( m_Brd->m_Track == NULL )
if( m_brd->m_Track == NULL )
return false;
bool modified = false;
@ -480,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
@ -496,23 +489,18 @@ bool TRACKS_CLEANER::deleteDanglingTracks()
* same layer */
// Check if there is nothing attached on the start
if( !(track->GetState( START_ON_PAD )) )
if( !( track->GetState( START_ON_PAD ) ) )
flag_erase |= testTrackEndpointDangling( track, ENDPOINT_START );
// Check if there is nothing attached on the end
if( !(track->GetState( END_ON_PAD )) )
if( !( track->GetState( END_ON_PAD ) ) )
flag_erase |= testTrackEndpointDangling( track, ENDPOINT_END );
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;
}
}
@ -521,62 +509,57 @@ bool TRACKS_CLEANER::deleteDanglingTracks()
return modified;
}
// 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;
}
}
return modified;
}
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;
// Must be of the same type, on the same layer and the endpoints
// must be the same (maybe swapped)
if( (aTrack->Type() == other->Type()) &&
(aTrack->GetLayer() == other->GetLayer()) )
if( ( aTrack->Type() == other->Type() ) &&
( aTrack->GetLayer() == other->GetLayer() ) )
{
if( ((aTrack->GetStart() == other->GetStart()) &&
(aTrack->GetEnd() == other->GetEnd())) ||
((aTrack->GetStart() == other->GetEnd()) &&
(aTrack->GetEnd() == other->GetStart())))
if( ( ( aTrack->GetStart() == other->GetStart() ) &&
( aTrack->GetEnd() == other->GetEnd() ) ) ||
( ( aTrack->GetStart() == other->GetEnd() ) &&
( aTrack->GetEnd() == other->GetStart() ) ) )
{
m_Brd->GetRatsnest()->Remove( other );
other->ViewRelease();
other->DeleteStructure();
m_removed.insert( other );
modified = true;
}
}
}
return modified;
}
bool TRACKS_CLEANER::merge_collinear_of_track( TRACK *aSegment )
bool TRACKS_CLEANER::merge_collinear_of_track( TRACK* aSegment )
{
bool merged_this = false;
@ -584,7 +567,8 @@ bool TRACKS_CLEANER::merge_collinear_of_track( TRACK *aSegment )
endpoint = ENDPOINT_T( endpoint + 1 ) )
{
// search for a possible segment connected to the current endpoint of the current one
TRACK *other = aSegment->Next();
TRACK* other = aSegment->Next();
if( other )
{
other = aSegment->GetTrack( other, NULL, endpoint, true, false );
@ -593,27 +577,25 @@ bool TRACKS_CLEANER::merge_collinear_of_track( TRACK *aSegment )
{
// the two segments must have the same width and the other
// cannot be a via
if( (aSegment->GetWidth() == other->GetWidth()) &&
if( ( aSegment->GetWidth() == other->GetWidth() ) &&
(other->Type() == PCB_TRACE_T) )
{
// 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 );
if( !yet_another )
{
// Try to merge them
TRACK *segDelete = mergeCollinearSegmentIfPossible( aSegment,
TRACK* segDelete = mergeCollinearSegmentIfPossible( aSegment,
other, endpoint );
// 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;
}
}
@ -625,6 +607,7 @@ bool TRACKS_CLEANER::merge_collinear_of_track( TRACK *aSegment )
return merged_this;
}
// Delete null length segments, and intermediate points ..
bool TRACKS_CLEANER::clean_segments()
{
@ -635,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;
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();
@ -660,6 +643,7 @@ bool TRACKS_CLEANER::clean_segments()
return modified;
}
/* Utility: check for parallelism between two segments */
static bool parallelism_test( int dx1, int dy1, int dx2, int dy2 )
{
@ -687,6 +671,7 @@ static bool parallelism_test( int dx1, int dy1, int dx2, int dy2 )
return ((double)dy1 * dx2 == (double)dx1 * dy2);
}
/** Function used by clean_segments.
* Test if aTrackRef and aCandidate (which must have a common end) are collinear.
* and see if the common point is not on a pad (i.e. if this common point can be removed).
@ -703,9 +688,9 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK*
ENDPOINT_T aEndType )
{
// First of all, they must be of the same width and must be both actual tracks
if( (aTrackRef->GetWidth() != aCandidate->GetWidth()) ||
(aTrackRef->Type() != PCB_TRACE_T) ||
(aCandidate->Type() != PCB_TRACE_T) )
if( ( aTrackRef->GetWidth() != aCandidate->GetWidth() ) ||
( aTrackRef->Type() != PCB_TRACE_T ) ||
( aCandidate->Type() != PCB_TRACE_T ) )
return NULL;
// Trivial case: exactly the same track
@ -732,16 +717,16 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK*
if( aEndType == ENDPOINT_START )
{
// We do not have a pad, which is a always terminal point for a track
if( aTrackRef->GetState( START_ON_PAD) )
if( aTrackRef->GetState( START_ON_PAD ) )
return NULL;
/* change the common point coordinate of pt_segm to use the other point
* of pt_segm (pt_segm will be removed later) */
if( aTrackRef->GetStart() == aCandidate->GetStart() )
{
aTrackRef->SetStart( aCandidate->GetEnd());
aTrackRef->SetStart( aCandidate->GetEnd() );
aTrackRef->start = aCandidate->end;
aTrackRef->SetState( START_ON_PAD, aCandidate->GetState( END_ON_PAD) );
aTrackRef->SetState( START_ON_PAD, aCandidate->GetState( END_ON_PAD ) );
aTrackRef->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
return aCandidate;
}
@ -749,7 +734,7 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK*
{
aTrackRef->SetStart( aCandidate->GetStart() );
aTrackRef->start = aCandidate->start;
aTrackRef->SetState( START_ON_PAD, aCandidate->GetState( START_ON_PAD) );
aTrackRef->SetState( START_ON_PAD, aCandidate->GetState( START_ON_PAD ) );
aTrackRef->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
return aCandidate;
}
@ -757,7 +742,7 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK*
else // aEndType == END
{
// We do not have a pad, which is a always terminal point for a track
if( aTrackRef->GetState( END_ON_PAD) )
if( aTrackRef->GetState( END_ON_PAD ) )
return NULL;
/* change the common point coordinate of pt_segm to use the other point
@ -766,7 +751,7 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK*
{
aTrackRef->SetEnd( aCandidate->GetEnd() );
aTrackRef->end = aCandidate->end;
aTrackRef->SetState( END_ON_PAD, aCandidate->GetState( END_ON_PAD) );
aTrackRef->SetState( END_ON_PAD, aCandidate->GetState( END_ON_PAD ) );
aTrackRef->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
return aCandidate;
}
@ -774,7 +759,7 @@ TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK*
{
aTrackRef->SetEnd( aCandidate->GetStart() );
aTrackRef->end = aCandidate->start;
aTrackRef->SetState( END_ON_PAD, aCandidate->GetState( START_ON_PAD) );
aTrackRef->SetState( END_ON_PAD, aCandidate->GetState( START_ON_PAD ) );
aTrackRef->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
return aCandidate;
}
@ -788,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 );

View File

@ -693,7 +693,7 @@ int ROUTER_TOOL::mainLoop( PNS::ROUTER_MODE aMode )
{
m_router->ClearWorld();
}
else if( evt->Action() == TA_UNDO_REDO_POST )
else if( evt->Action() == TA_UNDO_REDO_POST || evt->Action() == TA_MODEL_CHANGE )
{
m_router->SyncWorld();
}