From c8866b7d4cddd4d7b7d15490d1dd35ff50b4f780 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Tue, 26 Jun 2012 19:57:37 +0200 Subject: [PATCH 1/3] Pcbnew: minor changes in pcb-parser.cpp and kicad_plugin.cpp to make translations easier. Code cleaning in autoroute functions. --- pcbnew/autorouter/autoplac.cpp | 8 +- pcbnew/autorouter/autorout.cpp | 17 +-- pcbnew/autorouter/autorout.h | 40 +++---- pcbnew/autorouter/dist.cpp | 6 +- pcbnew/autorouter/graphpcb.cpp | 10 +- pcbnew/autorouter/routing_matrix.cpp | 80 ++++++------- pcbnew/autorouter/solve.cpp | 17 ++- pcbnew/autorouter/work.cpp | 162 ++++++++------------------- pcbnew/kicad_plugin.cpp | 4 +- pcbnew/pcb_parser.cpp | 2 +- 10 files changed, 137 insertions(+), 209 deletions(-) diff --git a/pcbnew/autorouter/autoplac.cpp b/pcbnew/autorouter/autoplac.cpp index f943e8116e..16f8b14958 100644 --- a/pcbnew/autorouter/autoplac.cpp +++ b/pcbnew/autorouter/autoplac.cpp @@ -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 ) diff --git a/pcbnew/autorouter/autorout.cpp b/pcbnew/autorouter/autorout.cpp index 4819575575..7ea56d1768 100644 --- a/pcbnew/autorouter/autorout.cpp +++ b/pcbnew/autorouter/autorout.cpp @@ -47,12 +47,6 @@ #include -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 ) diff --git a/pcbnew/autorouter/autorout.h b/pcbnew/autorouter/autorout.h index c6c01f431d..baa2074c65 100644 --- a/pcbnew/autorouter/autorout.h +++ b/pcbnew/autorouter/autorout.h @@ -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 ); diff --git a/pcbnew/autorouter/dist.cpp b/pcbnew/autorouter/dist.cpp index 8bc91921cf..5841073aad 100644 --- a/pcbnew/autorouter/dist.cpp +++ b/pcbnew/autorouter/dist.cpp @@ -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]; diff --git a/pcbnew/autorouter/graphpcb.cpp b/pcbnew/autorouter/graphpcb.cpp index 77d137ab55..ede59ae1c9 100644 --- a/pcbnew/autorouter/graphpcb.cpp +++ b/pcbnew/autorouter/graphpcb.cpp @@ -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 } diff --git a/pcbnew/autorouter/routing_matrix.cpp b/pcbnew/autorouter/routing_matrix.cpp index e48c35ab37..e9ac66eef9 100644 --- a/pcbnew/autorouter/routing_matrix.cpp +++ b/pcbnew/autorouter/routing_matrix.cpp @@ -46,6 +46,23 @@ #include +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 - * For single-sided Routing 1: - * BOTTOM side is used and Route_Layer_BOTTOM = Route_Layer_TOP + * 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) * - * According to the bits = 1 parameter flag: - * If FORCE_PADS: all pads will be placed even those same net_code. + * For single-sided Routing 1: + * 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 ) { @@ -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 ) diff --git a/pcbnew/autorouter/solve.cpp b/pcbnew/autorouter/solve.cpp index 8ef2af3e7d..c3c00a2c0a 100644 --- a/pcbnew/autorouter/solve.cpp +++ b/pcbnew/autorouter/solve.cpp @@ -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, diff --git a/pcbnew/autorouter/work.cpp b/pcbnew/autorouter/work.cpp index 0db5dad007..11d0f1841b 100644 --- a/pcbnew/autorouter/work.cpp +++ b/pcbnew/autorouter/work.cpp @@ -41,9 +41,9 @@ #include -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 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; - return 1; - } - else /* can't get any more memory */ - { - return 0; - } + 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; } @@ -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 */ +// 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() { - 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; - - q0->m_Next = q1; - } - else - p = q1; - - /* reposition Head and Tail */ - for( Head = Current = Tail = p; Tail && Tail->m_Next; Tail = Tail->m_Next ) - ; + 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 ); } diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index 5ff61d02da..c7e127ea2a 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -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 ); diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index b860f52b4c..9676a7925d 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -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() ); } From bdf725f86b98cfce2b4b332b6a973d90dc3739cc Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Tue, 26 Jun 2012 22:18:01 +0200 Subject: [PATCH 2/3] Pcbnew: fix compil issue under wxGTK 2.8.12 --- pcbnew/dialogs/dialog_copper_zones.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pcbnew/dialogs/dialog_copper_zones.cpp b/pcbnew/dialogs/dialog_copper_zones.cpp index e3e08bf146..b5426adced 100644 --- a/pcbnew/dialogs/dialog_copper_zones.cpp +++ b/pcbnew/dialogs/dialog_copper_zones.cpp @@ -40,6 +40,8 @@ #include #include #include + +#include // needed for wx/listctrl.h, in wxGTK 2.8.12 #include From 3b8118ac0b581e66cdb1b324a513cee539977afc Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Wed, 27 Jun 2012 22:07:37 +0200 Subject: [PATCH 3/3] 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) --- pcbnew/class_board.cpp | 119 ++++++++++++++++++++++++++++------------ pcbnew/class_board.h | 11 +++- pcbnew/kicad_plugin.cpp | 4 +- pcbnew/pcb_parser.cpp | 5 +- pcbnew/pcbplot.cpp | 9 +-- 5 files changed, 101 insertions(+), 47 deletions(-) diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 33715ce3da..654042e42c 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -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() - return m_Layer[aLayerIndex].m_Name; + // 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 ); + return GetDefaultLayerName( aLayerIndex, aTranslate ); } -wxString BOARD::GetDefaultLayerName( int aLayerNumber ) +// 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; + 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; } - return wxString( txt ); + wxString name; + if( aTranslate ) + { + name = wxGetTranslation( txt ); + name.Trim( true ); + name.Trim( false ); + } + else + name = txt; + + return name; } diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index 59cbdc76eb..facbd7f2a8 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -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 diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index c7e127ea2a..fea888811a 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -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" ); } diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index 9676a7925d..0419f62587 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -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 ) diff --git a/pcbnew/pcbplot.cpp b/pcbnew/pcbplot.cpp index d5e8678f8b..865dc2ac05 100644 --- a/pcbnew/pcbplot.cpp +++ b/pcbnew/pcbplot.cpp @@ -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