Pcbnew: code cleaning in ratsnest.cpp. Add comments.
This commit is contained in:
parent
6222a3a8f7
commit
90e3024517
|
@ -397,17 +397,39 @@ public:
|
||||||
*/
|
*/
|
||||||
void DrawGeneralRatsnest( wxDC* aDC, int aNetcode = 0 );
|
void DrawGeneralRatsnest( wxDC* aDC, int aNetcode = 0 );
|
||||||
|
|
||||||
void trace_ratsnest_pad( wxDC* DC );
|
/**
|
||||||
void build_ratsnest_pad( BOARD_ITEM* ref, const wxPoint& refpos, bool init );
|
* Function TraceAirWiresToTargets
|
||||||
|
* This functions shows airwires to nearest connecting points (pads)
|
||||||
|
* from the current new track end during track creation
|
||||||
|
* Uses data prepared by BuildAirWiresTargetsList()
|
||||||
|
* @param aDC = the current device context
|
||||||
|
*/
|
||||||
|
void TraceAirWiresToTargets( wxDC* DC );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fucntion TestRatsNest
|
* Function BuildAirWiresTargetsList
|
||||||
* computes the active rats nest
|
* Build a list of candidates that can be a coonection point
|
||||||
* The general rats nest list must exist.
|
* when a track is started.
|
||||||
* Compute the ACTIVE rats nest in the general rats nest list
|
* This functions prepares data to show airwires to nearest connecting points (pads)
|
||||||
* if aNetCode == 0, test all nets, else test only aNetCode
|
* from the current new track to candidates during track creation
|
||||||
|
* @param aItemRef = the item connected to the starting point of the new track (track or pad)
|
||||||
|
* @param aPosition = the position of the new track end (usually the mouse cursor on grid)
|
||||||
|
* @param aInit = true to build full candidate list or false to update data
|
||||||
|
* When aInit = false, aItemRef is not used (can be NULL)
|
||||||
*/
|
*/
|
||||||
void TestRatsNest( wxDC* aDC, int aNetCode );
|
void BuildAirWiresTargetsList( BOARD_CONNECTED_ITEM* aItemRef,
|
||||||
|
const wxPoint& aPosition, bool aInit );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function TestForActiveLinksInRatsnest
|
||||||
|
* Explores the full rats nest list (which must exist) to determine
|
||||||
|
* the ACTIVE links in the full rats nest list
|
||||||
|
* When tracks exist between pads, a link can connect 2 pads already connected by a track
|
||||||
|
* and the link is said inactive.
|
||||||
|
* When a link connects 2 pads not already connected by a track, the link is said active.
|
||||||
|
* @param aNetCode = net code to test. If 0, test all nets
|
||||||
|
*/
|
||||||
|
void TestForActiveLinksInRatsnest( int aNetCode );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function TestConnections
|
* Function TestConnections
|
||||||
|
|
|
@ -2133,7 +2133,7 @@ MODULE* BOARD::GetFootprint( const wxPoint& aPosition, int aActiveLayer,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOARD_ITEM* BOARD::GetLockPoint( const wxPoint& aPosition, int aLayerMask )
|
BOARD_CONNECTED_ITEM* BOARD::GetLockPoint( const wxPoint& aPosition, int aLayerMask )
|
||||||
{
|
{
|
||||||
for( MODULE* module = m_Modules; module; module = module->Next() )
|
for( MODULE* module = m_Modules; module; module = module->Next() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -1251,7 +1251,7 @@ public:
|
||||||
* layer mask.
|
* layer mask.
|
||||||
* @return A pointer to a BOARD_ITEM object if found otherwise NULL.
|
* @return A pointer to a BOARD_ITEM object if found otherwise NULL.
|
||||||
*/
|
*/
|
||||||
BOARD_ITEM* GetLockPoint( const wxPoint& aPosition, int aLayerMask );
|
BOARD_CONNECTED_ITEM* GetLockPoint( const wxPoint& aPosition, int aLayerMask );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function CreateLockPoint
|
* Function CreateLockPoint
|
||||||
|
|
|
@ -558,7 +558,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
||||||
|
|
||||||
SetCurItem( NULL ); // CurItem might be deleted by this command, clear the pointer
|
SetCurItem( NULL ); // CurItem might be deleted by this command, clear the pointer
|
||||||
TestConnections( NULL );
|
TestConnections( NULL );
|
||||||
TestRatsNest( NULL, 0 ); // Recalculate the active ratsnest, i.e. the unconnected links
|
TestForActiveLinksInRatsnest( 0 ); // Recalculate the active ratsnest, i.e. the unconnected links
|
||||||
OnModify();
|
OnModify();
|
||||||
GetBoard()->DisplayInfo( this );
|
GetBoard()->DisplayInfo( this );
|
||||||
DrawPanel->Refresh();
|
DrawPanel->Refresh();
|
||||||
|
|
|
@ -94,7 +94,7 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
|
||||||
D_PAD* pt_pad = NULL;
|
D_PAD* pt_pad = NULL;
|
||||||
TRACK* TrackOnStartPoint = NULL;
|
TRACK* TrackOnStartPoint = NULL;
|
||||||
int layerMask = g_TabOneLayerMask[( (PCB_SCREEN*) GetScreen() )->m_Active_Layer];
|
int layerMask = g_TabOneLayerMask[( (PCB_SCREEN*) GetScreen() )->m_Active_Layer];
|
||||||
BOARD_ITEM* LockPoint;
|
BOARD_CONNECTED_ITEM* LockPoint;
|
||||||
wxPoint pos = GetScreen()->GetCrossHairPosition();
|
wxPoint pos = GetScreen()->GetCrossHairPosition();
|
||||||
|
|
||||||
if( aTrack == NULL ) /* Starting a new track */
|
if( aTrack == NULL ) /* Starting a new track */
|
||||||
|
@ -148,7 +148,7 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
|
||||||
|
|
||||||
D( g_CurrentTrackList.VerifyListIntegrity(); );
|
D( g_CurrentTrackList.VerifyListIntegrity(); );
|
||||||
|
|
||||||
build_ratsnest_pad( LockPoint, wxPoint( 0, 0 ), true );
|
BuildAirWiresTargetsList( LockPoint, wxPoint( 0, 0 ), true );
|
||||||
|
|
||||||
D( g_CurrentTrackList.VerifyListIntegrity(); );
|
D( g_CurrentTrackList.VerifyListIntegrity(); );
|
||||||
|
|
||||||
|
@ -428,7 +428,7 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC )
|
||||||
|
|
||||||
ShowNewTrackWhenMovingCursor( DrawPanel, aDC, wxDefaultPosition, true );
|
ShowNewTrackWhenMovingCursor( DrawPanel, aDC, wxDefaultPosition, true );
|
||||||
ShowNewTrackWhenMovingCursor( DrawPanel, aDC, wxDefaultPosition, false );
|
ShowNewTrackWhenMovingCursor( DrawPanel, aDC, wxDefaultPosition, false );
|
||||||
trace_ratsnest_pad( aDC );
|
TraceAirWiresToTargets( aDC );
|
||||||
|
|
||||||
/* cleanup
|
/* cleanup
|
||||||
* if( g_CurrentTrackSegment->Next() != NULL )
|
* if( g_CurrentTrackSegment->Next() != NULL )
|
||||||
|
@ -447,7 +447,7 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC )
|
||||||
* This helps to reduce the computing time */
|
* This helps to reduce the computing time */
|
||||||
|
|
||||||
/* Attaching the end of the track. */
|
/* Attaching the end of the track. */
|
||||||
BOARD_ITEM* LockPoint = GetBoard()->GetLockPoint( pos, layerMask );
|
BOARD_CONNECTED_ITEM* LockPoint = GetBoard()->GetLockPoint( pos, layerMask );
|
||||||
|
|
||||||
if( LockPoint ) /* End of trace is on a pad. */
|
if( LockPoint ) /* End of trace is on a pad. */
|
||||||
{
|
{
|
||||||
|
@ -489,7 +489,7 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC )
|
||||||
GetBoard()->m_Track.Insert( track, insertBeforeMe );
|
GetBoard()->m_Track.Insert( track, insertBeforeMe );
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_ratsnest_pad( aDC );
|
TraceAirWiresToTargets( aDC );
|
||||||
|
|
||||||
DrawTraces( DrawPanel, aDC, firstTrack, newCount, GR_OR );
|
DrawTraces( DrawPanel, aDC, firstTrack, newCount, GR_OR );
|
||||||
|
|
||||||
|
@ -680,7 +680,7 @@ void ShowNewTrackWhenMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPo
|
||||||
{
|
{
|
||||||
DrawTraces( aPanel, aDC, g_FirstTrackSegment, g_CurrentTrackList.GetCount(), GR_XOR );
|
DrawTraces( aPanel, aDC, g_FirstTrackSegment, g_CurrentTrackList.GetCount(), GR_XOR );
|
||||||
|
|
||||||
frame->trace_ratsnest_pad( aDC );
|
frame->TraceAirWiresToTargets( aDC );
|
||||||
|
|
||||||
if( showTrackClearanceMode >= SHOW_CLEARANCE_NEW_TRACKS_AND_VIA_AREAS )
|
if( showTrackClearanceMode >= SHOW_CLEARANCE_NEW_TRACKS_AND_VIA_AREAS )
|
||||||
{
|
{
|
||||||
|
@ -807,8 +807,8 @@ void ShowNewTrackWhenMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPo
|
||||||
DisplayOpt.ShowTrackClearanceMode = showTrackClearanceMode;
|
DisplayOpt.ShowTrackClearanceMode = showTrackClearanceMode;
|
||||||
DisplayOpt.DisplayPcbTrackFill = Track_fill_copy;
|
DisplayOpt.DisplayPcbTrackFill = Track_fill_copy;
|
||||||
|
|
||||||
frame->build_ratsnest_pad( NULL, g_CurrentTrackSegment->m_End, false );
|
frame->BuildAirWiresTargetsList( NULL, g_CurrentTrackSegment->m_End, false );
|
||||||
frame->trace_ratsnest_pad( aDC );
|
frame->TraceAirWiresToTargets( aDC );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -49,12 +49,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function AddItemsToRatsnest
|
* Function AddTreeToRatsnest
|
||||||
* Adds the current minimum spanning tree as ratsnest items
|
* Adds the current minimum spanning tree as ratsnest items
|
||||||
* to the main ratsnest list
|
* to the main ratsnest list
|
||||||
* @param aRatsnestList = the main ratsnest list
|
* @param aRatsnestList = the main ratsnest list
|
||||||
*/
|
*/
|
||||||
void AddItemsToRatsnest( std::vector<RATSNEST_ITEM> &aRatsnestList );
|
void AddTreeToRatsnest( std::vector<RATSNEST_ITEM> &aRatsnestList );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetWeight
|
* Function GetWeight
|
||||||
|
@ -68,7 +68,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void MIN_SPAN_TREE_PADS::AddItemsToRatsnest( std::vector<RATSNEST_ITEM> &aRatsnestList )
|
void MIN_SPAN_TREE_PADS::AddTreeToRatsnest( std::vector<RATSNEST_ITEM> &aRatsnestList )
|
||||||
{
|
{
|
||||||
std::vector<D_PAD*> & padsBuffer = *m_PadsList;
|
std::vector<D_PAD*> & padsBuffer = *m_PadsList;
|
||||||
int netcode = padsBuffer[0]->GetNet();
|
int netcode = padsBuffer[0]->GetNet();
|
||||||
|
@ -163,7 +163,7 @@ void PCB_BASE_FRAME::Compile_Ratsnest( wxDC* aDC, bool aDisplayStatus )
|
||||||
|
|
||||||
/* Compute the active ratsnest, i.e. the unconnected links
|
/* Compute the active ratsnest, i.e. the unconnected links
|
||||||
*/
|
*/
|
||||||
TestRatsNest( aDC, 0 );
|
TestForActiveLinksInRatsnest( 0 );
|
||||||
|
|
||||||
// Redraw the active ratsnest ( if enabled )
|
// Redraw the active ratsnest ( if enabled )
|
||||||
if( GetBoard()->IsElementVisible(RATSNEST_VISIBLE) && aDC )
|
if( GetBoard()->IsElementVisible(RATSNEST_VISIBLE) && aDC )
|
||||||
|
@ -241,7 +241,7 @@ void PCB_BASE_FRAME::Build_Board_Ratsnest()
|
||||||
|
|
||||||
min_spanning_tree.MSP_Init( &net->m_ListPad );
|
min_spanning_tree.MSP_Init( &net->m_ListPad );
|
||||||
min_spanning_tree.BuildTree();
|
min_spanning_tree.BuildTree();
|
||||||
min_spanning_tree.AddItemsToRatsnest( m_Pcb->m_FullRatsnest );
|
min_spanning_tree.AddTreeToRatsnest( m_Pcb->m_FullRatsnest );
|
||||||
net->m_RatsnestEndIdx = m_Pcb->GetRatsnestsCount();
|
net->m_RatsnestEndIdx = m_Pcb->GetRatsnestsCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,7 +293,7 @@ void PCB_BASE_FRAME::DrawGeneralRatsnest( wxDC* aDC, int aNetcode )
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function used by TestRatsNest
|
* Function used by TestForActiveLinksInRatsnest
|
||||||
* Function testing the ratsnest between 2 blocks ( same net )
|
* Function testing the ratsnest between 2 blocks ( same net )
|
||||||
* The search is made between pads in block 1 and the others blocks
|
* The search is made between pads in block 1 and the others blocks
|
||||||
* The block n ( n > 1 ) is merged with block 1 by the smallest ratsnest
|
* The block n ( n > 1 ) is merged with block 1 by the smallest ratsnest
|
||||||
|
@ -301,52 +301,57 @@ void PCB_BASE_FRAME::DrawGeneralRatsnest( wxDC* aDC, int aNetcode )
|
||||||
* The function activate the smallest ratsnest between block 1 and the block n
|
* The function activate the smallest ratsnest between block 1 and the block n
|
||||||
* (activate a logical connexion)
|
* (activate a logical connexion)
|
||||||
* @param aRatsnestBuffer = the buffer to store NETINFO_ITEM* items
|
* @param aRatsnestBuffer = the buffer to store NETINFO_ITEM* items
|
||||||
* @param net = the current NETINFO_ITEM for the current net
|
* @param aNetinfo = the current NETINFO_ITEM for the current net
|
||||||
* output:
|
* output:
|
||||||
* .state member of the ratsnest
|
* .state member of the ratsnest
|
||||||
* @return blocks not connected count
|
* @return blocks not connected count
|
||||||
*/
|
*/
|
||||||
static int tst_rats_block_to_block( NETINFO_ITEM* net,
|
static int tst_rats_block_to_block( NETINFO_ITEM* aNetinfo,
|
||||||
vector<RATSNEST_ITEM>& aRatsnestBuffer )
|
vector<RATSNEST_ITEM>& aRatsnestBuffer )
|
||||||
{
|
{
|
||||||
int current_num_block, min_block;
|
int current_num_block, min_block;
|
||||||
RATSNEST_ITEM* rats, * min_rats;
|
RATSNEST_ITEM* link, * best_link;
|
||||||
|
|
||||||
/* Search a link from a block to an other block */
|
/* Search a link from a block to an other block */
|
||||||
min_rats = NULL;
|
best_link = NULL;
|
||||||
|
|
||||||
for( unsigned ii = net->m_RatsnestStartIdx; ii < net->m_RatsnestEndIdx; ii++ )
|
for( unsigned ii = aNetinfo->m_RatsnestStartIdx; ii < aNetinfo->m_RatsnestEndIdx; ii++ )
|
||||||
{
|
{
|
||||||
rats = &aRatsnestBuffer[ii];
|
link = &aRatsnestBuffer[ii];
|
||||||
|
|
||||||
if( rats->m_PadStart->GetSubRatsnest() == rats->m_PadEnd->GetSubRatsnest() ) // Same block
|
// If this link joints 2 pads inside the same block, do nothing
|
||||||
|
// (these pads are already connected)
|
||||||
|
if( link->m_PadStart->GetSubRatsnest() == link->m_PadEnd->GetSubRatsnest() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( min_rats == NULL )
|
// This link joints 2 pads of different blocks: this is a candidate,
|
||||||
min_rats = rats;
|
// but we want to select the shorter link, so use it only if it is shorter
|
||||||
else if( min_rats->m_Lenght > rats->m_Lenght )
|
// than the previous candidate:
|
||||||
min_rats = rats;
|
if( best_link == NULL ) // no candidate
|
||||||
|
best_link = link;
|
||||||
|
else if( best_link->m_Lenght > link->m_Lenght ) // It is a better candidate.
|
||||||
|
best_link = link;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( min_rats == NULL )
|
if( best_link == NULL )
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* At this point we have found a link between 2 different blocks (clusters)
|
/* At this point we have found a link between 2 different blocks (subratsnest)
|
||||||
* we must set its status to ACTIVE and merge the 2 blocks
|
* we must set its status to ACTIVE and merge the 2 blocks
|
||||||
*/
|
*/
|
||||||
min_rats->m_Status |= CH_ACTIF;
|
best_link->m_Status |= CH_ACTIF;
|
||||||
current_num_block = min_rats->m_PadStart->GetSubRatsnest();
|
current_num_block = best_link->m_PadStart->GetSubRatsnest();
|
||||||
min_block = min_rats->m_PadEnd->GetSubRatsnest();
|
min_block = best_link->m_PadEnd->GetSubRatsnest();
|
||||||
|
|
||||||
if( min_block > current_num_block )
|
if( min_block > current_num_block )
|
||||||
EXCHG( min_block, current_num_block );
|
EXCHG( min_block, current_num_block );
|
||||||
|
|
||||||
/* Merging the 2 blocks in one cluster */
|
// Merge the 2 blocks in one sub ratsnest:
|
||||||
for( unsigned ii = 0; ii < net->m_ListPad.size(); ii++ )
|
for( unsigned ii = 0; ii < aNetinfo->m_ListPad.size(); ii++ )
|
||||||
{
|
{
|
||||||
if( net->m_ListPad[ii]->GetSubRatsnest() == current_num_block )
|
if( aNetinfo->m_ListPad[ii]->GetSubRatsnest() == current_num_block )
|
||||||
{
|
{
|
||||||
net->m_ListPad[ii]->SetSubRatsnest( min_block );
|
aNetinfo->m_ListPad[ii]->SetSubRatsnest( min_block );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,46 +360,46 @@ static int tst_rats_block_to_block( NETINFO_ITEM* net,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function used by TestRatsNest_general
|
* Function used by TestForActiveLinksInRatsnest_general
|
||||||
* The general ratsnest list must exists because this function explore this ratsnest
|
* The general ratsnest list must exists because this function explores this ratsnest
|
||||||
* Activates (set the CH_ACTIF flag) the ratsnest links between 2 pads when needed
|
* Activates (i.e. set the CH_ACTIF flag) the ratsnest links between 2 pads when needed
|
||||||
* The function links 1 pad not already connected to an other pad (SubRatsnest = 0)
|
* The function links 1 pad not already connected to an other pad (SubRatsnest = 0)
|
||||||
* and active the correspondint link
|
* and active the correspondint link
|
||||||
*
|
*
|
||||||
* @param start_rat_list = starting address for the ratsnest list
|
* @param aFirstItem = starting address for the ratsnest list
|
||||||
* @param end_rat_list = ending address for the ratsnest list
|
* @param aLastItem = ending address for the ratsnest list
|
||||||
* @param current_num_block = last block number (computed from the track
|
* @param aCurrSubRatsnestId = last block number (computed from the track
|
||||||
* analysis)
|
* analysis)
|
||||||
*
|
*
|
||||||
* output:
|
* output:
|
||||||
* ratsnest list (status member set)
|
* ratsnest list (status member bit CH_ACTIF set)
|
||||||
* and pad list (m_SubRatsnest set)
|
* and pads linked (m_SubRatsnest value set)
|
||||||
*
|
*
|
||||||
* @return new block number
|
* @return new block number
|
||||||
*/
|
*/
|
||||||
static int tst_rats_pad_to_pad( int current_num_block,
|
static int tst_rats_pad_to_pad( int aCurrSubRatsnestId,
|
||||||
RATSNEST_ITEM* start_rat_list,
|
RATSNEST_ITEM* aFirstItem,
|
||||||
RATSNEST_ITEM* end_rat_list )
|
RATSNEST_ITEM* aLastItem )
|
||||||
{
|
{
|
||||||
D_PAD* pad_start, * pad_end;
|
for( RATSNEST_ITEM* item = aFirstItem; item < aLastItem; item++ )
|
||||||
RATSNEST_ITEM* item;
|
|
||||||
|
|
||||||
for( item = start_rat_list; item < end_rat_list; item++ )
|
|
||||||
{
|
{
|
||||||
pad_start = item->m_PadStart;
|
D_PAD* pad_start = item->m_PadStart;
|
||||||
pad_end = item->m_PadEnd;
|
D_PAD* pad_end = item->m_PadEnd;
|
||||||
|
|
||||||
/* Update the block if the 2 pads are not connected : a new block is created
|
/* Update the current SubRatsnest if the 2 pads are not connected :
|
||||||
|
* a new cluster is created and the link activated
|
||||||
*/
|
*/
|
||||||
if( (pad_start->GetSubRatsnest() == 0) && (pad_end->GetSubRatsnest() == 0) )
|
if( (pad_start->GetSubRatsnest() == 0) && (pad_end->GetSubRatsnest() == 0) )
|
||||||
{
|
{
|
||||||
current_num_block++;
|
aCurrSubRatsnestId++;
|
||||||
pad_start->SetSubRatsnest( current_num_block );
|
pad_start->SetSubRatsnest( aCurrSubRatsnestId );
|
||||||
pad_end->SetSubRatsnest( current_num_block );
|
pad_end->SetSubRatsnest( aCurrSubRatsnestId );
|
||||||
item->m_Status |= CH_ACTIF;
|
item->m_Status |= CH_ACTIF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If a pad is already connected : the other is merged in the current block */
|
/* If a pad is already connected to a subratsnest: activate the link
|
||||||
|
* the pad other is merged in the existing subratsnest
|
||||||
|
*/
|
||||||
else if( pad_start->GetSubRatsnest() == 0 )
|
else if( pad_start->GetSubRatsnest() == 0 )
|
||||||
{
|
{
|
||||||
pad_start->SetSubRatsnest( pad_end->GetSubRatsnest() );
|
pad_start->SetSubRatsnest( pad_end->GetSubRatsnest() );
|
||||||
|
@ -407,13 +412,17 @@ static int tst_rats_pad_to_pad( int current_num_block,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return current_num_block;
|
return aCurrSubRatsnestId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* function TestRatsNest
|
/* function TestForActiveLinksInRatsnest
|
||||||
* determine the active links inside the full ratsnest
|
* determine the active links inside the full ratsnest
|
||||||
*
|
*
|
||||||
* I used an derived from the "lee algorithm".
|
* I used an algorithm inspired by the "Lee algorithm".
|
||||||
|
* The idea is all pads must be connected by a physical track or a logical track
|
||||||
|
* a physical track is the existing track on copper layers.
|
||||||
|
* a logical track is the link that must be activated (visible) if
|
||||||
|
* no track found between 2 pads.
|
||||||
* The algorithm explore the existing full ratnest
|
* The algorithm explore the existing full ratnest
|
||||||
* This is a 2 steps algorithm (executed for each net).
|
* This is a 2 steps algorithm (executed for each net).
|
||||||
* - First:
|
* - First:
|
||||||
|
@ -426,8 +435,10 @@ static int tst_rats_pad_to_pad( int current_num_block,
|
||||||
* 2 pads having different subratsnest values
|
* 2 pads having different subratsnest values
|
||||||
* Active the link and merge the 2 subratsnest value.
|
* Active the link and merge the 2 subratsnest value.
|
||||||
*
|
*
|
||||||
|
* This is usually fast because the ratsnest is not built here: it is just explored
|
||||||
|
* to see what link must be activated
|
||||||
*/
|
*/
|
||||||
void PCB_BASE_FRAME::TestRatsNest( wxDC* aDC, int aNetCode )
|
void PCB_BASE_FRAME::TestForActiveLinksInRatsnest( int aNetCode )
|
||||||
{
|
{
|
||||||
RATSNEST_ITEM* rats;
|
RATSNEST_ITEM* rats;
|
||||||
D_PAD* pad;
|
D_PAD* pad;
|
||||||
|
@ -449,8 +460,8 @@ void PCB_BASE_FRAME::TestRatsNest( wxDC* aDC, int aNetCode )
|
||||||
if( aNetCode && (net_code != aNetCode) )
|
if( aNetCode && (net_code != aNetCode) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Create subratsnests id from subnets created by existing tracks:
|
||||||
int num_block = 0;
|
int num_block = 0;
|
||||||
|
|
||||||
for( unsigned ip = 0; ip < net->m_ListPad.size(); ip++ )
|
for( unsigned ip = 0; ip < net->m_ListPad.size(); ip++ )
|
||||||
{
|
{
|
||||||
pad = net->m_ListPad[ip];
|
pad = net->m_ListPad[ip];
|
||||||
|
@ -464,13 +475,13 @@ void PCB_BASE_FRAME::TestRatsNest( wxDC* aDC, int aNetCode )
|
||||||
m_Pcb->m_FullRatsnest[ii].m_Status &= ~CH_ACTIF;
|
m_Pcb->m_FullRatsnest[ii].m_Status &= ~CH_ACTIF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* a - test connection between pads */
|
// First pass - activate links for not connected pads pads
|
||||||
rats = &m_Pcb->m_FullRatsnest[0];
|
rats = &m_Pcb->m_FullRatsnest[0];
|
||||||
int icnt = tst_rats_pad_to_pad( num_block,
|
int icnt = tst_rats_pad_to_pad( num_block,
|
||||||
rats + net->m_RatsnestStartIdx,
|
rats + net->m_RatsnestStartIdx,
|
||||||
rats + net->m_RatsnestEndIdx );
|
rats + net->m_RatsnestEndIdx );
|
||||||
|
|
||||||
/* b - test connection between blocks (Iteration) */
|
// Second pass activate links between blocks (Iteration)
|
||||||
while( icnt > 1 )
|
while( icnt > 1 )
|
||||||
{
|
{
|
||||||
icnt = tst_rats_block_to_block( net, m_Pcb->m_FullRatsnest );
|
icnt = tst_rats_block_to_block( net, m_Pcb->m_FullRatsnest );
|
||||||
|
@ -490,7 +501,7 @@ void PCB_BASE_FRAME::TestRatsNest( wxDC* aDC, int aNetCode )
|
||||||
int PCB_BASE_FRAME::TestOneRatsNest( wxDC* aDC, int aNetCode )
|
int PCB_BASE_FRAME::TestOneRatsNest( wxDC* aDC, int aNetCode )
|
||||||
{
|
{
|
||||||
DrawGeneralRatsnest( aDC, aNetCode );
|
DrawGeneralRatsnest( aDC, aNetCode );
|
||||||
TestRatsNest( aDC, aNetCode );
|
TestForActiveLinksInRatsnest( aNetCode );
|
||||||
DrawGeneralRatsnest( aDC, aNetCode );
|
DrawGeneralRatsnest( aDC, aNetCode );
|
||||||
|
|
||||||
return m_Pcb->GetRatsnestsCount();
|
return m_Pcb->GetRatsnestsCount();
|
||||||
|
@ -616,7 +627,7 @@ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule )
|
||||||
padsBuffer.push_back( localPadList[kk] );
|
padsBuffer.push_back( localPadList[kk] );
|
||||||
min_spanning_tree.MSP_Init( &padsBuffer );
|
min_spanning_tree.MSP_Init( &padsBuffer );
|
||||||
min_spanning_tree.BuildTree();
|
min_spanning_tree.BuildTree();
|
||||||
min_spanning_tree.AddItemsToRatsnest( m_Pcb->m_LocalRatsnest );
|
min_spanning_tree.AddTreeToRatsnest( m_Pcb->m_LocalRatsnest );
|
||||||
padsBuffer.clear();
|
padsBuffer.clear();
|
||||||
ii = jj;
|
ii = jj;
|
||||||
if( ii < localPadList.size() )
|
if( ii < localPadList.size() )
|
||||||
|
@ -757,120 +768,137 @@ void PCB_BASE_FRAME::TraceModuleRatsNest( wxDC* DC )
|
||||||
* and when the mouse is moved, the g_MaxLinksShowed links to neighbors are
|
* and when the mouse is moved, the g_MaxLinksShowed links to neighbors are
|
||||||
* drawn
|
* drawn
|
||||||
*/
|
*/
|
||||||
static std::vector <wxPoint> s_RatsnestMouseToPads;
|
static std::vector <wxPoint> s_TargetsLocations;
|
||||||
static wxPoint s_CursorPos; // Coordinate of the moving point (mouse cursor and
|
static wxPoint s_CursorPos; // Coordinate of the moving point (mouse cursor and
|
||||||
// end of current track segment)
|
// end of current track segment)
|
||||||
|
|
||||||
/* Used by build_ratsnest_pad(): sort function by link length (manhattan
|
/* Used by BuildAirWiresTargetsList(): sort function by link length
|
||||||
* distance)
|
* (rectilinear distance between s_CursorPos and item pos)
|
||||||
*/
|
*/
|
||||||
static bool sort_by_localnetlength( const wxPoint& ref, const wxPoint& compare )
|
static bool sort_by_distance( const wxPoint& ref, const wxPoint& compare )
|
||||||
{
|
{
|
||||||
wxPoint deltaref = ref - s_CursorPos;
|
wxPoint deltaref = ref - s_CursorPos; // relative coordinate of ref
|
||||||
wxPoint deltacmp = compare - s_CursorPos;
|
wxPoint deltacmp = compare - s_CursorPos; // relative coordinate of compare
|
||||||
|
|
||||||
// = distance between ref coordinate and pad ref
|
// rectilinear distance between ref and s_CursorPos:
|
||||||
int lengthref = abs( deltaref.x ) + abs( deltaref.y );
|
int lengthref = abs( deltaref.x ) + abs( deltaref.y );
|
||||||
|
|
||||||
// distance between ref coordinate and the other pad
|
// rectilinear distance between compare and s_CursorPos:
|
||||||
int lengthcmp = abs( deltacmp.x ) + abs( deltacmp.y );
|
int lengthcmp = abs( deltacmp.x ) + abs( deltacmp.y );
|
||||||
|
|
||||||
return lengthref < lengthcmp;
|
return lengthref < lengthcmp;
|
||||||
}
|
}
|
||||||
|
static bool sort_by_point( const wxPoint& ref, const wxPoint& compare )
|
||||||
|
|
||||||
void PCB_BASE_FRAME::build_ratsnest_pad( BOARD_ITEM* ref, const wxPoint& refpos, bool init )
|
|
||||||
{
|
{
|
||||||
int current_net_code = 0, conn_number = 0;
|
if( ref.x == compare.x )
|
||||||
D_PAD* pad_ref = NULL;
|
return ref.y < compare.y;
|
||||||
|
|
||||||
|
return ref.x < compare.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function BuildAirWiresTargetsList
|
||||||
|
* Build a list of candidates that can be a coonection point
|
||||||
|
* when a track is started.
|
||||||
|
* This functions prepares data to show airwires to nearest connecting points (pads)
|
||||||
|
* from the current new track to candidates during track creation
|
||||||
|
*/
|
||||||
|
void PCB_BASE_FRAME::BuildAirWiresTargetsList( BOARD_CONNECTED_ITEM* aItemRef,
|
||||||
|
const wxPoint& aPosition, bool aInit )
|
||||||
|
{
|
||||||
if( ( ( m_Pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK ) == 0 )
|
if( ( ( m_Pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK ) == 0 )
|
||||||
|| ( ( m_Pcb->m_Status_Pcb & LISTE_PAD_OK ) == 0 )
|
|| ( ( m_Pcb->m_Status_Pcb & LISTE_PAD_OK ) == 0 )
|
||||||
|| ( ( m_Pcb->m_Status_Pcb & NET_CODES_OK ) == 0 ) )
|
|| ( ( m_Pcb->m_Status_Pcb & NET_CODES_OK ) == 0 ) )
|
||||||
{
|
{
|
||||||
s_RatsnestMouseToPads.clear();
|
s_TargetsLocations.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
s_CursorPos = refpos;
|
s_CursorPos = aPosition; // needed for sort_by_distance
|
||||||
|
|
||||||
if( init )
|
if( aInit )
|
||||||
{
|
{
|
||||||
s_RatsnestMouseToPads.clear();
|
s_TargetsLocations.clear();
|
||||||
|
|
||||||
if( ref == NULL )
|
if( aItemRef == NULL )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch( ref->Type() )
|
int net_code = aItemRef->GetNet();
|
||||||
{
|
int subnet = aItemRef->GetSubNet();
|
||||||
case PCB_PAD_T:
|
|
||||||
pad_ref = (D_PAD*) ref;
|
|
||||||
current_net_code = pad_ref->GetNet();
|
|
||||||
conn_number = pad_ref->GetSubNet();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PCB_TRACE_T:
|
if( net_code <= 0 )
|
||||||
case PCB_VIA_T:
|
|
||||||
{
|
|
||||||
TRACK* track_ref = (TRACK*) ref;
|
|
||||||
current_net_code = track_ref->GetNet();
|
|
||||||
conn_number = track_ref->GetSubNet();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( current_net_code <= 0 )
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
NETINFO_ITEM* net = m_Pcb->FindNet( current_net_code );
|
NETINFO_ITEM* net = m_Pcb->FindNet( net_code );
|
||||||
|
|
||||||
if( net == NULL ) // Should not occur
|
if( net == NULL ) // Should not occur
|
||||||
{
|
{
|
||||||
wxMessageBox( wxT( "build_ratsnest_pad() error: net not found" ) );
|
wxMessageBox( wxT( "BuildAirWiresTargetsList() error: net not found" ) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a list of pads candidates ( pads not already connected to the
|
// Create a list of pads candidates ( pads not already connected to the
|
||||||
// current track:
|
// current track ):
|
||||||
for( unsigned ii = 0; ii < net->m_ListPad.size(); ii++ )
|
for( unsigned ii = 0; ii < net->m_ListPad.size(); ii++ )
|
||||||
{
|
{
|
||||||
D_PAD* pad = net->m_ListPad[ii];
|
D_PAD* pad = net->m_ListPad[ii];
|
||||||
|
|
||||||
if( pad == pad_ref )
|
if( pad == aItemRef )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( !pad->GetSubNet() || (pad->GetSubNet() != conn_number) )
|
if( !pad->GetSubNet() || (pad->GetSubNet() != subnet) )
|
||||||
s_RatsnestMouseToPads.push_back( pad->m_Pos );
|
s_TargetsLocations.push_back( pad->m_Pos );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a list of tracks ends candidates, not already connected to the
|
||||||
|
// current track:
|
||||||
|
for( TRACK* track = m_Pcb->m_Track; track; track = track->Next() )
|
||||||
|
{
|
||||||
|
if( track->GetNet() < net_code )
|
||||||
|
continue;
|
||||||
|
if( track->GetNet() > net_code )
|
||||||
|
break;;
|
||||||
|
|
||||||
|
if( !track->GetSubNet() || (track->GetSubNet() != subnet) )
|
||||||
|
{
|
||||||
|
if( aPosition != track->m_Start )
|
||||||
|
s_TargetsLocations.push_back( track->m_Start );
|
||||||
|
if( aPosition != track->m_End )
|
||||||
|
s_TargetsLocations.push_back( track->m_End );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove duplicate targets, using the C++ unique algorithm
|
||||||
|
sort( s_TargetsLocations.begin(), s_TargetsLocations.end(), sort_by_point );
|
||||||
|
std::vector< wxPoint >::iterator it = unique( s_TargetsLocations.begin(), s_TargetsLocations.end() );
|
||||||
|
// Using the C++ unique algorithm only moves the duplicate entries to the end of
|
||||||
|
// of the array. This removes the duplicate entries from the array.
|
||||||
|
s_TargetsLocations.resize( it - s_TargetsLocations.begin() );
|
||||||
} /* end if Init */
|
} /* end if Init */
|
||||||
|
|
||||||
if( s_RatsnestMouseToPads.size() > 1 )
|
// in all cases, sort by distances:
|
||||||
sort( s_RatsnestMouseToPads.begin(), s_RatsnestMouseToPads.end(), sort_by_localnetlength );
|
sort( s_TargetsLocations.begin(), s_TargetsLocations.end(), sort_by_distance );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/* Function TraceAirWiresToTargets
|
||||||
* Displays a "ratsnest" during track creation
|
* This functions shows airwires to nearest connecting points (pads)
|
||||||
|
* from the current new track end during track creation
|
||||||
*/
|
*/
|
||||||
void PCB_BASE_FRAME::trace_ratsnest_pad( wxDC* DC )
|
void PCB_BASE_FRAME::TraceAirWiresToTargets( wxDC* DC )
|
||||||
{
|
{
|
||||||
if( DC == NULL )
|
if( DC == NULL )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( s_RatsnestMouseToPads.size() == 0 )
|
if( s_TargetsLocations.size() == 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
GRSetDrawMode( DC, GR_XOR );
|
GRSetDrawMode( DC, GR_XOR );
|
||||||
|
|
||||||
for( int ii = 0; ii < (int) s_RatsnestMouseToPads.size(); ii++ )
|
for( int ii = 0; ii < (int) s_TargetsLocations.size(); ii++ )
|
||||||
{
|
{
|
||||||
if( ii >= g_MaxLinksShowed )
|
if( ii >= g_MaxLinksShowed )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
GRLine( &DrawPanel->m_ClipBox, DC, s_CursorPos, s_RatsnestMouseToPads[ii], 0, YELLOW );
|
GRLine( &DrawPanel->m_ClipBox, DC, s_CursorPos, s_TargetsLocations[ii], 0, YELLOW );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,7 +174,7 @@ int PCB_EDIT_FRAME::Fill_All_Zones( bool verbose )
|
||||||
TestConnections( NULL );
|
TestConnections( NULL );
|
||||||
|
|
||||||
// Recalculate the active ratsnest, i.e. the unconnected links
|
// Recalculate the active ratsnest, i.e. the unconnected links
|
||||||
TestRatsNest( NULL, 0 );
|
TestForActiveLinksInRatsnest( 0 );
|
||||||
DrawPanel->Refresh( true );
|
DrawPanel->Refresh( true );
|
||||||
|
|
||||||
return errorLevel;
|
return errorLevel;
|
||||||
|
|
Loading…
Reference in New Issue