2011-09-20 13:57:40 +00:00
|
|
|
/**
|
|
|
|
* @file autorout.cpp
|
|
|
|
* @brief Autorouting command and control.
|
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
|
|
#include "fctsys.h"
|
2009-02-04 15:25:03 +00:00
|
|
|
#include "class_drawpanel.h"
|
2009-07-30 11:04:07 +00:00
|
|
|
#include "wxPcbStruct.h"
|
2011-09-23 13:57:12 +00:00
|
|
|
#include "gr_basic.h"
|
2011-09-20 13:57:40 +00:00
|
|
|
|
|
|
|
#include "pcbnew.h"
|
2007-06-05 12:10:51 +00:00
|
|
|
#include "cell.h"
|
2008-10-20 05:59:58 +00:00
|
|
|
#include "zones.h"
|
2011-09-20 13:57:40 +00:00
|
|
|
#include "ar_protos.h"
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2011-09-23 13:57:12 +00:00
|
|
|
#include "class_board.h"
|
|
|
|
#include "class_module.h"
|
|
|
|
#include "class_track.h"
|
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2009-11-12 15:43:38 +00:00
|
|
|
int E_scale; /* Scaling factor of distance tables. */
|
|
|
|
int Nb_Sides; /* Number of layer for autorouting (0 or 1) */
|
2009-04-05 20:49:15 +00:00
|
|
|
int Nrows = ILLEGAL;
|
|
|
|
int Ncols = ILLEGAL;
|
|
|
|
int Ntotal;
|
|
|
|
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 */
|
|
|
|
|
2011-03-09 14:30:39 +00:00
|
|
|
MATRIX_ROUTING_HEAD Board; /* 2-sided board */
|
2009-04-05 20:49:15 +00:00
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
|
|
/* init board, route traces*/
|
2011-03-01 19:26:17 +00:00
|
|
|
void PCB_EDIT_FRAME::Autoroute( wxDC* DC, int mode )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2009-05-28 08:42:24 +00:00
|
|
|
int start, stop;
|
2007-10-13 06:18:44 +00:00
|
|
|
MODULE* Module = NULL;
|
|
|
|
D_PAD* Pad = NULL;
|
|
|
|
int autoroute_net_code = -1;
|
|
|
|
wxString msg;
|
|
|
|
|
2010-01-31 20:01:46 +00:00
|
|
|
if( GetBoard()->GetCopperLayerCount() > 1 )
|
2007-10-13 06:18:44 +00:00
|
|
|
{
|
2011-03-09 14:30:39 +00:00
|
|
|
Route_Layer_TOP = GetScreen()->m_Route_Layer_TOP;
|
|
|
|
Route_Layer_BOTTOM = GetScreen()->m_Route_Layer_BOTTOM;
|
2007-10-13 06:18:44 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-09-20 13:57:40 +00:00
|
|
|
Route_Layer_TOP = Route_Layer_BOTTOM = LAYER_N_BACK;
|
2007-10-13 06:18:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
switch( mode )
|
|
|
|
{
|
|
|
|
case ROUTE_NET:
|
|
|
|
if( GetScreen()->GetCurItem() )
|
|
|
|
{
|
|
|
|
switch( GetScreen()->GetCurItem()->Type() )
|
|
|
|
{
|
2011-10-01 19:24:27 +00:00
|
|
|
case PCB_PAD_T:
|
2007-10-13 06:18:44 +00:00
|
|
|
Pad = (D_PAD*) GetScreen()->GetCurItem();
|
|
|
|
autoroute_net_code = Pad->GetNet();
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( autoroute_net_code <= 0 )
|
|
|
|
{
|
2011-03-09 14:30:39 +00:00
|
|
|
wxMessageBox( _( "Net not selected" ) ); return;
|
2007-10-13 06:18:44 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ROUTE_MODULE:
|
|
|
|
Module = (MODULE*) GetScreen()->GetCurItem();
|
2011-10-01 19:24:27 +00:00
|
|
|
if( (Module == NULL) || (Module->Type() != PCB_MODULE_T) )
|
2007-10-13 06:18:44 +00:00
|
|
|
{
|
2011-03-09 14:30:39 +00:00
|
|
|
wxMessageBox( _( "Module not selected" ) );
|
2009-11-12 15:43:38 +00:00
|
|
|
return;
|
2007-10-13 06:18:44 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ROUTE_PAD:
|
|
|
|
Pad = (D_PAD*) GetScreen()->GetCurItem();
|
2011-09-20 13:57:40 +00:00
|
|
|
|
2011-10-01 19:24:27 +00:00
|
|
|
if( (Pad == NULL) || (Pad->Type() != PCB_PAD_T) )
|
2007-10-13 06:18:44 +00:00
|
|
|
{
|
2011-03-09 14:30:39 +00:00
|
|
|
wxMessageBox( _( "Pad not selected" ) );
|
2009-11-12 15:43:38 +00:00
|
|
|
return;
|
2007-10-13 06:18:44 +00:00
|
|
|
}
|
2011-09-20 13:57:40 +00:00
|
|
|
|
2007-10-13 06:18:44 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-05-24 18:28:36 +00:00
|
|
|
if( (GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK ) == 0 )
|
2011-03-09 14:30:39 +00:00
|
|
|
Compile_Ratsnest( DC, true );
|
2007-10-13 06:18:44 +00:00
|
|
|
|
2009-11-12 15:43:38 +00:00
|
|
|
/* Set the flag on the ratsnest to CH_ROUTE_REQ. */
|
2009-05-28 08:42:24 +00:00
|
|
|
for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
|
2007-10-13 06:18:44 +00:00
|
|
|
{
|
2009-11-12 15:43:38 +00:00
|
|
|
RATSNEST_ITEM* ptmp = &GetBoard()->m_FullRatsnest[ii];
|
2009-05-24 18:28:36 +00:00
|
|
|
ptmp->m_Status &= ~CH_ROUTE_REQ;
|
2007-10-13 06:18:44 +00:00
|
|
|
|
|
|
|
switch( mode )
|
|
|
|
{
|
|
|
|
case ROUTE_ALL:
|
2009-11-12 15:43:38 +00:00
|
|
|
ptmp->m_Status |= CH_ROUTE_REQ;
|
|
|
|
break;
|
2007-10-13 06:18:44 +00:00
|
|
|
|
|
|
|
case ROUTE_NET:
|
|
|
|
if( autoroute_net_code == ptmp->GetNet() )
|
2009-05-24 18:28:36 +00:00
|
|
|
ptmp->m_Status |= CH_ROUTE_REQ;
|
2007-10-13 06:18:44 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ROUTE_MODULE:
|
|
|
|
{
|
|
|
|
D_PAD* pt_pad = (D_PAD*) Module->m_Pads;
|
2008-11-24 06:53:43 +00:00
|
|
|
for( ; pt_pad != NULL; pt_pad = pt_pad->Next() )
|
2007-10-13 06:18:44 +00:00
|
|
|
{
|
2009-05-24 18:28:36 +00:00
|
|
|
if( ptmp->m_PadStart == pt_pad )
|
|
|
|
ptmp->m_Status |= CH_ROUTE_REQ;
|
2011-09-20 13:57:40 +00:00
|
|
|
|
2009-05-24 18:28:36 +00:00
|
|
|
if( ptmp->m_PadEnd == pt_pad )
|
|
|
|
ptmp->m_Status |= CH_ROUTE_REQ;
|
2007-10-13 06:18:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ROUTE_PAD:
|
2009-11-12 15:43:38 +00:00
|
|
|
if( ( ptmp->m_PadStart == Pad ) || ( ptmp->m_PadEnd == Pad ) )
|
2009-05-24 18:28:36 +00:00
|
|
|
ptmp->m_Status |= CH_ROUTE_REQ;
|
2011-09-20 13:57:40 +00:00
|
|
|
|
2007-10-13 06:18:44 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
start = time( NULL );
|
|
|
|
|
2009-11-12 15:43:38 +00:00
|
|
|
/* Calculation of no fixed routing to 5 mils and more. */
|
2011-03-09 20:09:11 +00:00
|
|
|
Board.m_GridRouting = (int)GetScreen()->GetGridSize().x;
|
2011-09-20 13:57:40 +00:00
|
|
|
|
2011-03-09 20:09:11 +00:00
|
|
|
if( Board.m_GridRouting < 50 )
|
|
|
|
Board.m_GridRouting = 50;
|
2011-09-20 13:57:40 +00:00
|
|
|
|
|
|
|
E_scale = Board.m_GridRouting / 50;
|
|
|
|
|
|
|
|
if( E_scale < 1 )
|
2007-10-13 06:18:44 +00:00
|
|
|
E_scale = 1;
|
|
|
|
|
2009-11-12 15:43:38 +00:00
|
|
|
/* Calculated ncol and nrow, matrix size for routing. */
|
2011-03-09 20:09:11 +00:00
|
|
|
Board.ComputeMatrixSize( GetBoard() );
|
2007-10-13 06:18:44 +00:00
|
|
|
|
2011-12-12 14:02:37 +00:00
|
|
|
m_messagePanel->EraseMsgBox();
|
2007-10-13 06:18:44 +00:00
|
|
|
|
2009-11-12 15:43:38 +00:00
|
|
|
/* Map the board */
|
2007-10-13 06:18:44 +00:00
|
|
|
Nb_Sides = ONE_SIDE;
|
2011-09-20 13:57:40 +00:00
|
|
|
|
2007-10-13 06:18:44 +00:00
|
|
|
if( Route_Layer_TOP != Route_Layer_BOTTOM )
|
|
|
|
Nb_Sides = TWO_SIDES;
|
|
|
|
|
|
|
|
if( Board.InitBoard() < 0 )
|
|
|
|
{
|
2011-03-09 14:30:39 +00:00
|
|
|
wxMessageBox( _( "No memory for autorouting" ) );
|
2009-11-12 15:43:38 +00:00
|
|
|
Board.UnInitBoard(); /* Free memory. */
|
2007-10-13 06:18:44 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-02-11 20:48:13 +00:00
|
|
|
SetStatusText( _( "Place Cells" ) );
|
2009-01-05 05:21:35 +00:00
|
|
|
PlaceCells( GetBoard(), -1, FORCE_PADS );
|
2007-10-13 06:18:44 +00:00
|
|
|
|
2009-11-12 15:43:38 +00:00
|
|
|
/* Construction of the track list for router. */
|
2009-05-28 08:42:24 +00:00
|
|
|
Build_Work( GetBoard() );
|
2007-10-13 06:18:44 +00:00
|
|
|
|
|
|
|
// DisplayBoard(DrawPanel, DC);
|
|
|
|
|
|
|
|
if( Nb_Sides == TWO_SIDES )
|
|
|
|
Solve( DC, TWO_SIDES ); /* double face */
|
|
|
|
else
|
|
|
|
Solve( DC, ONE_SIDE ); /* simple face */
|
|
|
|
|
2009-11-12 15:43:38 +00:00
|
|
|
/* Free memory. */
|
|
|
|
FreeQueue();
|
|
|
|
InitWork(); /* Free memory for the list of router connections. */
|
|
|
|
Board.UnInitBoard();
|
2007-10-13 06:18:44 +00:00
|
|
|
stop = time( NULL ) - start;
|
2011-02-11 20:48:13 +00:00
|
|
|
msg.Printf( wxT( "time = %d second%s" ), stop, ( stop == 1 ) ? wxT( "" ) : wxT( "s" ) );
|
|
|
|
SetStatusText( msg );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-13 06:18:44 +00:00
|
|
|
|
2011-03-09 14:30:39 +00:00
|
|
|
/* Clear the flag CH_NOROUTABLE which is set to 1 by Solve(),
|
|
|
|
* when a track was not routed.
|
|
|
|
* (If this flag is 1 the corresponding track it is not rerouted)
|
2007-10-13 06:18:44 +00:00
|
|
|
*/
|
2011-03-01 19:26:17 +00:00
|
|
|
void PCB_EDIT_FRAME::Reset_Noroutable( wxDC* DC )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2009-11-12 15:43:38 +00:00
|
|
|
if( ( GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK )== 0 )
|
2011-03-09 14:30:39 +00:00
|
|
|
Compile_Ratsnest( DC, true );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2009-05-28 08:42:24 +00:00
|
|
|
for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
|
2007-10-13 06:18:44 +00:00
|
|
|
{
|
2009-05-28 08:42:24 +00:00
|
|
|
GetBoard()->m_FullRatsnest[ii].m_Status &= ~CH_UNROUTABLE;
|
2007-10-13 06:18:44 +00:00
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-10-13 06:18:44 +00:00
|
|
|
|
2011-03-09 14:30:39 +00:00
|
|
|
/* DEBUG Function: displays the routing matrix */
|
2011-01-21 19:30:59 +00:00
|
|
|
void DisplayBoard( EDA_DRAW_PANEL* panel, wxDC* DC )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-10-13 06:18:44 +00:00
|
|
|
int row, col, i, j;
|
|
|
|
int dcell0, dcell1 = 0, color;
|
|
|
|
int maxi;
|
|
|
|
|
2008-01-24 19:51:13 +00:00
|
|
|
maxi = 600 / Ncols;
|
2009-11-12 15:43:38 +00:00
|
|
|
maxi = ( maxi * 3 ) / 4;
|
2011-09-20 13:57:40 +00:00
|
|
|
|
2007-10-13 06:18:44 +00:00
|
|
|
if( !maxi )
|
|
|
|
maxi = 1;
|
|
|
|
|
2008-01-24 19:51:13 +00:00
|
|
|
GRSetDrawMode( DC, GR_COPY );
|
2011-09-20 13:57:40 +00:00
|
|
|
|
2007-10-13 06:18:44 +00:00
|
|
|
for( col = 0; col < Ncols; col++ )
|
|
|
|
{
|
|
|
|
for( row = 0; row < Nrows; row++ )
|
|
|
|
{
|
|
|
|
color = 0;
|
2008-01-24 19:51:13 +00:00
|
|
|
dcell0 = GetCell( row, col, BOTTOM );
|
2011-09-20 13:57:40 +00:00
|
|
|
|
2008-11-24 06:53:43 +00:00
|
|
|
if( dcell0 & HOLE )
|
2007-10-13 06:18:44 +00:00
|
|
|
color = GREEN;
|
2011-09-20 13:57:40 +00:00
|
|
|
|
2008-01-24 19:51:13 +00:00
|
|
|
// if( Nb_Sides )
|
|
|
|
// dcell1 = GetCell( row, col, TOP );
|
2011-09-20 13:57:40 +00:00
|
|
|
|
2007-10-13 06:18:44 +00:00
|
|
|
if( dcell1 & HOLE )
|
|
|
|
color |= RED;
|
2011-09-20 13:57:40 +00:00
|
|
|
|
2008-01-24 19:51:13 +00:00
|
|
|
// dcell0 |= dcell1;
|
2011-09-20 13:57:40 +00:00
|
|
|
|
2009-11-12 15:43:38 +00:00
|
|
|
if( !color && ( dcell0 & VIA_IMPOSSIBLE ) )
|
2007-10-13 06:18:44 +00:00
|
|
|
color = BLUE;
|
2011-09-20 13:57:40 +00:00
|
|
|
|
2008-11-24 06:53:43 +00:00
|
|
|
if( dcell0 & CELL_is_EDGE )
|
2008-01-24 19:51:13 +00:00
|
|
|
color = YELLOW;
|
2008-11-24 06:53:43 +00:00
|
|
|
else if( dcell0 & CELL_is_ZONE )
|
2008-01-24 19:51:13 +00:00
|
|
|
color = YELLOW;
|
2008-11-24 06:53:43 +00:00
|
|
|
|
|
|
|
#define DRAW_OFFSET_X -20
|
|
|
|
#define DRAW_OFFSET_Y 20
|
2008-01-24 19:51:13 +00:00
|
|
|
// if( color )
|
2007-10-13 06:18:44 +00:00
|
|
|
{
|
|
|
|
for( i = 0; i < maxi; i++ )
|
|
|
|
for( j = 0; j < maxi; j++ )
|
2011-01-30 22:22:38 +00:00
|
|
|
GRPutPixel( &panel->m_ClipBox, DC,
|
|
|
|
( col * maxi ) + i + DRAW_OFFSET_X,
|
|
|
|
( row * maxi ) + j + DRAW_OFFSET_Y, color );
|
2007-10-13 06:18:44 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|