213 lines
5.3 KiB
C++
213 lines
5.3 KiB
C++
/***************************************/
|
|
/* PCBNEW: Autorouting command control */
|
|
/***************************************/
|
|
|
|
#include "fctsys.h"
|
|
#include "gr_basic.h"
|
|
#include "common.h"
|
|
#include "pcbnew.h"
|
|
#include "autorout.h"
|
|
#include "cell.h"
|
|
|
|
#include "protos.h"
|
|
|
|
/* routines internes */
|
|
|
|
/* Variables locales */
|
|
|
|
/********************************************************/
|
|
void WinEDA_PcbFrame::Autoroute(wxDC * DC, int mode)
|
|
/********************************************************/
|
|
/* init board, route traces*/
|
|
{
|
|
int ii, start, stop;
|
|
CHEVELU* ptmp;
|
|
MODULE * Module = NULL;
|
|
D_PAD * Pad = NULL;
|
|
int autoroute_net_code = -1;
|
|
wxString msg;
|
|
|
|
|
|
Route_Layer_TOP = GetScreen()->m_Route_Layer_TOP;
|
|
Route_Layer_BOTTOM = GetScreen()->m_Route_Layer_BOTTOM;
|
|
|
|
switch ( mode )
|
|
{
|
|
case ROUTE_NET:
|
|
if ( GetScreen()->m_CurrentItem )
|
|
{
|
|
switch ( GetScreen()->m_CurrentItem->m_StructType )
|
|
{
|
|
case TYPEPAD:
|
|
Pad = (D_PAD*) GetScreen()->m_CurrentItem;
|
|
autoroute_net_code = Pad->m_NetCode;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
if( autoroute_net_code <= 0)
|
|
{
|
|
DisplayError(this, _("Net not selected")); return;
|
|
}
|
|
break;
|
|
|
|
case ROUTE_MODULE:
|
|
Module = (MODULE*) GetScreen()->m_CurrentItem;
|
|
if( (Module == NULL) || (Module->m_StructType != TYPEMODULE) )
|
|
{
|
|
DisplayError(this, _("Module not selected") ); return;
|
|
}
|
|
break;
|
|
|
|
case ROUTE_PAD:
|
|
Pad = (D_PAD*) GetScreen()->m_CurrentItem;
|
|
if( (Pad == NULL) || (Pad->m_StructType != TYPEPAD) )
|
|
{
|
|
DisplayError(this, _("Pad not selected") ); return;
|
|
}
|
|
break;
|
|
|
|
}
|
|
if( (m_Pcb->m_Status_Pcb & LISTE_CHEVELU_OK ) == 0 )
|
|
Compile_Ratsnest(DC, TRUE);
|
|
|
|
/* Placement du flag CH_ROUTE_REQ sur les chevelus demandes */
|
|
ptmp = (CHEVELU*) m_Pcb->m_Ratsnest;
|
|
for ( ii = m_Pcb->GetNumRatsnests(); ii > 0; ii--, ptmp ++ )
|
|
{
|
|
ptmp->status &= ~CH_ROUTE_REQ;
|
|
switch ( mode )
|
|
{
|
|
case ROUTE_ALL:
|
|
ptmp->status |= CH_ROUTE_REQ; break;
|
|
|
|
case ROUTE_NET:
|
|
if( autoroute_net_code == ptmp->m_NetCode)
|
|
ptmp->status |= CH_ROUTE_REQ;
|
|
break;
|
|
|
|
case ROUTE_MODULE:
|
|
{
|
|
D_PAD * pt_pad = (D_PAD *) Module->m_Pads;
|
|
for( ; pt_pad != NULL; pt_pad = (D_PAD *)pt_pad->Pnext)
|
|
{
|
|
if( ptmp->pad_start == pt_pad )
|
|
ptmp->status |= CH_ROUTE_REQ;
|
|
if( ptmp->pad_end == pt_pad )
|
|
ptmp->status |= CH_ROUTE_REQ;
|
|
}
|
|
break;
|
|
}
|
|
case ROUTE_PAD:
|
|
if( (ptmp->pad_start == Pad) || (ptmp->pad_end == Pad))
|
|
ptmp->status |= CH_ROUTE_REQ;
|
|
break;
|
|
}
|
|
}
|
|
ptmp = (CHEVELU*)m_Pcb->m_Ratsnest;
|
|
|
|
start = time( NULL );
|
|
|
|
/* Calcul du pas de routage fixe a 5 mils et plus */
|
|
g_GridRoutingSize = GetScreen()->GetGrid().x;
|
|
if (g_GridRoutingSize < 50 ) g_GridRoutingSize = 50 ;
|
|
E_scale = g_GridRoutingSize / 50 ; if (E_scale < 1 ) E_scale = 1 ;
|
|
|
|
/* calcule de Ncols et Nrow, taille de la matrice de routage */
|
|
ComputeMatriceSize(this, g_GridRoutingSize);
|
|
|
|
MsgPanel->EraseMsgBox();
|
|
|
|
/* Creation du mapping du board */
|
|
Nb_Sides = ONE_SIDE;
|
|
if(Route_Layer_TOP != Route_Layer_BOTTOM ) Nb_Sides = TWO_SIDES;
|
|
|
|
if ( Board.InitBoard() < 0 )
|
|
{
|
|
DisplayError(this, _("No memory for autorouting") );
|
|
Board.UnInitBoard(); /* Libere la memoire BitMap */
|
|
return;
|
|
}
|
|
|
|
Affiche_Message( _("Place Cells") );
|
|
PlaceCells(m_Pcb, -1, FORCE_PADS);
|
|
|
|
/* Construction de la liste des pistes a router */
|
|
Build_Work(m_Pcb, ptmp);
|
|
|
|
// DisplayBoard(DrawPanel, DC);
|
|
|
|
if( Nb_Sides == TWO_SIDES )
|
|
Solve(DC, TWO_SIDES); /* double face */
|
|
else Solve(DC, ONE_SIDE); /* simple face */
|
|
|
|
/* Liberation de la memoire */
|
|
FreeQueue(); /* Libere la memoire de routage */
|
|
InitWork(); /* Libere la memoire de la liste des connexions a router */
|
|
Board.UnInitBoard(); /* Libere la memoire BitMap */
|
|
stop = time( NULL ) - start;
|
|
msg.Printf( wxT("time = %d second%s"), stop, (stop == 1) ? wxT("") : wxT("s") );
|
|
Affiche_Message(msg);
|
|
}
|
|
|
|
/************************************************/
|
|
void WinEDA_PcbFrame::Reset_Noroutable(wxDC * DC)
|
|
/*************************************************/
|
|
/* Remet a 0 le flag CH_NOROUTABLE qui est positionne a 1 par Solve()
|
|
lorsque un chevelu n'a pas ete route.
|
|
Si ce flag est a 1 il n'est pas reroute
|
|
*/
|
|
{
|
|
int ii;
|
|
CHEVELU* pt_rats;
|
|
|
|
if( (m_Pcb->m_Status_Pcb & LISTE_CHEVELU_OK )== 0 )
|
|
Compile_Ratsnest(DC, TRUE);
|
|
|
|
pt_rats = (CHEVELU*)m_Pcb->m_Ratsnest;
|
|
if( pt_rats == NULL ) return;
|
|
|
|
for ( ii = m_Pcb->GetNumRatsnests(); ii > 0 ; ii-- , pt_rats++)
|
|
{
|
|
pt_rats->status &= ~CH_UNROUTABLE ;
|
|
}
|
|
}
|
|
|
|
/*****************************************************/
|
|
void DisplayBoard(WinEDA_DrawPanel * panel, wxDC * DC)
|
|
/****************************************************/
|
|
/* Fonction de DEBUG : affiche le remplissage des cellules TOP et BOTTOM */
|
|
{
|
|
int row, col, i , j;
|
|
int dcell0, dcell1 = 0, color;
|
|
int maxi;
|
|
|
|
maxi = (/*ActiveScreen->Lim_XD - 20*/ 500) / Ncols;
|
|
maxi = (maxi * 3 ) / 4;
|
|
if (!maxi) maxi = 1;
|
|
|
|
for ( col = 0; col < Ncols; col++)
|
|
{
|
|
for(row = 0; row < Nrows; row++)
|
|
{
|
|
color = 0;
|
|
dcell0 = GetCell(row,col,BOTTOM); if (dcell0 & HOLE) color = GREEN;
|
|
if(Nb_Sides) dcell1 = GetCell(row,col,TOP);
|
|
if ( dcell1 & HOLE ) color |= RED;
|
|
dcell0 |= dcell1;
|
|
if( !color && (dcell0 & VIA_IMPOSSIBLE)) color = BLUE ;
|
|
if(color)
|
|
{
|
|
for (i = 0; i < maxi; i++)
|
|
for (j = 0; j < maxi; j++)
|
|
GRSPutPixel(&panel->m_ClipBox, DC,
|
|
(col*maxi)+i + 10,(row*maxi) + 60 + j, color);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|