2007-08-23 04:28:46 +00:00
|
|
|
|
/****************************************/
|
|
|
|
|
/* EDITEUR de PCB: Menus d'AUTOROUTAGE: */
|
|
|
|
|
/****************************************/
|
|
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
|
// #define ROUTER
|
|
|
|
|
|
|
|
|
|
#include "fctsys.h"
|
|
|
|
|
#include "gr_basic.h"
|
|
|
|
|
#include "common.h"
|
|
|
|
|
#include "pcbnew.h"
|
|
|
|
|
#include "autorout.h"
|
|
|
|
|
#include "cell.h"
|
|
|
|
|
#include "trigo.h"
|
|
|
|
|
|
|
|
|
|
#include "protos.h"
|
|
|
|
|
|
|
|
|
|
#define ROUTER
|
|
|
|
|
|
|
|
|
|
#define PSCALE 1
|
|
|
|
|
|
|
|
|
|
/* routines internes */
|
2007-08-23 04:28:46 +00:00
|
|
|
|
static void Out_Pads( BOARD* Pcb, FILE* outfile );
|
|
|
|
|
static int GenEdges( BOARD* Pcb, FILE* outfile );
|
|
|
|
|
static void GenExistantTracks( BOARD* Pcb, FILE* outfile, int current_net_code, int type );
|
|
|
|
|
static void ReturnNbViasAndTracks( BOARD* Pcb, int netcode, int* nb_vias, int* nb_tracks );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
|
|
|
|
/* variables locales */
|
|
|
|
|
static int min_layer, max_layer;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************/
|
2007-08-23 04:28:46 +00:00
|
|
|
|
void WinEDA_PcbFrame::GlobalRoute( wxDC* DC )
|
2007-06-05 12:10:51 +00:00
|
|
|
|
/******************************************/
|
|
|
|
|
{
|
|
|
|
|
#ifdef ROUTER
|
2007-08-23 04:28:46 +00:00
|
|
|
|
FILE* outfile;
|
|
|
|
|
wxString FullFileName, ExecFileName, msg;
|
|
|
|
|
int ii;
|
|
|
|
|
int net_number;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
|
|
|
|
#ifdef __UNIX__
|
2007-08-23 04:28:46 +00:00
|
|
|
|
ExecFileName = FindKicadFile( wxT( "anneal" ) );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
#else
|
2007-08-23 04:28:46 +00:00
|
|
|
|
ExecFileName = FindKicadFile( wxT( "anneal.exe" ) );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
#endif
|
2007-08-23 04:28:46 +00:00
|
|
|
|
/* test de la presence du fichier et execution si present */
|
|
|
|
|
if( !wxFileExists( ExecFileName ) )
|
|
|
|
|
{
|
|
|
|
|
msg.Printf( wxT( "File <%s> not found" ), ExecFileName.GetData() );
|
|
|
|
|
DisplayError( this, msg, 20 );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Calcule du nom du fichier intermediaire de communication */
|
|
|
|
|
FullFileName = m_CurrentScreen->m_FileName;
|
|
|
|
|
ChangeFileNameExt( FullFileName, wxT( ".ipt" ) );
|
|
|
|
|
|
|
|
|
|
if( ( outfile = wxFopen( FullFileName, wxT( "wt" ) ) ) == NULL )
|
|
|
|
|
{
|
|
|
|
|
msg = _( "Unable to create temporary file " ) + FullFileName;
|
|
|
|
|
DisplayError( this, msg, 20 );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
msg = _( "Create temporary file " ) + FullFileName;
|
|
|
|
|
SetStatusText( msg );
|
|
|
|
|
|
|
|
|
|
/* calcul ratsnest */
|
|
|
|
|
m_Pcb->m_Status_Pcb = 0;
|
|
|
|
|
Compile_Ratsnest( DC, TRUE );
|
|
|
|
|
|
|
|
|
|
m_Pcb->ComputeBoundaryBox();
|
|
|
|
|
g_GridRoutingSize = GetScreen()->GetGrid().x;
|
|
|
|
|
|
|
|
|
|
// Sortie de la dimension hors tout du pcb (dimensions + marge + g_GridRoutingSize)
|
2007-06-05 12:10:51 +00:00
|
|
|
|
#define B_MARGE 1000 // en 1/10000 inch
|
2007-08-23 04:28:46 +00:00
|
|
|
|
fprintf( outfile, "j %d %d %d %d",
|
|
|
|
|
( -B_MARGE - g_GridRoutingSize + m_Pcb->m_BoundaryBox.GetX() ) / PSCALE,
|
|
|
|
|
( -B_MARGE - g_GridRoutingSize + m_Pcb->m_BoundaryBox.GetY() ) / PSCALE,
|
|
|
|
|
( B_MARGE + g_GridRoutingSize + m_Pcb->m_BoundaryBox.GetRight() ) / PSCALE,
|
|
|
|
|
( B_MARGE + g_GridRoutingSize + m_Pcb->m_BoundaryBox.GetBottom() ) / PSCALE );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
/* calcul du nombre de couches cuivre */
|
|
|
|
|
min_layer = 1; /* -> couche soudure = min layer */
|
|
|
|
|
max_layer = m_Pcb->m_BoardSettings->m_CopperLayerCount;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
fprintf( outfile, " %d %d", min_layer, max_layer );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
net_number = m_Pcb->m_NbNets;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
fprintf( outfile, " %d", net_number );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
fprintf( outfile, " %d", g_GridRoutingSize / PSCALE );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
fprintf( outfile, " %d %d %d", /* isolation Pad, track, via */
|
|
|
|
|
g_DesignSettings.m_TrackClearence / PSCALE,
|
|
|
|
|
g_DesignSettings.m_TrackClearence / PSCALE,
|
|
|
|
|
g_DesignSettings.m_TrackClearence / PSCALE );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
fprintf( outfile, " 0" ); /* via type */
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
fprintf( outfile, " %d", g_DesignSettings.m_CurrentViaSize / PSCALE ); /* via diam */
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
fprintf( outfile, " n" ); /* via enterree non permise */
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
fprintf( outfile, " 0" ); /* unused */
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
fprintf( outfile, " %d", g_DesignSettings.m_CurrentTrackWidth / PSCALE ); /* default track width */
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
fprintf( outfile, " 0" ); /* unused */
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
fprintf( outfile, " 0 0 0\n" ); /* unused */
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
fprintf( outfile, "k 0 0 0 0 0 0 0 0 0 0\n" ); /* spare record */
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
fprintf( outfile, "m 0 0 0 0 0 0 0 0 0 0\n" ); /* cost record */
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
for( ii = min_layer; ii <= max_layer; ii++ )
|
|
|
|
|
{
|
|
|
|
|
int dir;
|
|
|
|
|
dir = 3; /* horizontal */
|
|
|
|
|
if( ii & 1 )
|
|
|
|
|
dir = 1; /* vertical */
|
|
|
|
|
fprintf( outfile, "l %d %d\n", ii, dir ); /* layer direction record */
|
|
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
Out_Pads( m_Pcb, outfile );
|
|
|
|
|
GenEdges( m_Pcb, outfile );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
fclose( outfile );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
ExecFileName += wxT( " " ) + FullFileName;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
Affiche_Message( ExecFileName );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
wxExecute( ExecFileName );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
|
|
|
|
#else
|
2007-08-23 04:28:46 +00:00
|
|
|
|
wxMessageBox( wxT( "TODO, currently not available" ) );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************/
|
2007-08-23 04:28:46 +00:00
|
|
|
|
static void Out_Pads( BOARD* Pcb, FILE* outfile )
|
2007-06-05 12:10:51 +00:00
|
|
|
|
/************************************************/
|
|
|
|
|
{
|
2007-08-23 04:28:46 +00:00
|
|
|
|
D_PAD* pt_pad;
|
|
|
|
|
|
|
|
|
|
//MODULE * Module;
|
|
|
|
|
int netcode, mod_num, nb_pads, plink;
|
|
|
|
|
LISTE_PAD* pt_liste_pad, * pt_start_liste,
|
|
|
|
|
* pt_end_liste, * pt_liste_pad_limite;
|
|
|
|
|
int pin_min_layer, pin_max_layer;
|
|
|
|
|
int no_conn = Pcb->m_NbPads + 1;/* valeur incrementee pour indiquer
|
|
|
|
|
* que le pad n'est pas deja connecte a une piste*/
|
|
|
|
|
|
|
|
|
|
pt_liste_pad = pt_start_liste = Pcb->m_Pads;
|
|
|
|
|
pt_liste_pad_limite = pt_start_liste + Pcb->m_NbPads;
|
|
|
|
|
|
|
|
|
|
if( pt_liste_pad == NULL )
|
|
|
|
|
return;
|
|
|
|
|
|
2007-10-13 06:18:44 +00:00
|
|
|
|
netcode = (*pt_liste_pad)->GetNet();
|
2007-08-23 04:28:46 +00:00
|
|
|
|
nb_pads = 1; plink = 0;
|
|
|
|
|
for( ; pt_liste_pad < pt_liste_pad_limite; )
|
|
|
|
|
{
|
|
|
|
|
/* Recherche de la fin de la liste des pads du net courant */
|
|
|
|
|
for( pt_end_liste = pt_liste_pad + 1; ; pt_end_liste++ )
|
|
|
|
|
{
|
|
|
|
|
if( pt_end_liste >= pt_liste_pad_limite )
|
|
|
|
|
break;
|
2007-10-13 06:18:44 +00:00
|
|
|
|
if( (*pt_end_liste)->GetNet() != netcode )
|
2007-08-23 04:28:46 +00:00
|
|
|
|
break;
|
|
|
|
|
nb_pads++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* fin de liste trouvee : */
|
|
|
|
|
if( netcode > 0 )
|
|
|
|
|
{
|
|
|
|
|
int nb_vias, nb_tracks;
|
|
|
|
|
ReturnNbViasAndTracks( Pcb, netcode, &nb_vias, &nb_tracks );
|
|
|
|
|
if( nb_pads < 2 )
|
|
|
|
|
{
|
|
|
|
|
wxString Line;
|
|
|
|
|
EQUIPOT* equipot = Pcb->FindNet( netcode );
|
|
|
|
|
Line.Printf( wxT( "Warning: %d pad, net %s" ),
|
|
|
|
|
nb_pads, equipot->m_Netname.GetData() );
|
|
|
|
|
DisplayError( NULL, Line, 20 );
|
|
|
|
|
}
|
|
|
|
|
fprintf( outfile, "r %d %d %d %d %d %d 1 1\n",
|
|
|
|
|
netcode, nb_pads, nb_vias + nb_pads, nb_tracks, 0,
|
|
|
|
|
g_DesignSettings.m_CurrentTrackWidth / PSCALE );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for( ; pt_liste_pad < pt_end_liste; pt_liste_pad++ )
|
|
|
|
|
{
|
|
|
|
|
pt_pad = *pt_liste_pad;
|
2007-10-13 06:18:44 +00:00
|
|
|
|
netcode = pt_pad->GetNet();
|
2007-08-23 04:28:46 +00:00
|
|
|
|
plink = pt_pad->m_physical_connexion;
|
|
|
|
|
/* plink = numero unique si pad non deja connecte a une piste */
|
|
|
|
|
if( plink <= 0 )
|
|
|
|
|
plink = no_conn++;
|
|
|
|
|
|
|
|
|
|
if( netcode <= 0 ) /* pad non connecte */
|
|
|
|
|
fprintf( outfile, "u 0" );
|
|
|
|
|
else
|
|
|
|
|
fprintf( outfile, "p %d", netcode );
|
|
|
|
|
/* position */
|
|
|
|
|
fprintf( outfile, " %d %d",
|
|
|
|
|
pt_pad->m_Pos.x / PSCALE, pt_pad->m_Pos.y / PSCALE );
|
|
|
|
|
|
|
|
|
|
/* layers */
|
|
|
|
|
pin_min_layer = 0; pin_max_layer = max_layer;
|
|
|
|
|
|
|
|
|
|
if( (pt_pad->m_Masque_Layer & ALL_CU_LAYERS) == CUIVRE_LAYER )
|
|
|
|
|
pin_min_layer = pin_max_layer = min_layer;
|
|
|
|
|
|
|
|
|
|
else if( (pt_pad->m_Masque_Layer & ALL_CU_LAYERS) == CMP_LAYER )
|
|
|
|
|
pin_min_layer = pin_max_layer = max_layer;
|
|
|
|
|
|
|
|
|
|
fprintf( outfile, " %d %d", pin_min_layer, pin_min_layer );
|
|
|
|
|
|
|
|
|
|
/* link */
|
|
|
|
|
fprintf( outfile, " %d", plink );
|
|
|
|
|
|
|
|
|
|
/* type of device (1 = IC, 2 = edge conn, 3 = discret, 4 = other */
|
|
|
|
|
switch( pt_pad->m_Attribut )
|
|
|
|
|
{
|
|
|
|
|
case STANDARD:
|
|
|
|
|
case SMD:
|
|
|
|
|
fprintf( outfile, " %d", 1 );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case CONN:
|
|
|
|
|
fprintf( outfile, " %d", 2 );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case P_HOLE:
|
|
|
|
|
case MECA:
|
|
|
|
|
fprintf( outfile, " %d", 4 );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* pin number */
|
|
|
|
|
fprintf( outfile, " %ld", (long) (pt_pad->m_Padname) );
|
|
|
|
|
|
|
|
|
|
/* layer size number (tj = 1) */
|
|
|
|
|
fprintf( outfile, " %d", 1 );
|
|
|
|
|
|
|
|
|
|
/* device number */
|
|
|
|
|
mod_num = 1; /* A CHANGER */
|
|
|
|
|
fprintf( outfile, " %d", mod_num );
|
|
|
|
|
|
|
|
|
|
/* orientations pins 1 et 2 */
|
|
|
|
|
fprintf( outfile, " x" );
|
|
|
|
|
|
|
|
|
|
/* spare */
|
|
|
|
|
fprintf( outfile, " 0 0\n" );
|
|
|
|
|
|
|
|
|
|
/* output layer size record */
|
|
|
|
|
fprintf( outfile, "q" );
|
|
|
|
|
|
|
|
|
|
switch( pt_pad->m_PadShape ) /* out type, dims */
|
|
|
|
|
{
|
|
|
|
|
case CIRCLE:
|
|
|
|
|
fprintf( outfile, " c 0 %d 0",
|
|
|
|
|
pt_pad->m_Size.x / PSCALE );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case OVALE:
|
|
|
|
|
case RECT:
|
|
|
|
|
case TRAPEZE:
|
|
|
|
|
int lmax = pt_pad->m_Size.x;
|
|
|
|
|
int lmin = pt_pad->m_Size.y;
|
|
|
|
|
int angle = pt_pad->m_Orient / 10;
|
|
|
|
|
while( angle < 0 )
|
|
|
|
|
angle += 180;
|
|
|
|
|
|
|
|
|
|
while( angle > 180 )
|
|
|
|
|
angle -= 180;
|
|
|
|
|
|
|
|
|
|
while( angle > 135 )
|
|
|
|
|
{
|
|
|
|
|
angle -= 90;
|
|
|
|
|
EXCHG( lmax, lmin );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf( outfile, " r %d %d %d",
|
|
|
|
|
angle,
|
|
|
|
|
lmax / PSCALE, lmin / PSCALE );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* layers */
|
|
|
|
|
fprintf( outfile, " %d %d\n", pin_min_layer, pin_max_layer );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* fin generation liste pads pour 1 net */
|
|
|
|
|
|
|
|
|
|
if( netcode )
|
|
|
|
|
{
|
|
|
|
|
GenExistantTracks( Pcb, outfile, netcode, TYPEVIA );
|
|
|
|
|
GenExistantTracks( Pcb, outfile, netcode, TYPETRACK );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nb_pads = 1;
|
|
|
|
|
pt_liste_pad = pt_start_liste = pt_end_liste;
|
|
|
|
|
if( pt_start_liste < pt_liste_pad_limite )
|
2007-10-13 06:18:44 +00:00
|
|
|
|
netcode = (*pt_start_liste)->GetNet();
|
2007-08-23 04:28:46 +00:00
|
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**************************************************************************/
|
2007-08-23 04:28:46 +00:00
|
|
|
|
static void ReturnNbViasAndTracks( BOARD* Pcb, int netcode, int* nb_vias,
|
|
|
|
|
int* nb_tracks )
|
2007-06-05 12:10:51 +00:00
|
|
|
|
/**************************************************************************/
|
2007-08-23 04:28:46 +00:00
|
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
|
/* calcule le nombre de vias et segments de pistes pour le net netcode
|
2007-08-23 04:28:46 +00:00
|
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
|
{
|
2007-08-23 04:28:46 +00:00
|
|
|
|
TRACK* track;
|
|
|
|
|
|
|
|
|
|
*nb_vias = 0;
|
|
|
|
|
*nb_tracks = 0;
|
|
|
|
|
|
|
|
|
|
track = Pcb->m_Track;
|
|
|
|
|
if( track == NULL )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
for( ; track != NULL; track = (TRACK*) track->Pnext )
|
|
|
|
|
{
|
2007-10-13 06:18:44 +00:00
|
|
|
|
if( track->GetNet() > netcode )
|
2007-08-23 04:28:46 +00:00
|
|
|
|
return;
|
2007-10-13 06:18:44 +00:00
|
|
|
|
if( track->GetNet() != netcode )
|
2007-08-23 04:28:46 +00:00
|
|
|
|
continue;
|
2007-09-01 12:00:30 +00:00
|
|
|
|
if( track->Type() == TYPEVIA )
|
2007-08-23 04:28:46 +00:00
|
|
|
|
(*nb_vias)++;
|
2007-09-01 12:00:30 +00:00
|
|
|
|
if( track->Type() == TYPETRACK )
|
2007-08-23 04:28:46 +00:00
|
|
|
|
(*nb_tracks)++;
|
|
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
|
/*************************************************************/
|
2007-08-23 04:28:46 +00:00
|
|
|
|
static void GenExistantTracks( BOARD* Pcb, FILE* outfile,
|
|
|
|
|
int current_net_code, int type )
|
2007-06-05 12:10:51 +00:00
|
|
|
|
/*************************************************************/
|
|
|
|
|
/* generation des pistes existantes */
|
|
|
|
|
{
|
2007-08-23 04:28:46 +00:00
|
|
|
|
int netcode, plink;
|
|
|
|
|
int via_min_layer, via_max_layer;
|
|
|
|
|
TRACK* track;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
track = Pcb->m_Track;
|
|
|
|
|
if( track == NULL )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for( ; track != NULL; track = (TRACK*) track->Pnext )
|
|
|
|
|
{
|
2007-10-13 06:18:44 +00:00
|
|
|
|
netcode = track->GetNet();
|
2007-08-23 04:28:46 +00:00
|
|
|
|
if( netcode > current_net_code )
|
|
|
|
|
return;
|
|
|
|
|
if( netcode != current_net_code )
|
|
|
|
|
continue;
|
2007-10-13 06:18:44 +00:00
|
|
|
|
plink = track->GetSubNet();
|
2007-08-23 04:28:46 +00:00
|
|
|
|
via_min_layer = track->GetLayer();
|
|
|
|
|
|
2007-09-01 12:00:30 +00:00
|
|
|
|
if( track->Type() != type )
|
2007-08-23 04:28:46 +00:00
|
|
|
|
continue;
|
|
|
|
|
|
2007-09-01 12:00:30 +00:00
|
|
|
|
if( track->Type() == TYPEVIA )
|
2007-08-23 04:28:46 +00:00
|
|
|
|
{
|
|
|
|
|
via_min_layer &= 15;
|
|
|
|
|
via_max_layer = (track->GetLayer() >> 4) & 15;
|
|
|
|
|
|
|
|
|
|
if( via_min_layer == via_max_layer )
|
|
|
|
|
{
|
|
|
|
|
track->SetLayer( 0xF );
|
|
|
|
|
via_min_layer = 0; via_max_layer = 15;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( via_max_layer < via_min_layer )
|
|
|
|
|
EXCHG( via_max_layer, via_min_layer );
|
|
|
|
|
|
|
|
|
|
if( via_max_layer == CMP_N )
|
|
|
|
|
via_max_layer = max_layer;
|
|
|
|
|
else
|
|
|
|
|
via_max_layer++;
|
|
|
|
|
|
2007-10-07 18:24:15 +00:00
|
|
|
|
if( via_min_layer == COPPER_LAYER_N )
|
2007-08-23 04:28:46 +00:00
|
|
|
|
via_min_layer = min_layer;
|
|
|
|
|
else
|
|
|
|
|
via_min_layer++;
|
|
|
|
|
|
|
|
|
|
fprintf( outfile, "v 0 " );
|
|
|
|
|
fprintf( outfile, " %d %d", track->m_Start.x / PSCALE, track->m_Start.y / PSCALE );
|
|
|
|
|
fprintf( outfile, " %d %d", via_min_layer, via_max_layer );
|
|
|
|
|
fprintf( outfile, " %d", plink );
|
|
|
|
|
fprintf( outfile, " %d\n", 1 );
|
|
|
|
|
/* layer size record */
|
|
|
|
|
fprintf( outfile, "q c 0 %d 0 0 0\n", track->m_Width / PSCALE );
|
|
|
|
|
}
|
|
|
|
|
|
2007-09-01 12:00:30 +00:00
|
|
|
|
if( track->Type() == TYPETRACK )
|
2007-08-23 04:28:46 +00:00
|
|
|
|
{
|
|
|
|
|
fprintf( outfile, "t 0 %d", track->m_Width / PSCALE );
|
|
|
|
|
fprintf( outfile, " %d %d", track->m_Start.x / PSCALE, track->m_Start.y / PSCALE );
|
|
|
|
|
fprintf( outfile, " %d %d", track->m_End.x / PSCALE, track->m_End.y / PSCALE );
|
|
|
|
|
|
|
|
|
|
if( via_min_layer == CMP_N )
|
|
|
|
|
via_min_layer = max_layer;
|
|
|
|
|
else
|
|
|
|
|
via_min_layer++;
|
|
|
|
|
fprintf( outfile, " %d", via_min_layer );
|
|
|
|
|
|
|
|
|
|
fprintf( outfile, " %d\n", 1 ); /*Number of corners */
|
|
|
|
|
|
|
|
|
|
/* output corner */
|
|
|
|
|
fprintf( outfile, "c" );
|
|
|
|
|
fprintf( outfile, " %d %d\n", track->m_End.x / PSCALE, track->m_End.y / PSCALE );
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
|
/***********************************************/
|
2007-08-23 04:28:46 +00:00
|
|
|
|
static int GenEdges( BOARD* Pcb, FILE* outfile )
|
2007-06-05 12:10:51 +00:00
|
|
|
|
/***********************************************/
|
2007-08-23 04:28:46 +00:00
|
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
|
/* Generation des contours (edges).
|
2007-08-23 04:28:46 +00:00
|
|
|
|
* Il sont g<EFBFBD>n<EFBFBD>r<EFBFBD>s comme des segments de piste plac<EFBFBD>s sur chaque couche routable.
|
|
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
|
{
|
|
|
|
|
#define NB_CORNERS 4
|
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
EDA_BaseStruct* PtStruct;
|
|
|
|
|
DRAWSEGMENT* PtDrawSegment;
|
|
|
|
|
int ii;
|
|
|
|
|
int dx, dy, width, angle;
|
|
|
|
|
int ox, oy, fx, fy;
|
|
|
|
|
wxPoint lim[4];
|
|
|
|
|
int NbItems = 0;
|
|
|
|
|
|
|
|
|
|
/* impression des contours */
|
|
|
|
|
for( PtStruct = Pcb->m_Drawings; PtStruct != NULL; PtStruct = PtStruct->Pnext )
|
|
|
|
|
{
|
2007-09-01 12:00:30 +00:00
|
|
|
|
if( PtStruct->Type() != TYPEDRAWSEGMENT )
|
2007-08-23 04:28:46 +00:00
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
PtDrawSegment = (DRAWSEGMENT*) PtStruct;
|
|
|
|
|
if( PtDrawSegment->GetLayer() != EDGE_N )
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
fx = PtDrawSegment->m_End.x; ox = PtDrawSegment->m_Start.x;
|
|
|
|
|
fy = PtDrawSegment->m_End.y; oy = PtDrawSegment->m_Start.y;
|
|
|
|
|
dx = fx - ox; dy = fy - oy;
|
|
|
|
|
if( (dx == 0) && (dy == 0) )
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* elimination des segments non horizontaux, verticaux ou 45 degres,
|
|
|
|
|
* non g<EFBFBD>r<EFBFBD>s par l'autorouteur */
|
|
|
|
|
if( (dx != 0) && (dy != 0) && ( abs( dx ) != abs( dy ) ) )
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
NbItems++;
|
|
|
|
|
if( outfile == NULL )
|
|
|
|
|
continue; /* car simple decompte des items */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* generation de la zone interdite */
|
|
|
|
|
if( dx < 0 )
|
|
|
|
|
{
|
|
|
|
|
EXCHG( ox, fx ); EXCHG( oy, fy ); dx = -dx; dy = -dy;
|
|
|
|
|
}
|
|
|
|
|
if( (dx == 0) && (dy < 0 ) )
|
|
|
|
|
{
|
|
|
|
|
EXCHG( oy, fy ); dy = -dy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
width = PtDrawSegment->m_Width;
|
|
|
|
|
width += g_GridRoutingSize;
|
|
|
|
|
|
|
|
|
|
angle = -ArcTangente( dy, dx );
|
|
|
|
|
if( angle % 450 )/* not H, V or X */
|
|
|
|
|
{
|
|
|
|
|
wxBell();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 1er point */
|
|
|
|
|
dx = -width; dy = -width;
|
|
|
|
|
RotatePoint( &dx, &dy, angle );
|
|
|
|
|
lim[0].x = ox + dx;
|
|
|
|
|
lim[0].y = oy + dy;
|
|
|
|
|
|
|
|
|
|
/* 2eme point */
|
|
|
|
|
RotatePoint( &dx, &dy, -900 );
|
|
|
|
|
lim[1].x = fx + dx;
|
|
|
|
|
lim[1].y = fy + dy;
|
|
|
|
|
|
|
|
|
|
/* 3eme point */
|
|
|
|
|
RotatePoint( &dx, &dy, -900 );
|
|
|
|
|
lim[2].x = fx + dx;
|
|
|
|
|
lim[2].y = fy + dy;
|
|
|
|
|
|
|
|
|
|
/* 4eme point */
|
|
|
|
|
RotatePoint( &dx, &dy, -900 );
|
|
|
|
|
lim[3].x = ox + dx;
|
|
|
|
|
lim[3].y = oy + dy;
|
|
|
|
|
|
|
|
|
|
if( angle % 900 )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
/* mise a l'echelle */
|
|
|
|
|
for( ii = 0; ii < 4; ii++ )
|
|
|
|
|
{
|
|
|
|
|
lim[ii].x = (int) ( ( (double) lim[ii].x + 0.5 ) / PSCALE );
|
|
|
|
|
lim[ii].y = (int) ( ( (double) lim[ii].y + 0.5 ) / PSCALE );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* sortie du 1er point */
|
|
|
|
|
fprintf( outfile, "n %d %d %ld %ld %d\n",
|
|
|
|
|
0, /* layer number, 0 = all layers */
|
|
|
|
|
0, /* -1 (no via), 0 (no via no track), 1 (no track) */
|
|
|
|
|
(long) lim[0].x, (long) lim[0].y,
|
|
|
|
|
NB_CORNERS );
|
|
|
|
|
|
|
|
|
|
/* sortie des autres points */
|
|
|
|
|
for( ii = 1; ii < 4; ii++ )
|
|
|
|
|
{
|
|
|
|
|
fprintf( outfile, "c %ld %ld\n",
|
|
|
|
|
(long) lim[ii].x, (long) lim[ii].y );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NbItems;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************************/
|
2007-08-23 04:28:46 +00:00
|
|
|
|
void WinEDA_PcbFrame::ReadAutoroutedTracks( wxDC* DC )
|
2007-06-05 12:10:51 +00:00
|
|
|
|
/****************************************************/
|
|
|
|
|
{
|
2007-08-23 04:28:46 +00:00
|
|
|
|
char Line[1024];
|
|
|
|
|
wxString FullFileName, msg;
|
|
|
|
|
int LineNum = 0, NbTrack = 0, NetCode = 0;
|
|
|
|
|
FILE* File;
|
|
|
|
|
TRACK* NewTrack;
|
|
|
|
|
SEGVIA* NewVia;
|
|
|
|
|
int track_count, track_layer, image, track_width;
|
|
|
|
|
int via_layer1, via_layer2, via_size;
|
|
|
|
|
wxPoint track_start, track_end;
|
|
|
|
|
int max_layer = m_Pcb->m_BoardSettings->m_CopperLayerCount;
|
|
|
|
|
|
|
|
|
|
/* Calcule du nom du fichier intermediaire de communication */
|
|
|
|
|
FullFileName = m_CurrentScreen->m_FileName;
|
|
|
|
|
ChangeFileNameExt( FullFileName, wxT( ".trc" ) );
|
|
|
|
|
|
|
|
|
|
if( ( File = wxFopen( FullFileName, wxT( "rt" ) ) ) == NULL )
|
|
|
|
|
{
|
|
|
|
|
msg = _( "Unable to find data file " ) + FullFileName;
|
|
|
|
|
DisplayError( this, msg, 20 );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
msg = _( "Reading autorouter data file " ) + FullFileName;
|
|
|
|
|
Affiche_Message( msg );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setlocale( LC_NUMERIC, "C" );
|
|
|
|
|
|
|
|
|
|
track_width = g_DesignSettings.m_CurrentTrackWidth;
|
|
|
|
|
via_size = g_DesignSettings.m_CurrentViaSize;
|
|
|
|
|
while( GetLine( File, Line, &LineNum ) != NULL )
|
|
|
|
|
{
|
|
|
|
|
char ident = Line[0];
|
|
|
|
|
|
|
|
|
|
switch( ident )
|
|
|
|
|
{
|
|
|
|
|
case 'j': // Header, not used
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'R': // Net record
|
|
|
|
|
sscanf( Line + 2, "%d", &NetCode );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'V': // via record: fmt = V symbol pos_x pos_y layer1 layer2
|
|
|
|
|
sscanf( Line + 2, "%d %d %d %d %d", &image,
|
|
|
|
|
&track_start.x, &track_start.y, &via_layer1, &via_layer2 );
|
|
|
|
|
via_layer1--; via_layer2--;
|
|
|
|
|
if( via_layer1 == max_layer - 1 )
|
|
|
|
|
via_layer1 = CMP_N;
|
|
|
|
|
if( via_layer2 == max_layer - 1 )
|
|
|
|
|
via_layer2 = CMP_N;
|
|
|
|
|
NewVia = new SEGVIA( m_Pcb );
|
|
|
|
|
|
|
|
|
|
NewVia->m_Start = NewVia->m_End = track_start;
|
|
|
|
|
NewVia->m_Width = via_size;
|
|
|
|
|
NewVia->SetLayer( via_layer1 + (via_layer2 << 4) );
|
|
|
|
|
if( NewVia->GetLayer() == 0x0F || NewVia->GetLayer() == 0xF0 )
|
2007-10-19 16:24:44 +00:00
|
|
|
|
NewVia->m_Shape = VIA_THROUGH;
|
2007-08-23 04:28:46 +00:00
|
|
|
|
else
|
2007-10-19 16:24:44 +00:00
|
|
|
|
NewVia->m_Shape = VIA_BURIED;
|
2007-10-01 04:34:11 +00:00
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
NewVia->Insert( m_Pcb, NULL );
|
|
|
|
|
NbTrack++;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'T': // Track list start: fmt = T image layer t_count
|
|
|
|
|
sscanf( Line + 2, "%d %d %d", &image, &track_layer, &track_count );
|
|
|
|
|
track_layer--;
|
2007-10-07 18:24:15 +00:00
|
|
|
|
if( (track_layer != COPPER_LAYER_N) && (track_layer == max_layer - 1) )
|
2007-08-23 04:28:46 +00:00
|
|
|
|
track_layer = CMP_N;
|
|
|
|
|
|
|
|
|
|
// Read corners: fmt = C x_pos y_pos
|
|
|
|
|
for( int ii = 0; ii < track_count; ii++ )
|
|
|
|
|
{
|
|
|
|
|
if( GetLine( File, Line, &LineNum ) != NULL )
|
|
|
|
|
{
|
|
|
|
|
if( Line[0] != 'C' )
|
|
|
|
|
break;
|
|
|
|
|
if( ii == 0 )
|
|
|
|
|
sscanf( Line + 2, "%d %d", &track_start.x, &track_start.y );
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sscanf( Line + 2, "%d %d", &track_end.x, &track_end.y );
|
|
|
|
|
NewTrack = new TRACK( m_Pcb );
|
|
|
|
|
|
|
|
|
|
NewTrack->m_Width = track_width;
|
|
|
|
|
NewTrack->SetLayer( track_layer );
|
|
|
|
|
NewTrack->m_Start = track_start;
|
|
|
|
|
NewTrack->m_End = track_end;
|
|
|
|
|
track_start = track_end;
|
|
|
|
|
NewTrack->Insert( m_Pcb, NULL );
|
|
|
|
|
NbTrack++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fclose( File );
|
|
|
|
|
|
|
|
|
|
setlocale( LC_NUMERIC, "" );
|
|
|
|
|
|
|
|
|
|
if( NbTrack == 0 )
|
|
|
|
|
DisplayError( this, wxT( "Warning: No tracks" ), 10 );
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_Pcb->m_Status_Pcb = 0;
|
|
|
|
|
m_CurrentScreen->SetModify();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Compile_Ratsnest( DC, TRUE );
|
|
|
|
|
if( NbTrack )
|
|
|
|
|
m_CurrentScreen->SetRefreshReq();
|
2007-06-05 12:10:51 +00:00
|
|
|
|
}
|