readgerb.cpp 6.14 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 * Copyright (C) 2007-2014 Jean-Pierre Charras  jp.charras at wanadoo.fr
 * Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you may find one here:
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * or you may search the http://www.gnu.org website for the version 2 license,
 * or you may write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 */
24

25 26 27 28 29 30
#include <fctsys.h>
#include <common.h>
#include <confirm.h>
#include <kicad_string.h>
#include <gestfich.h>
#include <gerbview.h>
31
#include <gerbview_frame.h>
32 33 34
#include <class_GERBER.h>

#include <html_messagebox.h>
35
#include <macros.h>
36

37
/* Read a gerber file, RS274D, RS274X or RS274X2 format.
38
 */
39
bool GERBVIEW_FRAME::Read_GERBER_File( const wxString& GERBER_FullFileName,
dickelbeck's avatar
dickelbeck committed
40
                                           const wxString& D_Code_FullFileName )
41
{
42
    int      G_command = 0;        // command number for G commands like G04
43
    int      D_commande = 0;       // command number for D commands like D02
dickelbeck's avatar
dickelbeck committed
44

45
    char     line[GERBER_BUFZ];
dickelbeck's avatar
dickelbeck committed
46

47 48
    wxString msg;
    char*    text;
49
    int layer;         // current layer used in GerbView
dickelbeck's avatar
dickelbeck committed
50

51
    layer = getActiveLayer();
52
    GERBER_IMAGE* gerber = g_GERBER_List.GetGbrImage( layer );
dickelbeck's avatar
dickelbeck committed
53

54
    if( gerber == NULL )
dickelbeck's avatar
dickelbeck committed
55
    {
56 57
        gerber = new GERBER_IMAGE( this, layer );
        g_GERBER_List.AddGbrImage( gerber, layer );
dickelbeck's avatar
dickelbeck committed
58 59
    }

60
    ClearMessageList( );
61 62

    /* Set the gerber scale: */
63
    gerber->ResetDefaultValues();
dickelbeck's avatar
dickelbeck committed
64

65
    /* Read the gerber file */
66 67
    gerber->m_Current_File = wxFopen( GERBER_FullFileName, wxT( "rt" ) );
    if( gerber->m_Current_File == 0 )
dickelbeck's avatar
dickelbeck committed
68
    {
69
        msg.Printf( _( "File <%s> not found" ), GetChars( GERBER_FullFileName ) );
70
        DisplayError( this, msg, 10 );
71
        return false;
dickelbeck's avatar
dickelbeck committed
72 73
    }

74
    gerber->m_FileName = GERBER_FullFileName;
dickelbeck's avatar
dickelbeck committed
75

76 77 78
    wxString path = wxPathOnly( GERBER_FullFileName );
    if( path != wxEmptyString )
        wxSetWorkingDirectory( path );
dickelbeck's avatar
dickelbeck committed
79

80
    LOCALE_IO toggleIo;
dickelbeck's avatar
dickelbeck committed
81

82
    while( true )
dickelbeck's avatar
dickelbeck committed
83
    {
84
        if( fgets( line, sizeof(line), gerber->m_Current_File ) == NULL )
dickelbeck's avatar
dickelbeck committed
85
        {
86
            if( gerber->m_FilesPtr == 0 )
dickelbeck's avatar
dickelbeck committed
87
                break;
88

89
            fclose( gerber->m_Current_File );
90

91 92 93
            gerber->m_FilesPtr--;
            gerber->m_Current_File =
                gerber->m_FilesList[gerber->m_FilesPtr];
94

dickelbeck's avatar
dickelbeck committed
95 96
            continue;
        }
97

98
        text = StrPurge( line );
dickelbeck's avatar
dickelbeck committed
99 100 101 102 103 104 105 106 107 108 109

        while( text && *text )
        {
            switch( *text )
            {
            case ' ':
            case '\r':
            case '\n':
                text++;
                break;

110
            case '*':       // End command
111
                gerber->m_CommandState = END_BLOCK;
dickelbeck's avatar
dickelbeck committed
112 113 114 115
                text++;
                break;

            case 'M':       // End file
116
                gerber->m_CommandState = CMD_IDLE;
dickelbeck's avatar
dickelbeck committed
117 118 119 120
                while( *text )
                    text++;
                break;

121
            case 'G':    /* Line type Gxx : command */
122
                G_command = gerber->GCodeNumber( text );
123
                gerber->Execute_G_Command( text, G_command );
dickelbeck's avatar
dickelbeck committed
124 125
                break;

126 127
            case 'D':       /* Line type Dxx : Tool selection (xx > 0) or
                             * command if xx = 0..9 */
128
                D_commande = gerber->DCodeNumber( text );
129
                gerber->Execute_DCODE_Command( text, D_commande );
dickelbeck's avatar
dickelbeck committed
130 131 132
                break;

            case 'X':
133
            case 'Y':                   /* Move or draw command */
134
                gerber->m_CurrentPos = gerber->ReadXYCoord( text );
dickelbeck's avatar
dickelbeck committed
135 136
                if( *text == '*' )      // command like X12550Y19250*
                {
137
                    gerber->Execute_DCODE_Command( text,
138
                                                   gerber->m_Last_Pen_Command );
dickelbeck's avatar
dickelbeck committed
139 140 141 142
                }
                break;

            case 'I':
143
            case 'J':       /* Auxiliary Move command */
144 145 146
                gerber->m_IJPos = gerber->ReadIJCoord( text );
                if( *text == '*' )      // command like X35142Y15945J504*
                {
147
                    gerber->Execute_DCODE_Command( text,
148 149
                                                   gerber->m_Last_Pen_Command );
                }
dickelbeck's avatar
dickelbeck committed
150 151 152
                break;

            case '%':
153
                if( gerber->m_CommandState != ENTER_RS274X_CMD )
dickelbeck's avatar
dickelbeck committed
154
                {
155
                    gerber->m_CommandState = ENTER_RS274X_CMD;
156
                    gerber->ReadRS274XCommand( line, text );
dickelbeck's avatar
dickelbeck committed
157 158 159
                }
                else        //Error
                {
160
                    ReportMessage( wxT("Expected RS274X Command")  );
161
                    gerber->m_CommandState = CMD_IDLE;
dickelbeck's avatar
dickelbeck committed
162 163 164 165 166
                    text++;
                }
                break;

            default:
167
                text++;
168 169
                msg.Printf( wxT("Unexpected symbol <%c>"), *text );
                ReportMessage( msg );
dickelbeck's avatar
dickelbeck committed
170 171 172 173
                break;
            }
        }
    }
174

175
    fclose( gerber->m_Current_File );
dickelbeck's avatar
dickelbeck committed
176

177 178
    gerber->m_InUse = true;

179 180
    // Display errors list
    if( m_Messages.size() > 0 )
dickelbeck's avatar
dickelbeck committed
181
    {
182
        HTML_MESSAGE_BOX dlg( this, _("Errors") );
183 184
        dlg.ListSet(m_Messages);
        dlg.ShowModal();
dickelbeck's avatar
dickelbeck committed
185 186
    }

187 188
    /* if the gerber file is only a RS274D file
     * (i.e. without any aperture information), wran the user:
189
     */
190
    if( !gerber->m_Has_DCode )
dickelbeck's avatar
dickelbeck committed
191
    {
192 193 194 195
        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 );
dickelbeck's avatar
dickelbeck committed
196 197
    }

198
    return true;
199
}