PCB_EDIT_FRAME::EraseRedundantTrack() Fix incorrect detection of the new trace boundaries in a specific case.

It happens if the first segment of the new trace is inside a pad: the other segments are not found.
And the erased trace is not the right trace.

However this fix is more a workaround than a fix: currently the detection of the trace boundaries (BOARD::MarkTrace())
does not work very well for segments inside a pad.

Fixes: lp:1776121
https://bugs.launchpad.net/kicad/+bug/1776121
This commit is contained in:
jean-pierre charras 2018-06-12 10:05:12 +02:00
parent 4186626069
commit 5d276a43f6
3 changed files with 32 additions and 58 deletions

View File

@ -416,6 +416,7 @@ void BOARD::chainMarkedSegments( wxPoint aPosition, const LSET& aLayerSet, TRACK
if( !pad )
pad = GetPad( aPosition, layer_set );
if( pad )
distanceToPadCenter = GetLineLength( aPosition, pad->GetCenter() );
@ -431,7 +432,6 @@ void BOARD::chainMarkedSegments( wxPoint aPosition, const LSET& aLayerSet, TRACK
if( via )
{
layer_set = via->GetLayerSet();
aList->push_back( via );
}
@ -492,6 +492,7 @@ void BOARD::chainMarkedSegments( wxPoint aPosition, const LSET& aLayerSet, TRACK
{
if( GetPad( aPosition, layer_set ) != pad )
return;
if( GetLineLength( aPosition, pad->GetCenter() ) > distanceToPadCenter )
return;
}
@ -1811,29 +1812,6 @@ TRACK* BOARD::GetVisibleTrack( TRACK* aStartingTrace, const wxPoint& aPosition,
}
#if defined(DEBUG) && 0
static void dump_tracks( const char* aName, const TRACKS& aList )
{
printf( "%s: count=%zd\n", aName, aList.size() );
for( unsigned i = 0; i < aList.size(); ++i )
{
TRACK* seg = aList[i];
::VIA* via = dynamic_cast< ::VIA* >( seg );
if( via )
printf( " via[%u]: (%d, %d)\n", i, via->GetStart().x, via->GetStart().y );
else
printf( " seg[%u]: (%d, %d) (%d, %d)\n", i,
seg->GetStart().x, seg->GetStart().y,
seg->GetEnd().x, seg->GetEnd().y );
}
}
#endif
TRACK* BOARD::MarkTrace( TRACK* aTrace, int* aCount,
double* aTraceLength, double* aPadToDieLength,
bool aReorder )

View File

@ -249,15 +249,14 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC,
TRACK* StartTrack, * EndTrack;
TRACK* pt_segm;
TRACK* pt_del;
int ii, jj, nb_segm, nbconnect;
int nb_segm, nbconnect;
wxPoint start;
wxPoint end;
LSET startmasklayer, endmasklayer;
int netcode = aNewTrack->GetNetCode();
/* Reconstruct the complete track (the new track has to start on a segment of track).
*/
// Reconstruct the complete track (the new track has to start on a segment of track).
// Note: aNewTrackSegmentsCount conatins the number of new track segments
ListSetState( aNewTrack, aNewTrackSegmentsCount, BUSY, false );
/* If the new track begins with a via, complete the track segment using
@ -267,28 +266,30 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC,
if( aNewTrack->Type() == PCB_VIA_T && ( aNewTrackSegmentsCount > 1 ) )
aNewTrack = aNewTrack->Next();
aNewTrack = GetBoard()->MarkTrace( aNewTrack, &aNewTrackSegmentsCount, NULL, NULL, true );
wxASSERT( aNewTrack );
// When MarkTrace try to find the entire track, if the starting segment
// is fully inside a pad, MarkTrace does not find correctly the full trace,
// because the entire track is the set of segments between 2 nodes
// (pads or point connecting more than 2 items)
// so use an other (better) starting segment in this case
TRACK* track_segment = aNewTrack;
#if 0 && defined(DEBUG)
TRACK* EndNewTrack; // The last segment of the list chained to the track
EndNewTrack = aNewTrack;
for( ii = 1; ii < aNewTrackSegmentsCount; ii++ )
for( int ii = 0; ii < aNewTrackSegmentsCount; ii++ )
{
wxASSERT( EndNewTrack->GetState( -1 ) != 0 );
D( printf( "track %p is newly part of net %d\n", EndNewTrack, netcode ); )
EndNewTrack = EndNewTrack->Next();
D_PAD* pad_st = m_Pcb->GetPad( aNewTrack->GetStart() );
D_PAD* pad_end = m_Pcb->GetPad( aNewTrack->GetEnd() );
if( pad_st && pad_st == pad_end )
track_segment = aNewTrack->Next();
else
break;
}
wxASSERT( EndNewTrack->GetState( -1 ) != 0 );
D( printf( "track %p is newly part of net %d\n", EndNewTrack, netcode ); )
for( TRACK* track = m_Pcb->m_Track; track; track = track->Next() )
track->Show( 0, std::cout );
#endif
// Mark the full trace containing track_segment, and recalculate the
// beginning of the trace, and the number of segments, as the new trace
// can contain also already existing track segments
aNewTrack = GetBoard()->MarkTrace( track_segment, &aNewTrackSegmentsCount,
nullptr, nullptr, true );
wxASSERT( aNewTrack );
TRACK* bufStart = m_Pcb->m_Track->GetStartNetCode( netcode ); // Beginning of tracks of the net
TRACK* bufEnd = bufStart->GetEndNetCode( netcode ); // End of tracks of the net
@ -296,7 +297,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC,
// Flags for cleaning the net.
for( pt_del = bufStart; pt_del; pt_del = pt_del->Next() )
{
// D( std::cout<<"track "<<pt_del<<" turning off BUSY | IN_EDIT | IS_LINKED"<<std::endl; )
// printf( "track %p turning off BUSY | IN_EDIT | IS_LINKED\n", pt_del );
pt_del->SetState( BUSY | IN_EDIT | IS_LINKED, false );
if( pt_del == bufEnd ) // Last segment reached
@ -425,10 +426,10 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC,
/* Test if the marked track is redundant, i.e. if one of marked segments
* is connected to the starting point of the new track.
*/
ii = 0;
pt_segm = pt_del;
for( ; pt_segm && (ii < nb_segm); pt_segm = pt_segm->Next(), ii++ )
for( int ii = 0; pt_segm && (ii < nb_segm); pt_segm = pt_segm->Next(), ii++ )
{
if( pt_segm->GetState( BUSY ) == 0 )
break;
@ -440,7 +441,7 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC,
DrawTraces( m_canvas, aDC, pt_del, nb_segm, GR_XOR | GR_HIGHLIGHT );
for( jj = 0; jj < nb_segm; jj++, pt_del = NextS )
for( int jj = 0; jj < nb_segm; jj++, pt_del = NextS )
{
NextS = pt_del->Next();

View File

@ -469,26 +469,21 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC )
{
int netcode = g_FirstTrackSegment->GetNetCode();
TRACK* firstTrack = g_FirstTrackSegment;
int newCount = g_CurrentTrackList.GetCount();
int newCount = 0;
// Put entire new current segment list in BOARD, and prepare undo command
TRACK* track;
TRACK* insertBeforeMe = g_CurrentTrackSegment->GetBestInsertPoint( GetBoard() );
while( ( track = g_CurrentTrackList.PopFront() ) != NULL )
while( ( track = g_CurrentTrackList.PopFront() ) != nullptr )
{
ITEM_PICKER picker( track, UR_NEW );
s_ItemsListPicker.PushItem( picker );
GetBoard()->m_Track.Insert( track, insertBeforeMe );
GetBoard()->GetConnectivity()->Add( track );
}
int i = 0;
for( track = firstTrack; track && i < newCount; ++i, track = track->Next() )
{
track->ClearFlags();
track->SetState( BUSY, false );
newCount++;
}
// delete the old track, if it exists and is redundant