Example #1
0
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;
}
Example #4
0
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 &lt;%c&gt;" ), *text );
                if( GetParent() )
                    GetParent()->ReportMessage( msg );
            }
                break;
            }   // End switch
        }
    }
    SetLocaleTo_Default();
    return true;
}
Example #5
0
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 );
}
Example #7
0
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 );
        }
    }
}
Example #9
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;
}
Example #10
0
/**
 * 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;
}