kicad/gerbview/export_to_pcbnew.cpp

236 lines
6.3 KiB
C++

/* export_to_pcbnew.cpp */
/*
Export des couches vers pcbnew
*/
#include "fctsys.h"
#include "common.h"
#include "gerbview.h"
#include "protos.h"
/* Routines Locales : */
static int SavePcbFormatAscii(WinEDA_GerberFrame * frame,
FILE * File, int * LayerLookUpTable);
/* Variables Locales */
/************************************************************************/
void WinEDA_GerberFrame::ExportDataInPcbnewFormat(wxCommandEvent& event)
/************************************************************************/
/* Export data in pcbnew format
*/
{
wxString FullFileName, msg;
wxString PcbExt(wxT(".brd"));
FILE * dest;
msg = wxT("*") + PcbExt;
FullFileName = EDA_FileSelector(_("Board file name:"),
wxEmptyString, /* Chemin par defaut */
wxEmptyString, /* nom fichier par defaut */
PcbExt, /* extension par defaut */
msg, /* Masque d'affichage */
this,
wxFD_SAVE,
FALSE
);
if ( FullFileName == wxEmptyString ) return;
int * LayerLookUpTable;
if ( ( LayerLookUpTable = InstallDialogLayerPairChoice(this) ) != NULL )
{
if ( wxFileExists(FullFileName) )
{
if ( ! IsOK(this, _("Ok to change the existing file ?")) )
return;
}
dest = wxFopen(FullFileName, wxT("wt"));
if (dest == 0)
{
msg = _("Unable to create ") + FullFileName;
DisplayError(this, msg) ;
return;
}
GetScreen()->m_FileName = FullFileName;
SavePcbFormatAscii(this, dest, LayerLookUpTable);
fclose(dest) ;
}
}
/***************************************************************/
static int WriteSetup(FILE * File, BOARD * Pcb)
/***************************************************************/
{
char text[1024];
fprintf(File,"$SETUP\n");
sprintf(text, "InternalUnit %f INCH\n", 1.0/PCB_INTERNAL_UNIT);
to_point(text);
fprintf(File, text);
Pcb->m_BoardSettings->m_CopperLayerCount = g_DesignSettings.m_CopperLayerCount;
fprintf(File, "Layers %d\n", g_DesignSettings.m_CopperLayerCount);
fprintf(File,"$EndSETUP\n\n");
return(1);
}
/******************************************************/
static bool WriteGeneralDescrPcb(BOARD * Pcb, FILE * File)
/******************************************************/
{
int NbLayers;
/* generation du masque des couches autorisees */
NbLayers = Pcb->m_BoardSettings->m_CopperLayerCount;
fprintf(File,"$GENERAL\n");
fprintf(File,"LayerCount %d\n",NbLayers);
/* Generation des coord du rectangle d'encadrement */
Pcb->ComputeBoundaryBox();
fprintf(File,"Di %d %d %d %d\n",
Pcb->m_BoundaryBox.GetX(), Pcb->m_BoundaryBox.GetY(),
Pcb->m_BoundaryBox.GetRight(),
Pcb->m_BoundaryBox.GetBottom());
fprintf(File,"$EndGENERAL\n\n");
return TRUE;
}
/*******************************************************************/
static int SavePcbFormatAscii(WinEDA_GerberFrame * frame,FILE * File,
int * LayerLookUpTable)
/*******************************************************************/
/* Routine de sauvegarde du PCB courant sous format ASCII
retourne
1 si OK
0 si sauvegarde non faite
*/
{
char Line[256];
TRACK * track, *next_track;
EDA_BaseStruct * PtStruct, *NextStruct;
BOARD * GerberPcb = frame->m_Pcb;
BOARD * Pcb;
wxBeginBusyCursor();
/* Create an image of gerber data */
Pcb = new BOARD(NULL, frame);
for(track = GerberPcb->m_Track; track != NULL; track = (TRACK*) track->Pnext)
{
int layer = track->m_Layer;
int pcb_layer_number = LayerLookUpTable[layer];
if ( pcb_layer_number < 0 ) continue;
if ( pcb_layer_number > CMP_N )
{
DRAWSEGMENT * drawitem = new DRAWSEGMENT(NULL, TYPEDRAWSEGMENT);
drawitem->m_Layer = pcb_layer_number;
drawitem->m_Start = track->m_Start;
drawitem->m_End = track->m_End;
drawitem->m_Width = track->m_Width;
drawitem->Pnext = Pcb->m_Drawings;
Pcb->m_Drawings = drawitem;
}
else
{
TRACK * newtrack = new TRACK(*track);
newtrack->m_Layer = pcb_layer_number;
newtrack->Insert(Pcb, NULL);
}
}
/* replace spots by vias when possible */
for(track = Pcb->m_Track; track != NULL; track = (TRACK*) track->Pnext)
{
if( (track->m_Shape != S_SPOT_CIRCLE) && (track->m_Shape != S_SPOT_RECT) && (track->m_Shape != S_SPOT_OVALE) )
continue;
/* A spot is found, and can be a via: change it for via, and delete others
spots at same location */
track->m_Shape = VIA_NORMALE;
track->m_StructType = TYPEVIA;
track->m_Layer = 0x0F; // Layers are 0 to 15 (Cu/Cmp)
track->m_Drill = -1;
/* Compute the via position from track position ( Via position is the position of the middle of the track segment */
track->m_Start.x = (track->m_Start.x +track->m_End.x)/2;
track->m_Start.y = (track->m_Start.y +track->m_End.y)/2;
track->m_End = track->m_Start;
}
/* delete redundant vias */
for(track = Pcb->m_Track; track != NULL; track = track->Next())
{
if( track->m_Shape != VIA_NORMALE ) continue;
/* Search and delete others vias*/
TRACK * alt_track = track->Next();
for( ; alt_track != NULL; alt_track = next_track)
{
next_track = (TRACK*) alt_track->Pnext;
if( alt_track->m_Shape != VIA_NORMALE ) continue;
if ( alt_track->m_Start != track->m_Start ) continue;
/* delete track */
alt_track->UnLink();
delete alt_track;
}
}
// Switch the locale to standard C (needed to print floating point numbers like 1.3)
setlocale(LC_NUMERIC, "C");
/* Ecriture de l'entete PCB : */
fprintf(File,"PCBNEW-BOARD Version %d date %s\n\n",g_CurrentVersionPCB,
DateAndTime(Line) );
WriteGeneralDescrPcb(Pcb, File);
WriteSetup(File, Pcb);
/* Ecriture des donnes utiles du pcb */
PtStruct = Pcb->m_Drawings;
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
{
switch ( PtStruct->m_StructType )
{
case TYPETEXTE:
((TEXTE_PCB*)PtStruct)->WriteTextePcbDescr(File) ;
break;
case TYPEDRAWSEGMENT:
((DRAWSEGMENT *)PtStruct)->WriteDrawSegmentDescr(File);
break;
default:
break;
}
}
fprintf(File,"$TRACK\n");
for(track = Pcb->m_Track; track != NULL; track = (TRACK*) track->Pnext)
{
track->WriteTrackDescr(File);
}
fprintf(File,"$EndTRACK\n");
fprintf(File,"$EndBOARD\n");
/* Delete the copy */
for( PtStruct = Pcb->m_Drawings; PtStruct != NULL; PtStruct = NextStruct )
{
NextStruct = PtStruct->Pnext;
delete PtStruct;
}
for(track = Pcb->m_Track; track != NULL; track = next_track)
{
next_track = (TRACK*) track->Pnext;
delete track;
}
delete Pcb;
setlocale(LC_NUMERIC, ""); // revert to the current locale
wxEndBusyCursor();
return 1;
}