Finished code cleaning about ratsnets calculations and handling.

Minor others changes.
This commit is contained in:
charras 2009-05-28 08:42:24 +00:00
parent 8f36c1fc42
commit b1d1a71101
30 changed files with 5840 additions and 5063 deletions

View File

@ -78,7 +78,7 @@ Pcb3D_GLCanvas::~Pcb3D_GLCanvas()
/*************************************/ /*************************************/
{ {
ClearLists(); ClearLists();
m_init = FALSE; m_init = FALSE;
} }
@ -224,7 +224,7 @@ void Pcb3D_GLCanvas::OnMouseEvent( wxMouseEvent& event )
/********************************************************/ /********************************************************/
{ {
wxSize size( GetClientSize() ); wxSize size( GetClientSize() );
double spin_quat[4]; double spin_quat[4];
if( event.RightDown() ) if( event.RightDown() )
@ -474,6 +474,7 @@ void Pcb3D_GLCanvas::OnPaint( wxPaintEvent& event )
/*************************************************/ /*************************************************/
{ {
wxPaintDC dc( this ); wxPaintDC dc( this );
// Set the OpenGL viewport according to the client size of this canvas. // Set the OpenGL viewport according to the client size of this canvas.
// This is done here rather than in a wxSizeEvent handler because our // This is done here rather than in a wxSizeEvent handler because our
// OpenGL rendering context (and thus viewport setting) is used with // OpenGL rendering context (and thus viewport setting) is used with
@ -482,13 +483,12 @@ void Pcb3D_GLCanvas::OnPaint( wxPaintEvent& event )
// is wrong when next another canvas is repainted. // is wrong when next another canvas is repainted.
const wxSize ClientSize = GetClientSize(); const wxSize ClientSize = GetClientSize();
glViewport(0, 0, ClientSize.x, ClientSize.y); glViewport( 0, 0, ClientSize.x, ClientSize.y );
Redraw(); Redraw();
event.Skip(); event.Skip();
} }
/***********************************************************/ /***********************************************************/
void Pcb3D_GLCanvas::OnEraseBackground( wxEraseEvent& event ) void Pcb3D_GLCanvas::OnEraseBackground( wxEraseEvent& event )
/***********************************************************/ /***********************************************************/
@ -518,7 +518,7 @@ void Pcb3D_GLCanvas::InitGL()
glMatrixMode( GL_PROJECTION ); glMatrixMode( GL_PROJECTION );
glLoadIdentity(); glLoadIdentity();
#define MAX_VIEW_ANGLE 160.0 / 45.0 #define MAX_VIEW_ANGLE 160.0 / 45.0
if( g_Parm_3D_Visu.m_Zoom > MAX_VIEW_ANGLE ) if( g_Parm_3D_Visu.m_Zoom > MAX_VIEW_ANGLE )
g_Parm_3D_Visu.m_Zoom = MAX_VIEW_ANGLE; g_Parm_3D_Visu.m_Zoom = MAX_VIEW_ANGLE;
gluPerspective( 45.0 * g_Parm_3D_Visu.m_Zoom, ratio_HV, 1, 10 ); gluPerspective( 45.0 * g_Parm_3D_Visu.m_Zoom, ratio_HV, 1, 10 );
@ -599,9 +599,9 @@ void Pcb3D_GLCanvas::TakeScreenshot( wxCommandEvent& event )
*/ */
{ {
wxFileName fn( m_Parent->m_Parent->GetScreen()->m_FileName ); wxFileName fn( m_Parent->m_Parent->GetScreen()->m_FileName );
wxString FullFileName; wxString FullFileName;
wxString file_ext, mask; wxString file_ext, mask;
bool fmt_is_jpeg = FALSE; bool fmt_is_jpeg = FALSE;
if( event.GetId() == ID_MENU_SCREENCOPY_JPEG ) if( event.GetId() == ID_MENU_SCREENCOPY_JPEG )
fmt_is_jpeg = TRUE; fmt_is_jpeg = TRUE;
@ -627,13 +627,26 @@ void Pcb3D_GLCanvas::TakeScreenshot( wxCommandEvent& event )
} }
Redraw( true ); Redraw( true );
wxSize image_size = GetClientSize();
wxClientDC dc( this ); struct vieport_params
wxBitmap bitmap( image_size.x, image_size.y ); {
wxMemoryDC memdc; GLint originx;
memdc.SelectObject( bitmap ); GLint originy;
memdc.Blit( 0, 0, image_size.x, image_size.y, &dc, 0, 0 ); GLint x;
memdc.SelectObject( wxNullBitmap ); GLint y;
} viewport;
glGetIntegerv( GL_VIEWPORT, (GLint*) &viewport );
unsigned char* pixelbuffer = (unsigned char*) malloc( 3 * viewport.x * viewport.y );
glReadPixels( 0, 0, viewport.x, viewport.y, GL_RGB, GL_UNSIGNED_BYTE, pixelbuffer );
wxImage image( viewport.x, viewport.y );
image.SetData( pixelbuffer );
image = image.Mirror();
image = image.Rotate90().Rotate90();
wxBitmap bitmap( image, -1 );
if( event.GetId() == ID_TOOL_SCREENCOPY_TOCLIBBOARD ) if( event.GetId() == ID_TOOL_SCREENCOPY_TOCLIBBOARD )
{ {
@ -650,8 +663,6 @@ void Pcb3D_GLCanvas::TakeScreenshot( wxCommandEvent& event )
} }
else else
{ {
wxImage image = bitmap.ConvertToImage();
if( !image.SaveFile( FullFileName, if( !image.SaveFile( FullFileName,
fmt_is_jpeg ? wxBITMAP_TYPE_JPEG : wxBITMAP_TYPE_PNG ) ) fmt_is_jpeg ? wxBITMAP_TYPE_JPEG : wxBITMAP_TYPE_PNG ) )
wxLogError( wxT( "Can't save file" ) ); wxLogError( wxT( "Can't save file" ) );

View File

@ -1,22 +1,10 @@
////////////////////////////////////// //////////////////////////////////////
// Name: 3d_draw.cpp // Name: 3d_draw.cpp
////////////////////////////////////// //////////////////////////////////////
#ifdef __GNUG__
#pragma implementation
#pragma interface
#endif
#include "fctsys.h" #include "fctsys.h"
#include "common.h"
#include "trigo.h" #include "trigo.h"
#if !wxUSE_GLCANVAS
#error Please set wxUSE_GLCANVAS to 1 in setup.h.
#endif
#include "pcbstruct.h" #include "pcbstruct.h"
#include "macros.h" #include "macros.h"
#include "drawtxt.h" #include "drawtxt.h"
@ -27,6 +15,11 @@
#include "3d_struct.h" #include "3d_struct.h"
#if !wxUSE_GLCANVAS
#error Please set wxUSE_GLCANVAS to 1 in setup.h.
#endif
static void Draw3D_FilledCircle( double posx, double posy, static void Draw3D_FilledCircle( double posx, double posy,
double rayon, double hole_rayon, double zpos ); double rayon, double hole_rayon, double zpos );
static void Draw3D_FilledSegment( double startx, double starty, static void Draw3D_FilledSegment( double startx, double starty,
@ -489,7 +482,31 @@ void Pcb3D_GLCanvas::Draw3D_DrawText( TEXTE_PCB* text )
s_Text3DZPos = g_Parm_3D_Visu.m_LayerZcoord[layer]; s_Text3DZPos = g_Parm_3D_Visu.m_LayerZcoord[layer];
s_Text3DWidth = text->m_Width * g_Parm_3D_Visu.m_BoardScale; s_Text3DWidth = text->m_Width * g_Parm_3D_Visu.m_BoardScale;
glNormal3f( 0.0, 0.0, Get3DLayerSide( layer ) ); glNormal3f( 0.0, 0.0, Get3DLayerSide( layer ) );
DrawGraphicText( NULL, NULL, text->m_Pos, (EDA_Colors) color, if( text->m_MultilineAllowed )
{
wxPoint pos = text->m_Pos;
wxArrayString* list = wxStringSplit( text->m_Text, '\n' );
wxPoint offset;
offset.y = text->GetInterline();
RotatePoint( &offset, text->m_Orient );
for( unsigned i = 0; i<list->Count(); i++ )
{
wxString txt = list->Item( i );
DrawGraphicText( NULL, NULL, pos, (EDA_Colors) color,
txt, text->m_Orient, text->m_Size,
text->m_HJustify, text->m_VJustify,
text->m_Width, text->m_Italic,
true,
Draw3dTextSegm );
pos += offset;
}
delete (list);
}
else
DrawGraphicText( NULL, NULL, text->m_Pos, (EDA_Colors) color,
text->m_Text, text->m_Orient, text->m_Size, text->m_Text, text->m_Orient, text->m_Size,
text->m_HJustify, text->m_VJustify, text->m_HJustify, text->m_VJustify,
text->m_Width, text->m_Italic, text->m_Width, text->m_Italic,

View File

@ -31,7 +31,7 @@ void WinEDA3D_DrawFrame::ReCreateHToolbar()
m_HToolBar->AddTool( ID_RELOAD3D_BOARD, wxEmptyString, m_HToolBar->AddTool( ID_RELOAD3D_BOARD, wxEmptyString,
wxBitmap( import3d_xpm ), wxBitmap( import3d_xpm ),
_( "Reload board" ) ); _( "Reload board" ) );
#ifdef __WINDOWS__ // do not work properly under linux #if (defined(__WINDOWS__) || defined(__APPLE__)) // do not work properly under linux
m_HToolBar-> AddSeparator(); m_HToolBar-> AddSeparator();
m_HToolBar->AddTool( ID_TOOL_SCREENCOPY_TOCLIBBOARD, wxEmptyString, m_HToolBar->AddTool( ID_TOOL_SCREENCOPY_TOCLIBBOARD, wxEmptyString,

View File

@ -4,6 +4,14 @@ KiCad ChangeLog 2009
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2009-may-28 UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================
++Pcbnew:
Finished code cleaning about ratsnets calculations and handling
Obscure code removed ( I hope)
Better names for some members of BOARD class.
2009-may-24 UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr> 2009-may-24 UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================ ================================================================================
++Pcbnew: ++Pcbnew:

View File

@ -8,7 +8,7 @@
#include "appl_wxstruct.h" #include "appl_wxstruct.h"
#define BUILD_VERSION wxT("(20090513-unstable)") #define BUILD_VERSION wxT("(20090525-unstable)")
wxString g_BuildVersion wxString g_BuildVersion

View File

@ -60,8 +60,6 @@ bool WinEDA_GerberFrame::Clear_Pcb( bool query )
GetBoard()->m_BoundaryBox.SetOrigin( 0, 0 ); GetBoard()->m_BoundaryBox.SetOrigin( 0, 0 );
GetBoard()->m_BoundaryBox.SetSize( 0, 0 ); GetBoard()->m_BoundaryBox.SetSize( 0, 0 );
GetBoard()->m_Status_Pcb = 0; GetBoard()->m_Status_Pcb = 0;
GetBoard()->m_NbLoclinks = 0;
GetBoard()->m_NbLinks = 0;
GetBoard()->m_NbNodes = 0; GetBoard()->m_NbNodes = 0;
GetBoard()->m_NbNoconnect = 0; GetBoard()->m_NbNoconnect = 0;

View File

@ -281,7 +281,7 @@ public:
void Compile_Ratsnest( wxDC* DC, bool affiche ); /* Recalcul complet du chevelu */ void Compile_Ratsnest( wxDC* DC, bool affiche ); /* Recalcul complet du chevelu */
void ReCompile_Ratsnest_After_Changes( wxDC* DC ); void ReCompile_Ratsnest_After_Changes( wxDC* DC );
int Test_1_Net_Ratsnest( wxDC* DC, int net_code ); int Test_1_Net_Ratsnest( wxDC* DC, int net_code );
char* build_ratsnest_module( wxDC* DC, MODULE* Module ); void build_ratsnest_module( wxDC* DC, MODULE* Module );
void trace_ratsnest_module( wxDC* DC ); void trace_ratsnest_module( wxDC* DC );
void Build_Board_Ratsnest( wxDC* DC ); void Build_Board_Ratsnest( wxDC* DC );
void DrawGeneralRatsnest( wxDC* DC, int net_code = 0 ); void DrawGeneralRatsnest( wxDC* DC, int net_code = 0 );
@ -521,7 +521,14 @@ public:
/* Fonctions specifiques */ /* Fonctions specifiques */
MODULE* ListAndSelectModuleName(); MODULE* ListAndSelectModuleName();
void Liste_Equipot( wxCommandEvent& event );
/** Function ListNetsAndSelect
* called by a command event
* displays the sorted list of nets in a dialog frame
* If a net is selected, it is hightlighted
*/
void ListNetsAndSelect( wxCommandEvent& event );
void Swap_Layers( wxCommandEvent& event ); void Swap_Layers( wxCommandEvent& event );
void Install_Test_DRC_Frame( wxDC* DC ); void Install_Test_DRC_Frame( wxDC* DC );

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -69,7 +69,7 @@ int CalcDist( int, int, int ,int );
/* BOARD.CPP */ /* BOARD.CPP */
bool ComputeMatriceSize(WinEDA_BasePcbFrame * frame, int pas_route); bool ComputeMatriceSize(WinEDA_BasePcbFrame * frame, int pas_route);
int Build_Work(BOARD * Pcb, RATSNEST_ITEM* pt_chevelus); int Build_Work(BOARD * Pcb);
void PlaceCells(BOARD * Pcb, int net_code, int flag = 0); void PlaceCells(BOARD * Pcb, int net_code, int flag = 0);
BoardCell GetCell( int, int, int ); BoardCell GetCell( int, int, int );

View File

@ -61,10 +61,6 @@ static void TracePenaliteRectangle( BOARD* Pcb, int ux0, int uy0, int ux1, i
int marge, int Penalite, int masque_layer ); int marge, int Penalite, int masque_layer );
static MODULE* PickModule( WinEDA_PcbFrame* pcbframe, wxDC* DC ); static MODULE* PickModule( WinEDA_PcbFrame* pcbframe, wxDC* DC );
/* variables importees */
extern RATSNEST_ITEM* local_liste_chevelu; // adresse de base du buffer des chevelus locaux
extern int nb_local_chevelu; // nbr de links du module en deplacement
/********************************************************************************/ /********************************************************************************/
void WinEDA_PcbFrame::AutoPlaceModule( MODULE* Module, int place_mode, wxDC* DC ) void WinEDA_PcbFrame::AutoPlaceModule( MODULE* Module, int place_mode, wxDC* DC )
@ -866,22 +862,18 @@ float WinEDA_PcbFrame::Compute_Ratsnest_PlaceModule( wxDC* DC )
* penalite pour les inclinaisons se rapprochant de 45 degre * penalite pour les inclinaisons se rapprochant de 45 degre
*/ */
{ {
RATSNEST_ITEM* pt_local_chevelu; double cout, icout;
int ii;
float cout, icout;
int ox, oy; int ox, oy;
int fx, fy; int fx, fy;
int dx, dy; int dx, dy;
if( (GetBoard()->m_Status_Pcb & RATSNEST_ITEM_LOCAL_OK) == 0 ) if( (GetBoard()->m_Status_Pcb & RATSNEST_ITEM_LOCAL_OK) == 0 )
return -1; return -1;
pt_local_chevelu = local_liste_chevelu;
ii = nb_local_chevelu;
cout = 0; cout = 0;
while( ii-- > 0 ) for( unsigned ii = 0; ii < GetBoard()->m_LocalRatsnest.size(); ii++ )
{ {
RATSNEST_ITEM* pt_local_chevelu = &GetBoard()->m_LocalRatsnest[ii];
if( !(pt_local_chevelu->m_Status & LOCAL_RATSNEST_ITEM) ) if( !(pt_local_chevelu->m_Status & LOCAL_RATSNEST_ITEM) )
{ {
ox = pt_local_chevelu->m_PadStart->GetPosition().x - g_Offset_Module.x; ox = pt_local_chevelu->m_PadStart->GetPosition().x - g_Offset_Module.x;
@ -913,11 +905,9 @@ float WinEDA_PcbFrame::Compute_Ratsnest_PlaceModule( wxDC* DC )
icout = sqrt( icout ); icout = sqrt( icout );
cout += icout; /* cout total = somme des couts de chaque chevelu */ cout += icout; /* cout total = somme des couts de chaque chevelu */
} }
pt_local_chevelu++;
} }
return cout; return (float)cout;
} }
@ -1102,8 +1092,7 @@ static MODULE* PickModule( WinEDA_PcbFrame* pcbframe, wxDC* DC )
{ {
MODULE** BaseListeModules, ** pt_Dmod; MODULE** BaseListeModules, ** pt_Dmod;
MODULE* Module = NULL, * AltModule = NULL; MODULE* Module = NULL, * AltModule = NULL;
RATSNEST_ITEM* pt_local_chevelu; int NbModules;
int NbModules, ii;
BaseListeModules = GenListeModules( pcbframe->GetBoard(), &NbModules ); BaseListeModules = GenListeModules( pcbframe->GetBoard(), &NbModules );
if( BaseListeModules == NULL ) if( BaseListeModules == NULL )
@ -1127,13 +1116,10 @@ static MODULE* PickModule( WinEDA_PcbFrame* pcbframe, wxDC* DC )
pcbframe->build_ratsnest_module( DC, *pt_Dmod ); pcbframe->build_ratsnest_module( DC, *pt_Dmod );
/* calcul du nombre de chevelus externes */ /* calcul du nombre de chevelus externes */
pt_local_chevelu = local_liste_chevelu; for( unsigned ii = 0; ii < pcbframe->GetBoard()->m_LocalRatsnest.size(); ii++ )
ii = nb_local_chevelu;
while( ii-- > 0 )
{ {
if( (pt_local_chevelu->m_Status & LOCAL_RATSNEST_ITEM) == 0 ) if( (pcbframe->GetBoard()->m_LocalRatsnest[ii].m_Status & LOCAL_RATSNEST_ITEM) == 0 )
(*pt_Dmod)->flag++; (*pt_Dmod)->flag++;
pt_local_chevelu++;
} }
} }

View File

@ -33,8 +33,7 @@ void WinEDA_PcbFrame::Autoroute( wxDC* DC, int mode )
/********************************************************/ /********************************************************/
/* init board, route traces*/ /* init board, route traces*/
{ {
int ii, start, stop; int start, stop;
RATSNEST_ITEM* ptmp;
MODULE* Module = NULL; MODULE* Module = NULL;
D_PAD* Pad = NULL; D_PAD* Pad = NULL;
int autoroute_net_code = -1; int autoroute_net_code = -1;
@ -94,9 +93,9 @@ void WinEDA_PcbFrame::Autoroute( wxDC* DC, int mode )
Compile_Ratsnest( DC, TRUE ); Compile_Ratsnest( DC, TRUE );
/* Placement du flag CH_ROUTE_REQ sur les chevelus demandes */ /* Placement du flag CH_ROUTE_REQ sur les chevelus demandes */
ptmp = (RATSNEST_ITEM*) GetBoard()->m_Ratsnest; for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
for( ii = GetBoard()->GetNumRatsnests(); ii > 0; ii--, ptmp++ )
{ {
RATSNEST_ITEM* ptmp = &GetBoard()->m_FullRatsnest[ii];
ptmp->m_Status &= ~CH_ROUTE_REQ; ptmp->m_Status &= ~CH_ROUTE_REQ;
switch( mode ) switch( mode )
@ -130,8 +129,6 @@ void WinEDA_PcbFrame::Autoroute( wxDC* DC, int mode )
} }
} }
ptmp = (RATSNEST_ITEM*) GetBoard()->m_Ratsnest;
start = time( NULL ); start = time( NULL );
/* Calcul du pas de routage fixe a 5 mils et plus */ /* Calcul du pas de routage fixe a 5 mils et plus */
@ -162,7 +159,7 @@ void WinEDA_PcbFrame::Autoroute( wxDC* DC, int mode )
PlaceCells( GetBoard(), -1, FORCE_PADS ); PlaceCells( GetBoard(), -1, FORCE_PADS );
/* Construction de la liste des pistes a router */ /* Construction de la liste des pistes a router */
Build_Work( GetBoard(), ptmp ); Build_Work( GetBoard() );
// DisplayBoard(DrawPanel, DC); // DisplayBoard(DrawPanel, DC);
@ -190,19 +187,12 @@ void WinEDA_PcbFrame::Reset_Noroutable( wxDC* DC )
* Si ce flag est a 1 il n'est pas reroute * Si ce flag est a 1 il n'est pas reroute
*/ */
{ {
int ii;
RATSNEST_ITEM* pt_rats;
if( (GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK )== 0 ) if( (GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK )== 0 )
Compile_Ratsnest( DC, TRUE ); Compile_Ratsnest( DC, TRUE );
pt_rats = (RATSNEST_ITEM*) GetBoard()->m_Ratsnest; for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
if( pt_rats == NULL )
return;
for( ii = GetBoard()->GetNumRatsnests(); ii > 0; ii--, pt_rats++ )
{ {
pt_rats->m_Status &= ~CH_UNROUTABLE; GetBoard()->m_FullRatsnest[ii].m_Status &= ~CH_UNROUTABLE;
} }
} }

View File

@ -14,7 +14,7 @@
/* routines externes : */ /* routines externes : */
/* Routines definies ici: */ /* Routines definies ici: */
int Build_Work( BOARD* Pcb, RATSNEST_ITEM* pt_base_chevelu ); int Build_Work( BOARD* Pcb );
void PlaceCells( BOARD* Pcb, int net_code, int flag ); void PlaceCells( BOARD* Pcb, int net_code, int flag );
int InitBoard(); int InitBoard();
BoardCell GetCell( int, int, int ); BoardCell GetCell( int, int, int );
@ -336,12 +336,11 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag )
/******************************************************/ /******************************************************/
int Build_Work( BOARD* Pcb, RATSNEST_ITEM* pt_base_chevelu ) int Build_Work( BOARD* Pcb )
/*****************************************************/ /*****************************************************/
/* Build liste conn */ /* Build liste conn */
{ {
int ii; RATSNEST_ITEM* pt_rats;
RATSNEST_ITEM* pt_rats = pt_base_chevelu;
D_PAD* pt_pad; D_PAD* pt_pad;
int r1, r2, c1, c2, current_net_code; int r1, r2, c1, c2, current_net_code;
RATSNEST_ITEM* pt_ch; RATSNEST_ITEM* pt_ch;
@ -350,8 +349,9 @@ int Build_Work( BOARD* Pcb, RATSNEST_ITEM* pt_base_chevelu )
InitWork(); /* clear work list */ InitWork(); /* clear work list */
Ntotal = 0; Ntotal = 0;
for( ii = Pcb->GetNumRatsnests(); ii > 0; ii--, pt_rats++ ) for( unsigned ii = 0;Pcb->GetRatsnestsCount(); ii++ )
{ {
pt_rats = &Pcb->m_FullRatsnest[ii];
/* On ne route que les chevelus actifs et routables */ /* On ne route que les chevelus actifs et routables */
if( (pt_rats->m_Status & CH_ACTIF) == 0 ) if( (pt_rats->m_Status & CH_ACTIF) == 0 )
continue; continue;

File diff suppressed because it is too large Load Diff

View File

@ -82,12 +82,9 @@ private:
public: public:
WinEDA_BasePcbFrame* m_PcbFrame; // Window de visualisation WinEDA_BasePcbFrame* m_PcbFrame; // Window de visualisation
EDA_Rect m_BoundaryBox; // Board size and position EDA_Rect m_BoundaryBox; // Board size and position
int m_Unused;
int m_Status_Pcb; // Flags used in ratsnet calculation and update int m_Status_Pcb; // Flags used in ratsnet calculation and update
EDA_BoardDesignSettings* m_BoardSettings; // Link to current design settings EDA_BoardDesignSettings* m_BoardSettings; // Link to current design settings
int m_NbNodes; // Active pads (pads attached to a net ) count int m_NbNodes; // Active pads (pads attached to a net ) count
int m_NbLinks; // Ratsnest count
int m_NbLoclinks; // Number of ratsnests from mouse cursor to pads to show while creating a track
int m_NbNoconnect; // Active ratsnet count (rastnests not alraedy connected by tracks) int m_NbNoconnect; // Active ratsnet count (rastnests not alraedy connected by tracks)
DLIST<BOARD_ITEM> m_Drawings; // linked list of lines & texts DLIST<BOARD_ITEM> m_Drawings; // linked list of lines & texts
@ -98,8 +95,9 @@ public:
std::vector<D_PAD*> m_Pads; // Entry for a sorted pad list (used in ratsnest calculations) std::vector<D_PAD*> m_Pads; // Entry for a sorted pad list (used in ratsnest calculations)
NETINFO_LIST* m_NetInfo; // nets info list (name, design constraints .. NETINFO_LIST* m_NetInfo; // nets info list (name, design constraints ..
RATSNEST_ITEM* m_Ratsnest; // Rastnest list std::vector<RATSNEST_ITEM> m_FullRatsnest; // Rastnest list for the BOARD
RATSNEST_ITEM* m_LocalRatsnest; // Rastnest list used while moving a footprint std::vector<RATSNEST_ITEM> m_LocalRatsnest; /* Rastnest list relative to a given footprint
(used while moving a footprint) */
ZONE_CONTAINER* m_CurrentZoneContour; // zone contour currently in progress ZONE_CONTAINER* m_CurrentZoneContour; // zone contour currently in progress
@ -233,27 +231,26 @@ public:
/* Routines de calcul des nombres de segments pistes et zones */ /* Routines de calcul des nombres de segments pistes et zones */
int GetNumSegmTrack(); int GetNumSegmTrack();
int GetNumSegmZone(); int GetNumSegmZone();
int GetNumNoconnect(); // retourne le nombre de connexions manquantes unsigned GetNoconnectCount(); // retourne le nombre de connexions manquantes
/** /**
* Function GetNumRatsnests * Function GetNumRatsnests
* @return int - The number of rats * @return int - The number of rats
*/ */
int GetNumRatsnests() unsigned GetRatsnestsCount()
{ {
return m_NbLinks; return m_FullRatsnest.size();
} }
int GetNumNodes(); // retourne le nombre de pads a netcode > 0 unsigned GetNodesCount(); // retourne le nombre de pads a netcode > 0
/** Function Build_Pads_Full_List /** Function Build_Pads_Full_List
* Create the pad list * Create the pad list
* initialise: * initialise:
* m_Pads (list of pads) * m_Pads (list of pads)
* m_NbNodes = 0
* set m_Status_Pcb = LISTE_PAD_OK; * set m_Status_Pcb = LISTE_PAD_OK;
* and clear for all pads the m_SubRatsnest member; * and clear for all pads in list the m_SubRatsnest member;
* delete ( free memory) m_Pcb->m_Ratsnest and set m_Pcb->m_Ratsnest to NULL * clear m_Pcb->m_FullRatsnest
*/ */
void Build_Pads_Full_List(); void Build_Pads_Full_List();

View File

@ -81,10 +81,10 @@ public:
*/ */
void Append( NETINFO_ITEM* aNewElement ); void Append( NETINFO_ITEM* aNewElement );
/** Function Clear /** Function DeleteData
* delete the list of nets (and free memory) * delete the list of nets (and free memory)
*/ */
void Clear(); void DeleteData();
/** Function BuildListOfNets /** Function BuildListOfNets
* initialize the list of NETINFO_ITEM m_NetBuffer * initialize the list of NETINFO_ITEM m_NetBuffer
@ -112,9 +112,8 @@ public:
int m_NbNoconn; // Ratsnets remaining to route count int m_NbNoconn; // Ratsnets remaining to route count
int m_ForceWidth; // specific width (O = default width) int m_ForceWidth; // specific width (O = default width)
std::vector <D_PAD*> m_ListPad; // List of pads connected to this net std::vector <D_PAD*> m_ListPad; // List of pads connected to this net
RATSNEST_ITEM* m_RatsnestStart; // pointeur sur debut de liste ratsnests du net unsigned m_RatsnestStart; // debut de liste ratsnests du net (included)
RATSNEST_ITEM* m_RatsnestEnd; // pointeur sur fin de liste ratsnests du net unsigned m_RatsnestEnd; // fin de liste ratsnests du net (excluded)
std::vector <RATSNEST_ITEM*> m_ListRatsnest; // List of Ratsnests for this net
NETINFO_ITEM( BOARD_ITEM* aParent ); NETINFO_ITEM( BOARD_ITEM* aParent );
~NETINFO_ITEM(); ~NETINFO_ITEM();

View File

@ -19,8 +19,8 @@ NETINFO_ITEM::NETINFO_ITEM( BOARD_ITEM* aParent )
SetNet( 0 ); SetNet( 0 );
m_NbNodes = m_NbLink = m_NbNoconn = 0; m_NbNodes = m_NbLink = m_NbNoconn = 0;
m_ForceWidth = 0; m_ForceWidth = 0;
m_RatsnestStart = NULL; // pointeur sur debut de liste ratsnests du net m_RatsnestStart = 0; // debut de liste ratsnests du net
m_RatsnestEnd = NULL; // pointeur sur fin de liste ratsnests du net m_RatsnestEnd = 0; // fin de liste ratsnests du net
} }

View File

@ -19,7 +19,7 @@ NETINFO_LIST::NETINFO_LIST( BOARD* aParent )
NETINFO_LIST::~NETINFO_LIST() NETINFO_LIST::~NETINFO_LIST()
{ {
Clear(); DeleteData();
} }
@ -35,10 +35,10 @@ NETINFO_ITEM* NETINFO_LIST::GetItem( int aNetcode )
} }
/** Function Clear /** Function DeleteData
* delete the list of nets (and free memory) * delete the list of nets (and free memory)
*/ */
void NETINFO_LIST::Clear() void NETINFO_LIST::DeleteData()
{ {
for( unsigned ii = 0; ii < GetCount(); ii++ ) for( unsigned ii = 0; ii < GetCount(); ii++ )
delete m_NetBuffer[ii]; delete m_NetBuffer[ii];
@ -83,7 +83,7 @@ void NETINFO_LIST::BuildListOfNets()
int nodes_count = 0; int nodes_count = 0;
NETINFO_ITEM* net_item; NETINFO_ITEM* net_item;
Clear(); // Remove all nets info and free memory DeleteData(); // Remove all nets info and free memory
// Create and add the "unconnected net" // Create and add the "unconnected net"
net_item = new NETINFO_ITEM( m_Parent ); net_item = new NETINFO_ITEM( m_Parent );
@ -135,13 +135,12 @@ void BOARD::Build_Pads_Full_List()
/**********************************/ /**********************************/
/** Function Build_Pads_Full_List /** Function Build_Pads_Full_List
* Create the pad list * Create the pad list, sorted by net names
* initialise: * initialise:
* m_Pads (list of pads) * m_Pads (list of pads)
* m_NbNodes = 0
* set m_Status_Pcb = LISTE_PAD_OK; * set m_Status_Pcb = LISTE_PAD_OK;
* and clear for all pads the m_SubRatsnest member; * also clear m_Pcb->m_FullRatsnest that could have bad data
* delete ( free memory) m_Pcb->m_Ratsnest and set m_Pcb->m_Ratsnest to NULL * (m_Pcb->m_FullRatsnest uses pointer to pads)
*/ */
{ {
if( m_Status_Pcb & LISTE_PAD_OK ) if( m_Status_Pcb & LISTE_PAD_OK )
@ -149,8 +148,7 @@ void BOARD::Build_Pads_Full_List()
// empty the old list // empty the old list
m_Pads.clear(); m_Pads.clear();
m_FullRatsnest.clear();
m_NbNodes = 0;
/* Clear variables used in rastnest computation */ /* Clear variables used in rastnest computation */
for( MODULE* module = m_Modules; module; module = module->Next() ) for( MODULE* module = m_Modules; module; module = module->Next() )
@ -161,20 +159,11 @@ void BOARD::Build_Pads_Full_List()
pad->SetSubRatsnest( 0 ); pad->SetSubRatsnest( 0 );
pad->SetParent( module ); pad->SetParent( module );
if( pad->GetNet() )
m_NbNodes++;
} }
} }
// Sort pad list per net // Sort pad list per net
sort( m_Pads.begin(), m_Pads.end(), PadlistSortByNetnames ); sort( m_Pads.begin(), m_Pads.end(), PadlistSortByNetnames );
if( m_Ratsnest )
{
MyFree( m_Ratsnest );
m_Ratsnest = NULL;
}
m_Status_Pcb = LISTE_PAD_OK; m_Status_Pcb = LISTE_PAD_OK;
} }

View File

@ -886,10 +886,10 @@ void TRACK::DisplayInfo( WinEDA_DrawFrame* frame )
{ {
/* Display NetName pour les segments de piste type cuivre */ /* Display NetName pour les segments de piste type cuivre */
NETINFO_ITEM* equipot = board->FindNet( GetNet() ); NETINFO_ITEM* net = board->FindNet( GetNet() );
if( equipot ) if( net )
msg = equipot->GetNetname(); msg = net->GetNetname();
else else
msg = wxT( "<noname>" ); msg = wxT( "<noname>" );

View File

@ -363,7 +363,7 @@ void WinEDA_BasePcbFrame::test_1_net_connexion( wxDC* DC, int net_code )
/* Display results */ /* Display results */
msg.Printf( wxT( "links %d nc %d net:nc %d" ), msg.Printf( wxT( "links %d nc %d net:nc %d" ),
m_Pcb->m_NbLinks, m_Pcb->GetNumNoconnect(), m_Pcb->GetRatsnestsCount(), m_Pcb->GetNoconnectCount(),
nb_net_noconnect ); nb_net_noconnect );
Affiche_Message( msg ); Affiche_Message( msg );

View File

@ -302,12 +302,12 @@ void DRC::testUnconnected()
m_mainWindow->Compile_Ratsnest( &dc, TRUE ); m_mainWindow->Compile_Ratsnest( &dc, TRUE );
} }
if( m_pcb->m_Ratsnest == NULL ) if( m_pcb->GetRatsnestsCount() == 0 )
return; return;
RATSNEST_ITEM* rat = m_pcb->m_Ratsnest; for( unsigned ii = 0; ii < m_pcb->GetRatsnestsCount(); ++ii )
for( int i = 0; i<m_pcb->GetNumRatsnests(); ++i, ++rat )
{ {
RATSNEST_ITEM* rat = &m_pcb->m_FullRatsnest[ii];
if( (rat->m_Status & CH_ACTIF) == 0 ) if( (rat->m_Status & CH_ACTIF) == 0 )
continue; continue;

View File

@ -43,8 +43,7 @@ void WinEDA_PcbFrame::Ratsnest_On_Off( wxDC* DC )
/* Affiche ou efface le chevelu selon l'etat du bouton d'appel */ /* Affiche ou efface le chevelu selon l'etat du bouton d'appel */
{ {
int ii; unsigned ii;
RATSNEST_ITEM* pt_chevelu;
if( (GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 ) if( (GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 )
{ {
@ -55,24 +54,23 @@ void WinEDA_PcbFrame::Ratsnest_On_Off( wxDC* DC )
DrawGeneralRatsnest( DC, 0 ); /* effacement eventuel du chevelu affiche */ DrawGeneralRatsnest( DC, 0 ); /* effacement eventuel du chevelu affiche */
pt_chevelu = GetBoard()->m_Ratsnest; if( GetBoard()->GetRatsnestsCount() == 0 )
if( pt_chevelu == NULL )
return; return;
if( g_Show_Ratsnest ) if( g_Show_Ratsnest )
{ {
for( ii = GetBoard()->GetNumRatsnests(); ii > 0; pt_chevelu++, ii-- ) for( ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
{ {
pt_chevelu->m_Status |= CH_VISIBLE; GetBoard()->m_FullRatsnest[ii].m_Status |= CH_VISIBLE;
} }
DrawGeneralRatsnest( DC, 0 ); DrawGeneralRatsnest( DC, 0 );
} }
else else
{ {
for( ii = GetBoard()->GetNumRatsnests(); ii > 0; pt_chevelu++, ii-- ) for( ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
{ {
pt_chevelu->m_Status &= ~CH_VISIBLE; GetBoard()->m_FullRatsnest[ii].m_Status &= ~CH_VISIBLE;
} }
} }
} }
@ -344,18 +342,14 @@ void WinEDA_PcbFrame::Show_1_Ratsnest( EDA_BaseStruct* item, wxDC* DC )
* Efface le chevelu affiche si aucun module ou pad n'est selectionne * Efface le chevelu affiche si aucun module ou pad n'est selectionne
*/ */
{ {
int ii;
RATSNEST_ITEM* pt_chevelu;
D_PAD* pt_pad = NULL; D_PAD* pt_pad = NULL;
MODULE* Module = NULL; MODULE* Module = NULL;
if( g_Show_Ratsnest ) if( g_Show_Ratsnest )
return; // Deja Affich<63> return;
if( (GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 ) if( (GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 )
{
Compile_Ratsnest( DC, TRUE ); Compile_Ratsnest( DC, TRUE );
}
if( item ) if( item )
{ {
@ -368,24 +362,18 @@ void WinEDA_PcbFrame::Show_1_Ratsnest( EDA_BaseStruct* item, wxDC* DC )
if( pt_pad ) /* Affichage du chevelu du net correspondant */ if( pt_pad ) /* Affichage du chevelu du net correspondant */
{ {
pt_pad->DisplayInfo( this ); pt_pad->DisplayInfo( this );
pt_chevelu = (RATSNEST_ITEM*) GetBoard()->m_Ratsnest; for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
for( ii = GetBoard()->GetNumRatsnests(); ii > 0; pt_chevelu++, ii-- )
{ {
if( pt_chevelu->GetNet() == pt_pad->GetNet() ) RATSNEST_ITEM* net = &GetBoard()->m_FullRatsnest[ii];
if( net->GetNet() == pt_pad->GetNet() )
{ {
if( (pt_chevelu->m_Status & CH_VISIBLE) != 0 ) if( (net->m_Status & CH_VISIBLE) != 0 )
continue; continue;
pt_chevelu->m_Status |= CH_VISIBLE; net->m_Status |= CH_VISIBLE;
if( (pt_chevelu->m_Status & CH_ACTIF) == 0 ) if( (net->m_Status & CH_ACTIF) == 0 )
continue; continue;
GRSetDrawMode( DC, GR_XOR ); net->Draw( DrawPanel, DC, GR_XOR, wxPoint(0,0) );
GRLine( &DrawPanel->m_ClipBox, DC, pt_chevelu->m_PadStart->m_Pos.x,
pt_chevelu->m_PadStart->m_Pos.y,
pt_chevelu->m_PadEnd->m_Pos.x,
pt_chevelu->m_PadEnd->m_Pos.y,
0,
g_DesignSettings.m_RatsnestColor );
} }
} }
} }
@ -407,26 +395,19 @@ void WinEDA_PcbFrame::Show_1_Ratsnest( EDA_BaseStruct* item, wxDC* DC )
pt_pad = Module->m_Pads; pt_pad = Module->m_Pads;
for( ; pt_pad != NULL; pt_pad = (D_PAD*) pt_pad->Next() ) for( ; pt_pad != NULL; pt_pad = (D_PAD*) pt_pad->Next() )
{ {
pt_chevelu = (RATSNEST_ITEM*) GetBoard()->m_Ratsnest; for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
for( ii = GetBoard()->GetNumRatsnests(); ii > 0; pt_chevelu++, ii-- )
{ {
if( (pt_chevelu->m_PadStart == pt_pad) RATSNEST_ITEM* net = &GetBoard()->m_FullRatsnest[ii];
|| (pt_chevelu->m_PadEnd == pt_pad) ) if( (net->m_PadStart == pt_pad) || (net->m_PadEnd == pt_pad) )
{ {
if( pt_chevelu->m_Status & CH_VISIBLE ) if( net->m_Status & CH_VISIBLE )
continue; continue;
pt_chevelu->m_Status |= CH_VISIBLE; net->m_Status |= CH_VISIBLE;
if( (pt_chevelu->m_Status & CH_ACTIF) == 0 ) if( (net->m_Status & CH_ACTIF) == 0 )
continue; continue;
GRSetDrawMode( DC, GR_XOR ); net->Draw( DrawPanel, DC, GR_XOR, wxPoint(0,0) );
GRLine( &DrawPanel->m_ClipBox, DC, pt_chevelu->m_PadStart->m_Pos.x,
pt_chevelu->m_PadStart->m_Pos.y,
pt_chevelu->m_PadEnd->m_Pos.x,
pt_chevelu->m_PadEnd->m_Pos.y,
0,
g_DesignSettings.m_RatsnestColor );
} }
} }
} }
@ -436,15 +417,13 @@ void WinEDA_PcbFrame::Show_1_Ratsnest( EDA_BaseStruct* item, wxDC* DC )
} }
} }
/* Effacement complet des selections /* Effacement complet des selections si aucun pad ou module n'a ete localise */
* si aucun pad ou module n'a ete localise */
if( (pt_pad == NULL) && (Module == NULL) ) if( (pt_pad == NULL) && (Module == NULL) )
{ {
DrawGeneralRatsnest( DC ); DrawGeneralRatsnest( DC );
pt_chevelu = (RATSNEST_ITEM*) GetBoard()->m_Ratsnest;
for( ii = GetBoard()->GetNumRatsnests(); (ii > 0) && pt_chevelu; pt_chevelu++, ii-- ) for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
pt_chevelu->m_Status &= ~CH_VISIBLE; GetBoard()->m_FullRatsnest[ii].m_Status &= ~CH_VISIBLE;
} }
} }
@ -453,27 +432,16 @@ void WinEDA_PcbFrame::Show_1_Ratsnest( EDA_BaseStruct* item, wxDC* DC )
void WinEDA_PcbFrame::Affiche_PadsNoConnect( wxDC* DC ) void WinEDA_PcbFrame::Affiche_PadsNoConnect( wxDC* DC )
/*****************************************************/ /*****************************************************/
/* Met en surbrillance les pads non encore connectes ( correspondants aux /* Hight light the unconnected pads
* chevelus actifs
*/ */
{ {
int ii; for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
RATSNEST_ITEM* pt_chevelu;
D_PAD* pt_pad;
pt_chevelu = (RATSNEST_ITEM*) GetBoard()->m_Ratsnest;
for( ii = GetBoard()->GetNumRatsnests(); ii > 0; pt_chevelu++, ii-- )
{ {
if( (pt_chevelu->m_Status & CH_ACTIF) == 0 ) RATSNEST_ITEM* net = &GetBoard()->m_FullRatsnest[ii];
if( (net->m_Status & CH_ACTIF) == 0 )
continue; continue;
pt_pad = pt_chevelu->m_PadStart; net->m_PadStart->Draw( DrawPanel, DC, GR_OR | GR_SURBRILL );
net->m_PadEnd->Draw( DrawPanel, DC, GR_OR | GR_SURBRILL );
if( pt_pad )
pt_pad->Draw( DrawPanel, DC, GR_OR | GR_SURBRILL );
pt_pad = pt_chevelu->m_PadEnd;
if( pt_pad )
pt_pad->Draw( DrawPanel, DC, GR_OR | GR_SURBRILL );
} }
} }

View File

@ -263,11 +263,12 @@ int WinEDA_PcbFrame::LoadOnePcbFile( const wxString& FullFileName, bool Append )
/* Rebuild the new pad list (for drc and ratsnet control ...) */ /* Rebuild the new pad list (for drc and ratsnet control ...) */
GetBoard()->m_Status_Pcb = 0; GetBoard()->m_Status_Pcb = 0;
GetBoard()->Build_Pads_Full_List();
GetBoard()->DisplayInfo( this );
DrawPanel->Refresh( true); DrawPanel->Refresh( true);
Compile_Ratsnest( NULL, true );
GetBoard()->DisplayInfo( this );
/* reset the auto save timer */ /* reset the auto save timer */
g_SaveTime = time( NULL ); g_SaveTime = time( NULL );

View File

@ -279,10 +279,12 @@ void WinEDA_PcbFrame::Erase_Modules( bool query )
GetBoard()->m_Modules.DeleteAll(); GetBoard()->m_Modules.DeleteAll();
GetBoard()->m_Status_Pcb = 0; GetBoard()->m_Status_Pcb = 0;
GetBoard()->m_NbNodes = 0;
GetBoard()->m_NbLinks = 0;
GetBoard()->m_NbNoconnect = 0;
m_Pcb->m_Pads.clear(); // empty the pad list pointers m_Pcb->m_Pads.clear(); // empty the pad list pointers
m_Pcb->m_NetInfo->DeleteData();
m_Pcb->m_FullRatsnest.clear(); // empty the pad list pointers
m_Pcb->m_LocalRatsnest.clear(); // empty the pad list pointers
GetBoard()->m_NbNodes = 0;
GetBoard()->m_NbNoconnect = 0;
GetScreen()->SetModify(); GetScreen()->SetModify();
} }

View File

@ -208,8 +208,7 @@ int WinEDA_BasePcbFrame::ReadGeneralDescrPcb( FILE* File, int* LineNum )
if( strnicmp( data, "Links", 5 ) == 0 ) if( strnicmp( data, "Links", 5 ) == 0 )
{ {
data = strtok( NULL, " =\n\r" ); // Info only, do nothing
GetBoard()->m_NbLinks = atoi( data );
continue; continue;
} }
@ -571,7 +570,7 @@ bool WinEDA_PcbFrame::WriteGeneralDescrPcb( FILE* File )
// Write old format for Layer count (for compatibility with old versions of pcbnew // Write old format for Layer count (for compatibility with old versions of pcbnew
fprintf( File, "Ly %8X\n", g_TabAllCopperLayerMask[NbLayers - 1] | ALL_NO_CU_LAYERS ); // For compatibility with old version of pcbnew fprintf( File, "Ly %8X\n", g_TabAllCopperLayerMask[NbLayers - 1] | ALL_NO_CU_LAYERS ); // For compatibility with old version of pcbnew
fprintf( File, "Links %d\n", GetBoard()->m_NbLinks ); fprintf( File, "Links %d\n", GetBoard()->GetRatsnestsCount() );
fprintf( File, "NoConn %d\n", GetBoard()->m_NbNoconnect ); fprintf( File, "NoConn %d\n", GetBoard()->m_NbNoconnect );
/* Write Bounding box info */ /* Write Bounding box info */
@ -872,10 +871,7 @@ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append )
BestZoom(); BestZoom();
#ifdef PCBNEW GetBoard()->m_Status_Pcb = 0;
// Build connectivity info
Compile_Ratsnest( NULL, TRUE );
#endif
return 1; return 1;
} }

View File

@ -102,7 +102,7 @@ BEGIN_EVENT_TABLE( WinEDA_PcbFrame, WinEDA_BasePcbFrame )
EVT_MENU( ID_PCB_GEN_BOM_FILE_FROM_BOARD, WinEDA_PcbFrame::RecreateBOMFileFromBoard ) EVT_MENU( ID_PCB_GEN_BOM_FILE_FROM_BOARD, WinEDA_PcbFrame::RecreateBOMFileFromBoard )
// menu Miscellaneous // menu Miscellaneous
EVT_MENU( ID_MENU_LIST_NETS, WinEDA_PcbFrame::Liste_Equipot ) EVT_MENU( ID_MENU_LIST_NETS, WinEDA_PcbFrame::ListNetsAndSelect )
EVT_MENU( ID_PCB_GLOBAL_DELETE, WinEDA_PcbFrame::Process_Special_Functions ) EVT_MENU( ID_PCB_GLOBAL_DELETE, WinEDA_PcbFrame::Process_Special_Functions )
EVT_MENU( ID_MENU_PCB_CLEAN, WinEDA_PcbFrame::Process_Special_Functions ) EVT_MENU( ID_MENU_PCB_CLEAN, WinEDA_PcbFrame::Process_Special_Functions )
EVT_MENU( ID_MENU_PCB_SWAP_LAYERS, EVT_MENU( ID_MENU_PCB_SWAP_LAYERS,

View File

@ -40,11 +40,6 @@ bool g_TwoSegmentTrackBuild = TRUE;
bool g_HightLigt_Status; bool g_HightLigt_Status;
extern PARAM_CFG_BASE* ParamCfgList[]; extern PARAM_CFG_BASE* ParamCfgList[];
/* A buffer used in some computations (will be removed in next cleanup code,
* DO NOT use) */
#define BUFMEMSIZE 256000 /* buffer size (in bytes) */
char* adr_lowmem = NULL;
int Angle_Rot_Module; int Angle_Rot_Module;
int ModuleSegmentWidth; int ModuleSegmentWidth;
int ModuleTextWidth; int ModuleTextWidth;
@ -140,15 +135,6 @@ Changing extension to .brd." ),
* real hotkeys in menus or tool tips */ * real hotkeys in menus or tool tips */
/* allocation de la memoire pour le fichier et autres buffers: */
/* On reserve BUFMEMSIZE octets de ram pour calcul */
adr_lowmem = (char*) MyZMalloc( BUFMEMSIZE ); /* adresse de la zone de calcul */
if( adr_lowmem == NULL )
{
printf( "No Memory, Fatal err Memory alloc\n" );
return FALSE;
}
frame = new WinEDA_PcbFrame( NULL, wxT( "PcbNew" ), frame = new WinEDA_PcbFrame( NULL, wxT( "PcbNew" ),
wxPoint( 0, 0 ), wxSize( 600, 400 ) ); wxPoint( 0, 0 ), wxSize( 600, 400 ) );
frame->SetTitle( GetTitle() + wxT( " " ) + GetBuildVersion() ); frame->SetTitle( GetTitle() + wxT( " " ) + GetBuildVersion() );

View File

@ -13,20 +13,11 @@
#include "protos.h" #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 */ /* local variables */
static int nb_pads_ref; // node count (node = pad with a net code) for the footprint beeing moved static std::vector <D_PAD*> s_localPadBuffer; // for local ratsnest calculations when moving a footprint: buffer of pads to consider
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 bool DisplayRastnestInProgress; // Enable the display of the ratsnest during the ratsnest computations
/* Note about the ratsnest computation: /* Note about the ratsnest computation:
* Building the general ratsnest: * Building the general ratsnest:
@ -152,7 +143,7 @@ void WinEDA_BasePcbFrame::Compile_Ratsnest( wxDC* DC, bool display_status_pcb )
Tst_Ratsnest( DC, 0 ); Tst_Ratsnest( DC, 0 );
// Redraw the active ratsnest ( if enabled ) // Redraw the active ratsnest ( if enabled )
if( g_Show_Ratsnest ) if( g_Show_Ratsnest && DC )
DrawGeneralRatsnest( DC, 0 ); DrawGeneralRatsnest( DC, 0 );
if( display_status_pcb ) 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 /* 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, static int gen_rats_block_to_block( WinEDA_DrawPanel* aDrawPanel,
D_PAD** pt_liste_pad, D_PAD** pt_limite, int* nblinks ) 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. * 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 pt_liste_pad = starting address (within the pad list) for search * @param aPadList = starting address (within the pad list) for search
* @param pt_limite = ending address (within the pad list) for search * @param aPadMax = ending address (within the pad list) for search
* return in global variables: * @param aRatsnestBuffer = a std::vector<RATSNEST_ITEM> buffer to fill with new ratsnest items
* ratsnest list in buffer
* g_pt_chevelu updated to the first free memory location
* @return blocks not connected count * @return blocks not connected count
*/ */
{ {
@ -222,15 +213,12 @@ static int gen_rats_block_to_block( WinEDA_DrawPanel* DrawPanel, wxDC* DC,
dist_min = 0x7FFFFFFF; dist_min = 0x7FFFFFFF;
pt_start_liste = pt_liste_pad; pt_start_liste = aPadList;
if( DC )
GRSetDrawMode( DC, GR_XOR );
/* Search the nearest pad from block 1 */ /* 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 */ /* search a pad which is in the block 1 */
if( ref_pad->GetSubRatsnest() != 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; D_PAD* curr_pad = *pt_liste_pad_aux;
if( pt_liste_pad_aux >= pt_limite ) if( pt_liste_pad_aux >= aPadMax )
break; break;
if( curr_pad->GetSubRatsnest() == 1 ) // not in an other block 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; dist_min = current_dist;
pt_liste_pad_tmp = pt_liste_pad_aux; 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 : /* 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 * 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 ) if( (*aPadList)->GetSubRatsnest() == current_num_block )
(*pt_liste_pad)->SetSubRatsnest( 1 ); (*aPadList)->SetSubRatsnest( 1 );
} }
pt_liste_pad = pt_liste_pad_block1; aPadList = pt_liste_pad_block1;
/* Create the new ratsnet */ /* Create the new ratsnet */
(*nblinks)++; RATSNEST_ITEM net;
g_pt_chevelu->SetNet( (*pt_liste_pad)->GetNet() ); net.SetNet( (*aPadList)->GetNet() );
g_pt_chevelu->m_Status = CH_ACTIF | CH_VISIBLE; net.m_Status = CH_ACTIF | CH_VISIBLE;
g_pt_chevelu->m_Lenght = dist_min; net.m_Lenght = dist_min;
g_pt_chevelu->m_PadStart = *pt_liste_pad; net.m_PadStart = *aPadList;
g_pt_chevelu->m_PadEnd = *pt_liste_pad_tmp; net.m_PadEnd = *pt_liste_pad_tmp;
aRatsnestBuffer.push_back( net );
if( DisplayRastnestInProgress && DC )
g_pt_chevelu->Draw( DrawPanel, DC, GR_XOR, wxPoint( 0, 0 ) );
g_pt_chevelu++;
} }
return current_num_block; return current_num_block;
} }
/*****************************************************************************/ /*****************************************************************************/
static int gen_rats_pad_to_pad( WinEDA_DrawPanel* DrawPanel, wxDC* DC, static int gen_rats_pad_to_pad( WinEDA_DrawPanel* aDrawPanel,
D_PAD** pt_liste_pad, vector<RATSNEST_ITEM>& aRatsnestBuffer,
D_PAD** pt_limite, int current_num_block, int* nblinks ) 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_liste_pad = starting address in the pad buffer
* @param pt_limite = ending address * @param pt_limite = ending address
* @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
* *
* output: * @return the last block number used
* Ratsnest list
* g_pt_chevelu updated to the first free memory address
*
* @return:
* last block number used
*/ */
{ {
int dist_min, current_dist; 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** pt_start_liste;
D_PAD* ref_pad, * pad; 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() ) if( ref_pad->GetSubRatsnest() )
continue; // Pad already connected 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++ ) 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; break;
if( pt_liste_pad_aux == pt_liste_pad ) if( pt_liste_pad_aux == aPadList )
continue; continue;
pad = *pt_liste_pad_aux; 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() ); ref_pad->SetSubRatsnest( pad->GetSubRatsnest() );
} }
(*nblinks)++; /* Create the new ratsnet item */
g_pt_chevelu->SetNet( ref_pad->GetNet() ); RATSNEST_ITEM rast;
g_pt_chevelu->m_Status = CH_ACTIF | CH_VISIBLE; rast.SetNet( ref_pad->GetNet() );
g_pt_chevelu->m_Lenght = dist_min; rast.m_Status = CH_ACTIF | CH_VISIBLE;
g_pt_chevelu->m_PadStart = ref_pad; rast.m_Lenght = dist_min;
g_pt_chevelu->m_PadEnd = pad; rast.m_PadStart = ref_pad;
rast.m_PadEnd = pad;
if( DisplayRastnestInProgress && DC ) aRatsnestBuffer.push_back( rast );
g_pt_chevelu->Draw( DrawPanel, DC, GR_XOR, wxPoint( 0, 0 ) );
g_pt_chevelu++;
} }
} }
@ -437,12 +416,8 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
int noconn; int noconn;
m_Pcb->m_NbNoconnect = 0; 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 ) if( m_Pcb->m_Pads.size() == 0 )
return; return;
@ -457,22 +432,11 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
pad->SetSubRatsnest( 0 ); pad->SetSubRatsnest( 0 );
} }
/* Allocate memory for buffer ratsnest: there are nb_nodes - 1 ratsnest if( m_Pcb->GetNodesCount() == 0 )
* 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 )
return; /* pas de connexions utiles */ 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 */ /* Ratsnest computation */
DisplayRastnestInProgress = TRUE; DisplayRastnestInProgress = TRUE;
g_pt_chevelu = m_Pcb->m_Ratsnest;
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;
@ -480,10 +444,14 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
for( ; current_net_code < m_Pcb->m_NetInfo->GetCount(); current_net_code++ ) for( ; current_net_code < m_Pcb->m_NetInfo->GetCount(); current_net_code++ )
{ {
NETINFO_ITEM* net = m_Pcb->FindNet( current_net_code ); NETINFO_ITEM* net = m_Pcb->FindNet( current_net_code );
net->m_RatsnestStart = g_pt_chevelu; if ( net == NULL ) //Should not occur
m_Pcb->m_NbLinks += net->m_ListPad.size() - 1; {
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++ ) for( unsigned ii = 0; ii < net->m_ListPad.size(); ii++ )
{ {
pad = net->m_ListPad[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 */ /* a - first pass : create the blocks from not already in block pads */
D_PAD** pstart = &net->m_ListPad[0]; D_PAD** pstart = &net->m_ListPad[0];
D_PAD** pend = pstart + net->m_ListPad.size(); D_PAD** pend = pstart + net->m_ListPad.size();
int icnt = gen_rats_pad_to_pad( DrawPanel, DC, pstart, pend, int icnt = gen_rats_pad_to_pad( DrawPanel, m_Pcb->m_FullRatsnest, pstart, pend,
num_block, &noconn ); num_block );
/* b - blocks connection (Iteration) */ /* b - blocks connection (Iteration) */
while( icnt > 1 ) 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 */ /* sort by lenght */
qsort( net->m_RatsnestStart, if( (net->m_RatsnestEnd - net->m_RatsnestStart) > 1 )
net->m_RatsnestEnd - net->m_RatsnestStart, {
sizeof(RATSNEST_ITEM), RATSNEST_ITEM* rats = &m_Pcb->m_FullRatsnest[0];
sort_by_length ); 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_NbNoconnect = noconn;
m_Pcb->m_Status_Pcb |= LISTE_RATSNEST_ITEM_OK; m_Pcb->m_Status_Pcb |= LISTE_RATSNEST_ITEM_OK;
// erase the ratsnest displayed on screen if needed // erase the ratsnest displayed on screen if needed
RATSNEST_ITEM* Chevelu = m_Pcb->m_Ratsnest; for( unsigned ii = 0; ii < m_Pcb->GetRatsnestsCount(); ii++ )
for( int ii = m_Pcb->GetNumRatsnests(); ii > 0 && Chevelu; ii--, Chevelu++ )
{ {
if( !g_Show_Ratsnest ) if( !g_Show_Ratsnest ) // Clear VISIBLE flag
Chevelu->m_Status &= ~CH_VISIBLE; m_Pcb->m_FullRatsnest[ii].m_Status &= ~CH_VISIBLE;
if( DC ) 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 * @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 ) if( (m_Pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 )
return; return;
if( (m_Pcb->m_Status_Pcb & DO_NOT_SHOW_GENERAL_RASTNEST) ) 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 ) if( DC == NULL )
return; return;
Chevelu = m_Pcb->m_Ratsnest; for( unsigned ii = 0; ii < m_Pcb->GetRatsnestsCount(); ii++ )
if( Chevelu == NULL )
return;
for( ii = m_Pcb->GetNumRatsnests(); ii > 0; Chevelu++, 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; continue;
if( (net_code <= 0) || ( net_code == Chevelu->GetNet() ) ) if( (net_code <= 0) || ( net_code == m_Pcb->m_FullRatsnest[ii].GetNet() ) )
Chevelu->Draw( DrawPanel, DC, GR_XOR, wxPoint( 0, 0 ) ); 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; 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 */ /* Search a link from a block to an other block */
min_chevelu = NULL; min_rats = NULL;
for( chevelu = net->m_RatsnestStart; chevelu < net->m_RatsnestEnd; chevelu++ ) 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; continue;
if( min_chevelu == NULL ) if( min_rats == NULL )
min_chevelu = chevelu; min_rats = rats;
else if( min_chevelu->m_Lenght > chevelu->m_Lenght ) else if( min_rats->m_Lenght > rats->m_Lenght )
min_chevelu = chevelu; min_rats = rats;
} }
if( min_chevelu == NULL ) if( min_rats == NULL )
return 1; return 1;
/* At this point we have found a link between 2 differents blocks (clusters) : /* 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 * we must set its status to ACTIVE and merge the 2 blocks
*/ */
min_chevelu->m_Status |= CH_ACTIF; min_rats->m_Status |= CH_ACTIF;
current_num_block = min_chevelu->m_PadStart->GetSubRatsnest(); current_num_block = min_rats->m_PadStart->GetSubRatsnest();
min_block = min_chevelu->m_PadEnd->GetSubRatsnest(); min_block = min_rats->m_PadEnd->GetSubRatsnest();
if( min_block > current_num_block ) if( min_block > current_num_block )
EXCHG( min_block, current_num_block ); EXCHG( min_block, current_num_block );
@ -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, static int tst_rats_pad_to_pad( int current_num_block,
int current_num_block,
RATSNEST_ITEM* start_rat_list, RATSNEST_ITEM* end_rat_list ) 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 * if ref_netcode == 0, test all nets, else test only ref_netcode
*/ */
{ {
RATSNEST_ITEM* chevelu; RATSNEST_ITEM* rats;
D_PAD* pad; D_PAD* pad;
int net_code;
NETINFO_ITEM* net; NETINFO_ITEM* net;
if( m_Pcb->m_Pads.size() == 0 ) 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 ) if( (m_Pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 )
Build_Board_Ratsnest( DC ); 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 ); net = m_Pcb->FindNet( net_code );
if( net == NULL ) if ( net == NULL ) //Should not occur
break; {
DisplayError(this, wxT("Tst_Ratsnest() error: net not found") );
return;
}
if( ref_netcode && (net_code != ref_netcode) ) if( ref_netcode && (net_code != ref_netcode) )
continue; continue;
@ -737,27 +702,26 @@ void WinEDA_BasePcbFrame::Tst_Ratsnest( wxDC* DC, int ref_netcode )
num_block = MAX( num_block, subnet ); 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 */ /* a - tst connection between pads */
int ii = tst_rats_pad_to_pad( DrawPanel, DC, num_block, rats = &m_Pcb->m_FullRatsnest[0];
net->m_RatsnestStart, net->m_RatsnestEnd ); int icnt = tst_rats_pad_to_pad( num_block, rats + net->m_RatsnestStart, rats + net->m_RatsnestEnd );
/* b - test connexion between blocks (Iteration) */ /* 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; m_Pcb->m_NbNoconnect = 0;
RATSNEST_ITEM* Chevelu = m_Pcb->m_Ratsnest; for( unsigned ii = 0; ii < m_Pcb->GetRatsnestsCount(); ii++ )
for( int ii = m_Pcb->GetNumRatsnests(); ii > 0; ii--, Chevelu++ )
{ {
if( Chevelu->m_Status & CH_ACTIF ) if( m_Pcb->m_FullRatsnest[ii].m_Status & CH_ACTIF )
m_Pcb->m_NbNoconnect++; 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 ); Tst_Ratsnest( DC, ref_netcode );
DrawGeneralRatsnest( 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 * It shows the connections from a pad to the nearest conected pad
* @param Module = module to consider. * @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: * The ratsnest has 2 sections:
* - An "internal" ratsnet relative to pads of this footprint which are in the same net. * - An "internal" ratsnet relative to pads of this footprint which are in the same net.
* this ratsnest section is computed once. * 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 * The ratsnest section must be computed for each new position
*/ */
{ {
D_PAD** pt_liste_pad; static unsigned pads_module_count; // node count (node = pad with a net code) for the footprint beeing moved
D_PAD** pt_liste_ref; static unsigned internalRatsCount; // number of internal links (links between pads of the module)
D_PAD** pt_liste_generale; D_PAD** baseListePad;
D_PAD* pad_ref; D_PAD* pad_ref;
D_PAD* pad_externe; D_PAD* pad_externe;
D_PAD** pt_liste_pad_limite; int current_net_code;
D_PAD** pt_start_liste; int distance; // variables de calcul de ratsnest
D_PAD** pt_end_liste; wxPoint pad_pos; // True pad position according to the current footprint position
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
if( (GetBoard()->m_Status_Pcb & LISTE_PAD_OK) == 0 ) 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 * a pad in the current footprint
*/ */
if( (m_Pcb->m_Status_Pcb & RATSNEST_ITEM_LOCAL_OK) != 0 ) 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 */ /* Compute the "internal" ratsnest, i.e the links between the curent footprint pads */
pt_liste_pad = (D_PAD**) adr_lowmem; s_localPadBuffer.clear();
nb_pads_ref = 0; m_Pcb->m_LocalRatsnest.clear();
pad_ref = Module->m_Pads; for( pad_ref = Module->m_Pads; pad_ref != NULL; pad_ref = pad_ref->Next() )
for( ; pad_ref != NULL; pad_ref = pad_ref->Next() )
{ {
if( pad_ref->GetNet() == 0 ) if( pad_ref->GetNet() == 0 )
continue; continue;
*pt_liste_pad = pad_ref; s_localPadBuffer.push_back( pad_ref );
pad_ref->SetSubRatsnest( 0 ); pad_ref->SetSubRatsnest( 0 );
pad_ref->SetSubNet( 0 ); pad_ref->SetSubNet( 0 );
pt_liste_pad++; nb_pads_ref++;
} }
if( nb_pads_ref == 0 ) pads_module_count = s_localPadBuffer.size();
return (char*) pt_liste_pad; /* pas de connexions! */ 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 */ /* Build the list of pads linked to the current footprint pads */
DisplayRastnestInProgress = FALSE; DisplayRastnestInProgress = FALSE;
pt_liste_ref = (D_PAD**) adr_lowmem;
nb_pads_externes = 0;
current_net_code = 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 ) if( pad_ref->GetNet() == current_net_code )
continue; continue;
current_net_code = pad_ref->GetNet(); // A new net was found, load all pads of others modules members of this net:
NETINFO_ITEM* net = m_Pcb->FindNet( pad_ref->GetNet() );
pt_liste_generale = &m_Pcb->m_Pads[0]; if ( net == NULL ) //Should not occur
for( jj = m_Pcb->m_Pads.size(); jj > 0; jj-- )
{ {
pad_externe = *pt_liste_generale; pt_liste_generale++; DisplayError(this,wxT("build_ratsnest_module() error: net not found") );
if( pad_externe->GetNet() != current_net_code ) return;
continue; }
for( unsigned jj = 0; jj < net->m_ListPad.size(); jj++ )
{
pad_externe = net->m_ListPad[jj];
if( pad_externe->GetParent() == Module ) if( pad_externe->GetParent() == Module )
continue; continue;
pad_externe->SetSubRatsnest( 0 ); pad_externe->SetSubRatsnest( 0 );
pad_externe->SetSubNet( 0 ); pad_externe->SetSubNet( 0 );
*pt_liste_pad = pad_externe; s_localPadBuffer.push_back( pad_externe );
pt_liste_pad++;
nb_pads_externes++;
} }
} }
/* Sort the pad list by net_code */ /* Sort the pad list by net_code */
qsort( pt_liste_ref + nb_pads_ref, nb_pads_externes, sizeof(D_PAD*), baseListePad = &s_localPadBuffer[0];
tri_par_net ); qsort( baseListePad + pads_module_count,
s_localPadBuffer.size() - pads_module_count,
sizeof(D_PAD*), sortByNetcode );
/* Compute the internal rats nest: /* Compute the internal rats nest:
* this is the same as general ratsnest, but considers only the current footprint pads * 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 * 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 current_net_code = s_localPadBuffer[0]->GetNet();
nb_local_chevelu = 0;
pt_liste_ref = (D_PAD**) adr_lowmem;
g_pt_chevelu = local_liste_chevelu; for( unsigned ii = 0; ii < pads_module_count; ii++ )
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();
for( ; pt_liste_pad < pt_liste_pad_limite; )
{ {
/* Search the end of pad list relative to the current net */ /* Search the end of pad list relative to the current net */
unsigned jj = ii + 1;
for( pt_end_liste = pt_liste_pad + 1; ; pt_end_liste++ ) for( ; jj <= pads_module_count; jj++ )
{ {
if( pt_end_liste >= pt_liste_pad_limite ) if( jj >= pads_module_count )
break; break;
if( (*pt_end_liste)->GetNet() != current_net_code ) if( s_localPadBuffer[jj]->GetNet() != current_net_code )
break; break;
} }
/* 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 */
ii = gen_rats_pad_to_pad( DrawPanel, DC, pt_start_liste, pt_end_liste, int icnt = gen_rats_pad_to_pad( DrawPanel, m_Pcb->m_LocalRatsnest,
0, &nb_local_chevelu ); 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( ii > 1 ) while( icnt > 1 )
{ {
ii = gen_rats_block_to_block( DrawPanel, DC, pt_liste_pad, icnt = gen_rats_block_to_block( DrawPanel, m_Pcb->m_LocalRatsnest,
pt_end_liste, &nb_local_chevelu ); baseListePad + ii, baseListePad + jj );
} }
pt_liste_pad = pt_start_liste = pt_end_liste; ii = jj;
if( pt_start_liste < pt_liste_pad_limite ) if( ii < s_localPadBuffer.size() )
current_net_code = (*pt_start_liste)->GetNet(); current_net_code = s_localPadBuffer[ii]->GetNet();
} }
pt_fin_int_chevelu = local_chevelu = g_pt_chevelu; internalRatsCount = m_Pcb->m_LocalRatsnest.size();
nb_int_chevelu = nb_local_chevelu;
/* set the ratsnets status, flag LOCAL_RATSNEST_ITEM */ /* set the ratsnets status, flag LOCAL_RATSNEST_ITEM */
g_pt_chevelu = local_liste_chevelu; for( unsigned ii = 0; ii < m_Pcb->m_LocalRatsnest.size(); ii++ )
while( g_pt_chevelu < pt_fin_int_chevelu )
{ {
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; 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 * This section computes the "external" ratsnest: must be done when the footprint position changes
*/ */
calcul_chevelu_ext: 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),
* 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; RATSNEST_ITEM local_rats;
nb_local_chevelu = nb_int_chevelu; local_rats.m_Lenght = 0x7FFFFFFF;
pt_liste_ref = (D_PAD**) adr_lowmem; local_rats.m_Status = 0;
pad_ref = *pt_liste_ref; 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 = pad_ref->GetNet(); current_net_code = s_localPadBuffer[0]->GetNet();
local_chevelu->m_Lenght = 0x7FFFFFFF; for( unsigned ii = 0; ii < pads_module_count; ii++ )
local_chevelu->m_Status = 0;
increment = 0;
for( ii = 0; ii < nb_pads_ref; ii++ )
{ {
pad_ref = *(pt_liste_ref + ii); pad_ref = s_localPadBuffer[ii];
if( pad_ref->GetNet() != current_net_code ) if( pad_ref->GetNet() != current_net_code )
{ {
/* if needed a new ratsenest for each new net */ /* if needed, creates a new ratsnest for the old net */
if( increment ) if( addRats )
{ {
nb_local_chevelu++; local_chevelu++; m_Pcb->m_LocalRatsnest.push_back( local_rats );
} }
increment = 0; addRats = false;
current_net_code = pad_ref->GetNet(); current_net_code = pad_ref->GetNet();
local_chevelu->m_Lenght = 0x7FFFFFFF; local_rats.m_Lenght = 0x7FFFFFFF;
} }
pad_pos_X = pad_ref->m_Pos.x - g_Offset_Module.x; pad_pos = pad_ref->m_Pos - g_Offset_Module;
pad_pos_Y = pad_ref->m_Pos.y - g_Offset_Module.y;
pt_liste_generale = pt_liste_ref + nb_pads_ref;
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() ) if( pad_externe->GetNet() < pad_ref->GetNet() )
continue; continue;
if( pad_externe->GetNet() > pad_ref->GetNet() ) // remember pads are sorted by net code if( pad_externe->GetNet() > pad_ref->GetNet() ) // remember pads are sorted by net code
break; break;
distance = abs( pad_externe->m_Pos.x - pad_pos_X ) + distance = abs( pad_externe->m_Pos.x - pad_pos.x ) +
abs( pad_externe->m_Pos.y - pad_pos_Y ); 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_rats.m_PadStart = pad_ref;
local_chevelu->m_PadEnd = pad_externe; local_rats.m_PadEnd = pad_externe;
local_chevelu->SetNet( pad_ref->GetNet() ); local_rats.SetNet( pad_ref->GetNet() );
local_chevelu->m_Lenght = distance; local_rats.m_Lenght = distance;
local_chevelu->m_Status = 0; local_rats.m_Status = 0;
increment = 1; addRats = true;
} }
} }
} }
if( increment ) // fin de balayage : le ratsnest courant doit etre memorise if( addRats ) // Ensure the last created rats nest item is stored in buffer
{ m_Pcb->m_LocalRatsnest.push_back( local_rats );
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
*/
} }
@ -1030,35 +966,28 @@ void WinEDA_BasePcbFrame::trace_ratsnest_module( wxDC* DC )
* Display the rastnest of a moving footprint, computed by build_ratsnest_module() * Display the rastnest of a moving footprint, computed by build_ratsnest_module()
*/ */
{ {
RATSNEST_ITEM* local_chevelu;
int ii;
if( DC == NULL ) if( DC == NULL )
return; return;
if( (m_Pcb->m_Status_Pcb & RATSNEST_ITEM_LOCAL_OK) == 0 ) if( (m_Pcb->m_Status_Pcb & RATSNEST_ITEM_LOCAL_OK) == 0 )
return; return;
local_chevelu = local_liste_chevelu;
ii = nb_local_chevelu;
GRSetDrawMode( DC, GR_XOR );
int tmpcolor = g_DesignSettings.m_RatsnestColor; 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; 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 else
{ {
g_DesignSettings.m_RatsnestColor = tmpcolor; g_DesignSettings.m_RatsnestColor = tmpcolor;
wxPoint tmp = local_chevelu->m_PadStart->m_Pos; wxPoint tmp = rats->m_PadStart->m_Pos;
local_chevelu->m_PadStart->m_Pos -= g_Offset_Module; rats->m_PadStart->m_Pos -= g_Offset_Module;
local_chevelu->Draw( DrawPanel, DC, GR_XOR, wxPoint(0,0) ); rats->Draw( DrawPanel, DC, GR_XOR, wxPoint( 0, 0 ) );
local_chevelu->m_PadStart->m_Pos = tmp; rats->m_PadStart->m_Pos = tmp;
} }
local_chevelu++;
} }
g_DesignSettings.m_RatsnestColor = tmpcolor; g_DesignSettings.m_RatsnestColor = tmpcolor;
@ -1106,11 +1035,12 @@ void WinEDA_BasePcbFrame::build_ratsnest_pad( BOARD_ITEM* ref,
const wxPoint& refpos, bool init ) const wxPoint& refpos, bool init )
/****************************************************************************************/ /****************************************************************************************/
{ {
int current_net_code = 0, conn_number = 0; int current_net_code = 0, conn_number = 0;
D_PAD* pad_ref = NULL; D_PAD* pad_ref = NULL;
if( ( (m_Pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 ) if( ( (m_Pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 )
|| ( (m_Pcb->m_Status_Pcb & LISTE_PAD_OK) == 0 ) || ( (m_Pcb->m_Status_Pcb & 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(); s_RatsnestMouseToPads.clear();
return; return;
@ -1148,9 +1078,12 @@ void WinEDA_BasePcbFrame::build_ratsnest_pad( BOARD_ITEM* ref,
if( current_net_code <= 0 ) if( current_net_code <= 0 )
return; return;
NETINFO_ITEM * net = m_Pcb->FindNet(current_net_code); NETINFO_ITEM* net = m_Pcb->FindNet( current_net_code );
if ( net == NULL ) if ( net == NULL ) //Should not occur
{
DisplayError(this,wxT("build_ratsnest_pad() error: net not found") );
return; return;
}
// Create a list of pads candidates ( pads not already connected to the current track: // Create a list of pads candidates ( pads not already connected to the current track:
for( unsigned ii = 0; ii < net->m_ListPad.size(); ii++ ) 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 */ } /* end if Init */
if( s_RatsnestMouseToPads.size() > 1) if( s_RatsnestMouseToPads.size() > 1 )
sort( s_RatsnestMouseToPads.begin(), s_RatsnestMouseToPads.end(), sort_by_localnetlength ); 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 ) if( DC == NULL )
return; return;
if( s_RatsnestMouseToPads.size() == 0) if( s_RatsnestMouseToPads.size() == 0 )
return; return;
GRSetDrawMode( DC, GR_XOR ); GRSetDrawMode( DC, GR_XOR );
for( int ii = 0; ii < (int)s_RatsnestMouseToPads.size(); ii++ ) for( int ii = 0; ii < (int) s_RatsnestMouseToPads.size(); ii++ )
{ {
if( ii >= g_MaxLinksShowed ) if( ii >= g_MaxLinksShowed )
break; break;

View File

@ -17,67 +17,73 @@
/*********************************************************/ /*********************************************************/
void WinEDA_PcbFrame::Liste_Equipot( wxCommandEvent& event ) void WinEDA_PcbFrame::ListNetsAndSelect( wxCommandEvent& event )
/*********************************************************/ /*********************************************************/
/* Display a filtered list of equipot names /** Function ListNetsAndSelect
* if an equipot is selected the corresponding tracks and pads are highlighted * called by a command event
* displays the sorted list of nets in a dialog frame
* If a net is selected, it is hightlighted
*/ */
{ {
NETINFO_ITEM* net; NETINFO_ITEM* net;
wxString msg; wxString netFilter;
WinEDA_TextFrame* List; int selection;
unsigned ii;
msg = wxT( "*" ); netFilter = wxT( "*" );
Get_Message( _( "Filter for net names:" ), _("Net Filter"), msg, this ); Get_Message( _( "Filter for net names:" ), _( "Net Filter" ), netFilter, this );
if( msg.IsEmpty() ) if( netFilter.IsEmpty() )
return; return;
List = new WinEDA_TextFrame( this, _( "List Nets" ) ); WinEDA_TextFrame List( this, _( "List Nets" ) );
for( ii = 0; ii < GetBoard()->m_NetInfo->GetCount() ; ii++ ) for( unsigned ii = 0; ii < GetBoard()->m_NetInfo->GetCount(); ii++ )
{ {
net = GetBoard()->m_NetInfo->GetItem( ii ); net = GetBoard()->m_NetInfo->GetItem( ii );
wxString Line; wxString Line;
if( !WildCompareString( msg, net->GetNetname(), false ) ) if( !WildCompareString( netFilter, net->GetNetname(), false ) )
continue; continue;
Line.Printf( wxT( "net_code = %3.3d [%.16s] " ), net->GetNet(), Line.Printf( wxT( "net_code = %3.3d [%.16s] " ), net->GetNet(),
net->GetNetname().GetData() ); net->GetNetname().GetData() );
List->Append( Line ); List.Append( Line );
} }
ii = List->ShowModal(); selection = List.ShowModal();
List->Destroy(); if( selection < 0 )
if( ii < 0 )
return; return;
for( unsigned jj = 0; jj < GetBoard()->m_NetInfo->GetCount() ; jj++ ) bool found = false;
unsigned netcode = (unsigned) selection;
// Search for the net selected.
for( unsigned ii = 0; ii < GetBoard()->m_NetInfo->GetCount(); ii++ )
{ {
net = GetBoard()->m_NetInfo->GetItem( ii ); net = GetBoard()->m_NetInfo->GetItem( ii );
if( !WildCompareString( msg, net->GetNetname(), false ) ) if( !WildCompareString( netFilter, net->GetNetname(), false ) )
continue; continue;
if( ii == jj ) if( ii == netcode )
{ {
ii = net->GetNet(); netcode = net->GetNet();
found = true;
break; break;
} }
jj++;
} }
wxClientDC dc( DrawPanel ); if( found )
{
wxClientDC dc( DrawPanel );
DrawPanel->PrepareGraphicContext( &dc ); DrawPanel->PrepareGraphicContext( &dc );
if( g_HightLigt_Status ) if( g_HightLigt_Status )
Hight_Light( &dc );
g_HightLigth_NetCode = netcode;
Hight_Light( &dc ); Hight_Light( &dc );
}
g_HightLigth_NetCode = ii;
Hight_Light( &dc );
} }
@ -100,7 +106,7 @@ int WinEDA_PcbFrame::Select_High_Light( wxDC* DC )
// optionally, modify the "guide" here as needed using its member functions // optionally, modify the "guide" here as needed using its member functions
m_Collector->Collect( GetBoard(), GENERAL_COLLECTOR::PadsTracksOrZones, m_Collector->Collect( GetBoard(), GENERAL_COLLECTOR::PadsTracksOrZones,
GetScreen()->RefPos( true ), guide ); GetScreen()->RefPos( true ), guide );
BOARD_ITEM* item = (*m_Collector)[0]; BOARD_ITEM* item = (*m_Collector)[0];
@ -109,7 +115,7 @@ int WinEDA_PcbFrame::Select_High_Light( wxDC* DC )
switch( item->Type() ) switch( item->Type() )
{ {
case TYPE_PAD: case TYPE_PAD:
g_HightLigth_NetCode = ((D_PAD*)item)->GetNet(); g_HightLigth_NetCode = ( (D_PAD*) item )->GetNet();
Hight_Light( DC ); Hight_Light( DC );
SendMessageToEESCHEMA( item ); SendMessageToEESCHEMA( item );
return g_HightLigth_NetCode; return g_HightLigth_NetCode;
@ -117,14 +123,15 @@ int WinEDA_PcbFrame::Select_High_Light( wxDC* DC )
case TYPE_TRACK: case TYPE_TRACK:
case TYPE_VIA: case TYPE_VIA:
case TYPE_ZONE: case TYPE_ZONE:
// since these classes are all derived from TRACK, use a common // since these classes are all derived from TRACK, use a common
// GetNet() function: // GetNet() function:
g_HightLigth_NetCode = ((TRACK*)item)->GetNet(); g_HightLigth_NetCode = ( (TRACK*) item )->GetNet();
Hight_Light( DC ); Hight_Light( DC );
return g_HightLigth_NetCode; return g_HightLigth_NetCode;
case TYPE_ZONE_CONTAINER: case TYPE_ZONE_CONTAINER:
g_HightLigth_NetCode = ((ZONE_CONTAINER*)item)->GetNet(); g_HightLigth_NetCode = ( (ZONE_CONTAINER*) item )->GetNet();
Hight_Light( DC ); Hight_Light( DC );
return g_HightLigth_NetCode; return g_HightLigth_NetCode;
@ -151,4 +158,3 @@ void WinEDA_PcbFrame::Hight_Light( wxDC* DC )
GetBoard()->DrawHighLight( DrawPanel, DC, g_HightLigth_NetCode ); GetBoard()->DrawHighLight( DrawPanel, DC, g_HightLigth_NetCode );
} }