@ -7,7 +7,6 @@
# include "gr_basic.h"
# include "common.h"
# include "class_drawpanel.h"
# include "confirm.h"
# include "colors_selection.h"
# include "wxBasePcbFrame.h"
# include "macros.h"
@ -17,96 +16,116 @@
# include "class_track.h"
# include "pcbnew.h"
# include "protos.h"
# include "minumun_spanning_tree.h"
static std : : vector < D_PAD * > s_localPadBuffer ; // for local ratsnest
// calculations when moving a
// footprint: buffer of pads to
// consider
static bool DisplayRastnestInProgress ; // Enable the display of the
// ratsnest during the ratsnest
// computations
/**
* @ brief class MIN_SPAN_TREE_PADS ( derived from MIN_SPAN_TREE ) specialize
* the basic class to calculate a minimum spanning tree from a list of pads ,
* and to add this tree as ratsnest to the main ratsnest list .
*/
class MIN_SPAN_TREE_PADS : public MIN_SPAN_TREE
{
friend class MIN_SPAN_TREE ;
public :
std : : vector < D_PAD * > * m_PadsList ; // list of pads:
/* these pads are the parents of nodes of the tree.
* Each node position is the corresponding pad position .
* This pad list is used to evaluate the weight of an edge in tree .
* - > edge = link between 2 nodes = links between 2 pads .
* - > weight of a link = rectilinear distance between the 2 pads
*/
public :
MIN_SPAN_TREE_PADS ( ) : MIN_SPAN_TREE ( )
{
m_PadsList = NULL ;
}
void MSP_Init ( std : : vector < D_PAD * > * aPadsList )
{
m_PadsList = aPadsList ;
MIN_SPAN_TREE : : MSP_Init ( ( int ) m_PadsList - > size ( ) ) ;
}
/**
* Function AddItemsToRatsnest
* Adds the current minimum spanning tree as ratsnest items
* to the main ratsnest list
* @ param aRatsnestList = the main ratsnest list
*/
void AddItemsToRatsnest ( std : : vector < RATSNEST_ITEM > & aRatsnestList ) ;
/**
* Function GetWeight
* calculates the weight between 2 items
* NOTE : The weight between a node and itself should be 0
* @ param aItem1 = first item
* @ param aItem2 = other item
* @ return the weight between items ( the rectilinear distance )
*/
int GetWeight ( int aItem1 , int aItem2 ) ;
} ;
void MIN_SPAN_TREE_PADS : : AddItemsToRatsnest ( std : : vector < RATSNEST_ITEM > & aRatsnestList )
{
std : : vector < D_PAD * > & padsBuffer = * m_PadsList ;
int netcode = padsBuffer [ 0 ] - > GetNet ( ) ;
// Note: to get edges in minimum spanning tree,
// the index value 0 is not used: it is just
// the entry point of the minimum spanning tree.
// The first edge (i.e. rastnest) starts at index 1
for ( int ii = 1 ; ii < m_Size ; ii + + )
{
/* Create the new ratsnest */
RATSNEST_ITEM net ;
net . SetNet ( netcode ) ;
net . m_Status = CH_ACTIF | CH_VISIBLE ;
net . m_Lenght = GetDist ( ii ) ;
net . m_PadStart = padsBuffer [ ii ] ;
net . m_PadEnd = padsBuffer [ GetWhoTo ( ii ) ] ;
aRatsnestList . push_back ( net ) ;
}
}
/* Function GetWeight
* calculates the weight between 2 items
* Here it calculate the rectilinear distance between 2 pads ( 2 items )
* NOTE : The weight between a node and itself should be < = 0
* aItem1 and aItem2 are the 2 items
* return the rectilinear distance
*/
int MIN_SPAN_TREE_PADS : : GetWeight ( int aItem1 , int aItem2 )
{
// NOTE: The distance (weight) between a node and itself should be 0
// so we add 1 to other distances th be sure we never have 0
// in cases other than a node and itself
D_PAD * pad1 = ( * m_PadsList ) [ aItem1 ] ;
D_PAD * pad2 = ( * m_PadsList ) [ aItem2 ] ;
if ( pad1 = = pad2 )
return 0 ;
int weight = abs ( pad2 - > m_Pos . x - pad1 - > m_Pos . x ) +
abs ( pad2 - > m_Pos . y - pad1 - > m_Pos . y ) ;
return weight + 1 ;
}
/* Note about the ratsnest computation:
* Building the general ratsnest :
* I used the " lee algorithm " .
* This is a 2 steps algorithm .
* the m_SubRatsnest member of pads handle a " block number " or a " cluster
* number " or a " subnet number "
* initially , m_SubRatsnest = 0 ( pad not connected ) .
* Build_Board_Ratsnest ( wxDC * DC ) Create this ratsnest
* for each net :
* First :
* we create a link ( and therefore a logical block ) between 2 pad . This is
* achieved by :
* search for a pad without link .
* search its nearest pad
* link these 2 pads ( i . e . create a ratsnest item )
* the pads are grouped in a logical block ( a cluster ) .
* until no pad without link found .
* Each logical block has a number called block number or " subnet number " ,
* stored in m_SubRatsnest member for each pad of the block .
* The first block has its block number = 1 , the second is 2 . . .
* the function to do that is gen_rats_pad_to_pad ( )
*
* Secondly :
* The first pass created many logical blocks
* A block contains 2 or more pads .
* we create links between 2 block . This is achieved by :
* Test all pads in the first block , and search ( for each pad )
* a neighbor in other blocks and compute the distance between pads ,
* We select the pad pair which have the smallest distance .
* These 2 pads are linked ( i . e . a new ratsnest item is created between the 2
* pads )
* and the 2 block are merged .
* Therefore the logical block 1 contains the initial block 1 " eats " the pads
* of the other block
* The computation is made until only one block is found .
* the function used is gen_rats_block_to_block ( )
*
*
* How existing and new tracks are handled :
* The complete ratsnest ( using the pad analysis ) is computed .
* it is independent of the tracks and handle the " logical connections " .
* It depends only on the footprints geometry ( and the netlist ) ,
* and must be computed only after a netlist read or a footprints geometry
* change .
* Each link ( ratsnest ) can only be INACTIVE ( because pads are connected by a
* track ) or ACTIVE ( no tracks )
*
* After the complete ratsnest is built , or when a track is added or deleted ,
* we run an algorithm derived from the complete ratsnest computation .
* it is much faster because it analysis only the existing ratsnest and not all
* the pads list
* and determine only if an existing ratsnest must be activated
* ( no physical track exists ) or not ( a physical track exists )
* if a track is added or deleted only the corresponding net is tested .
*
* the m_SubRatsnest member of pads is set to 0 ( no blocks ) , and all links are
* set to INACTIVE ( ratsnest not show ) .
* Before running this fast lee algorithm , we create blocks ( and their
* corresponding block number )
* by grouping pads connected by tracks .
* So , when tracks exists , the fast lee algorithm is started with some blocks
* already created .
* because the fast lee algorithm test only the ratsnest and does not search
* for nearest pads ( this search was previously made ) the online ratsnest
* can be done when a track is created without noticeable computing time
* First :
* for all links ( in this step , all are inactive ) :
* search for a link which have 1 ( or 2 ) pad having the m_SubRatsnest member =
* 0.
* if found the link is set to ACTIVE ( i . e . the ratsnest will be showed ) and
* the pad is merged with the block
* or a new block is created ( see tst_rats_pad_to_pad ( ) ) .
* Secondly :
* blocks are tested :
* for all links we search if the 2 pads linked are in 2 different block .
* if yes , the link status is set to ACTIVE , and the 2 block are merged
* until only one block is found
* ( see tst_rats_block_to_block ( ) )
* Building the general ratsnest :
* For each net , the ratsnest is the set of lines connecting pads ,
* using the shorter distance
* Therefore this problem is well known in graph therory , and sloved
* using the " minimum spanning tree " .
* We use here an algorithm to build the minimum spanning tree known as Prim ' s algorithm
*/
/**
@ -121,8 +140,6 @@ void PCB_BASE_FRAME::Compile_Ratsnest( wxDC* aDC, bool aDisplayStatus )
{
wxString msg ;
DisplayRastnestInProgress = true ;
GetBoard ( ) - > m_Status_Pcb = 0 ; /* we want a full ratsnest computation, from the scratch */
ClearMsgPanel ( ) ;
@ -140,18 +157,16 @@ void PCB_BASE_FRAME::Compile_Ratsnest( wxDC* aDC, bool aDisplayStatus )
/* Compute the full ratsnest
* which can be see like all the possible links or logical connections .
* some of them are active ( no track connected ) and others are inactive
* ( when track connect pads )
* ( when tracks connect pads )
* This full ratsnest is not modified by track editing .
* It changes only when a netlist is read , or footprints are modified
*/
Build_Board_Ratsnest ( aDC ) ;
Build_Board_Ratsnest ( ) ;
/* Compute the pad connections due to the existing tracks (physical connections) */
TestConnections ( aDC ) ;
/* Compute the active ratsnest, i.e. the unconnected links
* it is faster than Build_Board_Ratsnest ( )
* because many optimizations and computations are already made
*/
TestRatsNest ( aDC , 0 ) ;
@ -167,256 +182,29 @@ void PCB_BASE_FRAME::Compile_Ratsnest( wxDC* aDC, bool aDisplayStatus )
/* Sort function used by QSORT
* Sort pads by net code
*/
static int sortByNetcode ( const void * o1 , const void * o2 )
static bool sortByNetcode ( const D_PAD * const & ref , const D_PAD * const & item )
{
D_PAD * * pt_ref = ( D_PAD * * ) o1 ;
D_PAD * * pt_compare = ( D_PAD * * ) o2 ;
return ( * pt_ref ) - > GetNet ( ) - ( * pt_compare ) - > GetNet ( ) ;
}
/* Sort function used by QSORT
* Sort ratsnest by length
*/
static int sort_by_length ( const void * o1 , const void * o2 )
{
RATSNEST_ITEM * ref = ( RATSNEST_ITEM * ) o1 ;
RATSNEST_ITEM * compare = ( RATSNEST_ITEM * ) o2 ;
return ref - > m_Lenght - compare - > m_Lenght ;
return ref - > GetNet ( ) < item - > GetNet ( ) ;
}
/**
* Function used by Build_Board_Ratsnest
* This function creates a ratsnest between two blocks ( which fit the same
* net )
* A block is a group of pads already linked ( by a previous ratsnest
* computation , or tracks )
* The search is made between the pads in block 1 ( the reference block ) and
* other blocks
* the block n ( n > 1 ) it connected to block 1 by their 2 nearest pads .
* When the block is found , it is merged with the block 1
* the D_PAD member m_SubRatsnest handles the block number
* @ param aRatsnestBuffer = a std : : vector < RATSNEST_ITEM > buffer to fill with
* new ratsnest items
* @ param aPadBuffer = a std : : vector < D_PAD * > that is the list of pads to consider
* @ param aPadIdxStart = starting index ( within the pad list ) for search
* @ param aPadIdxMax = ending index ( within the pad list ) for search
* @ return blocks not connected count
*/
static int gen_rats_block_to_block
(
std : : vector < RATSNEST_ITEM > & aRatsnestBuffer ,
std : : vector < D_PAD * > & aPadBuffer ,
unsigned aPadIdxStart ,
unsigned aPadIdxMax )
{
int dist_min , current_dist ;
int current_num_block = 1 ;
int padBlock1Idx = - 1 ; // Index in aPadBuffer for the "better" pad
// found in block 1
int padBlockToMergeIdx = - 1 ; // Index in aPadBuffer for the "better" pad
// found in block to merge
dist_min = 0x7FFFFFFF ;
/* Search the nearest pad from block 1 */
for ( unsigned ii = aPadIdxStart ; ii < aPadIdxMax ; ii + + )
{
D_PAD * ref_pad = aPadBuffer [ ii ] ;
/* search a pad which is in the block 1 */
if ( ref_pad - > GetSubRatsnest ( ) ! = 1 )
continue ;
/* pad is found, search its nearest neighbor in other blocks */
for ( unsigned jj = aPadIdxStart ; jj < aPadIdxMax ; jj + + )
{
D_PAD * curr_pad = aPadBuffer [ jj ] ;
if ( curr_pad - > GetSubRatsnest ( ) = = 1 ) // not in an other block
continue ;
/* Compare distance between pads ("Manhattan" distance) */
current_dist = abs ( curr_pad - > m_Pos . x - ref_pad - > m_Pos . x ) +
abs ( curr_pad - > m_Pos . y - ref_pad - > m_Pos . y ) ;
if ( dist_min > current_dist ) // we have found a better pad pair
{
// The tested block can be a good candidate for merging
// we memorize the "best" current values for merging
current_num_block = curr_pad - > GetSubRatsnest ( ) ;
dist_min = current_dist ;
padBlockToMergeIdx = jj ;
padBlock1Idx = ii ;
}
}
}
/* The reference block is labeled block 1.
* if current_num_block ! = 1 we have found an other block , and we must
* merge it with the reference block
* The link is made by the 2 nearest pads
*/
if ( current_num_block > 1 )
{
/* The block n (n=current_num_block) is merged with the bloc 1 :
* to do that , we set the m_SubRatsnest member to 1 for all pads in
* block n
*/
for ( unsigned ii = aPadIdxStart ; ii < aPadIdxMax ; ii + + )
{
D_PAD * pad = aPadBuffer [ ii ] ;
if ( pad - > GetSubRatsnest ( ) = = current_num_block )
pad - > SetSubRatsnest ( 1 ) ;
}
if ( padBlock1Idx < 0 )
{
DisplayError ( NULL ,
wxT ( " gen_rats_block_to_block() internal error " ) ) ;
}
else
{
/* Create the new ratsnest */
RATSNEST_ITEM net ;
net . SetNet ( aPadBuffer [ padBlock1Idx ] - > GetNet ( ) ) ;
net . m_Status = CH_ACTIF | CH_VISIBLE ;
net . m_Lenght = dist_min ;
net . m_PadStart = aPadBuffer [ padBlock1Idx ] ;
net . m_PadEnd = aPadBuffer [ padBlockToMergeIdx ] ;
aRatsnestBuffer . push_back ( net ) ;
}
}
return current_num_block ;
}
/**
* Function used by Build_Board_Ratsnest
* this is the first pass of the lee algorithm
* This function creates the link ( ratsnest ) between 2 pads ( fitting the same
* net )
* the function search for a first not connected pad and search its nearest
* neighbor
* Its creates a block if the 2 pads are not connected , or merge the
* unconnected pad to the existing block .
* These blocks include 2 pads and the 2 pads are linked by a ratsnest .
*
* @ param aRatsnestBuffer = a std : : vector < RATSNEST_ITEM > buffer to fill with
* new ratsnest items
* @ param aPadBuffer = a std : : vector < D_PAD * > that is the list of pads to
* consider
* @ param aPadIdxStart = starting index ( within the pad list ) for search
* @ param aPadIdxMax = ending index ( within the pad list ) for search
* @ param current_num_block = Last existing block number of pads
* These block are created by the existing tracks analysis
*
* @ return the last block number used
*/
static int gen_rats_pad_to_pad ( vector < RATSNEST_ITEM > & aRatsnestBuffer ,
std : : vector < D_PAD * > & aPadBuffer ,
unsigned aPadIdxStart ,
unsigned aPadIdxMax ,
int current_num_block )
{
int dist_min , current_dist ;
D_PAD * ref_pad , * pad ;
for ( unsigned ii = aPadIdxStart ; ii < aPadIdxMax ; ii + + )
{
ref_pad = aPadBuffer [ ii ] ;
if ( ref_pad - > GetSubRatsnest ( ) )
continue ; // Pad already connected
dist_min = 0x7FFFFFFF ;
int padBlockToMergeIdx = - 1 ; // Index in aPadBuffer for the "better"
// pad found in block to merge
for ( unsigned jj = aPadIdxStart ; jj < aPadIdxMax ; jj + + )
{
if ( ii = = jj )
continue ;
pad = aPadBuffer [ jj ] ;
/* Compare distance between pads ("Manhattan" distance) */
current_dist = abs ( pad - > m_Pos . x - ref_pad - > m_Pos . x ) +
abs ( pad - > m_Pos . y - ref_pad - > m_Pos . y ) ;
if ( dist_min > current_dist )
{
dist_min = current_dist ;
padBlockToMergeIdx = jj ;
}
}
if ( padBlockToMergeIdx > = 0 )
{
pad = aPadBuffer [ padBlockToMergeIdx ] ;
/* Update the block number
* if the 2 pads are not already created : a new block is created
*/
if ( ( pad - > GetSubRatsnest ( ) = = 0 ) & & ( ref_pad - > GetSubRatsnest ( ) = = 0 ) )
{
current_num_block + + ; // Creates a new block number (or subratsnest)
pad - > SetSubRatsnest ( current_num_block ) ;
ref_pad - > SetSubRatsnest ( current_num_block ) ;
}
/* If a pad is already connected connected : merge the other pad in
* the block */
else
{
ref_pad - > SetSubRatsnest ( pad - > GetSubRatsnest ( ) ) ;
}
/* Create the new ratsnest item */
RATSNEST_ITEM rast ;
rast . SetNet ( ref_pad - > GetNet ( ) ) ;
rast . m_Status = CH_ACTIF | CH_VISIBLE ;
rast . m_Lenght = dist_min ;
rast . m_PadStart = ref_pad ;
rast . m_PadEnd = pad ;
aRatsnestBuffer . push_back ( rast ) ;
}
}
return current_num_block ;
}
/**
* Function to compute the full ratsnest ( using the LEE algorithm )
* Function to compute the full ratsnest
* In the functions tracks are not considered
* This is only the " basic " ratsnest depending only on pads .
*
* - Create the sorted pad list ( if necessary )
* The active pads ( i . e included in a net ) are called nodes
* This pad list is sorted by net codes
*
* - Compute the ratsnest ( LEE algorithm ) :
* a - Create the ratsnest between a not connected pad and its nearest
* neighbor . Blocks of pads are created
* b - Create the ratsnest between blocks :
* Test the pads of the 1 st block and create a link ( ratsnest )
* with the nearest pad found in an other block .
* The other block is merged with the first block .
* until only one block is left .
*
* A ratsnest can be seen as a logical connection .
* Create the sorted pad list ( if necessary )
* The active pads ( i . e included in a net ) are called nodes
* This pad list is sorted by net codes
* A ratsnest can be seen as a logical connection .
*
* Update :
* nb_nodes = Active pads count for the board
* nb_links = link count for the board ( logical connection count )
* ( there are n - 1 links for an connection which have n active pads ) .
* ( there are n - 1 links for a connection which have n active pads ) .
*
*/
void PCB_BASE_FRAME : : Build_Board_Ratsnest ( wxDC * DC )
void PCB_BASE_FRAME : : Build_Board_Ratsnest ( )
{
D_PAD * pad ;
int noconn ;
@ -442,80 +230,36 @@ void PCB_BASE_FRAME::Build_Board_Ratsnest( wxDC* DC )
return ; /* No useful connections. */
/* Ratsnest computation */
DisplayRastnestInProgress = true ;
unsigned current_net_code = 1 ; // First net code is analyzed.
// (net_code = 0 -> no connect)
noconn = 0 ;
MIN_SPAN_TREE_PADS min_spanning_tree ;
for ( ; current_net_code < m_Pcb - > m_NetInfo - > GetCount ( ) ; current_net_code + + )
{
NETINFO_ITEM * net = m_Pcb - > FindNet ( current_net_code ) ;
if ( net = = NULL ) //Should not occur
{
DisplayError ( this ,
wxT ( " Build_Board_Ratsnest() error: net not found " ) ) ;
wxMessageBox ( wxT ( " Build_Board_Ratsnest() error: net not found " ) ) ;
return ;
}
net - > m_RatsnestStartIdx = m_Pcb - > GetRatsnestsCount ( ) ;
// Search for the last subratsnest already in use
int num_block = 0 ;
for ( unsigned ii = 0 ; ii < net - > m_ListPad . size ( ) ; ii + + )
{
pad = net - > m_ListPad [ ii ] ;
if ( num_block < pad - > GetSubRatsnest ( ) )
num_block = pad - > GetSubRatsnest ( ) ;
}
/* Compute the ratsnest relative to the current net */
/* a - first pass : create the blocks from not already in block pads */
int icnt = gen_rats_pad_to_pad ( m_Pcb - > m_FullRatsnest ,
net - > m_ListPad ,
0 ,
net - > m_ListPad . size ( ) ,
num_block ) ;
/* b - blocks connection (Iteration) */
while ( icnt > 1 )
{
icnt = gen_rats_block_to_block ( m_Pcb - > m_FullRatsnest ,
net - > m_ListPad ,
0 ,
net - > m_ListPad . size ( ) ) ;
net = m_Pcb - > FindNet ( current_net_code ) ;
}
min_spanning_tree . MSP_Init ( & net - > m_ListPad ) ;
min_spanning_tree . BuildTree ( ) ;
min_spanning_tree . AddItemsToRatsnest ( m_Pcb - > m_FullRatsnest ) ;
net - > m_RatsnestEndIdx = m_Pcb - > GetRatsnestsCount ( ) ;
/* sort by length */
net = m_Pcb - > FindNet ( current_net_code ) ;
if ( ( net - > m_RatsnestEndIdx - net - > m_RatsnestStartIdx ) > 1 )
{
RATSNEST_ITEM * rats = & m_Pcb - > m_FullRatsnest [ 0 ] ;
qsort ( rats + net - > m_RatsnestStartIdx ,
net - > m_RatsnestEndIdx - net - > m_RatsnestStartIdx ,
sizeof ( RATSNEST_ITEM ) , sort_by_length ) ;
}
}
m_Pcb - > m_NbNoconnect = noconn ;
m_Pcb - > m_Status_Pcb | = LISTE_RATSNEST_ITEM_OK ;
// erase the ratsnest displayed on screen if needed
// Update the ratsnest display option (visible/invisible) flag
for ( unsigned ii = 0 ; ii < m_Pcb - > GetRatsnestsCount ( ) ; ii + + )
{
if ( ! GetBoard ( ) - > IsElementVisible ( RATSNEST_VISIBLE ) ) // Clear VISIBLE flag
m_Pcb - > m_FullRatsnest [ ii ] . m_Status & = ~ CH_VISIBLE ;
if ( DC )
m_Pcb - > m_FullRatsnest [ ii ] . Draw ( DrawPanel , DC , GR_XOR , wxPoint ( 0 , 0 ) ) ;
}
}
@ -557,12 +301,10 @@ void PCB_BASE_FRAME::DrawGeneralRatsnest( wxDC* aDC, int aNetcode )
/**
* Function used by TestRatsNest
* Function like gen_rats_block_to_block ( . . )
* Function testing the ratsnest between 2 blocks ( same net )
* 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
* Difference between gen_rats_block_to_block ( . . ) :
* The analysis is not made pads to pads but uses the general ratsnest list .
* The analysis uses the general ratsnest list .
* The function activate the smallest ratsnest between block 1 and the block n
* ( activate a logical connexion )
* @ param aRatsnestBuffer = the buffer to store NETINFO_ITEM * items
@ -625,7 +367,7 @@ static int tst_rats_block_to_block( NETINFO_ITEM* net,
* Activates the ratsnest between 2 pads ( assumes the same net )
* The function links 1 pad not already connected an other pad and activate
* some blocks linked by a ratsnest
* Its test only the existing ratsnest and activate some ratsnest ( status bit
* It tests only the existing ratsnest and activate some ratsnest ( status bit
* CH_ACTIF set )
*
* @ param start_rat_list = starting address for the ratsnest list
@ -688,7 +430,7 @@ void PCB_BASE_FRAME::TestRatsNest( wxDC* aDC, int aNetCode )
return ;
if ( ( m_Pcb - > m_Status_Pcb & LISTE_RATSNEST_ITEM_OK ) = = 0 )
Build_Board_Ratsnest ( aDC ) ;
Build_Board_Ratsnest ( ) ;
for ( int net_code = 1 ; net_code < ( int ) m_Pcb - > m_NetInfo - > GetCount ( ) ; net_code + + )
{
@ -740,7 +482,6 @@ void PCB_BASE_FRAME::TestRatsNest( wxDC* aDC, int aNetCode )
int PCB_BASE_FRAME : : TestOneRatsNest ( wxDC * aDC , int aNetCode )
{
DisplayRastnestInProgress = false ;
DrawGeneralRatsnest ( aDC , aNetCode ) ;
TestRatsNest ( aDC , aNetCode ) ;
DrawGeneralRatsnest ( aDC , aNetCode ) ;
@ -755,7 +496,6 @@ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule )
// code) for the footprint being moved
static unsigned internalRatsCount ; // number of internal links (links
// between pads of the module)
D_PAD * * baseListePad ;
D_PAD * pad_ref ;
D_PAD * pad_externe ;
int current_net_code ;
@ -778,7 +518,8 @@ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule )
goto CalculateExternalRatsnest ;
/* Compute the "internal" ratsnest, i.e the links between the current
* footprint pads */
* footprint pads
*/
s_localPadBuffer . clear ( ) ;
m_Pcb - > m_LocalRatsnest . clear ( ) ;
@ -797,11 +538,9 @@ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule )
if ( pads_module_count = = 0 )
return ; /* no connection! */
qsort ( & s_localPadBuffer [ 0 ] , pads_module_count , sizeof ( D_PAD * ) , sortByNetcode ) ;
sort ( s_localPadBuffer . begin ( ) , s_localPadBuffer . end ( ) , sortByNetcode ) ;
/* Build the list of pads linked to the current footprint pads */
DisplayRastnestInProgress = false ;
current_net_code = 0 ;
for ( unsigned ii = 0 ; ii < pads_module_count ; ii + + )
@ -816,8 +555,7 @@ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule )
if ( net = = NULL ) //Should not occur
{
DisplayError ( this ,
wxT ( " build_ratsnest_module() error: net not found " ) ) ;
wxMessageBox ( wxT ( " build_ratsnest_module() error: net not found " ) ) ;
return ;
}
@ -836,10 +574,8 @@ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule )
}
/* Sort the pad list by net_code */
baseListePad = & s_localPadBuffer [ 0 ] ;
qsort ( baseListePad + pads_module_count , s_localPadBuffer . size ( ) - pads_module_count ,
sizeof ( D_PAD * ) , sortByNetcode ) ;
sort ( s_localPadBuffer . begin ( ) + pads_module_count , s_localPadBuffer . end ( ) ,
sortByNetcode ) ;
/* Compute the internal rats nest:
* this is the same as general ratsnest , but considers only the current
@ -848,6 +584,9 @@ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule )
*/
current_net_code = s_localPadBuffer [ 0 ] - > GetNet ( ) ;
{
MIN_SPAN_TREE_PADS min_spanning_tree ;
std : : vector < D_PAD * > padsBuffer ;
for ( unsigned ii = 0 ; ii < pads_module_count ; ii + + )
{
/* Search the end of pad list relative to the current net */
@ -862,22 +601,17 @@ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule )
break ;
}
/* End of list found: */
/* a - first step of lee algorithm : build the pad to pad link list */
int icnt = gen_rats_pad_to_pad ( m_Pcb - > m_LocalRatsnest , s_localPadBuffer , ii , jj , 0 ) ;
/* b - second step of lee algorithm : build the block to block link
* list ( Iteration ) */
while ( icnt > 1 )
{
icnt = gen_rats_block_to_block ( m_Pcb - > m_LocalRatsnest , s_localPadBuffer , ii , jj ) ;
}
for ( unsigned kk = ii ; kk < jj ; kk + + )
padsBuffer . push_back ( s_localPadBuffer [ kk ] ) ;
min_spanning_tree . MSP_Init ( & padsBuffer ) ;
min_spanning_tree . BuildTree ( ) ;
min_spanning_tree . AddItemsToRatsnest ( m_Pcb - > m_LocalRatsnest ) ;
padsBuffer . clear ( ) ;
ii = jj ;
if ( ii < s_localPadBuffer . size ( ) )
current_net_code = s_localPadBuffer [ ii ] - > GetNet ( ) ;
}
}
internalRatsCount = m_Pcb - > m_LocalRatsnest . size ( ) ;
@ -1088,7 +822,7 @@ void PCB_BASE_FRAME::build_ratsnest_pad( BOARD_ITEM* ref, const wxPoint& refpos,
if ( net = = NULL ) // Should not occur
{
DisplayError ( this , wxT ( " build_ratsnest_pad() error: net not found " ) ) ;
wxMessageBox ( wxT ( " build_ratsnest_pad() error: net not found " ) ) ;
return ;
}