void VRML_MODEL_PARSER::Load( const wxString aFilename ) { char line[1024], * text; FILE* file; int LineNum = 0; file = wxFopen( aFilename, wxT( "rt" ) ); if( file == NULL ) { return; } // Switch the locale to standard C (needed to print floating point numbers like 1.3) SetLocaleTo_C_standard(); while( GetLine( file, line, &LineNum, 512 ) ) { text = strtok( line, sep_chars ); if ( text == NULL ) continue; if( stricmp( text, "DEF" ) == 0 || stricmp( text, "Group" ) == 0 ) { while( GetLine( file, line, &LineNum, 512 ) ) { text = strtok( line, sep_chars ); if( text == NULL ) continue; if( *text == '}' ) break; if( stricmp( text, "children" ) == 0 ) { readChildren( file, &LineNum ); } } } } fclose( file ); SetLocaleTo_Default(); // revert to the current locale }
bool PCB_EDIT_FRAME::ExportVRML_File( const wxString& aFullFileName, double aMMtoWRMLunit, bool aExport3DFiles, const wxString& a3D_Subdir ) { wxString msg; BOARD* pcb = GetBoard(); bool ok = true; MODEL_VRML model3d; model_vrml = &model3d; std::ofstream output_file; try { output_file.exceptions( std::ofstream::failbit ); output_file.open( TO_UTF8( aFullFileName ), std::ios_base::out ); // Switch the locale to standard C (needed to print floating point numbers like 1.3) SetLocaleTo_C_standard(); // Begin with the usual VRML boilerplate wxString name = aFullFileName; name.Replace( wxT( "\\" ), wxT( "/" ) ); ChangeIllegalCharacters( name, false ); output_file << "#VRML V2.0 utf8\n"; output_file << "WorldInfo {\n"; output_file << " title \"" << TO_UTF8( name ) << " - Generated by Pcbnew\"\n"; output_file << "}\n"; // Set the VRML world scale factor model3d.SetScale( aMMtoWRMLunit ); output_file << "Transform {\n"; // compute the offset to center the board on (0, 0, 0) // XXX - NOTE: we should allow the user a GUI option to specify the offset EDA_RECT bbbox = pcb->ComputeBoundingBox(); model3d.SetOffset( -model3d.scale * bbbox.Centre().x, model3d.scale * bbbox.Centre().y ); output_file << " children [\n"; // Preliminary computation: the z value for each layer compute_layer_Zs( model3d, pcb ); // board edges and cutouts export_vrml_board( model3d, pcb ); // Drawing and text on the board export_vrml_drawings( model3d, pcb ); // Export vias and trackage export_vrml_tracks( model3d, pcb ); // Export zone fills export_vrml_zones( model3d, pcb); /* scaling factor to convert 3D models to board units (decimils) * Usually we use Wings3D to create thems. * One can consider the 3D units is 0.1 inch (2.54 mm) * So the scaling factor from 0.1 inch to board units * is 2.54 * aMMtoWRMLunit */ double wrml_3D_models_scaling_factor = 2.54 * aMMtoWRMLunit; // Export footprints for( MODULE* module = pcb->m_Modules; module != 0; module = module->Next() ) export_vrml_module( model3d, pcb, module, output_file, wrml_3D_models_scaling_factor, aExport3DFiles, a3D_Subdir ); // write out the board and all layers write_layers( model3d, output_file, pcb ); // Close the outer 'transform' node output_file << "]\n}\n"; } catch( const std::exception& e ) { wxString msg; msg << _( "IDF Export Failed:\n" ) << FROM_UTF8( e.what() ); wxMessageBox( msg ); ok = false; } // End of work output_file.exceptions( std::ios_base::goodbit ); output_file.close(); SetLocaleTo_Default(); // revert to the current locale return ok; }
int EXCELLON_WRITER::CreateDrillFile( FILE* aFile ) { m_file = aFile; int diam, holes_count; int x0, y0, xf, yf, xc, yc; double xt, yt; char line[1024]; SetLocaleTo_C_standard(); // Use the standard notation for double numbers WriteEXCELLONHeader(); holes_count = 0; /* Write the tool list */ for( unsigned ii = 0; ii < m_toolListBuffer.size(); ii++ ) { DRILL_TOOL& tool_descr = m_toolListBuffer[ii]; fprintf( m_file, "T%dC%.3f\n", ii + 1, tool_descr.m_Diameter * m_conversionUnits ); } fputs( "%\n", m_file ); // End of header info fputs( "G90\n", m_file ); // Absolute mode fputs( "G05\n", m_file ); // Drill mode // Units : if( !m_minimalHeader ) { if( m_unitsDecimal ) fputs( "M71\n", m_file ); /* M71 = metric mode */ else fputs( "M72\n", m_file ); /* M72 = inch mode */ } /* Read the hole file and generate lines for normal holes (oblong * holes will be created later) */ int tool_reference = -2; for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ ) { HOLE_INFO& hole_descr = m_holeListBuffer[ii]; if( hole_descr.m_Hole_Shape ) continue; // oblong holes will be created later if( tool_reference != hole_descr.m_Tool_Reference ) { tool_reference = hole_descr.m_Tool_Reference; fprintf( m_file, "T%d\n", tool_reference ); } x0 = hole_descr.m_Hole_Pos.x - m_offset.x; y0 = hole_descr.m_Hole_Pos.y - m_offset.y; if( !m_mirror ) y0 *= -1; xt = x0 * m_conversionUnits; yt = y0 * m_conversionUnits; WriteCoordinates( line, xt, yt ); fputs( line, m_file ); holes_count++; } /* Read the hole file and generate lines for normal holes (oblong holes * will be created later) */ tool_reference = -2; // set to a value not used for // m_holeListBuffer[ii].m_Tool_Reference for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ ) { HOLE_INFO& hole_descr = m_holeListBuffer[ii]; if( hole_descr.m_Hole_Shape == 0 ) continue; // wait for oblong holes if( tool_reference != hole_descr.m_Tool_Reference ) { tool_reference = hole_descr.m_Tool_Reference; fprintf( m_file, "T%d\n", tool_reference ); } diam = std::min( hole_descr.m_Hole_Size.x, hole_descr.m_Hole_Size.y ); if( diam == 0 ) continue; /* Compute the hole coordinates: */ xc = x0 = xf = hole_descr.m_Hole_Pos.x - m_offset.x; yc = y0 = yf = hole_descr.m_Hole_Pos.y - m_offset.y; /* Compute the start and end coordinates for the shape */ if( hole_descr.m_Hole_Size.x < hole_descr.m_Hole_Size.y ) { int delta = ( hole_descr.m_Hole_Size.y - hole_descr.m_Hole_Size.x ) / 2; y0 -= delta; yf += delta; } else { int delta = ( hole_descr.m_Hole_Size.x - hole_descr.m_Hole_Size.y ) / 2; x0 -= delta; xf += delta; } RotatePoint( &x0, &y0, xc, yc, hole_descr.m_Hole_Orient ); RotatePoint( &xf, &yf, xc, yc, hole_descr.m_Hole_Orient ); if( !m_mirror ) { y0 *= -1; yf *= -1; } xt = x0 * m_conversionUnits; yt = y0 * m_conversionUnits; WriteCoordinates( line, xt, yt ); /* remove the '\n' from end of line, because we must add the "G85" * command to the line: */ for( int kk = 0; line[kk] != 0; kk++ ) { if( line[kk] == '\n' || line[kk] =='\r' ) line[kk] = 0; } fputs( line, m_file ); fputs( "G85", m_file ); // add the "G85" command xt = xf * m_conversionUnits; yt = yf * m_conversionUnits; WriteCoordinates( line, xt, yt ); fputs( line, m_file ); fputs( "G05\n", m_file ); holes_count++; } WriteEXCELLONEndOfFile(); SetLocaleTo_Default(); // Revert to locale double notation return holes_count; }
bool EXCELLON_IMAGE::Read_EXCELLON_File( FILE * aFile, const wxString & aFullFileName ) { /* Set the gerber scale: */ ResetDefaultValues(); m_FileName = aFullFileName; m_Current_File = aFile; SetLocaleTo_C_standard(); // FILE_LINE_READER will close the file. if( m_Current_File == NULL ) { wxMessageBox( wxT("NULL!"), m_FileName ); return false; } FILE_LINE_READER excellonReader( m_Current_File, m_FileName ); while( true ) { if( excellonReader.ReadLine() == 0 ) break; char* line = excellonReader.Line(); char* text = StrPurge( line ); if( *text == ';' ) // comment: skip line continue; if( m_State == EXCELLON_IMAGE::READ_HEADER_STATE ) { Execute_HEADER_Command( text ); } else { switch( *text ) { case 'M': Execute_HEADER_Command( text ); break; case 'G': /* Line type Gxx : command */ Execute_EXCELLON_G_Command( text ); break; case 'X': case 'Y': // command like X12550Y19250 Execute_Drill_Command(text); break; case 'I': case 'J': /* Auxiliary Move command */ m_IJPos = ReadIJCoord( text ); if( *text == '*' ) // command like X35142Y15945J504 { Execute_Drill_Command( text); } break; case 'T': // Tool command Select_Tool( text ); break; case '%': break; default: { wxString msg; msg.Printf( wxT( "Unexpected symbol <%c>" ), *text ); if( GetParent() ) GetParent()->ReportMessage( msg ); } break; } // End switch } } SetLocaleTo_Default(); return true; }
bool EDA_APP::SetLanguage( bool first_time ) { bool retv = true; // dictionary file name without extend (full name is kicad.mo) wxString DictionaryName( wxT( "kicad" ) ); if( m_Locale ) delete m_Locale; m_Locale = new wxLocale; #if wxCHECK_VERSION( 2, 9, 0 ) if( !m_Locale->Init( m_LanguageId ) ) #else if( !m_Locale->Init( m_LanguageId, wxLOCALE_CONV_ENCODING ) ) #endif { wxLogDebug( wxT( "This language is not supported by the system." ) ); m_LanguageId = wxLANGUAGE_DEFAULT; delete m_Locale; m_Locale = new wxLocale; m_Locale->Init(); retv = false; } else if( !first_time ) { wxLogDebug( wxT( "Search for dictionary %s.mo in %s" ), GetChars( DictionaryName ), GetChars( m_Locale->GetName() ) ); } if( !first_time ) { wxString languageSel; // Search for the current selection for( unsigned int ii = 0; ii < LANGUAGE_DESCR_COUNT; ii++ ) { if( s_Language_List[ii].m_WX_Lang_Identifier == m_LanguageId ) { languageSel = s_Language_List[ii].m_Lang_Label; break; } } m_commonSettings->Write( languageCfgKey, languageSel ); } // Test if floating point notation is working (bug in cross compilation, using wine) // Make a conversion double <=> string double dtst = 0.5; wxString msg; extern bool g_DisableFloatingPointLocalNotation; // See common.cpp g_DisableFloatingPointLocalNotation = false; msg << dtst; double result; msg.ToDouble(&result); if( result != dtst ) // string to double encode/decode does not work! Bug detected { // Disable floating point localization: g_DisableFloatingPointLocalNotation = true; SetLocaleTo_C_standard( ); } if( !m_Locale->IsLoaded( DictionaryName ) ) m_Locale->AddCatalog( DictionaryName ); if( !retv ) return retv; return m_Locale->IsOk(); }
void DIALOG_PLOT_SCHEMATIC::createPDFFile( bool aPlotAll, bool aPlotFrameRef ) { SCH_SCREEN* screen = m_parent->GetScreen(); SCH_SHEET_PATH* sheetpath; SCH_SHEET_PATH oldsheetpath = m_parent->GetCurrentSheet(); // sheetpath is saved here wxPoint plot_offset; /* When printing all pages, the printed page is not the current page. In * complex hierarchies, we must update component references and others * parameters in the given printed SCH_SCREEN, accordint to the sheet path * because in complex hierarchies a SCH_SCREEN (a drawing ) is shared * between many sheets and component references depend on the actual sheet * path used */ SCH_SHEET_LIST SheetList( NULL ); sheetpath = SheetList.GetFirst(); // Allocate the plotter and set the job level parameter PDF_PLOTTER* plotter = new PDF_PLOTTER(); plotter->SetDefaultLineWidth( GetDefaultLineThickness() ); plotter->SetColorMode( getModeColor() ); plotter->SetCreator( wxT( "Eeschema-PDF" ) ); wxString msg; wxString plotFileName; // First page handling is different bool first_page = true; do { // Step over the schematic hierarchy if( aPlotAll ) { SCH_SHEET_PATH list; if( list.BuildSheetPathInfoFromSheetPathValue( sheetpath->Path() ) ) { m_parent->SetCurrentSheet( list ); m_parent->GetCurrentSheet().UpdateAllScreenReferences(); m_parent->SetSheetNumberAndCount(); screen = m_parent->GetCurrentSheet().LastScreen(); } else // Should not happen wxASSERT( 0 ); sheetpath = SheetList.GetNext(); } if( first_page ) { plotFileName = m_parent->GetUniqueFilenameForCurrentSheet() + wxT( "." ) + PDF_PLOTTER::GetDefaultFileExtension(); if( ! plotter->OpenFile( plotFileName ) ) { msg.Printf( _( "** Unable to create %s **\n" ), GetChars( plotFileName ) ); m_MessagesBox->AppendText( msg ); delete plotter; return; } // Open the plotter and do the first page SetLocaleTo_C_standard(); setupPlotPagePDF( plotter, screen ); plotter->StartPlot(); first_page = false; } else { /* For the following pages you need to close the (finished) page, * reconfigure, and then start a new one */ plotter->ClosePage(); setupPlotPagePDF( plotter, screen ); plotter->StartPage(); } plotOneSheetPDF( plotter, screen, aPlotFrameRef ); } while( aPlotAll && sheetpath ); // Everything done, close the plot and restore the environment plotter->EndPlot(); delete plotter; SetLocaleTo_Default(); // Restore the previous sheet m_parent->SetCurrentSheet( oldsheetpath ); m_parent->GetCurrentSheet().UpdateAllScreenReferences(); m_parent->SetSheetNumberAndCount(); msg.Printf( _( "Plot: %s OK\n" ), GetChars( plotFileName ) ); m_MessagesBox->AppendText( msg ); }
bool PGM_BASE::SetLanguage( bool first_time ) { bool retv = true; if( first_time ) { setLanguageId( wxLANGUAGE_DEFAULT ); // First time SetLanguage is called, the user selected language id is set // from commun user config settings wxString languageSel; m_common_settings->Read( languageCfgKey, &languageSel ); // Search for the current selection for( unsigned ii = 0; ii < DIM( s_Languages ); ii++ ) { if( s_Languages[ii].m_Lang_Label == languageSel ) { setLanguageId( s_Languages[ii].m_WX_Lang_Identifier ); break; } } } // dictionary file name without extend (full name is kicad.mo) wxString dictionaryName( wxT( "kicad" ) ); delete m_locale; m_locale = new wxLocale; if( !m_locale->Init( m_language_id ) ) { wxLogDebug( wxT( "This language is not supported by the system." ) ); setLanguageId( wxLANGUAGE_DEFAULT ); delete m_locale; m_locale = new wxLocale; m_locale->Init(); retv = false; } else if( !first_time ) { wxLogDebug( wxT( "Search for dictionary %s.mo in %s" ), GetChars( dictionaryName ), GetChars( m_locale->GetName() ) ); } if( !first_time ) { // If we are here, the user has selected an other language. // Therefore the new prefered language name is stored in common config. // Do NOT store the wxWidgets language Id, it can change between wxWidgets // versions, for a given language wxString languageSel; // Search for the current selection for( unsigned ii = 0; ii < DIM( s_Languages ); ii++ ) { if( s_Languages[ii].m_WX_Lang_Identifier == m_language_id ) { languageSel = s_Languages[ii].m_Lang_Label; break; } } m_common_settings->Write( languageCfgKey, languageSel ); } // Test if floating point notation is working (bug in cross compilation, using wine) // Make a conversion double <=> string double dtst = 0.5; wxString msg; extern bool g_DisableFloatingPointLocalNotation; // See common.cpp g_DisableFloatingPointLocalNotation = false; msg << dtst; double result; msg.ToDouble( &result ); if( result != dtst ) // string to double encode/decode does not work! Bug detected { // Disable floating point localization: g_DisableFloatingPointLocalNotation = true; SetLocaleTo_C_standard( ); } if( !m_locale->IsLoaded( dictionaryName ) ) m_locale->AddCatalog( dictionaryName ); if( !retv ) return retv; return m_locale->IsOk(); }
/* Driver function: processing starts here */ void PCB_EDIT_FRAME::ExportToGenCAD( wxCommandEvent& aEvent ) { wxFileName fn = GetBoard()->GetFileName(); FILE* file; wxString ext = wxT( "cad" ); wxString wildcard = _( "GenCAD 1.4 board files (.cad)|*.cad" ); fn.SetExt( ext ); wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() ); wxFileDialog dlg( this, _( "Save GenCAD Board File" ), pro_dir, fn.GetFullName(), wildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); if( dlg.ShowModal() == wxID_CANCEL ) return; if( ( file = wxFopen( dlg.GetPath(), wxT( "wt" ) ) ) == NULL ) { wxString msg; msg.Printf( _( "Unable to create <%s>" ), GetChars( dlg.GetPath() ) ); DisplayError( this, msg ); return; } SetLocaleTo_C_standard(); // No pesky decimal separators in gencad // Update some board data, to ensure a reliable gencad export GetBoard()->ComputeBoundingBox(); // Save the auxiliary origin for the rest of the module GencadOffsetX = GetAuxOrigin().x; GencadOffsetY = GetAuxOrigin().y; // No idea on *why* this should be needed... maybe to fix net names? Compile_Ratsnest( NULL, true ); /* Temporary modification of footprints that are flipped (i.e. on bottom * layer) to convert them to non flipped footprints. * This is necessary to easily export shapes to GenCAD, * that are given as normal orientation (non flipped, rotation = 0)) * these changes will be undone later */ BOARD* pcb = GetBoard(); MODULE* module; for( module = pcb->m_Modules; module; module = module->Next() ) { module->SetFlag( 0 ); if( module->GetLayer() == B_Cu ) { module->Flip( module->GetPosition() ); module->SetFlag( 1 ); } } /* Gencad has some mandatory and some optional sections: some importer * need the padstack section (which is optional) anyway. Also the * order of the section *is* important */ CreateHeaderInfoData( file, this ); // Gencad header CreateBoardSection( file, pcb ); // Board perimeter CreatePadsShapesSection( file, pcb ); // Pads and padstacks CreateArtworksSection( file ); // Empty but mandatory /* Gencad splits a component info in shape, component and device. * We don't do any sharing (it would be difficult since each module is * customizable after placement) */ CreateShapesSection( file, pcb ); CreateComponentsSection( file, pcb ); CreateDevicesSection( file, pcb ); // In a similar way the netlist is split in net, track and route CreateSignalsSection( file, pcb ); CreateTracksInfoData( file, pcb ); CreateRoutesSection( file, pcb ); fclose( file ); SetLocaleTo_Default(); // revert to the current locale // Undo the footprints modifications (flipped footprints) for( module = pcb->m_Modules; module; module = module->Next() ) { if( module->GetFlag() ) { module->Flip( module->GetPosition() ); module->SetFlag( 0 ); } } }
/* Note1: * When copying 3D shapes files, the new filename is build from * the full path name, changing the separators by underscore. * this is needed because files with the same shortname can exist in different directories * Note 2: * ExportVRML_File generates coordinates in board units (BIU) inside the file. * (TODO: use mm inside the file) * A general scale transform is applied to the whole file * (1.0 to have the actual WRML unit im mm, 0.001 to have the actual WRML unit im meter * Note 3: * For 3D models built by a 3D modeler, the unit is 0,1 inch * A specfic scale is applied to 3D models to convert them to BIU * */ bool PCB_EDIT_FRAME::ExportVRML_File( const wxString & aFullFileName, double aMMtoWRMLunit, bool aExport3DFiles, const wxString & a3D_Subdir ) { wxString msg; FILE* output_file; BOARD* pcb = GetBoard(); output_file = wxFopen( aFullFileName, wxT( "wt" ) ); if( output_file == NULL ) return false; // Switch the locale to standard C (needed to print floating point numbers like 1.3) SetLocaleTo_C_standard(); // Begin with the usual VRML boilerplate wxString name = aFullFileName; name.Replace(wxT("\\"), wxT("/" ) ); ChangeIllegalCharacters( name, false ); fprintf( output_file, "#VRML V2.0 utf8\n" "WorldInfo {\n" " title \"%s - Generated by Pcbnew\"\n" "}\n", TO_UTF8( name ) ); /* The would be in BIU and not in meters, as the standard wants. * It is trivial to embed everything in a transform node to * fix it. For example here we build the world in inches... */ // Global VRML scale to export to a different scale. // (aMMtoWRMLScale = 1.0 to export in mm) double boardIU2WRML = aMMtoWRMLunit / MM_PER_IU; fprintf( output_file, "Transform {\n" ); /* Define the translation to have the board centre to the 2D axis origin * more easy for rotations... */ EDA_RECT bbbox = pcb->ComputeBoundingBox(); double dx = boardIU2WRML * bbbox.Centre().x; double dy = boardIU2WRML * bbbox.Centre().y; fprintf( output_file, " translation %g %g 0.0\n", -dx, dy ); fprintf( output_file, " children [\n" ); // Preliminary computation: the z value for each layer compute_layer_Zs( pcb ); // Drawing and text on the board, and edges which are special export_vrml_drawings( pcb ); // Export vias and trackage export_vrml_tracks( pcb ); // Export zone fills /* TODO export_vrml_zones(pcb); */ /* scaling factor to convert 3D models to board units (decimils) * Usually we use Wings3D to create thems. * One can consider the 3D units is 0.1 inch (2.54 mm) * So the scaling factor from 0.1 inch to board units * is 2.54 * aMMtoWRMLunit */ double wrml_3D_models_scaling_factor = 2.54 * aMMtoWRMLunit; // Export footprints for( MODULE* module = pcb->m_Modules; module != 0; module = module->Next() ) export_vrml_module( pcb, module, output_file, wrml_3D_models_scaling_factor, aExport3DFiles, a3D_Subdir, boardIU2WRML ); /* Output the bagged triangles for each layer * Each layer will be a separate shape */ for( int layer = 0; layer < LAYER_COUNT; layer++ ) write_and_empty_triangle_bag( output_file, layer_triangles[layer], pcb->GetLayerColor(layer), boardIU2WRML ); // Same thing for the via layers for( int i = 0; i < 4; i++ ) write_and_empty_triangle_bag( output_file, via_triangles[i], pcb->GetVisibleElementColor( VIAS_VISIBLE + i ), boardIU2WRML ); // Close the outer 'transform' node fputs( "]\n}\n", output_file ); // End of work fclose( output_file ); SetLocaleTo_Default(); // revert to the current locale return true; }
/** * Function Export_IDF3 * generates IDFv3 compliant board (*.emn) and library (*.emp) * files representing the user's PCB design. */ bool Export_IDF3( BOARD* aPcb, const wxString& aFullFileName, bool aUseThou, double aXRef, double aYRef ) { IDF3_BOARD idfBoard( IDF3::CAD_ELEC ); SetLocaleTo_C_standard(); bool ok = true; double scale = MM_PER_IU; // we must scale internal units to mm for IDF IDF3::IDF_UNIT idfUnit; if( aUseThou ) { idfUnit = IDF3::UNIT_THOU; idfBoard.SetUserPrecision( 1 ); } else { idfUnit = IDF3::UNIT_MM; idfBoard.SetUserPrecision( 5 ); } wxFileName brdName = aPcb->GetFileName(); idfBoard.SetUserScale( scale ); idfBoard.SetBoardThickness( aPcb->GetDesignSettings().GetBoardThickness() * scale ); idfBoard.SetBoardName( TO_UTF8( brdName.GetFullName() ) ); idfBoard.SetBoardVersion( 0 ); idfBoard.SetLibraryVersion( 0 ); std::ostringstream ostr; ostr << "KiCad " << TO_UTF8( GetBuildVersion() ); idfBoard.SetIDFSource( ostr.str() ); try { // set up the board reference point idfBoard.SetUserOffset( -aXRef, aYRef ); // Export the board outline idf_export_outline( aPcb, idfBoard ); // Output the drill holes and module (library) data. for( MODULE* module = aPcb->m_Modules; module != 0; module = module->Next() ) idf_export_module( aPcb, module, idfBoard ); if( !idfBoard.WriteFile( aFullFileName, idfUnit, false ) ) { wxString msg; msg << _( "IDF Export Failed:\n" ) << FROM_UTF8( idfBoard.GetError().c_str() ); wxMessageBox( msg ); ok = false; } } catch( const IO_ERROR& ioe ) { wxString msg; msg << _( "IDF Export Failed:\n" ) << ioe.errorText; wxMessageBox( msg ); ok = false; } catch( const std::exception& e ) { wxString msg; msg << _( "IDF Export Failed:\n" ) << FROM_UTF8( e.what() ); wxMessageBox( msg ); ok = false; } SetLocaleTo_Default(); return ok; }
/* Read a gerber file, RS274D or RS274X format. */ bool GERBVIEW_FRAME::Read_GERBER_File( const wxString& GERBER_FullFileName, const wxString& D_Code_FullFileName ) { int G_command = 0; // command number for G commands like G04 int D_commande = 0; // command number for D commands like D02 char line[GERBER_BUFZ]; wxString msg; char* text; int layer; // current layer used in GerbView layer = getActiveLayer(); if( g_GERBER_List[layer] == NULL ) { g_GERBER_List[layer] = new GERBER_IMAGE( this, layer ); } GERBER_IMAGE* gerber = g_GERBER_List[layer]; ClearMessageList( ); /* Set the gerber scale: */ gerber->ResetDefaultValues(); /* Read the gerber file */ gerber->m_Current_File = wxFopen( GERBER_FullFileName, wxT( "rt" ) ); if( gerber->m_Current_File == 0 ) { msg.Printf( _( "File <%s> not found" ), GetChars( GERBER_FullFileName ) ); DisplayError( this, msg, 10 ); return false; } gerber->m_FileName = GERBER_FullFileName; wxString path = wxPathOnly( GERBER_FullFileName ); if( path != wxEmptyString ) wxSetWorkingDirectory( path ); SetLocaleTo_C_standard(); while( true ) { if( fgets( line, sizeof(line), gerber->m_Current_File ) == NULL ) { if( gerber->m_FilesPtr == 0 ) break; fclose( gerber->m_Current_File ); gerber->m_FilesPtr--; gerber->m_Current_File = gerber->m_FilesList[gerber->m_FilesPtr]; continue; } text = StrPurge( line ); while( text && *text ) { switch( *text ) { case ' ': case '\r': case '\n': text++; break; case '*': // End command gerber->m_CommandState = END_BLOCK; text++; break; case 'M': // End file gerber->m_CommandState = CMD_IDLE; while( *text ) text++; break; case 'G': /* Line type Gxx : command */ G_command = gerber->GCodeNumber( text ); gerber->Execute_G_Command( text, G_command ); break; case 'D': /* Line type Dxx : Tool selection (xx > 0) or * command if xx = 0..9 */ D_commande = gerber->DCodeNumber( text ); gerber->Execute_DCODE_Command( text, D_commande ); break; case 'X': case 'Y': /* Move or draw command */ gerber->m_CurrentPos = gerber->ReadXYCoord( text ); if( *text == '*' ) // command like X12550Y19250* { gerber->Execute_DCODE_Command( text, gerber->m_Last_Pen_Command ); } break; case 'I': case 'J': /* Auxiliary Move command */ gerber->m_IJPos = gerber->ReadIJCoord( text ); if( *text == '*' ) // command like X35142Y15945J504* { gerber->Execute_DCODE_Command( text, gerber->m_Last_Pen_Command ); } break; case '%': if( gerber->m_CommandState != ENTER_RS274X_CMD ) { gerber->m_CommandState = ENTER_RS274X_CMD; gerber->ReadRS274XCommand( line, text ); } else //Error { ReportMessage( wxT("Expected RS274X Command") ); gerber->m_CommandState = CMD_IDLE; text++; } break; default: text++; msg.Printf( wxT("Unexpected symbol <%c>"), *text ); ReportMessage( msg ); break; } } } fclose( gerber->m_Current_File ); SetLocaleTo_Default(); gerber->m_InUse = true; // Display errors list if( m_Messages.size() > 0 ) { HTML_MESSAGE_BOX dlg( this, _("Errors") ); dlg.ListSet(m_Messages); dlg.ShowModal(); } /* if the gerber file is only a RS274D file * (i.e. without any aperture information), wran the user: */ if( !gerber->m_Has_DCode ) { msg = _("Warning: this file has no D-Code definition\n" "It is perhaps an old RS274D file\n" "Therefore the size of items is undefined"); wxMessageBox( msg ); } return true; }