TRACK::GetTrack can now be told to confine search to the netlist and/or force the sequential (restartable) algorithm
Reworked the collinear track routines. Cleanup should be faster given the above modification.
This commit is contained in:
parent
41e41b95f8
commit
073a9e1724
|
@ -66,28 +66,6 @@ static bool ShowClearance( const TRACK* aTrack )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* return true if the dist between p1 and p2 < max_dist
|
|
||||||
* Currently in test (currently ratsnest algos work only if p1 == p2)
|
|
||||||
*/
|
|
||||||
inline bool IsNear( const wxPoint& p1, const wxPoint& p2, int max_dist )
|
|
||||||
{
|
|
||||||
#if 0 // Do not change it: does not work
|
|
||||||
int dist;
|
|
||||||
dist = abs( p1.x - p2.x ) + abs( p1.y - p2.y );
|
|
||||||
dist *= 7;
|
|
||||||
dist /= 10;
|
|
||||||
|
|
||||||
if ( dist < max_dist )
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
if ( p1 == p2 )
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TRACK* GetTrack( TRACK* aStartTrace, const TRACK* aEndTrace,
|
TRACK* GetTrack( TRACK* aStartTrace, const TRACK* aEndTrace,
|
||||||
const wxPoint& aPosition, LAYER_MSK aLayerMask )
|
const wxPoint& aPosition, LAYER_MSK aLayerMask )
|
||||||
{
|
{
|
||||||
|
@ -1303,125 +1281,79 @@ VIA* TRACK::GetVia( TRACK* aEndTrace, const wxPoint& aPosition, LAYER_MSK aLayer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TRACK* TRACK::GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, ENDPOINT_T aEndPoint )
|
TRACK* TRACK::GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, ENDPOINT_T aEndPoint,
|
||||||
|
bool aSameNetOnly, bool aSequential )
|
||||||
{
|
{
|
||||||
const int NEIGHTBOUR_COUNT_MAX = 50;
|
|
||||||
|
|
||||||
TRACK* previousSegment;
|
|
||||||
TRACK* nextSegment;
|
|
||||||
int Reflayer;
|
|
||||||
int ii;
|
|
||||||
int max_dist;
|
|
||||||
const wxPoint &position = GetEndPoint( aEndPoint );
|
const wxPoint &position = GetEndPoint( aEndPoint );
|
||||||
|
LAYER_MSK refLayers = GetLayerMask();
|
||||||
|
TRACK *previousSegment;
|
||||||
|
TRACK *nextSegment;
|
||||||
|
|
||||||
Reflayer = GetLayerMask();
|
if( aSequential )
|
||||||
|
|
||||||
previousSegment = nextSegment = this;
|
|
||||||
|
|
||||||
// Local search:
|
|
||||||
for( ii = 0; ii < NEIGHTBOUR_COUNT_MAX; ii++ )
|
|
||||||
{
|
{
|
||||||
if( (nextSegment == NULL) && (previousSegment == NULL) )
|
// Simple sequential search: from aStartTrace forward to aEndTrace
|
||||||
break;
|
previousSegment = NULL;
|
||||||
|
nextSegment = aStartTrace;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Local bidirectional search: from this backward to aStartTrace
|
||||||
|
* AND forward to aEndTrace. The idea is that nearest segments
|
||||||
|
* are found (on average) faster in this way. In fact same-net
|
||||||
|
* segments are almost guaranteed to be found faster, in a global
|
||||||
|
* search, since they are grouped together in the track list */
|
||||||
|
previousSegment = this;
|
||||||
|
nextSegment = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( nextSegment || previousSegment )
|
||||||
|
{
|
||||||
|
// Terminate the search in the direction if the netcode mismatches
|
||||||
|
if( aSameNetOnly )
|
||||||
|
{
|
||||||
|
if( nextSegment && (nextSegment->GetNetCode() != GetNetCode()) )
|
||||||
|
nextSegment = NULL;
|
||||||
|
if( previousSegment && (previousSegment->GetNetCode() != GetNetCode()) )
|
||||||
|
previousSegment = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if( nextSegment )
|
if( nextSegment )
|
||||||
{
|
{
|
||||||
if( nextSegment->GetState( BUSY | IS_DELETED ) )
|
if ( (nextSegment != this) &&
|
||||||
goto suite;
|
!nextSegment->GetState( BUSY | IS_DELETED ) &&
|
||||||
|
(refLayers & nextSegment->GetLayerMask()) )
|
||||||
if( nextSegment == this )
|
|
||||||
goto suite;
|
|
||||||
|
|
||||||
/* max_dist is the max distance between 2 track ends which
|
|
||||||
* ensure a copper continuity */
|
|
||||||
max_dist = ( nextSegment->m_Width + this->m_Width ) / 2;
|
|
||||||
|
|
||||||
if( IsNear( position, nextSegment->m_Start, max_dist ) )
|
|
||||||
{
|
{
|
||||||
if( Reflayer & nextSegment->GetLayerMask() )
|
if( (position == nextSegment->m_Start) ||
|
||||||
|
(position == nextSegment->m_End) )
|
||||||
return nextSegment;
|
return nextSegment;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( IsNear( position, nextSegment->m_End, max_dist ) )
|
// Keep looking forward
|
||||||
{
|
|
||||||
if( Reflayer & nextSegment->GetLayerMask() )
|
|
||||||
return nextSegment;
|
|
||||||
}
|
|
||||||
suite:
|
|
||||||
if( nextSegment == aEndTrace )
|
if( nextSegment == aEndTrace )
|
||||||
nextSegment = NULL;
|
nextSegment = NULL;
|
||||||
else
|
else
|
||||||
nextSegment = nextSegment->Next();
|
nextSegment = nextSegment->Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Same as above, looking back. During sequential search this branch is inactive
|
||||||
if( previousSegment )
|
if( previousSegment )
|
||||||
{
|
{
|
||||||
if( previousSegment->GetState( BUSY | IS_DELETED ) )
|
if ( (previousSegment != this) &&
|
||||||
goto suite1;
|
!previousSegment->GetState( BUSY | IS_DELETED ) &&
|
||||||
|
(refLayers & previousSegment->GetLayerMask()) )
|
||||||
if( previousSegment == this )
|
|
||||||
goto suite1;
|
|
||||||
|
|
||||||
max_dist = ( previousSegment->m_Width + m_Width ) / 2;
|
|
||||||
|
|
||||||
if( IsNear( position, previousSegment->m_Start, max_dist ) )
|
|
||||||
{
|
{
|
||||||
if( Reflayer & previousSegment->GetLayerMask() )
|
if( (position == previousSegment->m_Start) ||
|
||||||
|
(position == previousSegment->m_End) )
|
||||||
return previousSegment;
|
return previousSegment;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( IsNear( position, previousSegment->m_End, max_dist ) )
|
|
||||||
{
|
|
||||||
if( Reflayer & previousSegment->GetLayerMask() )
|
|
||||||
return previousSegment;
|
|
||||||
}
|
|
||||||
suite1:
|
|
||||||
if( previousSegment == aStartTrace )
|
if( previousSegment == aStartTrace )
|
||||||
previousSegment = NULL;
|
previousSegment = NULL;
|
||||||
else if( previousSegment->Type() != PCB_T )
|
|
||||||
previousSegment = previousSegment->Back();
|
|
||||||
else
|
else
|
||||||
previousSegment = NULL;
|
previousSegment = previousSegment->Back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// General search
|
|
||||||
for( nextSegment = aStartTrace; nextSegment != NULL; nextSegment = nextSegment->Next() )
|
|
||||||
{
|
|
||||||
if( nextSegment->GetState( IS_DELETED | BUSY ) )
|
|
||||||
{
|
|
||||||
if( nextSegment == aEndTrace )
|
|
||||||
break;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( nextSegment == this )
|
|
||||||
{
|
|
||||||
if( nextSegment == aEndTrace )
|
|
||||||
break;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
max_dist = ( nextSegment->m_Width + m_Width ) / 2;
|
|
||||||
|
|
||||||
if( IsNear( position, nextSegment->m_Start, max_dist ) )
|
|
||||||
{
|
|
||||||
if( Reflayer & nextSegment->GetLayerMask() )
|
|
||||||
return nextSegment;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( IsNear( position, nextSegment->m_End, max_dist ) )
|
|
||||||
{
|
|
||||||
if( Reflayer & nextSegment->GetLayerMask() )
|
|
||||||
return nextSegment;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( nextSegment == aEndTrace )
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -261,9 +261,14 @@ public:
|
||||||
* @param aEndTrace A pointer to the TRACK object to stop the search. A NULL value
|
* @param aEndTrace A pointer to the TRACK object to stop the search. A NULL value
|
||||||
* searches to the end of the list.
|
* searches to the end of the list.
|
||||||
* @param aEndPoint The start or end point of the segment to test against.
|
* @param aEndPoint The start or end point of the segment to test against.
|
||||||
|
* @param aSameNetOnly if true stop searching when the netcode changes
|
||||||
|
* @param aSequential If true, forces a forward sequential search,
|
||||||
|
* which is restartable; the default search can be faster but the
|
||||||
|
* position of the returned track in the list is unpredictable
|
||||||
* @return A TRACK object pointer if found otherwise NULL.
|
* @return A TRACK object pointer if found otherwise NULL.
|
||||||
*/
|
*/
|
||||||
TRACK* GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, ENDPOINT_T aEndPoint );
|
TRACK* GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, ENDPOINT_T aEndPoint,
|
||||||
|
bool aSameNetOnly, bool aSequential );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetEndSegments
|
* Function GetEndSegments
|
||||||
|
|
166
pcbnew/clean.cpp
166
pcbnew/clean.cpp
|
@ -303,7 +303,7 @@ bool TRACKS_CLEANER::testTrackEndpointDangling( TRACK *aTrack, ENDPOINT_T aEndPo
|
||||||
{
|
{
|
||||||
bool flag_erase = false;
|
bool flag_erase = false;
|
||||||
|
|
||||||
TRACK* other = aTrack->GetTrack( m_Brd->m_Track, NULL, aEndPoint );
|
TRACK* other = aTrack->GetTrack( m_Brd->m_Track, NULL, aEndPoint, true, false );
|
||||||
if( (other == NULL) &&
|
if( (other == NULL) &&
|
||||||
(zoneForTrackEndpoint( aTrack, aEndPoint ) == NULL) )
|
(zoneForTrackEndpoint( aTrack, aEndPoint ) == NULL) )
|
||||||
flag_erase = true; // Start endpoint is neither on pad, zone or other track
|
flag_erase = true; // Start endpoint is neither on pad, zone or other track
|
||||||
|
@ -324,7 +324,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 );
|
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 == NULL) &&
|
if( (other == NULL) &&
|
||||||
|
@ -450,95 +450,50 @@ bool TRACKS_CLEANER::remove_duplicates_of_track( const TRACK *aTrack )
|
||||||
bool TRACKS_CLEANER::merge_collinear_of_track( TRACK *aSegment )
|
bool TRACKS_CLEANER::merge_collinear_of_track( TRACK *aSegment )
|
||||||
{
|
{
|
||||||
bool merged_this = false;
|
bool merged_this = false;
|
||||||
bool flag = false; // If there are connections to this on the endpoint
|
|
||||||
|
|
||||||
// search for a possible point connected to the START point of the current segment
|
// *WHY* doesn't C++ have prec and succ (or ++ --) like PASCAL?
|
||||||
TRACK *segStart = aSegment->Next();
|
for( ENDPOINT_T endpoint = ENDPOINT_START; endpoint <= ENDPOINT_END;
|
||||||
while( true )
|
endpoint = ENDPOINT_T( endpoint + 1 ) )
|
||||||
{
|
{
|
||||||
segStart = aSegment->GetTrack( segStart, NULL, ENDPOINT_START );
|
// search for a possible segment connected to the current endpoint of the current one
|
||||||
|
TRACK *other = aSegment->Next();
|
||||||
if( segStart )
|
if( other )
|
||||||
{
|
{
|
||||||
// the two segments must have the same width
|
other = aSegment->GetTrack( other, NULL, endpoint, true, false );
|
||||||
if( aSegment->GetWidth() != segStart->GetWidth() )
|
|
||||||
break;
|
|
||||||
|
|
||||||
// it cannot be a via
|
if( other )
|
||||||
if( segStart->Type() != PCB_TRACE_T )
|
{
|
||||||
break;
|
// the two segments must have the same width and the other
|
||||||
|
// cannot be a via
|
||||||
|
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,
|
||||||
|
endpoint, true, false );
|
||||||
|
other->SetState( BUSY, false );
|
||||||
|
|
||||||
// We must have only one segment connected
|
if( !yet_another )
|
||||||
segStart->SetState( BUSY, true );
|
{
|
||||||
TRACK *other = aSegment->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_START );
|
// Try to merge them
|
||||||
segStart->SetState( BUSY, false );
|
TRACK *segDelete = mergeCollinearSegmentIfPossible( aSegment,
|
||||||
|
other, endpoint );
|
||||||
|
|
||||||
if( other == NULL )
|
// Merge succesful, the other one has to go away
|
||||||
flag = true; // OK
|
if( segDelete )
|
||||||
|
{
|
||||||
break;
|
m_Brd->GetRatsnest()->Remove( segDelete );
|
||||||
}
|
segDelete->ViewRelease();
|
||||||
break;
|
segDelete->DeleteStructure();
|
||||||
}
|
merged_this = true;
|
||||||
|
}
|
||||||
if( flag ) // We have the starting point of the segment is connected to an other segment
|
}
|
||||||
{
|
}
|
||||||
TRACK *segDelete = mergeCollinearSegmentIfPossible( aSegment, segStart, ENDPOINT_START );
|
}
|
||||||
|
|
||||||
if( segDelete )
|
|
||||||
{
|
|
||||||
m_Brd->GetRatsnest()->Remove( segDelete );
|
|
||||||
segDelete->ViewRelease();
|
|
||||||
segDelete->DeleteStructure();
|
|
||||||
merged_this = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do the same with the other endpoint
|
|
||||||
flag = false;
|
|
||||||
|
|
||||||
// search for a possible point connected to the END point of the current segment:
|
|
||||||
TRACK *segEnd = aSegment->Next();
|
|
||||||
while( true )
|
|
||||||
{
|
|
||||||
segEnd = aSegment->GetTrack( segEnd, NULL, ENDPOINT_END );
|
|
||||||
|
|
||||||
if( segEnd )
|
|
||||||
{
|
|
||||||
if( aSegment->GetWidth() != segEnd->GetWidth() )
|
|
||||||
break;
|
|
||||||
|
|
||||||
if( segEnd->Type() != PCB_TRACE_T )
|
|
||||||
break;
|
|
||||||
|
|
||||||
// We must have only one segment connected
|
|
||||||
segEnd->SetState( BUSY, true );
|
|
||||||
TRACK *other = aSegment->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_END );
|
|
||||||
segEnd->SetState( BUSY, false );
|
|
||||||
|
|
||||||
if( other == NULL )
|
|
||||||
flag = true; // Ok
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( flag ) // We have the ending point of the segment is connected to an other segment
|
|
||||||
{
|
|
||||||
TRACK *segDelete = mergeCollinearSegmentIfPossible( aSegment, segEnd, ENDPOINT_END );
|
|
||||||
|
|
||||||
if( segDelete )
|
|
||||||
{
|
|
||||||
m_Brd->GetRatsnest()->Remove( segDelete );
|
|
||||||
segDelete->ViewRelease();
|
|
||||||
segDelete->DeleteStructure();
|
|
||||||
merged_this = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return merged_this;
|
return merged_this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -550,12 +505,9 @@ bool TRACKS_CLEANER::clean_segments()
|
||||||
// Easy things first
|
// Easy things first
|
||||||
modified |= delete_null_segments();
|
modified |= delete_null_segments();
|
||||||
|
|
||||||
// Delete redundant segments, i.e. segments having the same end points
|
// Delete redundant segments, i.e. segments having the same end points and layers
|
||||||
// and layers
|
|
||||||
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;
|
||||||
|
@ -568,7 +520,7 @@ bool TRACKS_CLEANER::clean_segments()
|
||||||
bool merged_this = merge_collinear_of_track( segment );
|
bool merged_this = merge_collinear_of_track( segment );
|
||||||
modified |= merged_this;
|
modified |= merged_this;
|
||||||
|
|
||||||
if( merged_this ) // The current segment was modified, retry to merge it
|
if( merged_this ) // The current segment was modified, retry to merge it again
|
||||||
nextsegment = segment->Next();
|
nextsegment = segment->Next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -579,44 +531,24 @@ bool TRACKS_CLEANER::clean_segments()
|
||||||
/* Utility: check for parallelism between two segments */
|
/* Utility: check for parallelism between two segments */
|
||||||
static bool parallelism_test( int dx1, int dy1, int dx2, int dy2 )
|
static bool parallelism_test( int dx1, int dy1, int dx2, int dy2 )
|
||||||
{
|
{
|
||||||
// The following condition tree is ugly and repetitive, but I have
|
/* The following condition list is ugly and repetitive, but I have
|
||||||
// not a better way to express clearly the trivial cases. Hope the
|
* not a better way to express clearly the trivial cases. Hope the
|
||||||
// compiler optimize it better than always doing the product
|
* compiler optimize it better than always doing the product
|
||||||
// below...
|
* below... */
|
||||||
|
|
||||||
// test for vertical alignment (easy to handle)
|
// test for vertical alignment (easy to handle)
|
||||||
if( dx1 == 0 )
|
if( dx1 == 0 )
|
||||||
{
|
return dx2 == 0;
|
||||||
if( dx2 != 0 )
|
|
||||||
return false;
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( dx2 == 0 )
|
if( dx2 == 0 )
|
||||||
{
|
return dx1 == 0;
|
||||||
if( dx1 != 0 )
|
|
||||||
return false;
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// test for horizontal alignment (easy to handle)
|
// test for horizontal alignment (easy to handle)
|
||||||
if( dy1 == 0 )
|
if( dy1 == 0 )
|
||||||
{
|
return dy2 == 0;
|
||||||
if( dy2 != 0 )
|
|
||||||
return false;
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( dy2 == 0 )
|
if( dy2 == 0 )
|
||||||
{
|
return dy1 == 0;
|
||||||
if( dy1 != 0 )
|
|
||||||
return false;
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* test for alignment in other cases: Do the usual cross product test
|
/* test for alignment in other cases: Do the usual cross product test
|
||||||
* (the same as testing the slope, but without a division) */
|
* (the same as testing the slope, but without a division) */
|
||||||
|
@ -746,7 +678,7 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
other = segment->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_START );
|
other = segment->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_START, false, false );
|
||||||
|
|
||||||
if( other )
|
if( other )
|
||||||
net_code_s = other->GetNetCode();
|
net_code_s = other->GetNetCode();
|
||||||
|
@ -764,7 +696,7 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
other = segment->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_END );
|
other = segment->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_END, false, false );
|
||||||
|
|
||||||
if( other )
|
if( other )
|
||||||
net_code_e = other->GetNetCode();
|
net_code_e = other->GetNetCode();
|
||||||
|
|
|
@ -709,7 +709,7 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC
|
||||||
s_StartSegmentPresent = s_EndSegmentPresent = true;
|
s_StartSegmentPresent = s_EndSegmentPresent = true;
|
||||||
|
|
||||||
if( ( track->start == NULL ) || ( track->start->Type() == PCB_TRACE_T ) )
|
if( ( track->start == NULL ) || ( track->start->Type() == PCB_TRACE_T ) )
|
||||||
TrackToStartPoint = track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_START );
|
TrackToStartPoint = track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_START, true, false );
|
||||||
|
|
||||||
// Test if more than one segment is connected to this point
|
// Test if more than one segment is connected to this point
|
||||||
if( TrackToStartPoint )
|
if( TrackToStartPoint )
|
||||||
|
@ -717,14 +717,14 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC
|
||||||
TrackToStartPoint->SetState( BUSY, true );
|
TrackToStartPoint->SetState( BUSY, true );
|
||||||
|
|
||||||
if( ( TrackToStartPoint->Type() == PCB_VIA_T )
|
if( ( TrackToStartPoint->Type() == PCB_VIA_T )
|
||||||
|| track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_START ) )
|
|| track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_START, true, false ) )
|
||||||
error = true;
|
error = true;
|
||||||
|
|
||||||
TrackToStartPoint->SetState( BUSY, false );
|
TrackToStartPoint->SetState( BUSY, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( track->end == NULL ) || ( track->end->Type() == PCB_TRACE_T ) )
|
if( ( track->end == NULL ) || ( track->end->Type() == PCB_TRACE_T ) )
|
||||||
TrackToEndPoint = track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_END );
|
TrackToEndPoint = track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_END, true, false );
|
||||||
|
|
||||||
// Test if more than one segment is connected to this point
|
// Test if more than one segment is connected to this point
|
||||||
if( TrackToEndPoint )
|
if( TrackToEndPoint )
|
||||||
|
@ -732,7 +732,7 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC
|
||||||
TrackToEndPoint->SetState( BUSY, true );
|
TrackToEndPoint->SetState( BUSY, true );
|
||||||
|
|
||||||
if( (TrackToEndPoint->Type() == PCB_VIA_T)
|
if( (TrackToEndPoint->Type() == PCB_VIA_T)
|
||||||
|| track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_END ) )
|
|| track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_END, true, false ) )
|
||||||
error = true;
|
error = true;
|
||||||
|
|
||||||
TrackToEndPoint->SetState( BUSY, false );
|
TrackToEndPoint->SetState( BUSY, false );
|
||||||
|
|
Loading…
Reference in New Issue