Pcbnew: minor changes in pcb-parser.cpp and kicad_plugin.cpp to make translations easier.

Code cleaning in autoroute functions.
This commit is contained in:
jean-pierre charras 2012-06-26 19:57:37 +02:00
parent 1b08d1874f
commit 047bb44ef5
10 changed files with 137 additions and 209 deletions

View File

@ -440,7 +440,7 @@ int PCB_EDIT_FRAME::GenPlaceBoard()
m_messagePanel->SetMessage( 14, _( "Cells." ), msg, YELLOW ); m_messagePanel->SetMessage( 14, _( "Cells." ), msg, YELLOW );
/* Choose the number of board sides. */ /* Choose the number of board sides. */
Nb_Sides = TWO_SIDES; RoutingMatrix.m_RoutingLayersCount = 2;
RoutingMatrix.InitRoutingMatrix(); RoutingMatrix.InitRoutingMatrix();
@ -450,7 +450,7 @@ int PCB_EDIT_FRAME::GenPlaceBoard()
Route_Layer_BOTTOM = LAYER_N_FRONT; Route_Layer_BOTTOM = LAYER_N_FRONT;
if( Nb_Sides == TWO_SIDES ) if( RoutingMatrix.m_RoutingLayersCount > 1 )
Route_Layer_BOTTOM = LAYER_N_BACK; Route_Layer_BOTTOM = LAYER_N_BACK;
Route_Layer_TOP = LAYER_N_FRONT; Route_Layer_TOP = LAYER_N_FRONT;
@ -618,7 +618,7 @@ int PCB_EDIT_FRAME::GetOptimalModulePlacement( MODULE* aModule, wxDC* aDC )
*/ */
TstOtherSide = false; TstOtherSide = false;
if( Nb_Sides == TWO_SIDES ) if( RoutingMatrix.m_RoutingLayersCount > 1 )
{ {
D_PAD* Pad; D_PAD* Pad;
int otherLayerMask = LAYER_BACK; int otherLayerMask = LAYER_BACK;
@ -967,7 +967,7 @@ void CreateKeepOutRectangle( int ux0, int uy0, int ux1, int uy1,
if( aLayerMask & GetLayerMask( Route_Layer_BOTTOM ) ) if( aLayerMask & GetLayerMask( Route_Layer_BOTTOM ) )
trace = 1; /* Trace on bottom layer. */ trace = 1; /* Trace on bottom layer. */
if( ( aLayerMask & GetLayerMask( Route_Layer_TOP ) ) && Nb_Sides ) if( ( aLayerMask & GetLayerMask( Route_Layer_TOP ) ) && RoutingMatrix.m_RoutingLayersCount )
trace |= 2; /* Trace on top layer. */ trace |= 2; /* Trace on top layer. */
if( trace == 0 ) if( trace == 0 )

View File

@ -47,12 +47,6 @@
#include <autorout.h> #include <autorout.h>
int Nb_Sides; /* Number of layer for autorouting (0 or 1) */
int OpenNodes; /* total number of nodes opened */
int ClosNodes; /* total number of nodes closed */
int MoveNodes; /* total number of nodes moved */
int MaxNodes; /* maximum number of nodes opened at one time */
MATRIX_ROUTING_HEAD RoutingMatrix; // routing matrix (grid) to route 2-sided boards MATRIX_ROUTING_HEAD RoutingMatrix; // routing matrix (grid) to route 2-sided boards
/* init board, route traces*/ /* init board, route traces*/
@ -175,10 +169,10 @@ void PCB_EDIT_FRAME::Autoroute( wxDC* DC, int mode )
m_messagePanel->EraseMsgBox(); m_messagePanel->EraseMsgBox();
/* Map the board */ /* Map the board */
Nb_Sides = ONE_SIDE; RoutingMatrix.m_RoutingLayersCount = 1;
if( Route_Layer_TOP != Route_Layer_BOTTOM ) if( Route_Layer_TOP != Route_Layer_BOTTOM )
Nb_Sides = TWO_SIDES; RoutingMatrix.m_RoutingLayersCount = 2;
if( RoutingMatrix.InitRoutingMatrix() < 0 ) if( RoutingMatrix.InitRoutingMatrix() < 0 )
{ {
@ -195,10 +189,7 @@ void PCB_EDIT_FRAME::Autoroute( wxDC* DC, int mode )
// DisplayRoutingMatrix( m_canvas, DC ); // DisplayRoutingMatrix( m_canvas, DC );
if( Nb_Sides == TWO_SIDES ) Solve( DC, RoutingMatrix.m_RoutingLayersCount );
Solve( DC, TWO_SIDES ); /* double face */
else
Solve( DC, ONE_SIDE ); /* simple face */
/* Free memory. */ /* Free memory. */
FreeQueue(); FreeQueue();
@ -249,7 +240,7 @@ void DisplayRoutingMatrix( EDA_DRAW_PANEL* panel, wxDC* DC )
if( dcell0 & HOLE ) if( dcell0 & HOLE )
color = GREEN; color = GREEN;
// if( Nb_Sides ) // if( RoutingMatrix.m_RoutingLayersCount )
// dcell1 = GetCell( row, col, TOP ); // dcell1 = GetCell( row, col, TOP );
if( dcell1 & HOLE ) if( dcell1 & HOLE )

View File

@ -46,7 +46,8 @@ class BOARD;
/* Autorouter commands. */ /* Autorouter commands. */
enum CommandOpt { enum AUTOPLACEROUTE_OPTIONS
{
PLACE_ALL, PLACE_ALL,
PLACE_OUT_OF_BOARD, PLACE_OUT_OF_BOARD,
PLACE_INCREMENTAL, PLACE_INCREMENTAL,
@ -58,13 +59,7 @@ enum CommandOpt {
ROUTE_PAD ROUTE_PAD
}; };
#define MAX_ROUTING_LAYERS_COUNT 2
#define ONE_SIDE 0
#define TWO_SIDES 1
#define MAX_SIDES_COUNT 2
extern int Nb_Sides; /* Number of layers for autorouting (0 or 1) */
#define FORCE_PADS 1 /* Force placement of pads for any Netcode */ #define FORCE_PADS 1 /* Force placement of pads for any Netcode */
@ -88,20 +83,23 @@ typedef char DIR_CELL;
class MATRIX_ROUTING_HEAD class MATRIX_ROUTING_HEAD
{ {
public: public:
MATRIX_CELL* m_BoardSide[MAX_SIDES_COUNT]; // the image map of 2 board sides MATRIX_CELL* m_BoardSide[MAX_ROUTING_LAYERS_COUNT]; // the image map of 2 board sides
DIST_CELL* m_DistSide[MAX_SIDES_COUNT]; // the image map of 2 board sides: distance to DIST_CELL* m_DistSide[MAX_ROUTING_LAYERS_COUNT]; // the image map of 2 board sides:
// cells // distance to cells
DIR_CELL* m_DirSide[MAX_SIDES_COUNT]; // the image map of 2 board sides: pointers back to DIR_CELL* m_DirSide[MAX_ROUTING_LAYERS_COUNT]; // the image map of 2 board sides:
// source // pointers back to source
bool m_InitMatrixDone; bool m_InitMatrixDone;
int m_Layers; // Layer count (1 2 ) int m_RoutingLayersCount; // Number of layers for autorouting (0 or 1)
int m_GridRouting; // Size of grid for autoplace/autoroute int m_GridRouting; // Size of grid for autoplace/autoroute
EDA_RECT m_BrdBox; // Actual board bounding box EDA_RECT m_BrdBox; // Actual board bounding box
int m_Nrows, m_Ncols; // Matrix size int m_Nrows, m_Ncols; // Matrix size
int m_MemSize; // Memory requirement, just for statistics int m_MemSize; // Memory requirement, just for statistics
int m_RouteCount; // Number of routes int m_RouteCount; // Number of routes
private: private:
void (MATRIX_ROUTING_HEAD::* m_opWriteCell)( int aRow, int aCol, int aSide, MATRIX_CELL aCell); // a pointeur to the current selected cell op // a pointer to the current selected cell operation
void (MATRIX_ROUTING_HEAD::* m_opWriteCell)( int aRow, int aCol,
int aSide, MATRIX_CELL aCell);
public: public:
MATRIX_ROUTING_HEAD(); MATRIX_ROUTING_HEAD();
@ -114,7 +112,7 @@ public:
/** /**
* function GetBrdCoordOrigin * function GetBrdCoordOrigin
* @returns the board coordinate corresponding to the * @return the board coordinate corresponding to the
* routing matrix origin ( board coordinate offset ) * routing matrix origin ( board coordinate offset )
*/ */
wxPoint GetBrdCoordOrigin() wxPoint GetBrdCoordOrigin()
@ -156,6 +154,12 @@ public:
void SetDist( int aRow, int aCol, int aSide, DIST_CELL ); void SetDist( int aRow, int aCol, int aSide, DIST_CELL );
int GetDir( int aRow, int aCol, int aSide ); int GetDir( int aRow, int aCol, int aSide );
void SetDir( int aRow, int aCol, int aSide, int aDir); void SetDir( int aRow, int aCol, int aSide, int aDir);
// calculate distance (with penalty) of a trace through a cell
int CalcDist(int x,int y,int z ,int side );
// calculate approximate distance (manhattan distance)
int GetApxDist( int r1, int c1, int r2, int c2 );
}; };
extern MATRIX_ROUTING_HEAD RoutingMatrix; /* 2-sided board */ extern MATRIX_ROUTING_HEAD RoutingMatrix; /* 2-sided board */
@ -220,10 +224,6 @@ int SetWork( int, int, int , int, int, RATSNEST_ITEM *, int );
void GetWork( int *, int *, int *, int *, int *, RATSNEST_ITEM ** ); void GetWork( int *, int *, int *, int *, int *, RATSNEST_ITEM ** );
void SortWork(); /* order the work items; shortest first */ void SortWork(); /* order the work items; shortest first */
/* DIST.CPP */
int GetApxDist( int r1, int c1, int r2, int c2 );
int CalcDist(int x,int y,int z ,int side );
/* routing_matrix.cpp */ /* routing_matrix.cpp */
int Build_Work( BOARD * Pcb ); 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 );

View File

@ -39,7 +39,7 @@
/* calculate approximate distance (manhattan distance) /* calculate approximate distance (manhattan distance)
*/ */
int GetApxDist( int r1, int c1, int r2, int c2 ) int MATRIX_ROUTING_HEAD::GetApxDist( int r1, int c1, int r2, int c2 )
{ {
int d1, d2; /* row and column deltas */ int d1, d2; /* row and column deltas */
@ -135,7 +135,7 @@ static int dir_penalty_BOTTOM[10][10] =
/* calculate distance (with penalty) of a trace through a cell /* calculate distance (with penalty) of a trace through a cell
*/ */
int CalcDist(int x,int y,int z ,int side ) int MATRIX_ROUTING_HEAD::CalcDist(int x,int y,int z ,int side )
{ {
int adjust, ldist; int adjust, ldist;
@ -158,7 +158,7 @@ int CalcDist(int x,int y,int z ,int side )
ldist = dist[x-1][y-1] + penalty[x-1][y-1] + adjust; ldist = dist[x-1][y-1] + penalty[x-1][y-1] + adjust;
if( Nb_Sides ) if( m_RouteCount > 1 )
{ {
if( side == BOTTOM ) if( side == BOTTOM )
ldist += dir_penalty_TOP[x-1][y-1]; ldist += dir_penalty_TOP[x-1][y-1];

View File

@ -71,14 +71,14 @@ static void TraceCircle( int ux0, int uy0, int ux1, int uy1, int lg, int layer,
if( layer < 0 ) \ if( layer < 0 ) \
{ \ { \
RoutingMatrix.WriteCell( dy, dx, BOTTOM, color ); \ RoutingMatrix.WriteCell( dy, dx, BOTTOM, color ); \
if( Nb_Sides ) \ if( RoutingMatrix.m_RoutingLayersCount > 1 ) \
RoutingMatrix.WriteCell( dy, dx, TOP, color ); \ RoutingMatrix.WriteCell( dy, dx, TOP, color ); \
} \ } \
else \ else \
{ \ { \
if( layer == Route_Layer_BOTTOM ) \ if( layer == Route_Layer_BOTTOM ) \
RoutingMatrix.WriteCell( dy, dx, BOTTOM, color ); \ RoutingMatrix.WriteCell( dy, dx, BOTTOM, color ); \
if( Nb_Sides ) \ if( RoutingMatrix.m_RoutingLayersCount > 1 ) \
if( layer == Route_Layer_TOP ) \ if( layer == Route_Layer_TOP ) \
RoutingMatrix.WriteCell( dy, dx, TOP, color ); \ RoutingMatrix.WriteCell( dy, dx, TOP, color ); \
} \ } \
@ -156,7 +156,7 @@ void TraceFilledCircle( int cx, int cy, int radius,
trace = 1; // Trace on BOTTOM trace = 1; // Trace on BOTTOM
if( aLayerMask & GetLayerMask( Route_Layer_TOP ) ) if( aLayerMask & GetLayerMask( Route_Layer_TOP ) )
if( Nb_Sides ) if( RoutingMatrix.m_RoutingLayersCount > 1 )
trace |= 2; // Trace on TOP trace |= 2; // Trace on TOP
if( trace == 0 ) if( trace == 0 )
@ -475,7 +475,7 @@ void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1,
if( ( aLayerMask & GetLayerMask( Route_Layer_BOTTOM ) ) ) if( ( aLayerMask & GetLayerMask( Route_Layer_BOTTOM ) ) )
trace = 1; // Trace on BOTTOM trace = 1; // Trace on BOTTOM
if( ( aLayerMask & GetLayerMask( Route_Layer_TOP ) ) && Nb_Sides ) if( ( aLayerMask & GetLayerMask( Route_Layer_TOP ) ) && RoutingMatrix.m_RoutingLayersCount > 1 )
trace |= 2; // Trace on TOP trace |= 2; // Trace on TOP
if( trace == 0 ) if( trace == 0 )
@ -542,7 +542,7 @@ void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1,
if( aLayerMask & GetLayerMask( Route_Layer_TOP ) ) if( aLayerMask & GetLayerMask( Route_Layer_TOP ) )
{ {
if( Nb_Sides ) if( RoutingMatrix.m_RoutingLayersCount > 1 )
trace |= 2; // Trace on TOP trace |= 2; // Trace on TOP
} }

View File

@ -46,6 +46,23 @@
#include <class_pcb_text.h> #include <class_pcb_text.h>
MATRIX_ROUTING_HEAD::MATRIX_ROUTING_HEAD()
{
m_BoardSide[0] = m_BoardSide[1] = NULL;
m_DistSide[0] = m_DistSide[1] = NULL;
m_DirSide[0] = m_DirSide[1] = NULL;
m_InitMatrixDone = false;
m_Nrows = m_Ncols = 0;
m_MemSize = 0;
m_RoutingLayersCount = 1;
}
MATRIX_ROUTING_HEAD::~MATRIX_ROUTING_HEAD()
{
}
bool MATRIX_ROUTING_HEAD::ComputeMatrixSize( BOARD* aPcb, bool aUseBoardEdgesOnly ) bool MATRIX_ROUTING_HEAD::ComputeMatrixSize( BOARD* aPcb, bool aUseBoardEdgesOnly )
{ {
aPcb->ComputeBoundingBox( aUseBoardEdgesOnly ); aPcb->ComputeBoundingBox( aUseBoardEdgesOnly );
@ -80,22 +97,6 @@ bool MATRIX_ROUTING_HEAD::ComputeMatrixSize( BOARD* aPcb, bool aUseBoardEdgesOnl
} }
MATRIX_ROUTING_HEAD::MATRIX_ROUTING_HEAD()
{
m_BoardSide[0] = m_BoardSide[1] = NULL;
m_DistSide[0] = m_DistSide[1] = NULL;
m_DirSide[0] = m_DirSide[1] = NULL;
m_InitMatrixDone = false;
m_Layers = MAX_SIDES_COUNT;
m_Nrows = m_Ncols = 0;
m_MemSize = 0;
}
MATRIX_ROUTING_HEAD::~MATRIX_ROUTING_HEAD()
{
}
int MATRIX_ROUTING_HEAD::InitRoutingMatrix() int MATRIX_ROUTING_HEAD::InitRoutingMatrix()
{ {
@ -109,7 +110,7 @@ int MATRIX_ROUTING_HEAD::InitRoutingMatrix()
// give a small margin for memory allocation: // give a small margin for memory allocation:
ii = (RoutingMatrix.m_Nrows + 1) * (RoutingMatrix.m_Ncols + 1); ii = (RoutingMatrix.m_Nrows + 1) * (RoutingMatrix.m_Ncols + 1);
for( kk = 0; kk < m_Layers; kk++ ) for( kk = 0; kk < m_RoutingLayersCount; kk++ )
{ {
m_BoardSide[kk] = NULL; m_BoardSide[kk] = NULL;
m_DistSide[kk] = NULL; m_DistSide[kk] = NULL;
@ -137,7 +138,7 @@ int MATRIX_ROUTING_HEAD::InitRoutingMatrix()
return -1; return -1;
} }
m_MemSize = m_Layers * ii * ( sizeof(MATRIX_CELL) + sizeof(DIST_CELL) + sizeof(char) ); m_MemSize = m_RouteCount * ii * ( sizeof(MATRIX_CELL) + sizeof(DIST_CELL) + sizeof(char) );
return m_MemSize; return m_MemSize;
} }
@ -149,7 +150,7 @@ void MATRIX_ROUTING_HEAD::UnInitRoutingMatrix()
m_InitMatrixDone = false; m_InitMatrixDone = false;
for( ii = 0; ii < MAX_SIDES_COUNT; ii++ ) for( ii = 0; ii < MAX_ROUTING_LAYERS_COUNT; ii++ )
{ {
// de-allocate Dir matrix // de-allocate Dir matrix
if( m_DirSide[ii] ) if( m_DirSide[ii] )
@ -179,14 +180,17 @@ void MATRIX_ROUTING_HEAD::UnInitRoutingMatrix()
/** /**
* Function PlaceCells * Function PlaceCells
* initializes the cell board is set and VIA_IMPOSSIBLE HOLE according to the setbacks. * Initialize the matrix routing by setting obstacles for each occupied cell
* The elements of net_code = net_code will not be occupied as places but only * a cell set to HOLE is an obstacle for tracks and vias
* VIA_IMPOSSIBLE * a cell set to VIA_IMPOSSIBLE is an obstacle for vias only.
* For single-sided Routing 1: * a cell set to CELL_is_EDGE is a frontier.
* BOTTOM side is used and Route_Layer_BOTTOM = Route_Layer_TOP * Tracks and vias having the same net code as net_code are skipped
* (htey do not are obstacles)
* *
* According to the bits = 1 parameter flag: * For single-sided Routing 1:
* If FORCE_PADS: all pads will be placed even those same net_code. * BOTTOM side is used, and Route_Layer_BOTTOM = Route_Layer_TOP
*
* If flag == FORCE_PADS: all pads will be put in matrix as obstacles.
*/ */
void PlaceCells( BOARD* aPcb, int net_code, int flag ) void PlaceCells( BOARD* aPcb, int net_code, int flag )
{ {
@ -347,8 +351,6 @@ int Build_Work( BOARD* Pcb )
int demi_pas = RoutingMatrix.m_GridRouting / 2; int demi_pas = RoutingMatrix.m_GridRouting / 2;
wxString msg; wxString msg;
EDA_RECT bbbox = Pcb->GetBoundingBox();
InitWork(); /* clear work list */ InitWork(); /* clear work list */
int cellCount = 0; int cellCount = 0;
@ -356,7 +358,7 @@ int Build_Work( BOARD* Pcb )
{ {
pt_rats = &Pcb->m_FullRatsnest[ii]; pt_rats = &Pcb->m_FullRatsnest[ii];
/* We consider her only ratsnest that are active ( obviously not yet routed) /* We consider here only ratsnest that are active ( obviously not yet routed)
* and routables (that are not yet attempt to be routed and fail * and routables (that are not yet attempt to be routed and fail
*/ */
if( (pt_rats->m_Status & CH_ACTIF) == 0 ) if( (pt_rats->m_Status & CH_ACTIF) == 0 )
@ -373,45 +375,47 @@ int Build_Work( BOARD* Pcb )
current_net_code = pt_pad->GetNet(); current_net_code = pt_pad->GetNet();
pt_ch = pt_rats; pt_ch = pt_rats;
r1 = ( pt_pad->GetPosition().y - bbbox.GetY() + demi_pas ) / RoutingMatrix.m_GridRouting; r1 = ( pt_pad->GetPosition().y - RoutingMatrix.m_BrdBox.GetY() + demi_pas )
/ RoutingMatrix.m_GridRouting;
if( r1 < 0 || r1 >= RoutingMatrix.m_Nrows ) if( r1 < 0 || r1 >= RoutingMatrix.m_Nrows )
{ {
msg.Printf( wxT( "error : row = %d ( padY %d pcbY %d) " ), r1, msg.Printf( wxT( "error : row = %d ( padY %d pcbY %d) " ), r1,
pt_pad->GetPosition().y, bbbox.GetY() ); pt_pad->GetPosition().y, RoutingMatrix.m_BrdBox.GetY() );
wxMessageBox( msg ); wxMessageBox( msg );
return 0; return 0;
} }
c1 = ( pt_pad->GetPosition().x - bbbox.GetX() + demi_pas ) / RoutingMatrix.m_GridRouting; c1 = ( pt_pad->GetPosition().x - RoutingMatrix.m_BrdBox.GetX() + demi_pas ) / RoutingMatrix.m_GridRouting;
if( c1 < 0 || c1 >= RoutingMatrix.m_Ncols ) if( c1 < 0 || c1 >= RoutingMatrix.m_Ncols )
{ {
msg.Printf( wxT( "error : col = %d ( padX %d pcbX %d) " ), c1, msg.Printf( wxT( "error : col = %d ( padX %d pcbX %d) " ), c1,
pt_pad->GetPosition().x, bbbox.GetX() ); pt_pad->GetPosition().x, RoutingMatrix.m_BrdBox.GetX() );
wxMessageBox( msg ); wxMessageBox( msg );
return 0; return 0;
} }
pt_pad = pt_rats->m_PadEnd; pt_pad = pt_rats->m_PadEnd;
r2 = ( pt_pad->GetPosition().y - bbbox.GetY() r2 = ( pt_pad->GetPosition().y - RoutingMatrix.m_BrdBox.GetY()
+ demi_pas ) / RoutingMatrix.m_GridRouting; + demi_pas ) / RoutingMatrix.m_GridRouting;
if( r2 < 0 || r2 >= RoutingMatrix.m_Nrows ) if( r2 < 0 || r2 >= RoutingMatrix.m_Nrows )
{ {
msg.Printf( wxT( "error : row = %d ( padY %d pcbY %d) " ), r2, msg.Printf( wxT( "error : row = %d ( padY %d pcbY %d) " ), r2,
pt_pad->GetPosition().y, bbbox.GetY() ); pt_pad->GetPosition().y, RoutingMatrix.m_BrdBox.GetY() );
wxMessageBox( msg ); wxMessageBox( msg );
return 0; return 0;
} }
c2 = ( pt_pad->GetPosition().x - bbbox.GetX() + demi_pas ) / RoutingMatrix.m_GridRouting; c2 = ( pt_pad->GetPosition().x - RoutingMatrix.m_BrdBox.GetX() + demi_pas )
/ RoutingMatrix.m_GridRouting;
if( c2 < 0 || c2 >= RoutingMatrix.m_Ncols ) if( c2 < 0 || c2 >= RoutingMatrix.m_Ncols )
{ {
msg.Printf( wxT( "error : col = %d ( padX %d pcbX %d) " ), c2, msg.Printf( wxT( "error : col = %d ( padX %d pcbX %d) " ), c2,
pt_pad->GetPosition().x, bbbox.GetX() ); pt_pad->GetPosition().x, RoutingMatrix.m_BrdBox.GetX() );
wxMessageBox( msg ); wxMessageBox( msg );
return 0; return 0;
} }
@ -424,7 +428,7 @@ int Build_Work( BOARD* Pcb )
return cellCount; return cellCount;
} }
// Initialize WriteCell to make the aLogicOp // Initialize m_opWriteCell member to make the aLogicOp
void MATRIX_ROUTING_HEAD::SetCellOperation( int aLogicOp ) void MATRIX_ROUTING_HEAD::SetCellOperation( int aLogicOp )
{ {
switch( aLogicOp ) switch( aLogicOp )

View File

@ -86,6 +86,10 @@ static int s_Clearance; // Clearance value used in autorouter
static PICKED_ITEMS_LIST s_ItemsListPicker; static PICKED_ITEMS_LIST s_ItemsListPicker;
int OpenNodes; /* total number of nodes opened */
int ClosNodes; /* total number of nodes closed */
int MoveNodes; /* total number of nodes moved */
int MaxNodes; /* maximum number of nodes opened at one time */
#define NOSUCCESS 0 #define NOSUCCESS 0
#define STOP_FROM_ESC -1 #define STOP_FROM_ESC -1
@ -263,7 +267,7 @@ static long newmask[8] =
* -1 if escape (stop being routed) request * -1 if escape (stop being routed) request
* -2 if default memory allocation * -2 if default memory allocation
*/ */
int PCB_EDIT_FRAME::Solve( wxDC* DC, int two_sides ) int PCB_EDIT_FRAME::Solve( wxDC* DC, int aLayersCount )
{ {
int current_net_code; int current_net_code;
int row_source, col_source, row_target, col_target; int row_source, col_source, row_target, col_target;
@ -272,6 +276,7 @@ int PCB_EDIT_FRAME::Solve( wxDC* DC, int two_sides )
bool stop = false; bool stop = false;
wxString msg; wxString msg;
int routedCount = 0; // routed ratsnest count int routedCount = 0; // routed ratsnest count
bool two_sides = aLayersCount == 2;
m_canvas->SetAbortRequest( false ); m_canvas->SetAbortRequest( false );
@ -522,7 +527,7 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe,
} }
InitQueue(); /* initialize the search queue */ InitQueue(); /* initialize the search queue */
apx_dist = GetApxDist( row_source, col_source, row_target, col_target ); apx_dist = RoutingMatrix.GetApxDist( row_source, col_source, row_target, col_target );
/* Initialize first search. */ /* Initialize first search. */
if( two_sides ) /* Preferred orientation. */ if( two_sides ) /* Preferred orientation. */
@ -713,7 +718,7 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe,
} }
olddir = RoutingMatrix.GetDir( r, c, side ); olddir = RoutingMatrix.GetDir( r, c, side );
newdist = d + CalcDist( ndir[i], olddir, newdist = d + RoutingMatrix.CalcDist( ndir[i], olddir,
( olddir == FROM_OTHERSIDE ) ? ( olddir == FROM_OTHERSIDE ) ?
RoutingMatrix.GetDir( r, c, 1 - side ) : 0, side ); RoutingMatrix.GetDir( r, c, 1 - side ) : 0, side );
@ -725,7 +730,7 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe,
RoutingMatrix.SetDist( nr, nc, side, newdist ); RoutingMatrix.SetDist( nr, nc, side, newdist );
if( SetQueue( nr, nc, side, newdist, if( SetQueue( nr, nc, side, newdist,
GetApxDist( nr, nc, row_target, col_target ), RoutingMatrix.GetApxDist( nr, nc, row_target, col_target ),
row_target, col_target ) == 0 ) row_target, col_target ) == 0 )
{ {
return ERR_MEMORY; return ERR_MEMORY;
@ -736,7 +741,7 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe,
RoutingMatrix.SetDir( nr, nc, side, ndir[i] ); RoutingMatrix.SetDir( nr, nc, side, ndir[i] );
RoutingMatrix.SetDist( nr, nc, side, newdist ); RoutingMatrix.SetDist( nr, nc, side, newdist );
ReSetQueue( nr, nc, side, newdist, ReSetQueue( nr, nc, side, newdist,
GetApxDist( nr, nc, row_target, col_target ), RoutingMatrix.GetApxDist( nr, nc, row_target, col_target ),
row_target, col_target ); row_target, col_target );
} }
} }
@ -781,7 +786,7 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe,
if( skip ) /* neighboring hole or trace? */ if( skip ) /* neighboring hole or trace? */
continue; /* yes, can't drill via here */ continue; /* yes, can't drill via here */
newdist = d + CalcDist( FROM_OTHERSIDE, olddir, 0, side ); newdist = d + RoutingMatrix.CalcDist( FROM_OTHERSIDE, olddir, 0, side );
/* if (a) not visited yet, /* if (a) not visited yet,
* or (b) we have found a better path, * or (b) we have found a better path,

View File

@ -41,9 +41,9 @@
#include <cell.h> #include <cell.h>
struct CWORK // a unit of work is a source-target (a ratsnet item) to connect struct CWORK // a unit of work is a source-target to connect
// this is a ratsnest item in the routing matrix world
{ {
struct CWORK* m_Next;
int m_FromRow; // source row int m_FromRow; // source row
int m_FromCol; // source column int m_FromCol; // source column
int m_ToRow; // target row int m_ToRow; // target row
@ -53,34 +53,22 @@ struct CWORK // a unit of work is a source-target (a ratsnet item) to connect
int m_ApxDist; // approximate distance int m_ApxDist; // approximate distance
int m_Cost; // cost for sort by length int m_Cost; // cost for sort by length
int m_Priority; // route priority int m_Priority; // route priority
// the function that calculates the cost of this ratsnest:
void CalculateCost();
}; };
// pointers to the first and last item of work to do // the list of ratsnests
static CWORK* Head = NULL; static std::vector <CWORK> WorkList;
static CWORK* Tail = NULL; static unsigned Current = 0;
static CWORK* Current = NULL;
// initialize the work list // initialize the work list
void InitWork() void InitWork()
{ {
CWORK* ptr; WorkList.clear();
Current = 0;
while( ( ptr = Head ) != NULL )
{
Head = ptr->m_Next;
delete ptr;
}
Tail = Current = NULL;
}
// initialize the work list
void ReInitWork()
{
Current = Head;
} }
@ -89,40 +77,24 @@ void ReInitWork()
* 1 if OK * 1 if OK
* 0 if memory allocation failed * 0 if memory allocation failed
*/ */
static int GetCost( int r1, int c1, int r2, int c2 );
int SetWork( int r1, int c1, int SetWork( int r1, int c1,
int n_c, int n_c,
int r2, int c2, int r2, int c2,
RATSNEST_ITEM* pt_ch, int pri ) RATSNEST_ITEM* pt_ch, int pri )
{ {
CWORK* p; CWORK item;
item.m_FromRow = r1;
if( ( p = (CWORK*) operator new( sizeof(CWORK), std::nothrow ) ) != NULL ) item.m_FromCol = c1;
{ item.m_NetCode = n_c;
p->m_FromRow = r1; item.m_ToRow = r2;
p->m_FromCol = c1; item.m_ToCol = c2;
p->m_NetCode = n_c; item.m_Ratsnest = pt_ch;
p->m_ToRow = r2; item.m_ApxDist = RoutingMatrix.GetApxDist( r1, c1, r2, c2 );
p->m_ToCol = c2; item.CalculateCost();
p->m_Ratsnest = pt_ch; item.m_Priority = pri;
p->m_ApxDist = GetApxDist( r1, c1, r2, c2 ); WorkList.push_back( item );
p->m_Cost = GetCost( r1, c1, r2, c2 ); return 1;
p->m_Priority = pri;
p->m_Next = NULL;
if( Head ) /* attach at end */
Tail->m_Next = p;
else /* first in list */
Head = Current = p;
Tail = p;
return 1;
}
else /* can't get any more memory */
{
return 0;
}
} }
@ -132,15 +104,15 @@ void GetWork( int* r1, int* c1,
int* r2, int* c2, int* r2, int* c2,
RATSNEST_ITEM** pt_ch ) RATSNEST_ITEM** pt_ch )
{ {
if( Current ) if( Current < WorkList.size() )
{ {
*r1 = Current->m_FromRow; *r1 = WorkList[Current].m_FromRow;
*c1 = Current->m_FromCol; *c1 = WorkList[Current].m_FromCol;
*n_c = Current->m_NetCode; *n_c = WorkList[Current].m_NetCode;
*r2 = Current->m_ToRow; *r2 = WorkList[Current].m_ToRow;
*c2 = Current->m_ToCol; *c2 = WorkList[Current].m_ToCol;
*pt_ch = Current->m_Ratsnest; *pt_ch = WorkList[Current].m_Ratsnest;
Current = Current->m_Next; Current++;
} }
else /* none left */ else /* none left */
{ {
@ -151,64 +123,18 @@ void GetWork( int* r1, int* c1,
} }
/* order the work items; shortest (low cost) first */ // order the work items; shortest (low cost) first:
bool sort_by_cost( const CWORK& ref, const CWORK& item )
{
if( ref.m_Priority == item.m_Priority )
return ref.m_Cost < item.m_Cost;
return ref.m_Priority >= item.m_Priority;
}
void SortWork() void SortWork()
{ {
CWORK* p; sort( WorkList.begin(), WorkList.end(), sort_by_cost );
CWORK* q0; /* put PRIORITY PAD_CONNECTs in q0 */
CWORK* q1; /* sort other PAD_CONNECTs in q1 */
CWORK* r;
q0 = q1 = NULL;
while( (p = Head) != NULL ) /* prioritize each work item */
{
Head = Head->m_Next;
if( p->m_Priority ) /* put at end of priority list */
{
p->m_Next = NULL;
if( (r = q0) == NULL ) /* empty list? */
{
q0 = p;
}
else /* attach at end */
{
while( r->m_Next ) /* search for end */
r = r->m_Next;
r->m_Next = p; /* attach */
}
}
else if( ( ( r = q1 ) == NULL ) || ( p->m_Cost < q1->m_Cost ) )
{
p->m_Next = q1;
q1 = p;
}
else /* find proper position in list */
{
while( r->m_Next && p->m_Cost >= r->m_Next->m_Cost )
r = r->m_Next;
p->m_Next = r->m_Next;
r->m_Next = p;
}
}
if( (p = q0) != NULL ) /* any priority PAD_CONNECTs? */
{
while( q0->m_Next )
q0 = q0->m_Next;
q0->m_Next = q1;
}
else
p = q1;
/* reposition Head and Tail */
for( Head = Current = Tail = p; Tail && Tail->m_Next; Tail = Tail->m_Next )
;
} }
@ -216,13 +142,13 @@ void SortWork()
* cost = (| dx | + | dy |) * disability * cost = (| dx | + | dy |) * disability
* disability = 1 if dx or dy = 0, max if | dx | # | dy | * disability = 1 if dx or dy = 0, max if | dx | # | dy |
*/ */
static int GetCost( int r1, int c1, int r2, int c2 ) void CWORK::CalculateCost()
{ {
int dx, dy, mx, my; int dx, dy, mx, my;
double incl = 1.0; double incl = 1.0;
dx = abs( c2 - c1 ); dx = abs( m_ToCol - m_FromCol );
dy = abs( r2 - r1 ); dy = abs( m_ToRow - m_FromRow );
mx = dx; mx = dx;
my = dy; my = dy;
@ -234,5 +160,5 @@ static int GetCost( int r1, int c1, int r2, int c2 )
if( mx ) if( mx )
incl += (2 * (double) my / mx); incl += (2 * (double) my / mx);
return (int) ( ( dx + dy ) * incl ); m_Cost = (int) ( ( dx + dy ) * incl );
} }

View File

@ -1204,7 +1204,9 @@ BOARD* PCB_IO::Load( const wxString& aFileName, BOARD* aAppendToMe, PROPERTIES*
if( !file.IsOpened() ) if( !file.IsOpened() )
{ {
THROW_IO_ERROR( _( "Unable to read file \"" ) + aFileName + wxT( "\"" ) ); wxString msg;
msg.Printf( _( "Unable to read file \"%s\"" ), GetChars( aFileName ) );
THROW_IO_ERROR( msg );
} }
PCB_PARSER parser( new FILE_LINE_READER( file.fp(), aFileName ), aAppendToMe ); PCB_PARSER parser( new FILE_LINE_READER( file.fp(), aFileName ), aAppendToMe );

View File

@ -319,7 +319,7 @@ BOARD_ITEM* PCB_PARSER::Parse() throw( IO_ERROR, PARSE_ERROR )
default: default:
wxString err; wxString err;
err.Printf( _( "unknown token \"%s\" " ), GetChars( FromUTF8() ) ); err.Printf( _( "unknown token \"%s\"" ), GetChars( FromUTF8() ) );
THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() ); THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
} }