Pcbnew: Enhancement in connections calculations:

Until now, 2 tracks were seen as connected only if one end of the first track is *exactly* on one end of the other track.
Now the 2 ends are seen as connected when they are "near" i.e. the distance between the 2 ends is < track width/2
This commit is contained in:
jean-pierre charras 2013-01-08 18:58:06 +01:00
parent 518fdb93e5
commit 8b6d5cb42f
5 changed files with 94 additions and 19 deletions

View File

@ -282,6 +282,15 @@ void CONNECTIONS::BuildTracksCandidatesList( TRACK * aBegin, TRACK * aEnd)
sort( m_candidates.begin(), m_candidates.end(), sortConnectedPointByXthenYCoordinates );
}
/* Populates .m_connected with tracks/vias connected to aTrack
* param aTrack = track or via to use as reference
* For calculation time reason, an exhaustive search cannot be made
* and a proximity search is made:
* Only tracks with one end near one end of aTrack are collected.
* near means dist <= aTrack width / 2
* because with this constraint we can make a fast search in track list
* m_candidates is expected to be populated by the track candidates ends list
*/
int CONNECTIONS::SearchConnectedTracks( const TRACK * aTrack )
{
int count = 0;
@ -290,9 +299,15 @@ int CONNECTIONS::SearchConnectedTracks( const TRACK * aTrack )
int layerMask = aTrack->ReturnMaskLayer();
// Search for connections to starting point:
#define USE_EXTENDED_SEARCH
#ifdef USE_EXTENDED_SEARCH
int dist_max = aTrack->GetWidth() / 2;
static std::vector<CONNECTED_POINT*> tracks_candidates;
#endif
wxPoint position = aTrack->m_Start;
for( int kk = 0; kk < 2; kk++ )
{
#ifndef USE_EXTENDED_SEARCH
int idx = searchEntryPointInCandidatesList( position );
if ( idx >= 0 )
{
@ -317,6 +332,30 @@ int CONNECTIONS::SearchConnectedTracks( const TRACK * aTrack )
m_connected.push_back( m_candidates[ii].GetTrack() );
}
}
#else
tracks_candidates.clear();
CollectItemsNearTo( tracks_candidates, position, dist_max );
for ( unsigned ii = 0; ii < tracks_candidates.size(); ii ++ )
{
TRACK * ctrack = tracks_candidates[ii]->GetTrack();
if( ( ctrack->ReturnMaskLayer() & layerMask ) == 0 )
continue;
if( ctrack == aTrack )
continue;
// We have a good candidate: calculate the actual distance
// beteween ends, which should be <= dist max.
wxPoint delta = tracks_candidates[ii]->GetPoint() - position;
int dist = (int) hypot( (double) delta.x, (double) delta.y );
if( dist > dist_max )
continue;
m_connected.push_back( ctrack );
}
#endif
// Search for connections to ending point:
if( aTrack->Type() == PCB_VIA_T )

View File

@ -147,14 +147,15 @@ public:
/**
* Function BuildPadsCandidatesList
* Fills m_Candidates with all pads connecting points (pads position)
* m_sortedPads must be built
* Populates m_candidates with all pads connecting points (pads position)
* m_sortedPads is expected to be populated by the pad candidates list
*/
void BuildPadsCandidatesList();
/**
* function SearchConnectedTracks
* Fills m_Connected with tracks/vias connected to aTrack
* Populates .m_connected with tracks/vias connected to aTrack
* m_candidates is expected to be populated by the track candidates ends list
* @param aTrack = track or via to use as reference
*/
int SearchConnectedTracks( const TRACK * aTrack );

View File

@ -165,10 +165,19 @@ void DrawSegmentWhileMovingFootprint( EDA_DRAW_PANEL* panel, wxDC* DC );
*/
void EraseDragList();
/*
* function used to collect track segments in drag track segment
/**
* function Collect_TrackSegmentsToDrag.
* used to collect track segments in drag track segment
* Build the list of tracks connected to the ref point by calling
* AddSegmentToDragList for each selected track
* Net codes must be up to date, because only tracks having the right net code are tested.
* @param aRefPos = reference point of connection
* @param aLayerMask = layers mask to collect tracks
* @param aNetCode = the net code to consider
* @param aMaxDist = max distance from aRefPos to a track end candidate to collect the track
*/
void Collect_TrackSegmentsToDrag( BOARD* aPcb, wxPoint& point, int LayerMask, int net_code );
void Collect_TrackSegmentsToDrag( BOARD* aPcb, wxPoint& aRefPos, int aLayerMask,
int aNetCode, int aMaxDist );
/* Add aTrack to the drag list
* flag = STARTPOINT (if the point to drag is the start point of Track)

View File

@ -345,29 +345,55 @@ void AddSegmentToDragList( int flag, TRACK* aTrack )
/* Build the list of tracks connected to the ref point
* Net codes must be up to date, because only tracks having the right net code are tested.
* aRefPos = reference point of connection
* aLayerMask = layers mask to collect tracks
* aNetCode = the net code to consider
* aMaxDist = max distance from aRefPos to a track end candidate to collect the track
*/
void Collect_TrackSegmentsToDrag( BOARD* aPcb, wxPoint& aRefPos, int LayerMask, int net_code )
void Collect_TrackSegmentsToDrag( BOARD* aPcb, wxPoint& aRefPos, int aLayerMask,
int aNetCode, int aMaxDist )
{
TRACK* track = aPcb->m_Track->GetStartNetCode( net_code );
TRACK* track = aPcb->m_Track->GetStartNetCode( aNetCode );
for( ; track; track = track->Next() )
{
if( track->GetNet() != net_code ) // not the same netcodenet code: all candidates tested
if( track->GetNet() != aNetCode ) // not the same netcodenet code: all candidates tested
break;
if( ( LayerMask & track->ReturnMaskLayer() ) == 0 )
if( ( aLayerMask & track->ReturnMaskLayer() ) == 0 )
continue; // Cannot be connected, not on the same layer
if( track->IsDragging() )
continue; // already put in list
int flag = 0;
int maxdist = std::max( aMaxDist, track->GetWidth() / 2 );
if( (track->m_Start == aRefPos) && ((track->GetFlags() & STARTPOINT) == 0) )
flag |= STARTPOINT;
if( (track->GetFlags() & STARTPOINT) == 0 )
{
wxPoint delta = track->m_Start - aRefPos;
if( std::abs( delta.x ) <= maxdist && std::abs( delta.y ) <= maxdist )
{
int dist = (int) hypot( (double) delta.x, (double) delta.y );
if( dist <= maxdist )
{
flag |= STARTPOINT;
if( track->Type() == PCB_VIA_T )
flag |= ENDPOINT;
}
}
}
if( (track->GetFlags() & ENDPOINT) == 0 )
{
wxPoint delta = track->m_End - aRefPos;
if( std::abs( delta.x ) <= maxdist && std::abs( delta.y ) <= maxdist )
{
int dist = (int) hypot( (double) delta.x, (double) delta.y );
if( dist <= maxdist )
flag |= ENDPOINT;
}
}
if( track->m_End == aRefPos && ((track->GetFlags() & ENDPOINT) == 0) )
flag |= ENDPOINT;
// Note: vias will be flagged with both STARTPOINT and ENDPOINT
// and must not be entered twice.
@ -379,7 +405,7 @@ void Collect_TrackSegmentsToDrag( BOARD* aPcb, wxPoint& aRefPos, int LayerMask,
// collect also tracks connected by this via.
if( track->Type() == PCB_VIA_T )
Collect_TrackSegmentsToDrag( aPcb, aRefPos, track->ReturnMaskLayer(),
net_code );
aNetCode, track->GetWidth() / 2 );
}
}
}

View File

@ -632,7 +632,7 @@ void PCB_EDIT_FRAME::StartMoveOneNodeOrSegment( TRACK* aTrack, wxDC* aDC, int aC
{
Collect_TrackSegmentsToDrag( GetBoard(), aTrack->m_Start,
aTrack->ReturnMaskLayer(),
aTrack->GetNet() );
aTrack->GetNet(), aTrack->GetWidth() / 2 );
}
PosInit = aTrack->m_Start;
@ -652,17 +652,17 @@ void PCB_EDIT_FRAME::StartMoveOneNodeOrSegment( TRACK* aTrack, wxDC* aDC, int aC
case ID_POPUP_PCB_DRAG_TRACK_SEGMENT: // drag a segment
pos = aTrack->m_Start;
Collect_TrackSegmentsToDrag( GetBoard(), pos, aTrack->ReturnMaskLayer(),
aTrack->GetNet() );
aTrack->GetNet(), aTrack->GetWidth() / 2 );
pos = aTrack->m_End;
aTrack->SetFlags( IS_DRAGGED | ENDPOINT | STARTPOINT );
Collect_TrackSegmentsToDrag( GetBoard(), pos, aTrack->ReturnMaskLayer(),
aTrack->GetNet() );
aTrack->GetNet(), aTrack->GetWidth() / 2 );
break;
case ID_POPUP_PCB_MOVE_TRACK_NODE: // Drag via or move node
pos = (diag & STARTPOINT) ? aTrack->m_Start : aTrack->m_End;
Collect_TrackSegmentsToDrag( GetBoard(), pos, aTrack->ReturnMaskLayer(),
aTrack->GetNet() );
aTrack->GetNet(), aTrack->GetWidth() / 2 );
PosInit = pos;
break;
}