kicad/gerbview/export_to_pcbnew.cpp

250 lines
7.4 KiB
C++
Raw Normal View History

/* export_to_pcbnew.cpp */
2007-08-23 04:28:46 +00:00
/*
2007-09-01 12:00:30 +00:00
* Export the layers to pcbnew
2007-08-23 04:28:46 +00:00
*/
#include "fctsys.h"
#include "common.h"
#include "class_drawpanel.h"
#include "confirm.h"
#include "kicad_string.h"
#include "gestfich.h"
#include "gerbview.h"
2009-10-28 11:48:47 +00:00
#include "class_board_design_settings.h"
2010-09-28 14:42:05 +00:00
#include "class_gerber_draw_item.h"
2007-08-23 04:28:46 +00:00
static int SavePcbFormatAscii( WinEDA_GerberFrame* frame,
FILE* File, int* LayerLookUpTable );
2007-08-23 04:28:46 +00:00
/* Export data in pcbnew format
2007-08-23 04:28:46 +00:00
*/
void WinEDA_GerberFrame::ExportDataInPcbnewFormat( wxCommandEvent& event )
{
int ii = 0;
2007-10-07 03:08:24 +00:00
bool no_used_layers = true; // Changed to false if any used layer found
// Check whether any of the Gerber layers are actually currently used
while( no_used_layers && ii < 32 )
{
2008-11-08 06:44:07 +00:00
if( g_GERBER_List[ii] != NULL )
no_used_layers = false;
2007-10-07 03:08:24 +00:00
ii++;
}
if( no_used_layers )
{
DisplayInfoMessage( this,
_( "None of the Gerber layers contain any data" ) );
2007-10-07 03:08:24 +00:00
return;
}
2007-08-23 04:28:46 +00:00
wxString FullFileName, msg;
wxString PcbExt( wxT( ".brd" ) );
FILE* dest;
2007-08-23 04:28:46 +00:00
msg = wxT( "*" ) + PcbExt;
FullFileName = EDA_FileSelector( _( "Board file name:" ),
wxEmptyString,
wxEmptyString,
PcbExt,
msg,
2007-08-23 04:28:46 +00:00
this,
wxFD_SAVE,
FALSE
);
if( FullFileName == wxEmptyString )
return;
int* LayerLookUpTable;
if( ( LayerLookUpTable = InstallDialogLayerPairChoice( ) ) != NULL )
2007-08-23 04:28:46 +00:00
{
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 );
}
}
2007-08-23 04:28:46 +00:00
static int WriteSetup( FILE* File, BOARD* Pcb )
{
2007-08-23 04:28:46 +00:00
char text[1024];
fprintf( File, "$SETUP\n" );
sprintf( text, "InternalUnit %f INCH\n", 1.0 / PCB_INTERNAL_UNIT );
fprintf( File, "%s", text );
fprintf( File, "Layers %d\n", Pcb->GetCopperLayerCount() );
2007-08-23 04:28:46 +00:00
fprintf( File, "$EndSETUP\n\n" );
return 1;
}
2007-08-23 04:28:46 +00:00
static bool WriteGeneralDescrPcb( BOARD* Pcb, FILE* File )
{
2007-08-23 04:28:46 +00:00
int NbLayers;
/* Print the copper layer count */
NbLayers = Pcb->GetCopperLayerCount();
2007-08-23 04:28:46 +00:00
fprintf( File, "$GENERAL\n" );
fprintf( File, "LayerCount %d\n", NbLayers );
/* Compute and print the board bounding box */
2007-08-23 04:28:46 +00:00
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;
}
/* Routine to save the board
* @param frame = pointer to the main frame
* @param File = FILE * pointer to an already opened file
* @param LayerLookUpTable = look up table: pcbnew layer for each gerber layer
* @return 1 if OK, 0 if fail
2007-08-23 04:28:46 +00:00
*/
static int SavePcbFormatAscii( WinEDA_GerberFrame* frame, FILE* aFile,
int* LayerLookUpTable )
{
char line[256];
BOARD* gerberPcb = frame->GetBoard();
BOARD* pcb;
2007-08-23 04:28:46 +00:00
wxBeginBusyCursor();
2007-10-30 21:30:58 +00:00
// create an image of gerber data
pcb = new BOARD( NULL, frame );
2010-09-28 14:42:05 +00:00
BOARD_ITEM* item = gerberPcb->m_Drawings;
for( ; item; item = item->Next() )
2007-08-23 04:28:46 +00:00
{
2010-09-28 14:42:05 +00:00
GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item;
2010-09-29 09:25:48 +00:00
int layer = gerb_item->GetLayer();
2007-08-23 04:28:46 +00:00
int pcb_layer_number = LayerLookUpTable[layer];
if( pcb_layer_number < 0 || pcb_layer_number > LAST_NO_COPPER_LAYER )
2007-08-23 04:28:46 +00:00
continue;
2008-11-08 06:44:07 +00:00
if( pcb_layer_number > LAST_COPPER_LAYER )
2007-08-23 04:28:46 +00:00
{
DRAWSEGMENT* drawitem = new DRAWSEGMENT( pcb, TYPE_DRAWSEGMENT );
2007-08-23 04:28:46 +00:00
drawitem->SetLayer( pcb_layer_number );
2010-09-28 14:42:05 +00:00
drawitem->m_Start = gerb_item->m_Start;
drawitem->m_End = gerb_item->m_End;
drawitem->m_Width = gerb_item->m_Size.x;
2010-09-28 14:42:05 +00:00
if( gerb_item->m_Shape == GBR_ARC )
2009-05-26 04:43:14 +00:00
{
2010-09-28 14:42:05 +00:00
double cx = gerb_item->m_ArcCentre.x;
double cy = gerb_item->m_ArcCentre.y;
double a = atan2( gerb_item->m_Start.y - cy,
gerb_item->m_Start.x - cx );
double b = atan2( gerb_item->m_End.y - cy, gerb_item->m_End.x - cx );
drawitem->m_Shape = S_ARC;
drawitem->m_Angle = (int) fmod(
(a - b) / M_PI * 1800.0 + 3600.0, 3600.0 );
drawitem->m_Start.x = (int) cx;
drawitem->m_Start.y = (int) cy;
2009-05-26 04:43:14 +00:00
}
pcb->Add( drawitem );
2007-08-23 04:28:46 +00:00
}
else
{
TRACK* newtrack;
2008-11-08 06:44:07 +00:00
2007-09-01 12:00:30 +00:00
// replace spots with vias when possible
2010-09-28 14:42:05 +00:00
if( gerb_item->m_Shape == GBR_SPOT_CIRCLE
|| gerb_item->m_Shape == GBR_SPOT_RECT
|| gerb_item->m_Shape == GBR_SPOT_OVAL )
2007-09-01 12:00:30 +00:00
{
2010-09-28 14:42:05 +00:00
newtrack = new SEGVIA( pcb );
2007-09-01 12:00:30 +00:00
// A spot is found, and can be a via: change it to via, and
// delete other
2007-09-01 12:00:30 +00:00
// spots at same location
newtrack->m_Shape = VIA_THROUGH;
2007-09-01 12:00:30 +00:00
newtrack->SetLayer( 0x0F ); // Layers are 0 to 15 (Cu/Cmp)
newtrack->SetDrillDefault();
2010-09-28 14:42:05 +00:00
newtrack->m_Start = newtrack->m_End = gerb_item->m_Start;
newtrack->m_Width = (gerb_item->m_Size.x + gerb_item->m_Size.y) / 2;
2007-09-01 12:00:30 +00:00
}
else // a true TRACK
{
2010-09-28 14:42:05 +00:00
newtrack = new TRACK( pcb );
2007-09-01 12:00:30 +00:00
newtrack->SetLayer( pcb_layer_number );
2010-09-28 14:42:05 +00:00
newtrack->m_Start = gerb_item->m_Start;
newtrack->m_End = gerb_item->m_End;
newtrack->m_Width = gerb_item->m_Size.x;
2007-09-01 12:00:30 +00:00
}
2008-11-08 06:44:07 +00:00
pcb->Add( newtrack );
2007-08-23 04:28:46 +00:00
}
}
2007-09-01 12:00:30 +00:00
// delete redundant vias
2010-09-28 14:42:05 +00:00
for( TRACK * track = pcb->m_Track; track; track = track->Next() )
2007-08-23 04:28:46 +00:00
{
if( track->m_Shape != VIA_THROUGH )
2007-08-23 04:28:46 +00:00
continue;
2008-11-08 06:44:07 +00:00
2007-09-01 12:00:30 +00:00
// Search and delete others vias
2007-10-30 21:30:58 +00:00
TRACK* next_track;
2007-08-23 04:28:46 +00:00
TRACK* alt_track = track->Next();
for( ; alt_track; alt_track = next_track )
2007-08-23 04:28:46 +00:00
{
2007-09-01 12:00:30 +00:00
next_track = alt_track->Next();
if( alt_track->m_Shape != VIA_THROUGH )
2007-08-23 04:28:46 +00:00
continue;
2007-09-01 12:00:30 +00:00
2007-08-23 04:28:46 +00:00
if( alt_track->m_Start != track->m_Start )
continue;
2007-09-01 12:00:30 +00:00
// delete track
2007-08-23 04:28:46 +00:00
alt_track->UnLink();
delete alt_track;
}
}
// Switch the locale to standard C (needed to print floating point numbers
// like 1.3)
SetLocaleTo_C_standard();
2008-11-08 06:44:07 +00:00
2007-09-01 12:00:30 +00:00
// write the PCB heading
2007-10-30 21:30:58 +00:00
fprintf( aFile, "PCBNEW-BOARD Version %d date %s\n\n", g_CurrentVersionPCB,
DateAndTime( line ) );
WriteGeneralDescrPcb( pcb, aFile );
WriteSetup( aFile, pcb );
2007-08-23 04:28:46 +00:00
2007-09-01 12:00:30 +00:00
// write the useful part of the pcb
2007-10-30 21:30:58 +00:00
pcb->Save( aFile );
2007-08-23 04:28:46 +00:00
2007-10-30 21:30:58 +00:00
// the destructor should destroy all owned sub-objects
delete pcb;
2007-08-23 04:28:46 +00:00
SetLocaleTo_Default(); // revert to the current locale
2007-08-23 04:28:46 +00:00
wxEndBusyCursor();
return 1;
}