|
|
|
@ -13,20 +13,11 @@ |
|
|
|
|
|
|
|
#include "protos.h"
|
|
|
|
|
|
|
|
extern char* adr_lowmem; /* adresse de base memoire de calcul disponible */ |
|
|
|
|
|
|
|
|
|
|
|
/* exported variables */ |
|
|
|
RATSNEST_ITEM* g_pt_chevelu; |
|
|
|
RATSNEST_ITEM* local_liste_chevelu; // Buffer address for local ratsnest
|
|
|
|
// (ratnest relative to one footprint while moving it
|
|
|
|
int nb_local_chevelu; // link count (active ratnest count) for the footprint beeing moved
|
|
|
|
|
|
|
|
/* local variables */ |
|
|
|
static int nb_pads_ref; // node count (node = pad with a net code) for the footprint beeing moved
|
|
|
|
static int nb_pads_externes; // Connected pads count ( pads which are
|
|
|
|
// in other footprints and connected to a pad of the footprint beeing moved
|
|
|
|
static bool DisplayRastnestInProgress; // Enable the display of the ratsnest during the ratsnest computations
|
|
|
|
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
|
|
|
|
|
|
|
|
/* Note about the ratsnest computation:
|
|
|
|
* Building the general ratsnest: |
|
|
|
@ -152,7 +143,7 @@ void WinEDA_BasePcbFrame::Compile_Ratsnest( wxDC* DC, bool display_status_pcb ) |
|
|
|
Tst_Ratsnest( DC, 0 ); |
|
|
|
|
|
|
|
// Redraw the active ratsnest ( if enabled )
|
|
|
|
if( g_Show_Ratsnest ) |
|
|
|
if( g_Show_Ratsnest && DC ) |
|
|
|
DrawGeneralRatsnest( DC, 0 ); |
|
|
|
|
|
|
|
if( display_status_pcb ) |
|
|
|
@ -161,7 +152,7 @@ void WinEDA_BasePcbFrame::Compile_Ratsnest( wxDC* DC, bool display_status_pcb ) |
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************/ |
|
|
|
static int tri_par_net( const void* o1, const void* o2 ) |
|
|
|
static int sortByNetcode( const void* o1, const void* o2 ) |
|
|
|
/****************************************************************/ |
|
|
|
|
|
|
|
/* Sort function used by QSORT
|
|
|
|
@ -191,8 +182,10 @@ static int sort_by_length( const void* o1, const void* o2 ) |
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/ |
|
|
|
static int gen_rats_block_to_block( WinEDA_DrawPanel* DrawPanel, wxDC* DC, |
|
|
|
D_PAD** pt_liste_pad, D_PAD** pt_limite, int* nblinks ) |
|
|
|
static int gen_rats_block_to_block( WinEDA_DrawPanel* aDrawPanel, |
|
|
|
std::vector<RATSNEST_ITEM>& aRatsnestBuffer, |
|
|
|
D_PAD** aPadList, |
|
|
|
D_PAD** aPadMax ) |
|
|
|
/*****************************************************************************/ |
|
|
|
|
|
|
|
/**
|
|
|
|
@ -203,11 +196,9 @@ static int gen_rats_block_to_block( WinEDA_DrawPanel* DrawPanel, wxDC* DC, |
|
|
|
* 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 pt_liste_pad = starting address (within the pad list) for search |
|
|
|
* @param pt_limite = ending address (within the pad list) for search |
|
|
|
* return in global variables: |
|
|
|
* ratsnest list in buffer |
|
|
|
* g_pt_chevelu updated to the first free memory location |
|
|
|
* @param aPadList = starting address (within the pad list) for search |
|
|
|
* @param aPadMax = ending address (within the pad list) for search |
|
|
|
* @param aRatsnestBuffer = a std::vector<RATSNEST_ITEM> buffer to fill with new ratsnest items |
|
|
|
* @return blocks not connected count |
|
|
|
*/ |
|
|
|
{ |
|
|
|
@ -222,15 +213,12 @@ static int gen_rats_block_to_block( WinEDA_DrawPanel* DrawPanel, wxDC* DC, |
|
|
|
|
|
|
|
dist_min = 0x7FFFFFFF; |
|
|
|
|
|
|
|
pt_start_liste = pt_liste_pad; |
|
|
|
|
|
|
|
if( DC ) |
|
|
|
GRSetDrawMode( DC, GR_XOR ); |
|
|
|
pt_start_liste = aPadList; |
|
|
|
|
|
|
|
/* Search the nearest pad from block 1 */ |
|
|
|
for( ; pt_liste_pad < pt_limite; pt_liste_pad++ ) |
|
|
|
for( ; aPadList < aPadMax; aPadList++ ) |
|
|
|
{ |
|
|
|
D_PAD* ref_pad = *pt_liste_pad; |
|
|
|
D_PAD* ref_pad = *aPadList; |
|
|
|
|
|
|
|
/* search a pad which is in the block 1 */ |
|
|
|
if( ref_pad->GetSubRatsnest() != 1 ) |
|
|
|
@ -241,7 +229,7 @@ static int gen_rats_block_to_block( WinEDA_DrawPanel* DrawPanel, wxDC* DC, |
|
|
|
{ |
|
|
|
D_PAD* curr_pad = *pt_liste_pad_aux; |
|
|
|
|
|
|
|
if( pt_liste_pad_aux >= pt_limite ) |
|
|
|
if( pt_liste_pad_aux >= aPadMax ) |
|
|
|
break; |
|
|
|
|
|
|
|
if( curr_pad->GetSubRatsnest() == 1 ) // not in an other block
|
|
|
|
@ -259,7 +247,7 @@ static int gen_rats_block_to_block( WinEDA_DrawPanel* DrawPanel, wxDC* DC, |
|
|
|
dist_min = current_dist; |
|
|
|
|
|
|
|
pt_liste_pad_tmp = pt_liste_pad_aux; |
|
|
|
pt_liste_pad_block1 = pt_liste_pad; |
|
|
|
pt_liste_pad_block1 = aPadList; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -274,35 +262,33 @@ static int gen_rats_block_to_block( WinEDA_DrawPanel* DrawPanel, wxDC* DC, |
|
|
|
/* The block n is merged with the bloc 1 :
|
|
|
|
* to do that, we set the m_SubRatsnest member to 1 for all pads in block n |
|
|
|
*/ |
|
|
|
for( pt_liste_pad = pt_start_liste; pt_liste_pad < pt_limite; pt_liste_pad++ ) |
|
|
|
for( aPadList = pt_start_liste; aPadList < aPadMax; aPadList++ ) |
|
|
|
{ |
|
|
|
if( (*pt_liste_pad)->GetSubRatsnest() == current_num_block ) |
|
|
|
(*pt_liste_pad)->SetSubRatsnest( 1 ); |
|
|
|
if( (*aPadList)->GetSubRatsnest() == current_num_block ) |
|
|
|
(*aPadList)->SetSubRatsnest( 1 ); |
|
|
|
} |
|
|
|
|
|
|
|
pt_liste_pad = pt_liste_pad_block1; |
|
|
|
aPadList = pt_liste_pad_block1; |
|
|
|
|
|
|
|
/* Create the new ratsnet */ |
|
|
|
(*nblinks)++; |
|
|
|
g_pt_chevelu->SetNet( (*pt_liste_pad)->GetNet() ); |
|
|
|
g_pt_chevelu->m_Status = CH_ACTIF | CH_VISIBLE; |
|
|
|
g_pt_chevelu->m_Lenght = dist_min; |
|
|
|
g_pt_chevelu->m_PadStart = *pt_liste_pad; |
|
|
|
g_pt_chevelu->m_PadEnd = *pt_liste_pad_tmp; |
|
|
|
|
|
|
|
if( DisplayRastnestInProgress && DC ) |
|
|
|
g_pt_chevelu->Draw( DrawPanel, DC, GR_XOR, wxPoint( 0, 0 ) ); |
|
|
|
|
|
|
|
g_pt_chevelu++; |
|
|
|
RATSNEST_ITEM net; |
|
|
|
net.SetNet( (*aPadList)->GetNet() ); |
|
|
|
net.m_Status = CH_ACTIF | CH_VISIBLE; |
|
|
|
net.m_Lenght = dist_min; |
|
|
|
net.m_PadStart = *aPadList; |
|
|
|
net.m_PadEnd = *pt_liste_pad_tmp; |
|
|
|
aRatsnestBuffer.push_back( net ); |
|
|
|
} |
|
|
|
return current_num_block; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/ |
|
|
|
static int gen_rats_pad_to_pad( WinEDA_DrawPanel* DrawPanel, wxDC* DC, |
|
|
|
D_PAD** pt_liste_pad, |
|
|
|
D_PAD** pt_limite, int current_num_block, int* nblinks ) |
|
|
|
static int gen_rats_pad_to_pad( WinEDA_DrawPanel* aDrawPanel, |
|
|
|
vector<RATSNEST_ITEM>& aRatsnestBuffer, |
|
|
|
D_PAD** aPadList, |
|
|
|
D_PAD** aPadMax, |
|
|
|
int current_num_block ) |
|
|
|
/*****************************************************************************/ |
|
|
|
|
|
|
|
/**
|
|
|
|
@ -317,14 +303,10 @@ static int gen_rats_pad_to_pad( WinEDA_DrawPanel* DrawPanel, wxDC* DC, |
|
|
|
* @param pt_liste_pad = starting address in the pad buffer |
|
|
|
* @param pt_limite = ending address |
|
|
|
* @param current_num_block = Last existing block number de pads |
|
|
|
* These block are created by the existing tracks analysis |
|
|
|
* These block are created by the existing tracks analysis |
|
|
|
* @param aRatsnestBuffer = a std::vector<RATSNEST_ITEM> buffer to fill with new ratsnest items |
|
|
|
* |
|
|
|
* output: |
|
|
|
* Ratsnest list |
|
|
|
* g_pt_chevelu updated to the first free memory address |
|
|
|
* |
|
|
|
* @return: |
|
|
|
* last block number used |
|
|
|
* @return the last block number used |
|
|
|
*/ |
|
|
|
{ |
|
|
|
int dist_min, current_dist; |
|
|
|
@ -333,11 +315,11 @@ static int gen_rats_pad_to_pad( WinEDA_DrawPanel* DrawPanel, wxDC* DC, |
|
|
|
D_PAD** pt_start_liste; |
|
|
|
D_PAD* ref_pad, * pad; |
|
|
|
|
|
|
|
pt_start_liste = pt_liste_pad; |
|
|
|
pt_start_liste = aPadList; |
|
|
|
|
|
|
|
for( ; pt_liste_pad < pt_limite; pt_liste_pad++ ) |
|
|
|
for( ; aPadList < aPadMax; aPadList++ ) |
|
|
|
{ |
|
|
|
ref_pad = *pt_liste_pad; |
|
|
|
ref_pad = *aPadList; |
|
|
|
|
|
|
|
if( ref_pad->GetSubRatsnest() ) |
|
|
|
continue; // Pad already connected
|
|
|
|
@ -347,10 +329,10 @@ static int gen_rats_pad_to_pad( WinEDA_DrawPanel* DrawPanel, wxDC* DC, |
|
|
|
|
|
|
|
for( pt_liste_pad_aux = pt_start_liste; ; pt_liste_pad_aux++ ) |
|
|
|
{ |
|
|
|
if( pt_liste_pad_aux >= pt_limite ) |
|
|
|
if( pt_liste_pad_aux >= aPadMax ) |
|
|
|
break; |
|
|
|
|
|
|
|
if( pt_liste_pad_aux == pt_liste_pad ) |
|
|
|
if( pt_liste_pad_aux == aPadList ) |
|
|
|
continue; |
|
|
|
|
|
|
|
pad = *pt_liste_pad_aux; |
|
|
|
@ -385,17 +367,14 @@ static int gen_rats_pad_to_pad( WinEDA_DrawPanel* DrawPanel, wxDC* DC, |
|
|
|
ref_pad->SetSubRatsnest( pad->GetSubRatsnest() ); |
|
|
|
} |
|
|
|
|
|
|
|
(*nblinks)++; |
|
|
|
g_pt_chevelu->SetNet( ref_pad->GetNet() ); |
|
|
|
g_pt_chevelu->m_Status = CH_ACTIF | CH_VISIBLE; |
|
|
|
g_pt_chevelu->m_Lenght = dist_min; |
|
|
|
g_pt_chevelu->m_PadStart = ref_pad; |
|
|
|
g_pt_chevelu->m_PadEnd = pad; |
|
|
|
|
|
|
|
if( DisplayRastnestInProgress && DC ) |
|
|
|
g_pt_chevelu->Draw( DrawPanel, DC, GR_XOR, wxPoint( 0, 0 ) ); |
|
|
|
|
|
|
|
g_pt_chevelu++; |
|
|
|
/* Create the new ratsnet 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 ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -437,12 +416,8 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC ) |
|
|
|
int noconn; |
|
|
|
|
|
|
|
m_Pcb->m_NbNoconnect = 0; |
|
|
|
m_Pcb->m_NbLinks = 0; |
|
|
|
|
|
|
|
if( m_Pcb->m_Ratsnest ) |
|
|
|
MyFree( m_Pcb->m_Ratsnest ); |
|
|
|
m_Pcb->m_Ratsnest = NULL; |
|
|
|
|
|
|
|
m_Pcb->m_FullRatsnest.clear(); |
|
|
|
|
|
|
|
if( m_Pcb->m_Pads.size() == 0 ) |
|
|
|
return; |
|
|
|
@ -457,22 +432,11 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC ) |
|
|
|
pad->SetSubRatsnest( 0 ); |
|
|
|
} |
|
|
|
|
|
|
|
/* Allocate memory for buffer ratsnest: there are nb_nodes - 1 ratsnest
|
|
|
|
* maximum ( 1 node = 1 active pad ). |
|
|
|
* Memory is allocated for nb_nodes ratsnests... (+ a bit more, just in case) |
|
|
|
* The real ratsnests count nb_links < nb_nodes |
|
|
|
*/ |
|
|
|
if( m_Pcb->m_NbNodes == 0 ) |
|
|
|
if( m_Pcb->GetNodesCount() == 0 ) |
|
|
|
return; /* pas de connexions utiles */ |
|
|
|
|
|
|
|
m_Pcb->m_Ratsnest = |
|
|
|
(RATSNEST_ITEM*) MyZMalloc( (m_Pcb->m_NbNodes + 10 ) * sizeof(RATSNEST_ITEM) ); |
|
|
|
if( m_Pcb->m_Ratsnest == NULL ) |
|
|
|
return; |
|
|
|
|
|
|
|
/* Ratsnest computation */ |
|
|
|
DisplayRastnestInProgress = TRUE; |
|
|
|
g_pt_chevelu = m_Pcb->m_Ratsnest; |
|
|
|
|
|
|
|
unsigned current_net_code = 1; // 1er net_code a analyser (net_code = 0 -> no connect)
|
|
|
|
noconn = 0; |
|
|
|
@ -480,10 +444,14 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC ) |
|
|
|
for( ; current_net_code < m_Pcb->m_NetInfo->GetCount(); current_net_code++ ) |
|
|
|
{ |
|
|
|
NETINFO_ITEM* net = m_Pcb->FindNet( current_net_code ); |
|
|
|
net->m_RatsnestStart = g_pt_chevelu; |
|
|
|
m_Pcb->m_NbLinks += net->m_ListPad.size() - 1; |
|
|
|
if ( net == NULL ) //Should not occur
|
|
|
|
{ |
|
|
|
DisplayError(this,wxT("Build_Board_Ratsnest() error: net not found") ); |
|
|
|
return; |
|
|
|
} |
|
|
|
net->m_RatsnestStart = m_Pcb->GetRatsnestsCount(); |
|
|
|
|
|
|
|
int num_block = 0; |
|
|
|
int num_block = 0; |
|
|
|
for( unsigned ii = 0; ii < net->m_ListPad.size(); ii++ ) |
|
|
|
{ |
|
|
|
pad = net->m_ListPad[ii]; |
|
|
|
@ -496,36 +464,38 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC ) |
|
|
|
/* a - first pass : create the blocks from not already in block pads */ |
|
|
|
D_PAD** pstart = &net->m_ListPad[0]; |
|
|
|
D_PAD** pend = pstart + net->m_ListPad.size(); |
|
|
|
int icnt = gen_rats_pad_to_pad( DrawPanel, DC, pstart, pend, |
|
|
|
num_block, &noconn ); |
|
|
|
int icnt = gen_rats_pad_to_pad( DrawPanel, m_Pcb->m_FullRatsnest, pstart, pend, |
|
|
|
num_block ); |
|
|
|
|
|
|
|
/* b - blocks connection (Iteration) */ |
|
|
|
while( icnt > 1 ) |
|
|
|
{ |
|
|
|
icnt = gen_rats_block_to_block( DrawPanel, DC, pstart, pend, &noconn ); |
|
|
|
icnt = gen_rats_block_to_block( DrawPanel, m_Pcb->m_FullRatsnest, pstart, pend ); |
|
|
|
} |
|
|
|
|
|
|
|
net->m_RatsnestEnd = g_pt_chevelu; |
|
|
|
net->m_RatsnestEnd = m_Pcb->GetRatsnestsCount(); |
|
|
|
|
|
|
|
/* sort by lenght */ |
|
|
|
qsort( net->m_RatsnestStart, |
|
|
|
net->m_RatsnestEnd - net->m_RatsnestStart, |
|
|
|
sizeof(RATSNEST_ITEM), |
|
|
|
sort_by_length ); |
|
|
|
if( (net->m_RatsnestEnd - net->m_RatsnestStart) > 1 ) |
|
|
|
{ |
|
|
|
RATSNEST_ITEM* rats = &m_Pcb->m_FullRatsnest[0]; |
|
|
|
qsort( rats + net->m_RatsnestStart, |
|
|
|
net->m_RatsnestEnd - net->m_RatsnestStart, |
|
|
|
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
|
|
|
|
RATSNEST_ITEM* Chevelu = m_Pcb->m_Ratsnest; |
|
|
|
for( int ii = m_Pcb->GetNumRatsnests(); ii > 0 && Chevelu; ii--, Chevelu++ ) |
|
|
|
for( unsigned ii = 0; ii < m_Pcb->GetRatsnestsCount(); ii++ ) |
|
|
|
{ |
|
|
|
if( !g_Show_Ratsnest ) |
|
|
|
Chevelu->m_Status &= ~CH_VISIBLE; |
|
|
|
if( !g_Show_Ratsnest ) // Clear VISIBLE flag
|
|
|
|
m_Pcb->m_FullRatsnest[ii].m_Status &= ~CH_VISIBLE; |
|
|
|
|
|
|
|
if( DC ) |
|
|
|
Chevelu->Draw( DrawPanel, DC, GR_XOR, wxPoint( 0, 0 ) ); |
|
|
|
m_Pcb->m_FullRatsnest[ii].Draw( DrawPanel, DC, GR_XOR, wxPoint( 0, 0 ) ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -552,9 +522,6 @@ void WinEDA_BasePcbFrame::DrawGeneralRatsnest( wxDC* DC, int net_code ) |
|
|
|
* @param netcode if > 0, Display only the ratsnest relative to the correponding net_code |
|
|
|
*/ |
|
|
|
{ |
|
|
|
int ii; |
|
|
|
RATSNEST_ITEM* Chevelu; |
|
|
|
|
|
|
|
if( (m_Pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 ) |
|
|
|
return; |
|
|
|
if( (m_Pcb->m_Status_Pcb & DO_NOT_SHOW_GENERAL_RASTNEST) ) |
|
|
|
@ -562,23 +529,19 @@ void WinEDA_BasePcbFrame::DrawGeneralRatsnest( wxDC* DC, int net_code ) |
|
|
|
if( DC == NULL ) |
|
|
|
return; |
|
|
|
|
|
|
|
Chevelu = m_Pcb->m_Ratsnest; |
|
|
|
if( Chevelu == NULL ) |
|
|
|
return; |
|
|
|
|
|
|
|
for( ii = m_Pcb->GetNumRatsnests(); ii > 0; Chevelu++, ii-- ) |
|
|
|
for( unsigned ii = 0; ii < m_Pcb->GetRatsnestsCount(); ii++ ) |
|
|
|
{ |
|
|
|
if( ( Chevelu->m_Status & (CH_VISIBLE | CH_ACTIF) ) != (CH_VISIBLE | CH_ACTIF) ) |
|
|
|
if( ( m_Pcb->m_FullRatsnest[ii].m_Status & (CH_VISIBLE | CH_ACTIF) ) != (CH_VISIBLE | CH_ACTIF) ) |
|
|
|
continue; |
|
|
|
|
|
|
|
if( (net_code <= 0) || ( net_code == Chevelu->GetNet() ) ) |
|
|
|
Chevelu->Draw( DrawPanel, DC, GR_XOR, wxPoint( 0, 0 ) ); |
|
|
|
if( (net_code <= 0) || ( net_code == m_Pcb->m_FullRatsnest[ii].GetNet() ) ) |
|
|
|
m_Pcb->m_FullRatsnest[ii].Draw( DrawPanel, DC, GR_XOR, wxPoint( 0, 0 ) ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************************************************/ |
|
|
|
static int tst_rats_block_to_block( WinEDA_DrawPanel* DrawPanel, wxDC* DC, NETINFO_ITEM* net ) |
|
|
|
static int tst_rats_block_to_block( NETINFO_ITEM* net, vector<RATSNEST_ITEM>& aRatsnestBuffer ) |
|
|
|
/**********************************************************************************************/ |
|
|
|
|
|
|
|
/**
|
|
|
|
@ -599,30 +562,31 @@ static int tst_rats_block_to_block( WinEDA_DrawPanel* DrawPanel, wxDC* DC, NETIN |
|
|
|
*/ |
|
|
|
{ |
|
|
|
int current_num_block, min_block; |
|
|
|
RATSNEST_ITEM* chevelu, * min_chevelu; |
|
|
|
RATSNEST_ITEM* rats, * min_rats; |
|
|
|
|
|
|
|
/* Search a link from a block to an other block */ |
|
|
|
min_chevelu = NULL; |
|
|
|
for( chevelu = net->m_RatsnestStart; chevelu < net->m_RatsnestEnd; chevelu++ ) |
|
|
|
min_rats = NULL; |
|
|
|
for( unsigned ii = net->m_RatsnestStart; ii < net->m_RatsnestEnd; ii++ ) |
|
|
|
{ |
|
|
|
if( chevelu->m_PadStart->GetSubRatsnest() == chevelu->m_PadEnd->GetSubRatsnest() ) // Same block
|
|
|
|
rats = &aRatsnestBuffer[ii]; |
|
|
|
if( rats->m_PadStart->GetSubRatsnest() == rats->m_PadEnd->GetSubRatsnest() ) // Same block
|
|
|
|
continue; |
|
|
|
|
|
|
|
if( min_chevelu == NULL ) |
|
|
|
min_chevelu = chevelu; |
|
|
|
else if( min_chevelu->m_Lenght > chevelu->m_Lenght ) |
|
|
|
min_chevelu = chevelu; |
|
|
|
if( min_rats == NULL ) |
|
|
|
min_rats = rats; |
|
|
|
else if( min_rats->m_Lenght > rats->m_Lenght ) |
|
|
|
min_rats = rats; |
|
|
|
} |
|
|
|
|
|
|
|
if( min_chevelu == NULL ) |
|
|
|
if( min_rats == NULL ) |
|
|
|
return 1; |
|
|
|
|
|
|
|
/* At this point we have found a link between 2 differents blocks (clusters) :
|
|
|
|
* we must set its status to ACTIVE and merge the 2 blocks |
|
|
|
*/ |
|
|
|
min_chevelu->m_Status |= CH_ACTIF; |
|
|
|
current_num_block = min_chevelu->m_PadStart->GetSubRatsnest(); |
|
|
|
min_block = min_chevelu->m_PadEnd->GetSubRatsnest(); |
|
|
|
min_rats->m_Status |= CH_ACTIF; |
|
|
|
current_num_block = min_rats->m_PadStart->GetSubRatsnest(); |
|
|
|
min_block = min_rats->m_PadEnd->GetSubRatsnest(); |
|
|
|
|
|
|
|
if( min_block > current_num_block ) |
|
|
|
EXCHG( min_block, current_num_block ); |
|
|
|
@ -641,8 +605,7 @@ static int tst_rats_block_to_block( WinEDA_DrawPanel* DrawPanel, wxDC* DC, NETIN |
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************/ |
|
|
|
static int tst_rats_pad_to_pad( WinEDA_DrawPanel* DrawPanel, wxDC* DC, |
|
|
|
int current_num_block, |
|
|
|
static int tst_rats_pad_to_pad( int current_num_block, |
|
|
|
RATSNEST_ITEM* start_rat_list, RATSNEST_ITEM* end_rat_list ) |
|
|
|
/**********************************************************************/ |
|
|
|
|
|
|
|
@ -709,9 +672,8 @@ void WinEDA_BasePcbFrame::Tst_Ratsnest( wxDC* DC, int ref_netcode ) |
|
|
|
* if ref_netcode == 0, test all nets, else test only ref_netcode |
|
|
|
*/ |
|
|
|
{ |
|
|
|
RATSNEST_ITEM* chevelu; |
|
|
|
RATSNEST_ITEM* rats; |
|
|
|
D_PAD* pad; |
|
|
|
int net_code; |
|
|
|
NETINFO_ITEM* net; |
|
|
|
|
|
|
|
if( m_Pcb->m_Pads.size() == 0 ) |
|
|
|
@ -719,11 +681,14 @@ void WinEDA_BasePcbFrame::Tst_Ratsnest( wxDC* DC, int ref_netcode ) |
|
|
|
if( (m_Pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 ) |
|
|
|
Build_Board_Ratsnest( DC ); |
|
|
|
|
|
|
|
for( net_code = 1; ; net_code++ ) |
|
|
|
for( int net_code = 1; net_code < (int) m_Pcb->m_NetInfo->GetCount(); net_code++ ) |
|
|
|
{ |
|
|
|
net = m_Pcb->FindNet( net_code ); |
|
|
|
if( net == NULL ) |
|
|
|
break; |
|
|
|
if ( net == NULL ) //Should not occur
|
|
|
|
{ |
|
|
|
DisplayError(this, wxT("Tst_Ratsnest() error: net not found") ); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if( ref_netcode && (net_code != ref_netcode) ) |
|
|
|
continue; |
|
|
|
@ -737,27 +702,26 @@ void WinEDA_BasePcbFrame::Tst_Ratsnest( wxDC* DC, int ref_netcode ) |
|
|
|
num_block = MAX( num_block, subnet ); |
|
|
|
} |
|
|
|
|
|
|
|
for( chevelu = net->m_RatsnestStart; chevelu < net->m_RatsnestEnd; chevelu++ ) |
|
|
|
for( unsigned ii = net->m_RatsnestStart; ii < net->m_RatsnestEnd; ii++ ) |
|
|
|
{ |
|
|
|
chevelu->m_Status &= ~CH_ACTIF; |
|
|
|
m_Pcb->m_FullRatsnest[ii].m_Status &= ~CH_ACTIF; |
|
|
|
} |
|
|
|
|
|
|
|
/* a - tst connection between pads */ |
|
|
|
int ii = tst_rats_pad_to_pad( DrawPanel, DC, num_block, |
|
|
|
net->m_RatsnestStart, net->m_RatsnestEnd ); |
|
|
|
rats = &m_Pcb->m_FullRatsnest[0]; |
|
|
|
int icnt = tst_rats_pad_to_pad( num_block, rats + net->m_RatsnestStart, rats + net->m_RatsnestEnd ); |
|
|
|
|
|
|
|
/* b - test connexion between blocks (Iteration) */ |
|
|
|
while( ii > 1 ) |
|
|
|
while( icnt > 1 ) |
|
|
|
{ |
|
|
|
ii = tst_rats_block_to_block( DrawPanel, DC, net ); |
|
|
|
icnt = tst_rats_block_to_block( net, m_Pcb->m_FullRatsnest ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
m_Pcb->m_NbNoconnect = 0; |
|
|
|
RATSNEST_ITEM* Chevelu = m_Pcb->m_Ratsnest; |
|
|
|
for( int ii = m_Pcb->GetNumRatsnests(); ii > 0; ii--, Chevelu++ ) |
|
|
|
for( unsigned ii = 0; ii < m_Pcb->GetRatsnestsCount(); ii++ ) |
|
|
|
{ |
|
|
|
if( Chevelu->m_Status & CH_ACTIF ) |
|
|
|
if( m_Pcb->m_FullRatsnest[ii].m_Status & CH_ACTIF ) |
|
|
|
m_Pcb->m_NbNoconnect++; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -777,12 +741,12 @@ int WinEDA_BasePcbFrame::Test_1_Net_Ratsnest( wxDC* DC, int ref_netcode ) |
|
|
|
Tst_Ratsnest( DC, ref_netcode ); |
|
|
|
DrawGeneralRatsnest( DC, ref_netcode ); |
|
|
|
|
|
|
|
return m_Pcb->GetNumRatsnests(); |
|
|
|
return m_Pcb->GetRatsnestsCount(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/ |
|
|
|
char* WinEDA_BasePcbFrame::build_ratsnest_module( wxDC* DC, MODULE* Module ) |
|
|
|
void WinEDA_BasePcbFrame::build_ratsnest_module( wxDC* DC, MODULE* Module ) |
|
|
|
/*****************************************************************************/ |
|
|
|
|
|
|
|
/**
|
|
|
|
@ -792,7 +756,6 @@ char* WinEDA_BasePcbFrame::build_ratsnest_module( wxDC* DC, MODULE* Module ) |
|
|
|
* It shows the connections from a pad to the nearest conected pad |
|
|
|
* @param Module = module to consider. |
|
|
|
* |
|
|
|
* the general buffer adr_lowmem is used to store the local footprint ratnest (to do: better to allocate memory) |
|
|
|
* The ratsnest has 2 sections: |
|
|
|
* - An "internal" ratsnet relative to pads of this footprint which are in the same net. |
|
|
|
* this ratsnest section is computed once. |
|
|
|
@ -800,21 +763,14 @@ char* WinEDA_BasePcbFrame::build_ratsnest_module( wxDC* DC, MODULE* Module ) |
|
|
|
* The ratsnest section must be computed for each new position |
|
|
|
*/ |
|
|
|
{ |
|
|
|
D_PAD** pt_liste_pad; |
|
|
|
D_PAD** pt_liste_ref; |
|
|
|
D_PAD** pt_liste_generale; |
|
|
|
D_PAD* pad_ref; |
|
|
|
D_PAD* pad_externe; |
|
|
|
D_PAD** pt_liste_pad_limite; |
|
|
|
D_PAD** pt_start_liste; |
|
|
|
D_PAD** pt_end_liste; |
|
|
|
int ii, jj; |
|
|
|
RATSNEST_ITEM* local_chevelu; |
|
|
|
static RATSNEST_ITEM* pt_fin_int_chevelu; // End list for "internal" ratsnest
|
|
|
|
static int nb_int_chevelu; // "internal" ratsnest count
|
|
|
|
int current_net_code; |
|
|
|
int increment, distance; // variables de calcul de ratsnest
|
|
|
|
int pad_pos_X, pad_pos_Y; // True pad position according to the current footprint position
|
|
|
|
static unsigned pads_module_count; // node count (node = pad with a net code) for the footprint beeing 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; |
|
|
|
int distance; // variables de calcul de ratsnest
|
|
|
|
wxPoint pad_pos; // True pad position according to the current footprint position
|
|
|
|
|
|
|
|
|
|
|
|
if( (GetBoard()->m_Status_Pcb & LISTE_PAD_OK) == 0 ) |
|
|
|
@ -827,120 +783,108 @@ char* WinEDA_BasePcbFrame::build_ratsnest_module( wxDC* DC, MODULE* Module ) |
|
|
|
* a pad in the current footprint |
|
|
|
*/ |
|
|
|
if( (m_Pcb->m_Status_Pcb & RATSNEST_ITEM_LOCAL_OK) != 0 ) |
|
|
|
goto calcul_chevelu_ext; |
|
|
|
goto CalculateExternalRatsnest; |
|
|
|
|
|
|
|
/* Compute the "internal" ratsnest, i.e the links between the curent footprint pads */ |
|
|
|
pt_liste_pad = (D_PAD**) adr_lowmem; |
|
|
|
nb_pads_ref = 0; |
|
|
|
s_localPadBuffer.clear(); |
|
|
|
m_Pcb->m_LocalRatsnest.clear(); |
|
|
|
|
|
|
|
pad_ref = Module->m_Pads; |
|
|
|
for( ; pad_ref != NULL; pad_ref = pad_ref->Next() ) |
|
|
|
for( pad_ref = Module->m_Pads; pad_ref != NULL; pad_ref = pad_ref->Next() ) |
|
|
|
{ |
|
|
|
if( pad_ref->GetNet() == 0 ) |
|
|
|
continue; |
|
|
|
|
|
|
|
*pt_liste_pad = pad_ref; |
|
|
|
s_localPadBuffer.push_back( pad_ref ); |
|
|
|
pad_ref->SetSubRatsnest( 0 ); |
|
|
|
pad_ref->SetSubNet( 0 ); |
|
|
|
pt_liste_pad++; nb_pads_ref++; |
|
|
|
} |
|
|
|
|
|
|
|
if( nb_pads_ref == 0 ) |
|
|
|
return (char*) pt_liste_pad; /* pas de connexions! */ |
|
|
|
pads_module_count = s_localPadBuffer.size(); |
|
|
|
if( pads_module_count == 0 ) |
|
|
|
return; /* no connection! */ |
|
|
|
|
|
|
|
qsort( adr_lowmem, nb_pads_ref, sizeof(D_PAD*), tri_par_net ); |
|
|
|
qsort( &s_localPadBuffer[0], pads_module_count, sizeof(D_PAD*), sortByNetcode ); |
|
|
|
|
|
|
|
/* Build the list of pads linked to the current footprint pads */ |
|
|
|
DisplayRastnestInProgress = FALSE; |
|
|
|
pt_liste_ref = (D_PAD**) adr_lowmem; |
|
|
|
|
|
|
|
nb_pads_externes = 0; |
|
|
|
current_net_code = 0; |
|
|
|
for( ii = 0; ii < nb_pads_ref; ii++ ) |
|
|
|
for( unsigned ii = 0; ii < pads_module_count; ii++ ) |
|
|
|
{ |
|
|
|
pad_ref = pt_liste_ref[ii]; |
|
|
|
pad_ref = s_localPadBuffer[ii]; |
|
|
|
if( pad_ref->GetNet() == current_net_code ) |
|
|
|
continue; |
|
|
|
|
|
|
|
current_net_code = pad_ref->GetNet(); |
|
|
|
|
|
|
|
pt_liste_generale = &m_Pcb->m_Pads[0]; |
|
|
|
for( jj = m_Pcb->m_Pads.size(); jj > 0; jj-- ) |
|
|
|
// A new net was found, load all pads of others modules members of this net:
|
|
|
|
NETINFO_ITEM* net = m_Pcb->FindNet( pad_ref->GetNet() ); |
|
|
|
if ( net == NULL ) //Should not occur
|
|
|
|
{ |
|
|
|
pad_externe = *pt_liste_generale; pt_liste_generale++; |
|
|
|
if( pad_externe->GetNet() != current_net_code ) |
|
|
|
continue; |
|
|
|
DisplayError(this,wxT("build_ratsnest_module() error: net not found") ); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
for( unsigned jj = 0; jj < net->m_ListPad.size(); jj++ ) |
|
|
|
{ |
|
|
|
pad_externe = net->m_ListPad[jj]; |
|
|
|
if( pad_externe->GetParent() == Module ) |
|
|
|
continue; |
|
|
|
|
|
|
|
pad_externe->SetSubRatsnest( 0 ); |
|
|
|
pad_externe->SetSubNet( 0 ); |
|
|
|
|
|
|
|
*pt_liste_pad = pad_externe; |
|
|
|
pt_liste_pad++; |
|
|
|
|
|
|
|
nb_pads_externes++; |
|
|
|
s_localPadBuffer.push_back( pad_externe ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* Sort the pad list by net_code */ |
|
|
|
qsort( pt_liste_ref + nb_pads_ref, nb_pads_externes, sizeof(D_PAD*), |
|
|
|
tri_par_net ); |
|
|
|
baseListePad = &s_localPadBuffer[0]; |
|
|
|
qsort( baseListePad + pads_module_count, |
|
|
|
s_localPadBuffer.size() - pads_module_count, |
|
|
|
sizeof(D_PAD*), sortByNetcode ); |
|
|
|
|
|
|
|
/* Compute the internal rats nest:
|
|
|
|
* this is the same as general ratsnest, but considers only the current footprint pads |
|
|
|
* it is therefore not time consuming, and it is made only once |
|
|
|
*/ |
|
|
|
local_liste_chevelu = (RATSNEST_ITEM*) pt_liste_pad; // buffer chevelu a la suite de la liste des pads
|
|
|
|
nb_local_chevelu = 0; |
|
|
|
pt_liste_ref = (D_PAD**) adr_lowmem; |
|
|
|
|
|
|
|
g_pt_chevelu = local_liste_chevelu; |
|
|
|
pt_liste_pad = pt_start_liste = (D_PAD**) adr_lowmem; |
|
|
|
|
|
|
|
pt_liste_pad_limite = pt_liste_pad + nb_pads_ref; |
|
|
|
|
|
|
|
current_net_code = (*pt_liste_pad)->GetNet(); |
|
|
|
current_net_code = s_localPadBuffer[0]->GetNet(); |
|
|
|
|
|
|
|
for( ; pt_liste_pad < pt_liste_pad_limite; ) |
|
|
|
for( unsigned ii = 0; ii < pads_module_count; ii++ ) |
|
|
|
{ |
|
|
|
/* Search the end of pad list relative to the current net */ |
|
|
|
|
|
|
|
for( pt_end_liste = pt_liste_pad + 1; ; pt_end_liste++ ) |
|
|
|
unsigned jj = ii + 1; |
|
|
|
for( ; jj <= pads_module_count; jj++ ) |
|
|
|
{ |
|
|
|
if( pt_end_liste >= pt_liste_pad_limite ) |
|
|
|
if( jj >= pads_module_count ) |
|
|
|
break; |
|
|
|
|
|
|
|
if( (*pt_end_liste)->GetNet() != current_net_code ) |
|
|
|
if( s_localPadBuffer[jj]->GetNet() != current_net_code ) |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
/* End of list found: */ |
|
|
|
/* a - first step of lee algorithm : build the pad to pad link list */ |
|
|
|
ii = gen_rats_pad_to_pad( DrawPanel, DC, pt_start_liste, pt_end_liste, |
|
|
|
0, &nb_local_chevelu ); |
|
|
|
int icnt = gen_rats_pad_to_pad( DrawPanel, m_Pcb->m_LocalRatsnest, |
|
|
|
baseListePad + ii, baseListePad + jj, |
|
|
|
0 ); |
|
|
|
|
|
|
|
/* b - second step of lee algorithm : build the block to block link list (Iteration) */ |
|
|
|
while( ii > 1 ) |
|
|
|
while( icnt > 1 ) |
|
|
|
{ |
|
|
|
ii = gen_rats_block_to_block( DrawPanel, DC, pt_liste_pad, |
|
|
|
pt_end_liste, &nb_local_chevelu ); |
|
|
|
icnt = gen_rats_block_to_block( DrawPanel, m_Pcb->m_LocalRatsnest, |
|
|
|
baseListePad + ii, baseListePad + jj ); |
|
|
|
} |
|
|
|
|
|
|
|
pt_liste_pad = pt_start_liste = pt_end_liste; |
|
|
|
if( pt_start_liste < pt_liste_pad_limite ) |
|
|
|
current_net_code = (*pt_start_liste)->GetNet(); |
|
|
|
ii = jj; |
|
|
|
if( ii < s_localPadBuffer.size() ) |
|
|
|
current_net_code = s_localPadBuffer[ii]->GetNet(); |
|
|
|
} |
|
|
|
|
|
|
|
pt_fin_int_chevelu = local_chevelu = g_pt_chevelu; |
|
|
|
nb_int_chevelu = nb_local_chevelu; |
|
|
|
internalRatsCount = m_Pcb->m_LocalRatsnest.size(); |
|
|
|
|
|
|
|
/* set the ratsnets status, flag LOCAL_RATSNEST_ITEM */ |
|
|
|
g_pt_chevelu = local_liste_chevelu; |
|
|
|
while( g_pt_chevelu < pt_fin_int_chevelu ) |
|
|
|
for( unsigned ii = 0; ii < m_Pcb->m_LocalRatsnest.size(); ii++ ) |
|
|
|
{ |
|
|
|
g_pt_chevelu->m_Status = LOCAL_RATSNEST_ITEM; g_pt_chevelu++; |
|
|
|
m_Pcb->m_LocalRatsnest[ii].m_Status = LOCAL_RATSNEST_ITEM; |
|
|
|
} |
|
|
|
|
|
|
|
m_Pcb->m_Status_Pcb |= RATSNEST_ITEM_LOCAL_OK; |
|
|
|
@ -948,77 +892,69 @@ char* WinEDA_BasePcbFrame::build_ratsnest_module( wxDC* DC, MODULE* Module ) |
|
|
|
/*
|
|
|
|
* This section computes the "external" ratsnest: must be done when the footprint position changes |
|
|
|
*/ |
|
|
|
calcul_chevelu_ext: |
|
|
|
|
|
|
|
CalculateExternalRatsnest: |
|
|
|
/* This section search:
|
|
|
|
* for each current module pad the nearest neighbour external pad (of course for the same net code). |
|
|
|
* For each current footprint cluster of pad (pads having the same net code), |
|
|
|
* we keep the smaller ratsnest. |
|
|
|
* we search the smaller rats nest. |
|
|
|
* so, for each net, only one rats nest item is created |
|
|
|
*/ |
|
|
|
local_chevelu = pt_fin_int_chevelu; |
|
|
|
nb_local_chevelu = nb_int_chevelu; |
|
|
|
pt_liste_ref = (D_PAD**) adr_lowmem; |
|
|
|
pad_ref = *pt_liste_ref; |
|
|
|
|
|
|
|
current_net_code = pad_ref->GetNet(); |
|
|
|
local_chevelu->m_Lenght = 0x7FFFFFFF; |
|
|
|
local_chevelu->m_Status = 0; |
|
|
|
increment = 0; |
|
|
|
for( ii = 0; ii < nb_pads_ref; ii++ ) |
|
|
|
RATSNEST_ITEM local_rats; |
|
|
|
local_rats.m_Lenght = 0x7FFFFFFF; |
|
|
|
local_rats.m_Status = 0; |
|
|
|
bool addRats = false; |
|
|
|
if( internalRatsCount < m_Pcb->m_LocalRatsnest.size() ) |
|
|
|
m_Pcb->m_LocalRatsnest.erase( m_Pcb->m_LocalRatsnest.begin() + internalRatsCount, |
|
|
|
m_Pcb->m_LocalRatsnest.end() ); |
|
|
|
|
|
|
|
current_net_code = s_localPadBuffer[0]->GetNet(); |
|
|
|
for( unsigned ii = 0; ii < pads_module_count; ii++ ) |
|
|
|
{ |
|
|
|
pad_ref = *(pt_liste_ref + ii); |
|
|
|
pad_ref = s_localPadBuffer[ii]; |
|
|
|
if( pad_ref->GetNet() != current_net_code ) |
|
|
|
{ |
|
|
|
/* if needed a new ratsenest for each new net */ |
|
|
|
if( increment ) |
|
|
|
/* if needed, creates a new ratsnest for the old net */ |
|
|
|
if( addRats ) |
|
|
|
{ |
|
|
|
nb_local_chevelu++; local_chevelu++; |
|
|
|
m_Pcb->m_LocalRatsnest.push_back( local_rats ); |
|
|
|
} |
|
|
|
increment = 0; |
|
|
|
current_net_code = pad_ref->GetNet(); |
|
|
|
local_chevelu->m_Lenght = 0x7FFFFFFF; |
|
|
|
addRats = false; |
|
|
|
current_net_code = pad_ref->GetNet(); |
|
|
|
local_rats.m_Lenght = 0x7FFFFFFF; |
|
|
|
} |
|
|
|
|
|
|
|
pad_pos_X = pad_ref->m_Pos.x - g_Offset_Module.x; |
|
|
|
pad_pos_Y = pad_ref->m_Pos.y - g_Offset_Module.y; |
|
|
|
pt_liste_generale = pt_liste_ref + nb_pads_ref; |
|
|
|
pad_pos = pad_ref->m_Pos - g_Offset_Module; |
|
|
|
|
|
|
|
for( jj = nb_pads_externes; jj > 0; jj-- ) |
|
|
|
// Search the nearest external pad of this current pad
|
|
|
|
for( unsigned jj = pads_module_count; jj < s_localPadBuffer.size(); jj++ ) |
|
|
|
{ |
|
|
|
pad_externe = *pt_liste_generale; pt_liste_generale++; |
|
|
|
pad_externe = s_localPadBuffer[jj]; |
|
|
|
|
|
|
|
/* we search pads having the same net coade */ |
|
|
|
/* we search pads having the same net code */ |
|
|
|
if( pad_externe->GetNet() < pad_ref->GetNet() ) |
|
|
|
continue; |
|
|
|
|
|
|
|
if( pad_externe->GetNet() > pad_ref->GetNet() ) // remember pads are sorted by net code
|
|
|
|
break; |
|
|
|
|
|
|
|
distance = abs( pad_externe->m_Pos.x - pad_pos_X ) + |
|
|
|
abs( pad_externe->m_Pos.y - pad_pos_Y ); |
|
|
|
distance = abs( pad_externe->m_Pos.x - pad_pos.x ) + |
|
|
|
abs( pad_externe->m_Pos.y - pad_pos.y ); |
|
|
|
|
|
|
|
if( distance < local_chevelu->m_Lenght ) |
|
|
|
if( distance < local_rats.m_Lenght ) |
|
|
|
{ |
|
|
|
local_chevelu->m_PadStart = pad_ref; |
|
|
|
local_chevelu->m_PadEnd = pad_externe; |
|
|
|
local_chevelu->SetNet( pad_ref->GetNet() ); |
|
|
|
local_chevelu->m_Lenght = distance; |
|
|
|
local_chevelu->m_Status = 0; |
|
|
|
local_rats.m_PadStart = pad_ref; |
|
|
|
local_rats.m_PadEnd = pad_externe; |
|
|
|
local_rats.SetNet( pad_ref->GetNet() ); |
|
|
|
local_rats.m_Lenght = distance; |
|
|
|
local_rats.m_Status = 0; |
|
|
|
|
|
|
|
increment = 1; |
|
|
|
addRats = true; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if( increment ) // fin de balayage : le ratsnest courant doit etre memorise
|
|
|
|
{ |
|
|
|
nb_local_chevelu++; |
|
|
|
local_chevelu++; |
|
|
|
} |
|
|
|
|
|
|
|
return (char*) (local_chevelu + 1); /* the struct pointed by local_chevelu is used
|
|
|
|
* in temporary computations, so we skip it |
|
|
|
*/ |
|
|
|
if( addRats ) // Ensure the last created rats nest item is stored in buffer
|
|
|
|
m_Pcb->m_LocalRatsnest.push_back( local_rats ); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -1030,35 +966,28 @@ void WinEDA_BasePcbFrame::trace_ratsnest_module( wxDC* DC ) |
|
|
|
* Display the rastnest of a moving footprint, computed by build_ratsnest_module() |
|
|
|
*/ |
|
|
|
{ |
|
|
|
RATSNEST_ITEM* local_chevelu; |
|
|
|
int ii; |
|
|
|
|
|
|
|
if( DC == NULL ) |
|
|
|
return; |
|
|
|
if( (m_Pcb->m_Status_Pcb & RATSNEST_ITEM_LOCAL_OK) == 0 ) |
|
|
|
return; |
|
|
|
|
|
|
|
local_chevelu = local_liste_chevelu; |
|
|
|
ii = nb_local_chevelu; |
|
|
|
|
|
|
|
GRSetDrawMode( DC, GR_XOR ); |
|
|
|
int tmpcolor = g_DesignSettings.m_RatsnestColor; |
|
|
|
while( ii-- > 0 ) |
|
|
|
for( unsigned ii = 0; ii < m_Pcb->m_LocalRatsnest.size(); ii++ ) |
|
|
|
{ |
|
|
|
if( local_chevelu->m_Status & LOCAL_RATSNEST_ITEM ) |
|
|
|
RATSNEST_ITEM* rats = &m_Pcb->m_LocalRatsnest[ii]; |
|
|
|
if( rats->m_Status & LOCAL_RATSNEST_ITEM ) |
|
|
|
{ |
|
|
|
g_DesignSettings.m_RatsnestColor = YELLOW; |
|
|
|
local_chevelu->Draw( DrawPanel, DC, GR_XOR, g_Offset_Module ); |
|
|
|
rats->Draw( DrawPanel, DC, GR_XOR, g_Offset_Module ); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
g_DesignSettings.m_RatsnestColor = tmpcolor; |
|
|
|
wxPoint tmp = local_chevelu->m_PadStart->m_Pos; |
|
|
|
local_chevelu->m_PadStart->m_Pos -= g_Offset_Module; |
|
|
|
local_chevelu->Draw( DrawPanel, DC, GR_XOR, wxPoint(0,0) ); |
|
|
|
local_chevelu->m_PadStart->m_Pos = tmp; |
|
|
|
wxPoint tmp = rats->m_PadStart->m_Pos; |
|
|
|
rats->m_PadStart->m_Pos -= g_Offset_Module; |
|
|
|
rats->Draw( DrawPanel, DC, GR_XOR, wxPoint( 0, 0 ) ); |
|
|
|
rats->m_PadStart->m_Pos = tmp; |
|
|
|
} |
|
|
|
local_chevelu++; |
|
|
|
} |
|
|
|
|
|
|
|
g_DesignSettings.m_RatsnestColor = tmpcolor; |
|
|
|
@ -1106,11 +1035,12 @@ void WinEDA_BasePcbFrame::build_ratsnest_pad( BOARD_ITEM* ref, |
|
|
|
const wxPoint& refpos, bool init ) |
|
|
|
/****************************************************************************************/ |
|
|
|
{ |
|
|
|
int current_net_code = 0, conn_number = 0; |
|
|
|
D_PAD* pad_ref = NULL; |
|
|
|
int current_net_code = 0, conn_number = 0; |
|
|
|
D_PAD* pad_ref = NULL; |
|
|
|
|
|
|
|
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 & NET_CODES_OK) == 0 ) ) |
|
|
|
|| ( (m_Pcb->m_Status_Pcb & LISTE_PAD_OK) == 0 ) |
|
|
|
|| ( (m_Pcb->m_Status_Pcb & NET_CODES_OK) == 0 ) ) |
|
|
|
{ |
|
|
|
s_RatsnestMouseToPads.clear(); |
|
|
|
return; |
|
|
|
@ -1148,9 +1078,12 @@ void WinEDA_BasePcbFrame::build_ratsnest_pad( BOARD_ITEM* ref, |
|
|
|
if( current_net_code <= 0 ) |
|
|
|
return; |
|
|
|
|
|
|
|
NETINFO_ITEM * net = m_Pcb->FindNet(current_net_code); |
|
|
|
if ( net == NULL ) |
|
|
|
NETINFO_ITEM* net = m_Pcb->FindNet( current_net_code ); |
|
|
|
if ( net == NULL ) //Should not occur
|
|
|
|
{ |
|
|
|
DisplayError(this,wxT("build_ratsnest_pad() error: net not found") ); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// Create a list of pads candidates ( pads not already connected to the current track:
|
|
|
|
for( unsigned ii = 0; ii < net->m_ListPad.size(); ii++ ) |
|
|
|
@ -1164,7 +1097,7 @@ void WinEDA_BasePcbFrame::build_ratsnest_pad( BOARD_ITEM* ref, |
|
|
|
} |
|
|
|
} /* end if Init */ |
|
|
|
|
|
|
|
if( s_RatsnestMouseToPads.size() > 1) |
|
|
|
if( s_RatsnestMouseToPads.size() > 1 ) |
|
|
|
sort( s_RatsnestMouseToPads.begin(), s_RatsnestMouseToPads.end(), sort_by_localnetlength ); |
|
|
|
} |
|
|
|
|
|
|
|
@ -1180,12 +1113,12 @@ void WinEDA_BasePcbFrame::trace_ratsnest_pad( wxDC* DC ) |
|
|
|
if( DC == NULL ) |
|
|
|
return; |
|
|
|
|
|
|
|
if( s_RatsnestMouseToPads.size() == 0) |
|
|
|
if( s_RatsnestMouseToPads.size() == 0 ) |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
GRSetDrawMode( DC, GR_XOR ); |
|
|
|
for( int ii = 0; ii < (int)s_RatsnestMouseToPads.size(); ii++ ) |
|
|
|
for( int ii = 0; ii < (int) s_RatsnestMouseToPads.size(); ii++ ) |
|
|
|
{ |
|
|
|
if( ii >= g_MaxLinksShowed ) |
|
|
|
break; |
|
|
|
|