Commit 20f0a5f8 authored by jean-pierre charras's avatar jean-pierre charras

Pcbnew: save/load .kicad_pcb files: fix 2 minor issues.

Use now English layers names to build filenames in plot functions (for techical layers), because translated names create sometimes problems in filenames.
(should do not change anything for English users)
Fix compil issue under wxGTK 2.8.12, created by my recent commit.
Minor changes to make translations easier.
parents 1b08d187 91b0191a
......@@ -440,7 +440,7 @@ int PCB_EDIT_FRAME::GenPlaceBoard()
m_messagePanel->SetMessage( 14, _( "Cells." ), msg, YELLOW );
/* Choose the number of board sides. */
Nb_Sides = TWO_SIDES;
RoutingMatrix.m_RoutingLayersCount = 2;
RoutingMatrix.InitRoutingMatrix();
......@@ -450,7 +450,7 @@ int PCB_EDIT_FRAME::GenPlaceBoard()
Route_Layer_BOTTOM = LAYER_N_FRONT;
if( Nb_Sides == TWO_SIDES )
if( RoutingMatrix.m_RoutingLayersCount > 1 )
Route_Layer_BOTTOM = LAYER_N_BACK;
Route_Layer_TOP = LAYER_N_FRONT;
......@@ -618,7 +618,7 @@ int PCB_EDIT_FRAME::GetOptimalModulePlacement( MODULE* aModule, wxDC* aDC )
*/
TstOtherSide = false;
if( Nb_Sides == TWO_SIDES )
if( RoutingMatrix.m_RoutingLayersCount > 1 )
{
D_PAD* Pad;
int otherLayerMask = LAYER_BACK;
......@@ -967,7 +967,7 @@ void CreateKeepOutRectangle( int ux0, int uy0, int ux1, int uy1,
if( aLayerMask & GetLayerMask( Route_Layer_BOTTOM ) )
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. */
if( trace == 0 )
......
......@@ -47,12 +47,6 @@
#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
/* init board, route traces*/
......@@ -175,10 +169,10 @@ void PCB_EDIT_FRAME::Autoroute( wxDC* DC, int mode )
m_messagePanel->EraseMsgBox();
/* Map the board */
Nb_Sides = ONE_SIDE;
RoutingMatrix.m_RoutingLayersCount = 1;
if( Route_Layer_TOP != Route_Layer_BOTTOM )
Nb_Sides = TWO_SIDES;
RoutingMatrix.m_RoutingLayersCount = 2;
if( RoutingMatrix.InitRoutingMatrix() < 0 )
{
......@@ -195,10 +189,7 @@ void PCB_EDIT_FRAME::Autoroute( wxDC* DC, int mode )
// DisplayRoutingMatrix( m_canvas, DC );
if( Nb_Sides == TWO_SIDES )
Solve( DC, TWO_SIDES ); /* double face */
else
Solve( DC, ONE_SIDE ); /* simple face */
Solve( DC, RoutingMatrix.m_RoutingLayersCount );
/* Free memory. */
FreeQueue();
......@@ -249,7 +240,7 @@ void DisplayRoutingMatrix( EDA_DRAW_PANEL* panel, wxDC* DC )
if( dcell0 & HOLE )
color = GREEN;
// if( Nb_Sides )
// if( RoutingMatrix.m_RoutingLayersCount )
// dcell1 = GetCell( row, col, TOP );
if( dcell1 & HOLE )
......
......@@ -46,7 +46,8 @@ class BOARD;
/* Autorouter commands. */
enum CommandOpt {
enum AUTOPLACEROUTE_OPTIONS
{
PLACE_ALL,
PLACE_OUT_OF_BOARD,
PLACE_INCREMENTAL,
......@@ -58,13 +59,7 @@ enum CommandOpt {
ROUTE_PAD
};
#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 MAX_ROUTING_LAYERS_COUNT 2
#define FORCE_PADS 1 /* Force placement of pads for any Netcode */
......@@ -88,20 +83,23 @@ typedef char DIR_CELL;
class MATRIX_ROUTING_HEAD
{
public:
MATRIX_CELL* m_BoardSide[MAX_SIDES_COUNT]; // the image map of 2 board sides
DIST_CELL* m_DistSide[MAX_SIDES_COUNT]; // the image map of 2 board sides: distance to
// cells
DIR_CELL* m_DirSide[MAX_SIDES_COUNT]; // the image map of 2 board sides: pointers back to
// source
MATRIX_CELL* m_BoardSide[MAX_ROUTING_LAYERS_COUNT]; // the image map of 2 board sides
DIST_CELL* m_DistSide[MAX_ROUTING_LAYERS_COUNT]; // the image map of 2 board sides:
// distance to cells
DIR_CELL* m_DirSide[MAX_ROUTING_LAYERS_COUNT]; // the image map of 2 board sides:
// pointers back to source
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
EDA_RECT m_BrdBox; // Actual board bounding box
int m_Nrows, m_Ncols; // Matrix size
int m_MemSize; // Memory requirement, just for statistics
int m_RouteCount; // Number of routes
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:
MATRIX_ROUTING_HEAD();
......@@ -114,7 +112,7 @@ public:
/**
* function GetBrdCoordOrigin
* @returns the board coordinate corresponding to the
* @return the board coordinate corresponding to the
* routing matrix origin ( board coordinate offset )
*/
wxPoint GetBrdCoordOrigin()
......@@ -156,6 +154,12 @@ public:
void SetDist( int aRow, int aCol, int aSide, DIST_CELL );
int GetDir( int aRow, int aCol, int aSide );
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 */
......@@ -220,10 +224,6 @@ int SetWork( int, int, int , int, int, RATSNEST_ITEM *, int );
void GetWork( int *, int *, int *, int *, int *, RATSNEST_ITEM ** );
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 */
int Build_Work( BOARD * Pcb );
void PlaceCells( BOARD * Pcb, int net_code, int flag = 0 );
......
......@@ -39,7 +39,7 @@
/* 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 */
......@@ -135,7 +135,7 @@ static int dir_penalty_BOTTOM[10][10] =
/* 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;
......@@ -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;
if( Nb_Sides )
if( m_RouteCount > 1 )
{
if( side == BOTTOM )
ldist += dir_penalty_TOP[x-1][y-1];
......
......@@ -71,14 +71,14 @@ static void TraceCircle( int ux0, int uy0, int ux1, int uy1, int lg, int layer,
if( layer < 0 ) \
{ \
RoutingMatrix.WriteCell( dy, dx, BOTTOM, color ); \
if( Nb_Sides ) \
if( RoutingMatrix.m_RoutingLayersCount > 1 ) \
RoutingMatrix.WriteCell( dy, dx, TOP, color ); \
} \
else \
{ \
if( layer == Route_Layer_BOTTOM ) \
RoutingMatrix.WriteCell( dy, dx, BOTTOM, color ); \
if( Nb_Sides ) \
if( RoutingMatrix.m_RoutingLayersCount > 1 ) \
if( layer == Route_Layer_TOP ) \
RoutingMatrix.WriteCell( dy, dx, TOP, color ); \
} \
......@@ -156,7 +156,7 @@ void TraceFilledCircle( int cx, int cy, int radius,
trace = 1; // Trace on BOTTOM
if( aLayerMask & GetLayerMask( Route_Layer_TOP ) )
if( Nb_Sides )
if( RoutingMatrix.m_RoutingLayersCount > 1 )
trace |= 2; // Trace on TOP
if( trace == 0 )
......@@ -475,7 +475,7 @@ void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1,
if( ( aLayerMask & GetLayerMask( Route_Layer_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
if( trace == 0 )
......@@ -542,7 +542,7 @@ void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1,
if( aLayerMask & GetLayerMask( Route_Layer_TOP ) )
{
if( Nb_Sides )
if( RoutingMatrix.m_RoutingLayersCount > 1 )
trace |= 2; // Trace on TOP
}
......
......@@ -46,6 +46,23 @@
#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 )
{
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()
{
......@@ -109,7 +110,7 @@ int MATRIX_ROUTING_HEAD::InitRoutingMatrix()
// give a small margin for memory allocation:
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_DistSide[kk] = NULL;
......@@ -137,7 +138,7 @@ int MATRIX_ROUTING_HEAD::InitRoutingMatrix()
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;
}
......@@ -149,7 +150,7 @@ void MATRIX_ROUTING_HEAD::UnInitRoutingMatrix()
m_InitMatrixDone = false;
for( ii = 0; ii < MAX_SIDES_COUNT; ii++ )
for( ii = 0; ii < MAX_ROUTING_LAYERS_COUNT; ii++ )
{
// de-allocate Dir matrix
if( m_DirSide[ii] )
......@@ -179,14 +180,17 @@ void MATRIX_ROUTING_HEAD::UnInitRoutingMatrix()
/**
* Function PlaceCells
* initializes the cell board is set and VIA_IMPOSSIBLE HOLE according to the setbacks.
* The elements of net_code = net_code will not be occupied as places but only
* VIA_IMPOSSIBLE
* Initialize the matrix routing by setting obstacles for each occupied cell
* a cell set to HOLE is an obstacle for tracks and vias
* a cell set to VIA_IMPOSSIBLE is an obstacle for vias only.
* a cell set to CELL_is_EDGE is a frontier.
* Tracks and vias having the same net code as net_code are skipped
* (htey do not are obstacles)
*
* For single-sided Routing 1:
* BOTTOM side is used and Route_Layer_BOTTOM = Route_Layer_TOP
* BOTTOM side is used, and Route_Layer_BOTTOM = Route_Layer_TOP
*
* According to the bits = 1 parameter flag:
* If FORCE_PADS: all pads will be placed even those same net_code.
* If flag == FORCE_PADS: all pads will be put in matrix as obstacles.
*/
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;
wxString msg;
EDA_RECT bbbox = Pcb->GetBoundingBox();
InitWork(); /* clear work list */
int cellCount = 0;
......@@ -356,7 +358,7 @@ int Build_Work( BOARD* Pcb )
{
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
*/
if( (pt_rats->m_Status & CH_ACTIF) == 0 )
......@@ -373,45 +375,47 @@ int Build_Work( BOARD* Pcb )
current_net_code = pt_pad->GetNet();
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 )
{
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 );
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 )
{
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 );
return 0;
}
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;
if( r2 < 0 || r2 >= RoutingMatrix.m_Nrows )
{
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 );
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 )
{
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 );
return 0;
}
......@@ -424,7 +428,7 @@ int Build_Work( BOARD* Pcb )
return cellCount;
}
// Initialize WriteCell to make the aLogicOp
// Initialize m_opWriteCell member to make the aLogicOp
void MATRIX_ROUTING_HEAD::SetCellOperation( int aLogicOp )
{
switch( aLogicOp )
......
......@@ -86,6 +86,10 @@ static int s_Clearance; // Clearance value used in autorouter
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 STOP_FROM_ESC -1
......@@ -263,7 +267,7 @@ static long newmask[8] =
* -1 if escape (stop being routed) request
* -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 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;
wxString msg;
int routedCount = 0; // routed ratsnest count
bool two_sides = aLayersCount == 2;
m_canvas->SetAbortRequest( false );
......@@ -522,7 +527,7 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe,
}
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. */
if( two_sides ) /* Preferred orientation. */
......@@ -713,7 +718,7 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe,
}
olddir = RoutingMatrix.GetDir( r, c, side );
newdist = d + CalcDist( ndir[i], olddir,
newdist = d + RoutingMatrix.CalcDist( ndir[i], olddir,
( olddir == FROM_OTHERSIDE ) ?
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 );
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 )
{
return ERR_MEMORY;
......@@ -736,7 +741,7 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe,
RoutingMatrix.SetDir( nr, nc, side, ndir[i] );
RoutingMatrix.SetDist( 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 );
}
}
......@@ -781,7 +786,7 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe,
if( skip ) /* neighboring hole or trace? */
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,
* or (b) we have found a better path,
......
......@@ -41,9 +41,9 @@
#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_FromCol; // source column
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_Cost; // cost for sort by length
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
static CWORK* Head = NULL;
static CWORK* Tail = NULL;
static CWORK* Current = NULL;
// the list of ratsnests
static std::vector <CWORK> WorkList;
static unsigned Current = 0;
// initialize the work list
void InitWork()
{
CWORK* ptr;
while( ( ptr = Head ) != NULL )
{
Head = ptr->m_Next;
delete ptr;
}
Tail = Current = NULL;
}
// initialize the work list
void ReInitWork()
{
Current = Head;
WorkList.clear();
Current = 0;
}
......@@ -89,40 +77,24 @@ void ReInitWork()
* 1 if OK
* 0 if memory allocation failed
*/
static int GetCost( int r1, int c1, int r2, int c2 );
int SetWork( int r1, int c1,
int n_c,
int r2, int c2,
RATSNEST_ITEM* pt_ch, int pri )
{
CWORK* p;
if( ( p = (CWORK*) operator new( sizeof(CWORK), std::nothrow ) ) != NULL )
{
p->m_FromRow = r1;
p->m_FromCol = c1;
p->m_NetCode = n_c;
p->m_ToRow = r2;
p->m_ToCol = c2;
p->m_Ratsnest = pt_ch;
p->m_ApxDist = GetApxDist( r1, c1, r2, c2 );
p->m_Cost = GetCost( r1, c1, r2, c2 );
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;
CWORK item;
item.m_FromRow = r1;
item.m_FromCol = c1;
item.m_NetCode = n_c;
item.m_ToRow = r2;
item.m_ToCol = c2;
item.m_Ratsnest = pt_ch;
item.m_ApxDist = RoutingMatrix.GetApxDist( r1, c1, r2, c2 );
item.CalculateCost();
item.m_Priority = pri;
WorkList.push_back( item );
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,
RATSNEST_ITEM** pt_ch )
{
if( Current )
if( Current < WorkList.size() )
{
*r1 = Current->m_FromRow;
*c1 = Current->m_FromCol;
*n_c = Current->m_NetCode;
*r2 = Current->m_ToRow;
*c2 = Current->m_ToCol;
*pt_ch = Current->m_Ratsnest;
Current = Current->m_Next;
*r1 = WorkList[Current].m_FromRow;
*c1 = WorkList[Current].m_FromCol;
*n_c = WorkList[Current].m_NetCode;
*r2 = WorkList[Current].m_ToRow;
*c2 = WorkList[Current].m_ToCol;
*pt_ch = WorkList[Current].m_Ratsnest;
Current++;
}
else /* none left */
{
......@@ -151,64 +123,18 @@ void GetWork( int* r1, int* c1,
}
/* order the work items; shortest (low cost) first */
void SortWork()
// order the work items; shortest (low cost) first:
bool sort_by_cost( const CWORK& ref, const CWORK& item )
{
CWORK* p;
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;
if( ref.m_Priority == item.m_Priority )
return ref.m_Cost < item.m_Cost;
q0->m_Next = q1;
}
else
p = q1;
return ref.m_Priority >= item.m_Priority;
}
/* reposition Head and Tail */
for( Head = Current = Tail = p; Tail && Tail->m_Next; Tail = Tail->m_Next )
;
void SortWork()
{
sort( WorkList.begin(), WorkList.end(), sort_by_cost );
}
......@@ -216,13 +142,13 @@ void SortWork()
* cost = (| dx | + | dy |) * disability
* 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;
double incl = 1.0;
dx = abs( c2 - c1 );
dy = abs( r2 - r1 );
dx = abs( m_ToCol - m_FromCol );
dy = abs( m_ToRow - m_FromRow );
mx = dx;
my = dy;
......@@ -234,5 +160,5 @@ static int GetCost( int r1, int c1, int r2, int c2 )
if( mx )
incl += (2 * (double) my / mx);
return (int) ( ( dx + dy ) * incl );
m_Cost = (int) ( ( dx + dy ) * incl );
}
......@@ -76,7 +76,7 @@ BOARD::BOARD() :
for( int layer = 0; layer < LAYER_COUNT; ++layer )
{
m_Layer[layer].m_Name = GetDefaultLayerName( layer );
m_Layer[layer].m_Name = GetDefaultLayerName( layer, true );
if( layer <= LAST_COPPER_LAYER )
m_Layer[layer].m_Type = LT_SIGNAL;
......@@ -355,7 +355,7 @@ bool BOARD::SetLayer( int aIndex, const LAYER& aLayer )
}
wxString BOARD::GetLayerName( int aLayerIndex ) const
wxString BOARD::GetLayerName( int aLayerIndex, bool aTranslate ) const
{
if( !IsValidLayerIndex( aLayerIndex ) )
return wxEmptyString;
......@@ -365,14 +365,51 @@ wxString BOARD::GetLayerName( int aLayerIndex ) const
{
// default names were set in BOARD::BOARD() but they may be
// over-ridden by BOARD::SetLayerName()
// For non translated name, return the actual copper layer names,
// otherwise, return the native layer names
if( aTranslate || aLayerIndex < FIRST_NO_COPPER_LAYER )
return m_Layer[aLayerIndex].m_Name;
}
return GetDefaultLayerName( aLayerIndex );
}
wxString BOARD::GetDefaultLayerName( int aLayerNumber )
return GetDefaultLayerName( aLayerIndex, aTranslate );
}
// Default layer names are statically initialized,
// because we want the Enghish name and the translation
// The Enghish name is stored here, and to get the tranlation
// wxGetTranslation must be called explicitely
static const wxChar * layer_FRONT_name = _( "Front" );
static const wxChar * layer_INNER1_name = _( "Inner1" );
static const wxChar * layer_INNER2_name = _( "Inner2" );
static const wxChar * layer_INNER3_name = _( "Inner3" );
static const wxChar * layer_INNER4_name = _( "Inner4" );
static const wxChar * layer_INNER5_name = _( "Inner5" );
static const wxChar * layer_INNER6_name = _( "Inner6" );
static const wxChar * layer_INNER7_name = _( "Inner7" );
static const wxChar * layer_INNER8_name = _( "Inner8" );
static const wxChar * layer_INNER9_name = _( "Inner9" );
static const wxChar * layer_INNER10_name = _( "Inner10" );
static const wxChar * layer_INNER11_name = _( "Inner11" );
static const wxChar * layer_INNER12_name = _( "Inner12" );
static const wxChar * layer_INNER13_name = _( "Inner13" );
static const wxChar * layer_INNER14_name = _( "Inner14" );
static const wxChar * layer_BACK_name = _( "Back" );
static const wxChar * layer_ADHESIVE_BACK_name = _( "Adhes_Back" );
static const wxChar * layer_ADHESIVE_FRONT_name = _( "Adhes_Front" );
static const wxChar * layer_SOLDERPASTE_BACK_namet = _( "SoldP_Back" );
static const wxChar * layer_SOLDERPASTE_FRONT_name = _( "SoldP_Front" );
static const wxChar * layer_SILKSCREEN_BACK_name = _( "SilkS_Back" );
static const wxChar * layer_SILKSCREEN_FRONT_name = _( "SilkS_Front" );
static const wxChar * layer_SOLDERMASK_BACK_name = _( "Mask_Back" );
static const wxChar * layer_SOLDERMASK_FRONT_name = _( "Mask_Front" );
static const wxChar * layer_DRAW_name = _( "Drawings" );
static const wxChar * layer_COMMENT_name = _( "Comments" );
static const wxChar * layer_ECO1_name = _( "Eco1" );
static const wxChar * layer_ECO2_name = _( "Eco2" );
static const wxChar * layer_EDGE_name = _( "PCB_Edges" );
wxString BOARD::GetDefaultLayerName( int aLayerNumber, bool aTranslate )
{
const wxChar* txt;
......@@ -382,39 +419,49 @@ wxString BOARD::GetDefaultLayerName( int aLayerNumber )
// Use a switch to explicitly show the mapping more clearly
switch( aLayerNumber )
{
case LAYER_N_FRONT: txt = _( "Front" ); break;
case LAYER_N_2: txt = _( "Inner2" ); break;
case LAYER_N_3: txt = _( "Inner3" ); break;
case LAYER_N_4: txt = _( "Inner4" ); break;
case LAYER_N_5: txt = _( "Inner5" ); break;
case LAYER_N_6: txt = _( "Inner6" ); break;
case LAYER_N_7: txt = _( "Inner7" ); break;
case LAYER_N_8: txt = _( "Inner8" ); break;
case LAYER_N_9: txt = _( "Inner9" ); break;
case LAYER_N_10: txt = _( "Inner10" ); break;
case LAYER_N_11: txt = _( "Inner11" ); break;
case LAYER_N_12: txt = _( "Inner12" ); break;
case LAYER_N_13: txt = _( "Inner13" ); break;
case LAYER_N_14: txt = _( "Inner14" ); break;
case LAYER_N_15: txt = _( "Inner15" ); break;
case LAYER_N_BACK: txt = _( "Back" ); break;
case ADHESIVE_N_BACK: txt = _( "Adhes_Back" ); break;
case ADHESIVE_N_FRONT: txt = _( "Adhes_Front" ); break;
case SOLDERPASTE_N_BACK: txt = _( "SoldP_Back" ); break;
case SOLDERPASTE_N_FRONT: txt = _( "SoldP_Front" ); break;
case SILKSCREEN_N_BACK: txt = _( "SilkS_Back" ); break;
case SILKSCREEN_N_FRONT: txt = _( "SilkS_Front" ); break;
case SOLDERMASK_N_BACK: txt = _( "Mask_Back" ); break;
case SOLDERMASK_N_FRONT: txt = _( "Mask_Front" ); break;
case DRAW_N: txt = _( "Drawings" ); break;
case COMMENT_N: txt = _( "Comments" ); break;
case ECO1_N: txt = _( "Eco1" ); break;
case ECO2_N: txt = _( "Eco2" ); break;
case EDGE_N: txt = _( "PCB_Edges" ); break;
default: txt = _( "BAD INDEX" ); break;
}
return wxString( txt );
case LAYER_N_FRONT: txt = layer_FRONT_name; break;
case LAYER_N_2: txt = layer_INNER1_name; break;
case LAYER_N_3: txt = layer_INNER2_name; break;
case LAYER_N_4: txt = layer_INNER3_name; break;
case LAYER_N_5: txt = layer_INNER4_name; break;
case LAYER_N_6: txt = layer_INNER5_name; break;
case LAYER_N_7: txt = layer_INNER6_name; break;
case LAYER_N_8: txt = layer_INNER7_name; break;
case LAYER_N_9: txt = layer_INNER8_name; break;
case LAYER_N_10: txt = layer_INNER9_name; break;
case LAYER_N_11: txt = layer_INNER10_name; break;
case LAYER_N_12: txt = layer_INNER11_name; break;
case LAYER_N_13: txt = layer_INNER12_name; break;
case LAYER_N_14: txt = layer_INNER13_name; break;
case LAYER_N_15: txt = layer_INNER14_name; break;
case LAYER_N_BACK: txt = layer_BACK_name; break;
case ADHESIVE_N_BACK: txt =layer_ADHESIVE_BACK_name; break;
case ADHESIVE_N_FRONT: txt = layer_ADHESIVE_FRONT_name; break;
case SOLDERPASTE_N_BACK: txt = layer_SOLDERPASTE_BACK_namet; break;
case SOLDERPASTE_N_FRONT: txt = layer_SOLDERPASTE_FRONT_name; break;
case SILKSCREEN_N_BACK: txt = layer_SILKSCREEN_BACK_name; break;
case SILKSCREEN_N_FRONT: txt = layer_SILKSCREEN_FRONT_name; break;
case SOLDERMASK_N_BACK: txt = layer_SOLDERMASK_BACK_name; break;
case SOLDERMASK_N_FRONT: txt = layer_SOLDERMASK_FRONT_name; break;
case DRAW_N: txt = layer_DRAW_name; break;
case COMMENT_N: txt = layer_COMMENT_name; break;
case ECO1_N: txt = layer_ECO1_name; break;
case ECO2_N: txt = layer_ECO2_name; break;
case EDGE_N: txt = layer_EDGE_name; break;
default: txt = wxT( "BAD_INDEX" ); break;
}
wxString name;
if( aTranslate )
{
name = wxGetTranslation( txt );
name.Trim( true );
name.Trim( false );
}
else
name = txt;
return name;
}
......
......@@ -303,10 +303,12 @@ public:
* be different than the default if the user has renamed any copper layers.
*
* @param aLayerNumber is the layer number to fetch
* @param aTranslate = true to return the translated version
* = false to get the native version
* @return wxString - containing the layer name or "BAD INDEX" if aLayerNumber
* is not legal
*/
static wxString GetDefaultLayerName( int aLayerNumber );
static wxString GetDefaultLayerName( int aLayerNumber, bool aTranslate );
/**
* Function ReturnFlippedLayerNumber
......@@ -619,10 +621,13 @@ public:
* Function GetLayerName
* returns the name of the layer given by aLayerIndex.
*
* @param aLayerIndex A layer index, like LAYER_N_BACK, etc.
* @param aLayerIndex = A layer index, like LAYER_N_BACK, etc.
* @param aTranslate = true to return the translated version (default)
* = false to get the native English name
* (Useful to build filenames from layer names)
* @return wxString - the layer name.
*/
wxString GetLayerName( int aLayerIndex ) const;
wxString GetLayerName( int aLayerIndex, bool aTranslate = true ) const;
/**
* Function SetLayerName
......
......@@ -40,6 +40,8 @@
#include <class_zone_settings.h>
#include <class_board.h>
#include <dialog_copper_zones_base.h>
#include <wx/imaglist.h> // needed for wx/listctrl.h, in wxGTK 2.8.12
#include <wx/listctrl.h>
......
......@@ -192,7 +192,7 @@ void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const
#endif
if( !( aBoard->GetVisibleLayers() & mask ) )
m_out->Print( 0, "hide" );
m_out->Print( 0, " hide" );
m_out->Print( 0, ")\n" );
}
......@@ -218,7 +218,7 @@ void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const
#endif
if( !( aBoard->GetVisibleLayers() & mask ) )
m_out->Print( 0, "hide" );
m_out->Print( 0, " hide" );
m_out->Print( 0, ")\n" );
}
......@@ -1204,7 +1204,9 @@ BOARD* PCB_IO::Load( const wxString& aFileName, BOARD* aAppendToMe, PROPERTIES*
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 );
......
......@@ -319,7 +319,7 @@ BOARD_ITEM* PCB_PARSER::Parse() throw( IO_ERROR, PARSE_ERROR )
default:
wxString err;
err.Printf( _( "unknown token \"%s\" " ), GetChars( FromUTF8() ) );
err.Printf( _( "unknown token \"%s\"" ), GetChars( FromUTF8() ) );
THROW_PARSE_ERROR( err, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
}
......@@ -1528,13 +1528,13 @@ MODULE* PCB_PARSER::parseMODULE() throw( IO_ERROR, PARSE_ERROR )
break;
case T_descr:
NeedSYMBOL();
NeedSYMBOLorNUMBER(); // some symbols can be 0508, so a number is also a symbol here
module->SetDescription( FromUTF8() );
NeedRIGHT();
break;
case T_tags:
NeedSYMBOL();
NeedSYMBOLorNUMBER(); // some symbols can be 0508, so a number is also a symbol here
module->SetKeywords( FromUTF8() );
NeedRIGHT();
break;
......@@ -1788,6 +1788,7 @@ EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR )
pt.y = parseBoardUnits( "Y coordinate" );
segment->SetStart0( pt );
NeedRIGHT();
NeedLEFT();
token = NextTok();
if( token != T_end )
......
......@@ -111,7 +111,7 @@ private:
};
const int UNITS_MILS = 1000;
//const int UNITS_MILS = 1000;
DIALOG_PLOT::DIALOG_PLOT( PCB_EDIT_FRAME* aParent ) :
DIALOG_PLOT_BASE( aParent ),
......@@ -725,9 +725,10 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event )
fn = m_parent->GetScreen()->GetFileName();
fn.SetPath( outputDir.GetPath() );
// Create file name.
wxString layername = m_board->GetLayerName( layer );
layername.Trim( true ); layername.Trim( false ); // remove leading and trailing spaces if any
// Create file name (from the English layer name for non copper layers).
wxString layername = m_board->GetLayerName( layer, false );
// remove leading and trailing spaces if any
layername.Trim( true ); layername.Trim( false );
fn.SetName( fn.GetName() + wxT( "-" ) + layername );
// Use Gerber Extensions based on layer number
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment