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() ); }