Pcbnew: fixed a recent bug that could be creates errors in rats nest calculations (forgotten rats nets)
This commit is contained in:
parent
7fc9e5f177
commit
6791556e3a
|
@ -8,7 +8,11 @@
|
||||||
#include "appl_wxstruct.h"
|
#include "appl_wxstruct.h"
|
||||||
|
|
||||||
|
|
||||||
#define BUILD_VERSION wxT("(20090602-unstable)")
|
#define BUILD_VERSION "(20090621-unstable)"
|
||||||
|
#ifndef KICAD_ABOUT_VERSION
|
||||||
|
#define KICAD_ABOUT_VERSION BUILD_VERSION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
wxString g_BuildVersion
|
wxString g_BuildVersion
|
||||||
|
|
||||||
|
@ -16,7 +20,7 @@ wxString g_BuildVersion
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
( wxT( KICAD_SVN_VERSION ) )
|
( wxT( KICAD_SVN_VERSION ) )
|
||||||
#else
|
#else
|
||||||
( BUILD_VERSION )
|
( wxT( BUILD_VERSION ) )
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -25,7 +29,7 @@ wxString g_BuildAboutVersion
|
||||||
# include "version.h"
|
# include "version.h"
|
||||||
( wxT( KICAD_ABOUT_VERSION ) )
|
( wxT( KICAD_ABOUT_VERSION ) )
|
||||||
#else
|
#else
|
||||||
( BUILD_VERSION )
|
( wxT( BUILD_VERSION ) )
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -4,16 +4,11 @@
|
||||||
|
|
||||||
/* read the generic netlist created by eeschema and convert it to a pads-pcb form
|
/* read the generic netlist created by eeschema and convert it to a pads-pcb form
|
||||||
*/
|
*/
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#if defined( HAVE_STRINGS_H )
|
|
||||||
#include <strings.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
/* Pads-pcb sample:
|
/* Pads-pcb sample:
|
||||||
|
@ -109,6 +104,7 @@
|
||||||
char* GetLine( FILE* File, char* Line, int* LineNum, int SizeLine );
|
char* GetLine( FILE* File, char* Line, int* LineNum, int SizeLine );
|
||||||
int ReadAndWriteComponentDataSection( FILE* InFile, FILE* OutFile, int* LineNumber );
|
int ReadAndWriteComponentDataSection( FILE* InFile, FILE* OutFile, int* LineNumber );
|
||||||
int ReadAndWriteNetsDataSection( FILE* InFile, FILE* OutFile, int* LineNumber );
|
int ReadAndWriteNetsDataSection( FILE* InFile, FILE* OutFile, int* LineNumber );
|
||||||
|
int AreStringsEqual( const char * src, const char * ref );
|
||||||
|
|
||||||
|
|
||||||
class ComponentDataClass
|
class ComponentDataClass
|
||||||
|
@ -174,12 +170,12 @@ int main( int argc, char** argv )
|
||||||
/* Read and write data lines */
|
/* Read and write data lines */
|
||||||
while( GetLine( InFile, Line, &LineNumber, sizeof(Line) ) )
|
while( GetLine( InFile, Line, &LineNumber, sizeof(Line) ) )
|
||||||
{
|
{
|
||||||
if( stricmp( Line, "$BeginComponent" ) == 0 )
|
if( AreStringsEqual( Line, "$BeginComponent" ) )
|
||||||
{
|
{
|
||||||
ReadAndWriteComponentDataSection( InFile, OutFile, &LineNumber );
|
ReadAndWriteComponentDataSection( InFile, OutFile, &LineNumber );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if( stricmp( Line, "$BeginNets" ) == 0 )
|
if( AreStringsEqual( Line, "$BeginNets" ) )
|
||||||
{
|
{
|
||||||
fprintf( OutFile, "\n*NET*\n" );
|
fprintf( OutFile, "\n*NET*\n" );
|
||||||
ReadAndWriteNetsDataSection( InFile, OutFile, &LineNumber );
|
ReadAndWriteNetsDataSection( InFile, OutFile, &LineNumber );
|
||||||
|
@ -215,16 +211,16 @@ int ReadAndWriteComponentDataSection( FILE* InFile, FILE* OutFile, int* LineNumb
|
||||||
|
|
||||||
while( GetLine( InFile, Line, LineNumber, sizeof(Line) ) )
|
while( GetLine( InFile, Line, LineNumber, sizeof(Line) ) )
|
||||||
{
|
{
|
||||||
if( stricmp( Line, "$BeginPinList" ) == 0 )
|
if( AreStringsEqual( Line, "$BeginPinList" ) )
|
||||||
{
|
{
|
||||||
while( GetLine( InFile, Line, LineNumber, sizeof(Line) ) )
|
while( GetLine( InFile, Line, LineNumber, sizeof(Line) ) )
|
||||||
if( stricmp( Line, "$EndPinList" ) == 0 )
|
if( AreStringsEqual( Line, "$EndPinList" ) )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( stricmp( Line, "$EndComponent" ) == 0 ) // Create the output for the component:
|
if( AreStringsEqual( Line, "$EndComponent" ) ) // Create the output for the component:
|
||||||
{
|
{
|
||||||
/* Create the line like: C2 unknown */
|
/* Create the line like: C2 unknown */
|
||||||
|
|
||||||
|
@ -237,27 +233,27 @@ int ReadAndWriteComponentDataSection( FILE* InFile, FILE* OutFile, int* LineNumb
|
||||||
data = strtok( NULL, "=\n\r" );
|
data = strtok( NULL, "=\n\r" );
|
||||||
if( data == NULL )
|
if( data == NULL )
|
||||||
continue;
|
continue;
|
||||||
if( stricmp( Line, "TimeStamp" ) == 0 )
|
if( AreStringsEqual( Line, "TimeStamp" ) )
|
||||||
{
|
{
|
||||||
ComponentData.m_TimeStamp = atol( data );
|
ComponentData.m_TimeStamp = atol( data );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if( stricmp( Line, "Footprint" ) == 0 )
|
if( AreStringsEqual( Line, "Footprint" ) )
|
||||||
{
|
{
|
||||||
strncpy( ComponentData.m_Footprint, data, 255 );
|
strncpy( ComponentData.m_Footprint, data, 255 );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if( stricmp( Line, "Reference" ) == 0 )
|
if( AreStringsEqual( Line, "Reference" ) )
|
||||||
{
|
{
|
||||||
strncpy( ComponentData.m_Reference, data, 255 );
|
strncpy( ComponentData.m_Reference, data, 255 );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if( stricmp( Line, "Value" ) == 0 )
|
if( AreStringsEqual( Line, "Value" ) )
|
||||||
{
|
{
|
||||||
strncpy( ComponentData.m_Value, data, 255 );
|
strncpy( ComponentData.m_Value, data, 255 );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if( stricmp( Line, "Libref" ) == 0 )
|
if( AreStringsEqual( Line, "Libref" ) )
|
||||||
{
|
{
|
||||||
strncpy( ComponentData.m_LibRef, data, 255 );
|
strncpy( ComponentData.m_LibRef, data, 255 );
|
||||||
continue;
|
continue;
|
||||||
|
@ -283,10 +279,10 @@ int ReadAndWriteNetsDataSection( FILE* InFile, FILE* OutFile, int* LineNumber )
|
||||||
|
|
||||||
while( GetLine( InFile, Line, LineNumber, sizeof(Line) ) )
|
while( GetLine( InFile, Line, LineNumber, sizeof(Line) ) )
|
||||||
{
|
{
|
||||||
if( stricmp( Line, "$EndNets" ) == 0 )
|
if( AreStringsEqual( Line, "$EndNets" ) )
|
||||||
return 0;
|
return 0;
|
||||||
ident = strtok( Line, " \n\r" );
|
ident = strtok( Line, " \n\r" );
|
||||||
if( stricmp( ident, "Net" ) == 0 )
|
if( AreStringsEqual( ident, "Net" ) )
|
||||||
{
|
{
|
||||||
netnum = strtok( NULL, " \n\r" );
|
netnum = strtok( NULL, " \n\r" );
|
||||||
netname = strtok( NULL, " \"\n\r" );
|
netname = strtok( NULL, " \"\n\r" );
|
||||||
|
@ -330,3 +326,32 @@ char* GetLine( FILE* File, char* Line, int* LineNum, int SizeLine )
|
||||||
strtok( Line, "\n\r" );
|
strtok( Line, "\n\r" );
|
||||||
return Line;
|
return Line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************/
|
||||||
|
int AreStringsEqual( const char * src, const char * ref )
|
||||||
|
/***************************************************/
|
||||||
|
/* Compare 2 chains, and return 0 if equal or 1 if different
|
||||||
|
* stricmp does the same job, but does not exist under all systems
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
int match = 1;
|
||||||
|
while (src && ref )
|
||||||
|
{
|
||||||
|
unsigned char c1 = *src;
|
||||||
|
unsigned char c2 = *ref;
|
||||||
|
if ( c1 >= 'a' && c1 <= 'z' )
|
||||||
|
c1 += 'A' - 'a';
|
||||||
|
if ( c2 >= 'a' && c2 <= 'z' )
|
||||||
|
c2 += 'A' - 'a';
|
||||||
|
if ( c1 != c2 )
|
||||||
|
{
|
||||||
|
match = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ( c1 == 0 || c2 == 0 )
|
||||||
|
break;
|
||||||
|
src++; ref++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
|
@ -121,7 +121,7 @@ bool SCH_SCREEN::Save( FILE* aFile ) const
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for( LibraryStruct* Lib = g_LibraryList; Lib != NULL; Lib = Lib->m_Pnext )
|
for( LibraryStruct* Lib = g_LibraryList; Lib != NULL; Lib = Lib->m_Pnext )
|
||||||
{
|
{
|
||||||
if( first )
|
if( ! first )
|
||||||
Name += wxT( "," );
|
Name += wxT( "," );
|
||||||
Name += Lib->m_Name;
|
Name += Lib->m_Name;
|
||||||
first = false;
|
first = false;
|
||||||
|
|
|
@ -50,7 +50,7 @@ DIALOG_EXCHANGE_MODULE_BASE::DIALOG_EXCHANGE_MODULE_BASE( wxWindow* parent, wxWi
|
||||||
|
|
||||||
wxString m_SelectionChoices[] = { _("Change module"), _("Change same modules"), _("Ch. same module+value"), _("Change all") };
|
wxString m_SelectionChoices[] = { _("Change module"), _("Change same modules"), _("Ch. same module+value"), _("Change all") };
|
||||||
int m_SelectionNChoices = sizeof( m_SelectionChoices ) / sizeof( wxString );
|
int m_SelectionNChoices = sizeof( m_SelectionChoices ) / sizeof( wxString );
|
||||||
m_Selection = new wxRadioBox( this, ID_SELECTION_CLICKED, _("wxRadioBox"), wxDefaultPosition, wxDefaultSize, m_SelectionNChoices, m_SelectionChoices, 1, wxRA_SPECIFY_COLS );
|
m_Selection = new wxRadioBox( this, ID_SELECTION_CLICKED, _("Browse Libs modules"), wxDefaultPosition, wxDefaultSize, m_SelectionNChoices, m_SelectionChoices, 1, wxRA_SPECIFY_COLS );
|
||||||
m_Selection->SetSelection( 0 );
|
m_Selection->SetSelection( 0 );
|
||||||
bMiddleSizer->Add( m_Selection, 0, wxALL, 5 );
|
bMiddleSizer->Add( m_Selection, 0, wxALL, 5 );
|
||||||
|
|
||||||
|
|
|
@ -435,7 +435,7 @@
|
||||||
<property name="font"></property>
|
<property name="font"></property>
|
||||||
<property name="hidden">0</property>
|
<property name="hidden">0</property>
|
||||||
<property name="id">ID_SELECTION_CLICKED</property>
|
<property name="id">ID_SELECTION_CLICKED</property>
|
||||||
<property name="label">wxRadioBox</property>
|
<property name="label">Browse Libs modules</property>
|
||||||
<property name="majorDimension">1</property>
|
<property name="majorDimension">1</property>
|
||||||
<property name="maximum_size"></property>
|
<property name="maximum_size"></property>
|
||||||
<property name="minimum_size"></property>
|
<property name="minimum_size"></property>
|
||||||
|
|
|
@ -13,7 +13,14 @@
|
||||||
|
|
||||||
#include "protos.h"
|
#include "protos.h"
|
||||||
|
|
||||||
#define DBG_BUID_NETINFO
|
/* Sometimes Pcbnew crashes when calculating net info (Heap Error)
|
||||||
|
* gen_rats_block_to_block() seems the culprit, but because this is a memory allocation error, it is not sure.
|
||||||
|
* define DBG_BUILD_NETINFO diplays som diags.
|
||||||
|
* All code between #define DBG_BUILD_NETINFO and #endif will be removed when ths issue will be solved
|
||||||
|
* Comment this next line for normal use
|
||||||
|
* JP Charras
|
||||||
|
*/
|
||||||
|
//#define DBG_BUILD_NETINFO
|
||||||
|
|
||||||
/* local variables */
|
/* local variables */
|
||||||
static std::vector <D_PAD*> s_localPadBuffer; // for local ratsnest calculations when moving a footprint: buffer of pads to consider
|
static std::vector <D_PAD*> s_localPadBuffer; // for local ratsnest calculations when moving a footprint: buffer of pads to consider
|
||||||
|
@ -109,7 +116,7 @@ void WinEDA_BasePcbFrame::Compile_Ratsnest( wxDC* DC, bool display_status_pcb )
|
||||||
|
|
||||||
GetBoard()->m_Status_Pcb = 0; /* we want a full ratnest computation, from the scratch */
|
GetBoard()->m_Status_Pcb = 0; /* we want a full ratnest computation, from the scratch */
|
||||||
MsgPanel->EraseMsgBox();
|
MsgPanel->EraseMsgBox();
|
||||||
#ifdef DBG_BUID_NETINFO
|
#ifdef DBG_BUILD_NETINFO
|
||||||
wxSafeYield();
|
wxSafeYield();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -128,7 +135,7 @@ void WinEDA_BasePcbFrame::Compile_Ratsnest( wxDC* DC, bool display_status_pcb )
|
||||||
msg.Printf( wxT( " %d" ), m_Pcb->m_NetInfo->GetNetsCount() );
|
msg.Printf( wxT( " %d" ), m_Pcb->m_NetInfo->GetNetsCount() );
|
||||||
Affiche_1_Parametre( this, 8, wxT( "Nets" ), msg, CYAN );
|
Affiche_1_Parametre( this, 8, wxT( "Nets" ), msg, CYAN );
|
||||||
}
|
}
|
||||||
#ifdef DBG_BUID_NETINFO
|
#ifdef DBG_BUILD_NETINFO
|
||||||
wxSafeYield();
|
wxSafeYield();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -138,17 +145,34 @@ void WinEDA_BasePcbFrame::Compile_Ratsnest( wxDC* DC, bool display_status_pcb )
|
||||||
* This full ratsnest is not modified by track editing.
|
* This full ratsnest is not modified by track editing.
|
||||||
* It changes only when a netlist is read, or footprints are modified
|
* It changes only when a netlist is read, or footprints are modified
|
||||||
*/
|
*/
|
||||||
|
#ifdef DBG_BUILD_NETINFO
|
||||||
|
Affiche_Message( wxT( "Build Board Ratsnest" ) );
|
||||||
|
wxSafeYield();
|
||||||
|
#endif
|
||||||
Build_Board_Ratsnest( DC );
|
Build_Board_Ratsnest( DC );
|
||||||
|
|
||||||
/* Compute the pad connections due to the existing tracks (physical connections)*/
|
/* Compute the pad connections due to the existing tracks (physical connections)*/
|
||||||
|
#ifdef DBG_BUILD_NETINFO
|
||||||
|
Affiche_Message( wxT( "testconnexions" ) );
|
||||||
|
wxSafeYield();
|
||||||
|
#endif
|
||||||
test_connexions( DC );
|
test_connexions( DC );
|
||||||
|
|
||||||
/* Compute the active ratsnest, i.e. the unconnected links
|
/* Compute the active ratsnest, i.e. the unconnected links
|
||||||
* it is faster than Build_Board_Ratsnest()
|
* it is faster than Build_Board_Ratsnest()
|
||||||
* because many optimisations and computations are already made
|
* because many optimisations and computations are already made
|
||||||
*/
|
*/
|
||||||
|
#ifdef DBG_BUILD_NETINFO
|
||||||
|
Affiche_Message( wxT( "Tst Ratsnest" ) );
|
||||||
|
wxSafeYield();
|
||||||
|
#endif
|
||||||
Tst_Ratsnest( DC, 0 );
|
Tst_Ratsnest( DC, 0 );
|
||||||
|
|
||||||
|
#ifdef DBG_BUILD_NETINFO
|
||||||
|
Affiche_Message( wxT( "End Tst Ratsnest" ) );
|
||||||
|
wxSafeYield();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Redraw the active ratsnest ( if enabled )
|
// Redraw the active ratsnest ( if enabled )
|
||||||
if( g_Show_Ratsnest && DC )
|
if( g_Show_Ratsnest && DC )
|
||||||
DrawGeneralRatsnest( DC, 0 );
|
DrawGeneralRatsnest( DC, 0 );
|
||||||
|
@ -189,10 +213,10 @@ static int sort_by_length( const void* o1, const void* o2 )
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
static int gen_rats_block_to_block( WinEDA_DrawPanel* aDrawPanel,
|
static int gen_rats_block_to_block( std::vector<RATSNEST_ITEM>& aRatsnestBuffer,
|
||||||
std::vector<RATSNEST_ITEM>& aRatsnestBuffer,
|
std::vector<D_PAD*>& aPadBuffer,
|
||||||
D_PAD** aPadList,
|
unsigned aPadIdxStart,
|
||||||
D_PAD** aPadMax )
|
unsigned aPadIdxMax )
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -203,41 +227,37 @@ static int gen_rats_block_to_block( WinEDA_DrawPanel* aDrawPanel,
|
||||||
* the block n ( n > 1 ) it connected to block 1 by their 2 nearest pads.
|
* 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
|
* When the block is found, it is merged with the block 1
|
||||||
* the D_PAD member m_SubRatsnest handles the block number
|
* the D_PAD member m_SubRatsnest handles the block number
|
||||||
* @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
|
* @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
|
* @return blocks not connected count
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
int dist_min, current_dist;
|
int dist_min, current_dist;
|
||||||
int current_num_block = 1;
|
int current_num_block = 1;
|
||||||
D_PAD** pt_liste_pad_tmp;
|
int padBlock1Idx = -1; // Index in aPadBuffer for the "better" pad found in block 1
|
||||||
D_PAD** pt_liste_pad_aux;
|
int padBlockToMergeIdx = -1; // Index in aPadBuffer for the "better" pad found in block to merge
|
||||||
D_PAD** pt_liste_pad_block1 = NULL;
|
|
||||||
D_PAD** pt_start_liste;
|
|
||||||
|
|
||||||
pt_liste_pad_tmp = NULL;
|
|
||||||
|
|
||||||
dist_min = 0x7FFFFFFF;
|
dist_min = 0x7FFFFFFF;
|
||||||
|
|
||||||
pt_start_liste = aPadList;
|
|
||||||
|
|
||||||
/* Search the nearest pad from block 1 */
|
/* Search the nearest pad from block 1 */
|
||||||
for( ; aPadList < aPadMax; aPadList++ )
|
for( unsigned ii = aPadIdxStart; ii < aPadIdxMax; ii++ )
|
||||||
{
|
{
|
||||||
D_PAD* ref_pad = *aPadList;
|
D_PAD* ref_pad = aPadBuffer[ii];
|
||||||
|
#ifdef DBG_BUILD_NETINFO
|
||||||
|
if( ref_pad->Type() != TYPE_PAD )
|
||||||
|
wxMessageBox( wxT( "gen_rats_block_to_block() err: ref_pad is not a D_PAD" ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
/* search a pad which is in the block 1 */
|
/* search a pad which is in the block 1 */
|
||||||
if( ref_pad->GetSubRatsnest() != 1 )
|
if( ref_pad->GetSubRatsnest() != 1 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* pad is found, search its nearest neighbour in other blocks */
|
/* pad is found, search its nearest neighbour in other blocks */
|
||||||
for( pt_liste_pad_aux = pt_start_liste; ; pt_liste_pad_aux++ )
|
for( unsigned jj = aPadIdxStart; jj < aPadIdxMax; jj++ )
|
||||||
{
|
{
|
||||||
D_PAD* curr_pad = *pt_liste_pad_aux;
|
D_PAD* curr_pad = aPadBuffer[jj];
|
||||||
|
|
||||||
if( pt_liste_pad_aux >= aPadMax )
|
|
||||||
break;
|
|
||||||
|
|
||||||
if( curr_pad->GetSubRatsnest() == 1 ) // not in an other block
|
if( curr_pad->GetSubRatsnest() == 1 ) // not in an other block
|
||||||
continue;
|
continue;
|
||||||
|
@ -253,8 +273,8 @@ static int gen_rats_block_to_block( WinEDA_DrawPanel* aDrawPanel,
|
||||||
current_num_block = curr_pad->GetSubRatsnest();
|
current_num_block = curr_pad->GetSubRatsnest();
|
||||||
dist_min = current_dist;
|
dist_min = current_dist;
|
||||||
|
|
||||||
pt_liste_pad_tmp = pt_liste_pad_aux;
|
padBlockToMergeIdx = jj;
|
||||||
pt_liste_pad_block1 = aPadList;
|
padBlock1Idx = ii;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,35 +286,39 @@ static int gen_rats_block_to_block( WinEDA_DrawPanel* aDrawPanel,
|
||||||
*/
|
*/
|
||||||
if( current_num_block > 1 )
|
if( current_num_block > 1 )
|
||||||
{
|
{
|
||||||
/* The block n is merged with the bloc 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
|
* to do that, we set the m_SubRatsnest member to 1 for all pads in block n
|
||||||
*/
|
*/
|
||||||
for( aPadList = pt_start_liste; aPadList < aPadMax; aPadList++ )
|
for( unsigned ii = aPadIdxStart; ii < aPadIdxMax; ii++ )
|
||||||
{
|
{
|
||||||
if( (*aPadList)->GetSubRatsnest() == current_num_block )
|
D_PAD* pad = aPadBuffer[ii];
|
||||||
(*aPadList)->SetSubRatsnest( 1 );
|
if( pad->GetSubRatsnest() == current_num_block )
|
||||||
|
pad->SetSubRatsnest( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
aPadList = pt_liste_pad_block1;
|
if( padBlock1Idx < 0 )
|
||||||
|
DisplayError( NULL, wxT( "gen_rats_block_to_block() internal error" ) );
|
||||||
|
else
|
||||||
|
{
|
||||||
/* Create the new ratsnet */
|
/* Create the new ratsnet */
|
||||||
RATSNEST_ITEM net;
|
RATSNEST_ITEM net;
|
||||||
net.SetNet( (*aPadList)->GetNet() );
|
net.SetNet( aPadBuffer[padBlock1Idx]->GetNet() );
|
||||||
net.m_Status = CH_ACTIF | CH_VISIBLE;
|
net.m_Status = CH_ACTIF | CH_VISIBLE;
|
||||||
net.m_Lenght = dist_min;
|
net.m_Lenght = dist_min;
|
||||||
net.m_PadStart = *aPadList;
|
net.m_PadStart = aPadBuffer[padBlock1Idx];
|
||||||
net.m_PadEnd = *pt_liste_pad_tmp;
|
net.m_PadEnd = aPadBuffer[padBlockToMergeIdx];
|
||||||
aRatsnestBuffer.push_back( net );
|
aRatsnestBuffer.push_back( net );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return current_num_block;
|
return current_num_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
static int gen_rats_pad_to_pad( WinEDA_DrawPanel* aDrawPanel,
|
static int gen_rats_pad_to_pad( vector<RATSNEST_ITEM>& aRatsnestBuffer,
|
||||||
vector<RATSNEST_ITEM>& aRatsnestBuffer,
|
std::vector<D_PAD*>& aPadBuffer,
|
||||||
D_PAD** aPadList,
|
unsigned aPadIdxStart,
|
||||||
D_PAD** aPadMax,
|
unsigned aPadIdxMax,
|
||||||
int current_num_block )
|
int current_num_block )
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
@ -307,42 +331,34 @@ static int gen_rats_pad_to_pad( WinEDA_DrawPanel* aDrawPanel,
|
||||||
* Its creates a block if the 2 pads are not connected, or merge the unconnected pad to the existing block.
|
* 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.
|
* These blocks include 2 pads and the 2 pads are linked by a ratsnest.
|
||||||
*
|
*
|
||||||
* @param pt_liste_pad = starting address in the pad buffer
|
* @param aRatsnestBuffer = a std::vector<RATSNEST_ITEM> buffer to fill with new ratsnest items
|
||||||
* @param pt_limite = ending address
|
* @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 de pads
|
* @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
|
|
||||||
*
|
*
|
||||||
* @return the last block number used
|
* @return the last block number used
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
int dist_min, current_dist;
|
int dist_min, current_dist;
|
||||||
D_PAD** pt_liste_pad_tmp;
|
|
||||||
D_PAD** pt_liste_pad_aux;
|
|
||||||
D_PAD** pt_start_liste;
|
|
||||||
D_PAD* ref_pad, * pad;
|
D_PAD* ref_pad, * pad;
|
||||||
|
|
||||||
pt_start_liste = aPadList;
|
for( unsigned ii = aPadIdxStart; ii < aPadIdxMax; ii++ )
|
||||||
|
|
||||||
for( ; aPadList < aPadMax; aPadList++ )
|
|
||||||
{
|
{
|
||||||
ref_pad = *aPadList;
|
ref_pad = aPadBuffer[ii];
|
||||||
|
|
||||||
if( ref_pad->GetSubRatsnest() )
|
if( ref_pad->GetSubRatsnest() )
|
||||||
continue; // Pad already connected
|
continue; // Pad already connected
|
||||||
|
|
||||||
pt_liste_pad_tmp = NULL;
|
|
||||||
dist_min = 0x7FFFFFFF;
|
dist_min = 0x7FFFFFFF;
|
||||||
|
int padBlockToMergeIdx = -1; // Index in aPadBuffer for the "better" pad found in block to merge
|
||||||
for( pt_liste_pad_aux = pt_start_liste; ; pt_liste_pad_aux++ )
|
for( unsigned jj = aPadIdxStart; jj < aPadIdxMax; jj++ )
|
||||||
{
|
{
|
||||||
if( pt_liste_pad_aux >= aPadMax )
|
if( ii == jj )
|
||||||
break;
|
|
||||||
|
|
||||||
if( pt_liste_pad_aux == aPadList )
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pad = *pt_liste_pad_aux;
|
pad = aPadBuffer[jj];
|
||||||
|
|
||||||
/* Compare distance between pads ("Manhattan" distance) */
|
/* Compare distance between pads ("Manhattan" distance) */
|
||||||
current_dist = abs( pad->m_Pos.x - ref_pad->m_Pos.x ) +
|
current_dist = abs( pad->m_Pos.x - ref_pad->m_Pos.x ) +
|
||||||
|
@ -351,20 +367,20 @@ static int gen_rats_pad_to_pad( WinEDA_DrawPanel* aDrawPanel,
|
||||||
if( dist_min > current_dist )
|
if( dist_min > current_dist )
|
||||||
{
|
{
|
||||||
dist_min = current_dist;
|
dist_min = current_dist;
|
||||||
pt_liste_pad_tmp = pt_liste_pad_aux;
|
padBlockToMergeIdx = jj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pt_liste_pad_tmp != NULL )
|
if( padBlockToMergeIdx >= 0 )
|
||||||
{
|
{
|
||||||
pad = *pt_liste_pad_tmp;
|
pad = aPadBuffer[padBlockToMergeIdx];
|
||||||
|
|
||||||
/* Update the block number
|
/* Update the block number
|
||||||
* if the 2 pads are not already created : a new block is created
|
* if the 2 pads are not already created : a new block is created
|
||||||
*/
|
*/
|
||||||
if( (pad->GetSubRatsnest() == 0) && (ref_pad->GetSubRatsnest() == 0) )
|
if( (pad->GetSubRatsnest() == 0) && (ref_pad->GetSubRatsnest() == 0) )
|
||||||
{
|
{
|
||||||
current_num_block++;
|
current_num_block++; // Creates a new block number (or subratsnest)
|
||||||
pad->SetSubRatsnest( current_num_block );
|
pad->SetSubRatsnest( current_num_block );
|
||||||
ref_pad->SetSubRatsnest( current_num_block );
|
ref_pad->SetSubRatsnest( current_num_block );
|
||||||
}
|
}
|
||||||
|
@ -447,6 +463,10 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
|
||||||
|
|
||||||
unsigned current_net_code = 1; // 1er net_code a analyser (net_code = 0 -> no connect)
|
unsigned current_net_code = 1; // 1er net_code a analyser (net_code = 0 -> no connect)
|
||||||
noconn = 0;
|
noconn = 0;
|
||||||
|
#ifdef DBG_BUILD_NETINFO
|
||||||
|
Affiche_Message( wxT( "Build Board Ratsnest - 1" ) );
|
||||||
|
wxSafeYield();
|
||||||
|
#endif
|
||||||
|
|
||||||
for( ; current_net_code < m_Pcb->m_NetInfo->GetNetsCount(); current_net_code++ )
|
for( ; current_net_code < m_Pcb->m_NetInfo->GetNetsCount(); current_net_code++ )
|
||||||
{
|
{
|
||||||
|
@ -457,7 +477,16 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
net->m_RatsnestStartIdx = m_Pcb->GetRatsnestsCount();
|
net->m_RatsnestStartIdx = m_Pcb->GetRatsnestsCount();
|
||||||
|
#ifdef DBG_BUILD_NETINFO
|
||||||
|
wxString msg;
|
||||||
|
msg.Printf( wxT(
|
||||||
|
"Build Board Ratsnest net %d/%d start" ), current_net_code,
|
||||||
|
m_Pcb->m_NetInfo->GetNetsCount() );
|
||||||
|
Affiche_Message( msg );
|
||||||
|
wxSafeYield();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Search for the last subratsnest already in use
|
||||||
int num_block = 0;
|
int num_block = 0;
|
||||||
for( unsigned ii = 0; ii < net->m_ListPad.size(); ii++ )
|
for( unsigned ii = 0; ii < net->m_ListPad.size(); ii++ )
|
||||||
{
|
{
|
||||||
|
@ -467,22 +496,47 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute the ratsnest relative to the current net */
|
/* Compute the ratsnest relative to the current net */
|
||||||
|
#ifdef DBG_BUILD_NETINFO
|
||||||
|
msg.Printf( wxT(
|
||||||
|
"Build Board Ratsnest net %d/%d first pass" ), current_net_code,
|
||||||
|
m_Pcb->m_NetInfo->GetNetsCount() );
|
||||||
|
Affiche_Message( msg );
|
||||||
|
wxSafeYield();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* a - first pass : create the blocks from not already in block pads */
|
/* a - first pass : create the blocks from not already in block pads */
|
||||||
D_PAD** pstart = &net->m_ListPad[0];
|
int icnt = gen_rats_pad_to_pad( m_Pcb->m_FullRatsnest,
|
||||||
D_PAD** pend = pstart + net->m_ListPad.size();
|
net->m_ListPad,
|
||||||
int icnt = gen_rats_pad_to_pad( DrawPanel, m_Pcb->m_FullRatsnest, pstart, pend,
|
0,
|
||||||
|
net->m_ListPad.size(),
|
||||||
num_block );
|
num_block );
|
||||||
|
|
||||||
|
#ifdef DBG_BUILD_NETINFO
|
||||||
|
msg.Printf( wxT( "Build Board Ratsnest net (%s) %d/%d iteration" ),
|
||||||
|
m_Pcb->FindNet( current_net_code )->GetNetname().GetData(),
|
||||||
|
current_net_code, m_Pcb->m_NetInfo->GetNetsCount() );
|
||||||
|
Affiche_Message( msg );
|
||||||
|
wxSafeYield();
|
||||||
|
#endif
|
||||||
/* b - blocks connection (Iteration) */
|
/* b - blocks connection (Iteration) */
|
||||||
while( icnt > 1 )
|
while( icnt > 1 )
|
||||||
{
|
{
|
||||||
icnt = gen_rats_block_to_block( DrawPanel, m_Pcb->m_FullRatsnest, pstart, pend );
|
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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
net->m_RatsnestEndIdx = m_Pcb->GetRatsnestsCount();
|
net->m_RatsnestEndIdx = m_Pcb->GetRatsnestsCount();
|
||||||
|
|
||||||
|
#ifdef DBG_BUILD_NETINFO
|
||||||
|
msg.Printf( wxT(
|
||||||
|
"Build Board Ratsnest net %d/%d sort" ), current_net_code,
|
||||||
|
m_Pcb->m_NetInfo->GetNetsCount() );
|
||||||
|
Affiche_Message( msg );
|
||||||
|
wxSafeYield();
|
||||||
|
#endif
|
||||||
/* sort by lenght */
|
/* sort by lenght */
|
||||||
|
net = m_Pcb->FindNet( current_net_code );
|
||||||
if( (net->m_RatsnestEndIdx - net->m_RatsnestStartIdx) > 1 )
|
if( (net->m_RatsnestEndIdx - net->m_RatsnestStartIdx) > 1 )
|
||||||
{
|
{
|
||||||
RATSNEST_ITEM* rats = &m_Pcb->m_FullRatsnest[0];
|
RATSNEST_ITEM* rats = &m_Pcb->m_FullRatsnest[0];
|
||||||
|
@ -492,6 +546,10 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DBG_BUILD_NETINFO
|
||||||
|
Affiche_Message( wxT( "Build Board Ratsnest - 2" ) );
|
||||||
|
wxSafeYield();
|
||||||
|
#endif
|
||||||
m_Pcb->m_NbNoconnect = noconn;
|
m_Pcb->m_NbNoconnect = noconn;
|
||||||
m_Pcb->m_Status_Pcb |= LISTE_RATSNEST_ITEM_OK;
|
m_Pcb->m_Status_Pcb |= LISTE_RATSNEST_ITEM_OK;
|
||||||
|
|
||||||
|
@ -507,7 +565,6 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
void WinEDA_BasePcbFrame::DrawGeneralRatsnest( wxDC* DC, int net_code )
|
void WinEDA_BasePcbFrame::DrawGeneralRatsnest( wxDC* DC, int net_code )
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
@ -527,7 +584,8 @@ void WinEDA_BasePcbFrame::DrawGeneralRatsnest( wxDC* DC, int net_code )
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < m_Pcb->GetRatsnestsCount(); ii++ )
|
for( unsigned ii = 0; ii < m_Pcb->GetRatsnestsCount(); ii++ )
|
||||||
{
|
{
|
||||||
if( ( m_Pcb->m_FullRatsnest[ii].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;
|
continue;
|
||||||
|
|
||||||
if( (net_code <= 0) || ( net_code == m_Pcb->m_FullRatsnest[ii].GetNet() ) )
|
if( (net_code <= 0) || ( net_code == m_Pcb->m_FullRatsnest[ii].GetNet() ) )
|
||||||
|
@ -546,7 +604,7 @@ static int tst_rats_block_to_block( NETINFO_ITEM* net, vector<RATSNEST_ITEM>& aR
|
||||||
* 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
|
||||||
* Différence between gen_rats_block_to_block(..):
|
* Difference between gen_rats_block_to_block(..):
|
||||||
* The analysis is not made pads to pads but uses the general ratsnest list.
|
* The analysis is not made pads to pads but uses the general ratsnest list.
|
||||||
* 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)
|
||||||
|
@ -705,7 +763,9 @@ void WinEDA_BasePcbFrame::Tst_Ratsnest( wxDC* DC, int ref_netcode )
|
||||||
|
|
||||||
/* a - tst connection between pads */
|
/* a - tst connection between pads */
|
||||||
rats = &m_Pcb->m_FullRatsnest[0];
|
rats = &m_Pcb->m_FullRatsnest[0];
|
||||||
int icnt = tst_rats_pad_to_pad( num_block, rats + net->m_RatsnestStartIdx, rats + net->m_RatsnestEndIdx );
|
int icnt = tst_rats_pad_to_pad( num_block,
|
||||||
|
rats + net->m_RatsnestStartIdx,
|
||||||
|
rats + net->m_RatsnestEndIdx );
|
||||||
|
|
||||||
/* b - test connexion between blocks (Iteration) */
|
/* b - test connexion between blocks (Iteration) */
|
||||||
while( icnt > 1 )
|
while( icnt > 1 )
|
||||||
|
@ -860,15 +920,12 @@ void WinEDA_BasePcbFrame::build_ratsnest_module( wxDC* DC, MODULE* Module )
|
||||||
|
|
||||||
/* End of list found: */
|
/* End of list found: */
|
||||||
/* a - first step of lee algorithm : build the pad to pad link list */
|
/* a - first step of lee algorithm : build the pad to pad link list */
|
||||||
int icnt = gen_rats_pad_to_pad( DrawPanel, m_Pcb->m_LocalRatsnest,
|
int icnt = gen_rats_pad_to_pad( m_Pcb->m_LocalRatsnest, s_localPadBuffer, ii, jj, 0 );
|
||||||
baseListePad + ii, baseListePad + jj,
|
|
||||||
0 );
|
|
||||||
|
|
||||||
/* b - second step of lee algorithm : build the block to block link list (Iteration) */
|
/* b - second step of lee algorithm : build the block to block link list (Iteration) */
|
||||||
while( icnt > 1 )
|
while( icnt > 1 )
|
||||||
{
|
{
|
||||||
icnt = gen_rats_block_to_block( DrawPanel, m_Pcb->m_LocalRatsnest,
|
icnt = gen_rats_block_to_block( m_Pcb->m_LocalRatsnest, s_localPadBuffer, ii, jj );
|
||||||
baseListePad + ii, baseListePad + jj );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ii = jj;
|
ii = jj;
|
||||||
|
@ -890,6 +947,7 @@ void WinEDA_BasePcbFrame::build_ratsnest_module( wxDC* DC, MODULE* Module )
|
||||||
* This section computes the "external" ratsnest: must be done when the footprint position changes
|
* This section computes the "external" ratsnest: must be done when the footprint position changes
|
||||||
*/
|
*/
|
||||||
CalculateExternalRatsnest:
|
CalculateExternalRatsnest:
|
||||||
|
|
||||||
/* This section search:
|
/* This section search:
|
||||||
* for each current module pad the nearest neighbour external pad (of course for the same net code).
|
* 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),
|
* For each current footprint cluster of pad (pads having the same net code),
|
||||||
|
|
Loading…
Reference in New Issue